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

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

Issue 2435823002: [V8][asm.js] Adds support to global const variables. (Closed)
Patch Set: Addresses comments. Created 4 years, 2 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 744 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 if (target_info != nullptr) { 755 if (target_info != nullptr) {
756 FAIL(target, "Redefined global variable."); 756 FAIL(target, "Redefined global variable.");
757 } 757 }
758 758
759 auto* value = assign->value(); 759 auto* value = assign->value();
760 // Not all types of assignment are allowed by asm.js. See 760 // Not all types of assignment are allowed by asm.js. See
761 // 5.5 Global Variable Type Annotations. 761 // 5.5 Global Variable Type Annotations.
762 bool global_variable = false; 762 bool global_variable = false;
763 if (value->IsLiteral() || value->IsCall()) { 763 if (value->IsLiteral() || value->IsCall()) {
764 AsmType* type = nullptr; 764 AsmType* type = nullptr;
765 RECURSE(type = VariableTypeAnnotations(value, true)); 765 VariableInfo::Mutability mutability;
766 if (target_variable->mode() == CONST) {
767 mutability = VariableInfo::kConstGlobal;
768 } else {
769 mutability = VariableInfo::kMutableGlobal;
770 }
771 RECURSE(type = VariableTypeAnnotations(value, mutability));
766 target_info = new (zone_) VariableInfo(type); 772 target_info = new (zone_) VariableInfo(type);
767 target_info->set_mutability(VariableInfo::kMutableGlobal); 773 target_info->set_mutability(mutability);
768 global_variable = true; 774 global_variable = true;
769 } else if (value->IsProperty()) { 775 } else if (value->IsProperty()) {
770 target_info = ImportLookup(value->AsProperty()); 776 target_info = ImportLookup(value->AsProperty());
771 if (target_info == nullptr) { 777 if (target_info == nullptr) {
772 FAIL(assign, "Invalid import."); 778 FAIL(assign, "Invalid import.");
773 } 779 }
774 CHECK(target_info->mutability() == VariableInfo::kImmutableGlobal); 780 CHECK(target_info->mutability() == VariableInfo::kImmutableGlobal);
775 if (target_info->IsFFI()) { 781 if (target_info->IsFFI()) {
776 // create a new target info that represents a foreign variable. 782 // create a new target info that represents a foreign variable.
777 target_info = new (zone_) VariableInfo(ffi_type_); 783 target_info = new (zone_) VariableInfo(ffi_type_);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 } 827 }
822 828
823 // Create a new target info that represents the foreign import. 829 // Create a new target info that represents the foreign import.
824 target_info = new (zone_) VariableInfo(import_type); 830 target_info = new (zone_) VariableInfo(import_type);
825 target_info->set_mutability(VariableInfo::kMutableGlobal); 831 target_info->set_mutability(VariableInfo::kMutableGlobal);
826 } else if (value->IsCallNew()) { 832 } else if (value->IsCallNew()) {
827 AsmType* type = nullptr; 833 AsmType* type = nullptr;
828 RECURSE(type = NewHeapView(value->AsCallNew())); 834 RECURSE(type = NewHeapView(value->AsCallNew()));
829 target_info = new (zone_) VariableInfo(type); 835 target_info = new (zone_) VariableInfo(type);
830 target_info->set_mutability(VariableInfo::kImmutableGlobal); 836 target_info->set_mutability(VariableInfo::kImmutableGlobal);
837 } else if (auto* proxy = value->AsVariableProxy()) {
838 auto* var_info = Lookup(proxy->var());
839
840 if (var_info == nullptr) {
841 FAIL(value, "Undeclared identifier in global initializer");
842 }
843
844 if (var_info->mutability() != VariableInfo::kConstGlobal) {
845 FAIL(value, "Identifier used to initialize a global must be a const");
846 }
847
848 target_info = new (zone_) VariableInfo(var_info->type());
849 if (target_variable->mode() == CONST) {
850 target_info->set_mutability(VariableInfo::kConstGlobal);
851 } else {
852 target_info->set_mutability(VariableInfo::kMutableGlobal);
853 }
831 } 854 }
832 855
833 if (target_info == nullptr) { 856 if (target_info == nullptr) {
834 FAIL(assign, "Invalid global variable initializer."); 857 FAIL(assign, "Invalid global variable initializer.");
835 } 858 }
836 859
837 if (!ValidAsmIdentifier(target_variable->name())) { 860 if (!ValidAsmIdentifier(target_variable->name())) {
838 FAIL(target, "Invalid asm.js identifier in global variable."); 861 FAIL(target, "Invalid asm.js identifier in global variable.");
839 } 862 }
840 863
(...skipping 1836 matching lines...) Expand 10 before | Expand all | Expand 10 after
2677 // return; 2700 // return;
2678 // 2701 //
2679 // into 2702 // into
2680 // 2703 //
2681 // return undefined 2704 // return undefined
2682 return AsmType::Void(); 2705 return AsmType::Void();
2683 } 2706 }
2684 FAIL(statement, "Invalid literal in return statement."); 2707 FAIL(statement, "Invalid literal in return statement.");
2685 } 2708 }
2686 2709
2710 if (auto* proxy = ret_expr->AsVariableProxy()) {
2711 auto* var_info = Lookup(proxy->var());
2712
2713 if (var_info == nullptr) {
2714 FAIL(statement, "Undeclared identifier in return statement.");
2715 }
2716
2717 if (var_info->mutability() != VariableInfo::kConstGlobal) {
2718 FAIL(statement, "Identifier in return statement is not const.");
2719 }
2720
2721 return var_info->type();
2722 }
2723
2687 FAIL(statement, "Invalid return type expression."); 2724 FAIL(statement, "Invalid return type expression.");
2688 } 2725 }
2689 2726
2690 // 5.4 VariableTypeAnnotations 2727 // 5.4 VariableTypeAnnotations
2691 // Also used for 5.5 GlobalVariableTypeAnnotations 2728 // Also used for 5.5 GlobalVariableTypeAnnotations
2692 AsmType* AsmTyper::VariableTypeAnnotations(Expression* initializer, 2729 AsmType* AsmTyper::VariableTypeAnnotations(
2693 bool global) { 2730 Expression* initializer, VariableInfo::Mutability mutability_type) {
2694 if (auto* literal = initializer->AsLiteral()) { 2731 if (auto* literal = initializer->AsLiteral()) {
2695 if (literal->raw_value()->ContainsDot()) { 2732 if (literal->raw_value()->ContainsDot()) {
2696 SetTypeOf(initializer, AsmType::Double()); 2733 SetTypeOf(initializer, AsmType::Double());
2697 return AsmType::Double(); 2734 return AsmType::Double();
2698 } 2735 }
2699 int32_t i32; 2736 int32_t i32;
2700 uint32_t u32; 2737 uint32_t u32;
2738
2739 AsmType* initializer_type = nullptr;
2701 if (literal->value()->ToUint32(&u32)) { 2740 if (literal->value()->ToUint32(&u32)) {
2702 if (u32 > LargestFixNum) { 2741 if (u32 > LargestFixNum) {
2703 SetTypeOf(initializer, AsmType::Unsigned()); 2742 initializer_type = AsmType::Unsigned();
2743 SetTypeOf(initializer, initializer_type);
2704 } else { 2744 } else {
2705 SetTypeOf(initializer, AsmType::FixNum()); 2745 initializer_type = AsmType::FixNum();
2746 SetTypeOf(initializer, initializer_type);
2747 initializer_type = AsmType::Signed();
2706 } 2748 }
2707 } else if (literal->value()->ToInt32(&i32)) { 2749 } else if (literal->value()->ToInt32(&i32)) {
2708 SetTypeOf(initializer, AsmType::Signed()); 2750 initializer_type = AsmType::Signed();
2751 SetTypeOf(initializer, initializer_type);
2709 } else { 2752 } else {
2710 FAIL(initializer, "Invalid type annotation - forbidden literal."); 2753 FAIL(initializer, "Invalid type annotation - forbidden literal.");
2711 } 2754 }
2712 return AsmType::Int(); 2755 if (mutability_type != VariableInfo::kConstGlobal) {
2756 return AsmType::Int();
2757 }
2758 return initializer_type;
2759 }
2760
2761 if (auto* proxy = initializer->AsVariableProxy()) {
2762 auto* var_info = Lookup(proxy->var());
2763
2764 if (var_info == nullptr) {
2765 FAIL(initializer,
2766 "Undeclared identifier in variable declaration initializer.");
2767 }
2768
2769 if (var_info->mutability() != VariableInfo::kConstGlobal) {
2770 FAIL(initializer,
2771 "Identifier in variable declaration initializer must be const.");
2772 }
2773
2774 SetTypeOf(initializer, var_info->type());
2775 return var_info->type();
2713 } 2776 }
2714 2777
2715 auto* call = initializer->AsCall(); 2778 auto* call = initializer->AsCall();
2716 if (call == nullptr) { 2779 if (call == nullptr) {
2717 FAIL(initializer, 2780 FAIL(initializer,
2718 "Invalid variable initialization - it should be a literal, or " 2781 "Invalid variable initialization - it should be a literal, const, or "
2719 "fround(literal)."); 2782 "fround(literal).");
2720 } 2783 }
2721 2784
2722 if (!IsCallToFround(call)) { 2785 if (!IsCallToFround(call)) {
2723 FAIL(initializer, 2786 FAIL(initializer,
2724 "Invalid float coercion - expected call fround(literal)."); 2787 "Invalid float coercion - expected call fround(literal).");
2725 } 2788 }
2726 2789
2727 auto* src_expr = call->arguments()->at(0)->AsLiteral(); 2790 auto* src_expr = call->arguments()->at(0)->AsLiteral();
2728 if (src_expr == nullptr) { 2791 if (src_expr == nullptr) {
2729 FAIL(initializer, 2792 FAIL(initializer,
2730 "Invalid float type annotation - expected literal argument for call " 2793 "Invalid float type annotation - expected literal argument for call "
2731 "to fround."); 2794 "to fround.");
2732 } 2795 }
2733 2796
2734 // Float constants must contain dots in local, but not in globals. 2797 // Float constants must contain dots in local, but not in globals.
2735 if (!global) { 2798 if (mutability_type == VariableInfo::kLocal) {
2736 if (!src_expr->raw_value()->ContainsDot()) { 2799 if (!src_expr->raw_value()->ContainsDot()) {
2737 FAIL(initializer, 2800 FAIL(initializer,
2738 "Invalid float type annotation - expected literal argument to be a " 2801 "Invalid float type annotation - expected literal argument to be a "
2739 "floating point literal."); 2802 "floating point literal.");
2740 } 2803 }
2741 } 2804 }
2742 2805
2743 return AsmType::Float(); 2806 return AsmType::Float();
2744 } 2807 }
2745 2808
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2795 return true; 2858 return true;
2796 } 2859 }
2797 2860
2798 *error_message = typer.error_message(); 2861 *error_message = typer.error_message();
2799 return false; 2862 return false;
2800 } 2863 }
2801 2864
2802 } // namespace wasm 2865 } // namespace wasm
2803 } // namespace internal 2866 } // namespace internal
2804 } // namespace v8 2867 } // 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