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

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

Issue 2398023002: [wasm] asm.js - Parse and convert asm.js to wasm a function at a time. (Closed)
Patch Set: clear function node each time 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
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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 context_stack_.emplace_back( 84 context_stack_.emplace_back(
85 Context(current_statement->AsBlock()->statements())); 85 Context(current_statement->AsBlock()->statements()));
86 continue; 86 continue;
87 } 87 }
88 88
89 return current_statement; 89 return current_statement;
90 } 90 }
91 } 91 }
92 92
93 // ---------------------------------------------------------------------------- 93 // ----------------------------------------------------------------------------
94 // Implementation of AsmTyper::SourceLayoutTracker
95
96 bool AsmTyper::SourceLayoutTracker::IsValid() const {
97 const Section* kAllSections[] = {&use_asm_, &globals_, &functions_, &tables_,
98 &exports_};
99 for (size_t ii = 0; ii < arraysize(kAllSections); ++ii) {
100 const auto& curr_section = *kAllSections[ii];
101 for (size_t jj = ii + 1; jj < arraysize(kAllSections); ++jj) {
102 if (curr_section.OverlapsWith(*kAllSections[jj])) {
103 return false;
104 }
105 }
106 }
107 return true;
108 }
109
110 void AsmTyper::SourceLayoutTracker::Section::AddNewElement(
111 const AstNode& node) {
112 const int node_pos = node.position();
113 if (start_ == kNoSourcePosition) {
114 start_ = node_pos;
115 } else {
116 start_ = std::max(start_, node_pos);
117 }
118 if (end_ == kNoSourcePosition) {
119 end_ = node_pos;
120 } else {
121 end_ = std::max(end_, node_pos);
122 }
123 }
124
125 bool AsmTyper::SourceLayoutTracker::Section::OverlapsWith(
126 const Section& other) const {
127 if (start_ == kNoSourcePosition) {
128 DCHECK_EQ(end_, kNoSourcePosition);
129 return false;
130 }
131 if (other.start_ == kNoSourcePosition) {
132 DCHECK_EQ(other.end_, kNoSourcePosition);
133 return false;
134 }
135 return other.start_ < end_ || other.end_ < start_;
136 }
137
138 // ----------------------------------------------------------------------------
94 // Implementation of AsmTyper::VariableInfo 139 // Implementation of AsmTyper::VariableInfo
95 140
96 AsmTyper::VariableInfo* AsmTyper::VariableInfo::ForSpecialSymbol( 141 AsmTyper::VariableInfo* AsmTyper::VariableInfo::ForSpecialSymbol(
97 Zone* zone, StandardMember standard_member) { 142 Zone* zone, StandardMember standard_member) {
98 DCHECK(standard_member == kStdlib || standard_member == kFFI || 143 DCHECK(standard_member == kStdlib || standard_member == kFFI ||
99 standard_member == kHeap || standard_member == kModule); 144 standard_member == kHeap || standard_member == kModule);
100 auto* new_var_info = new (zone) VariableInfo(AsmType::None()); 145 auto* new_var_info = new (zone) VariableInfo(AsmType::None());
101 new_var_info->standard_member_ = standard_member; 146 new_var_info->standard_member_ = standard_member;
102 new_var_info->mutability_ = kImmutableGlobal; 147 new_var_info->mutability_ = kImmutableGlobal;
103 return new_var_info; 148 return new_var_info;
(...skipping 26 matching lines...) Expand all
130 forward_definitions_(zone), 175 forward_definitions_(zone),
131 ffi_use_signatures_(zone), 176 ffi_use_signatures_(zone),
132 stdlib_types_(zone), 177 stdlib_types_(zone),
133 stdlib_math_types_(zone), 178 stdlib_math_types_(zone),
134 module_info_(VariableInfo::ForSpecialSymbol(zone_, kModule)), 179 module_info_(VariableInfo::ForSpecialSymbol(zone_, kModule)),
135 global_scope_(ZoneHashMap::kDefaultHashMapCapacity, 180 global_scope_(ZoneHashMap::kDefaultHashMapCapacity,
136 ZoneAllocationPolicy(zone)), 181 ZoneAllocationPolicy(zone)),
137 local_scope_(ZoneHashMap::kDefaultHashMapCapacity, 182 local_scope_(ZoneHashMap::kDefaultHashMapCapacity,
138 ZoneAllocationPolicy(zone)), 183 ZoneAllocationPolicy(zone)),
139 stack_limit_(isolate->stack_guard()->real_climit()), 184 stack_limit_(isolate->stack_guard()->real_climit()),
140 node_types_(zone_), 185 module_node_types_(zone_),
186 function_node_types_(zone_),
141 fround_type_(AsmType::FroundType(zone_)), 187 fround_type_(AsmType::FroundType(zone_)),
142 ffi_type_(AsmType::FFIType(zone_)) { 188 ffi_type_(AsmType::FFIType(zone_)),
189 function_pointer_tables_(zone_) {
143 InitializeStdlib(); 190 InitializeStdlib();
144 } 191 }
145 192
146 namespace { 193 namespace {
147 bool ValidAsmIdentifier(Handle<String> name) { 194 bool ValidAsmIdentifier(Handle<String> name) {
148 static const char* kInvalidAsmNames[] = {"eval", "arguments"}; 195 static const char* kInvalidAsmNames[] = {"eval", "arguments"};
149 196
150 for (size_t ii = 0; ii < arraysize(kInvalidAsmNames); ++ii) { 197 for (size_t ii = 0; ii < arraysize(kInvalidAsmNames); ++ii) {
151 if (strcmp(name->ToCString().get(), kInvalidAsmNames[ii]) == 0) { 198 if (strcmp(name->ToCString().get(), kInvalidAsmNames[ii]) == 0) {
152 return false; 199 return false;
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 if (entry->value != nullptr) { 430 if (entry->value != nullptr) {
384 return false; 431 return false;
385 } 432 }
386 433
387 entry->value = info; 434 entry->value = info;
388 return true; 435 return true;
389 } 436 }
390 437
391 void AsmTyper::SetTypeOf(AstNode* node, AsmType* type) { 438 void AsmTyper::SetTypeOf(AstNode* node, AsmType* type) {
392 DCHECK_NE(type, AsmType::None()); 439 DCHECK_NE(type, AsmType::None());
393 DCHECK(node_types_.find(node) == node_types_.end()); 440 if (in_function_) {
394 node_types_.insert(std::make_pair(node, type)); 441 DCHECK(function_node_types_.find(node) == function_node_types_.end());
442 function_node_types_.insert(std::make_pair(node, type));
443 } else {
444 DCHECK(module_node_types_.find(node) == module_node_types_.end());
445 module_node_types_.insert(std::make_pair(node, type));
446 }
395 } 447 }
396 448
397 AsmType* AsmTyper::TypeOf(AstNode* node) const { 449 AsmType* AsmTyper::TypeOf(AstNode* node) const {
398 auto node_type_iter = node_types_.find(node); 450 auto node_type_iter = function_node_types_.find(node);
399 if (node_type_iter != node_types_.end()) { 451 if (node_type_iter != function_node_types_.end()) {
452 return node_type_iter->second;
453 }
454 node_type_iter = module_node_types_.find(node);
455 if (node_type_iter != module_node_types_.end()) {
400 return node_type_iter->second; 456 return node_type_iter->second;
401 } 457 }
402 458
403 // Sometimes literal nodes are not added to the node_type_ map simply because 459 // Sometimes literal nodes are not added to the node_type_ map simply because
404 // their are not visited with ValidateExpression(). 460 // their are not visited with ValidateExpression().
405 if (auto* literal = node->AsLiteral()) { 461 if (auto* literal = node->AsLiteral()) {
406 if (literal->raw_value()->ContainsDot()) { 462 if (literal->raw_value()->ContainsDot()) {
407 return AsmType::Double(); 463 return AsmType::Double();
408 } 464 }
409 uint32_t u; 465 uint32_t u;
(...skipping 17 matching lines...) Expand all
427 AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(Variable* var) { 483 AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(Variable* var) {
428 auto* var_info = Lookup(var); 484 auto* var_info = Lookup(var);
429 if (var_info == nullptr) { 485 if (var_info == nullptr) {
430 return kNone; 486 return kNone;
431 } 487 }
432 StandardMember member = var_info->standard_member(); 488 StandardMember member = var_info->standard_member();
433 return member; 489 return member;
434 } 490 }
435 491
436 bool AsmTyper::Validate() { 492 bool AsmTyper::Validate() {
437 if (!AsmType::None()->IsExactly(ValidateModule(root_))) { 493 return ValidateBeforeFunctionsPhase() &&
494 !AsmType::None()->IsExactly(ValidateModuleFunctions(root_)) &&
495 ValidateAfterFunctionsPhase();
496 }
497
498 bool AsmTyper::ValidateBeforeFunctionsPhase() {
499 if (!AsmType::None()->IsExactly(ValidateModuleBeforeFunctionsPhase(root_))) {
438 return true; 500 return true;
439 } 501 }
440 return false; 502 return false;
441 } 503 }
442 504
505 bool AsmTyper::ValidateInnerFunction(FunctionDeclaration* fun_decl) {
506 if (!AsmType::None()->IsExactly(ValidateModuleFunction(fun_decl))) {
507 return true;
508 }
509 return false;
510 }
511
512 bool AsmTyper::ValidateAfterFunctionsPhase() {
513 if (!AsmType::None()->IsExactly(ValidateModuleAfterFunctionsPhase(root_))) {
514 return true;
515 }
516 return false;
517 }
518
519 void AsmTyper::ClearFunctionNodeTypes() { function_node_types_.clear(); }
520
443 namespace { 521 namespace {
444 bool IsUseAsmDirective(Statement* first_statement) { 522 bool IsUseAsmDirective(Statement* first_statement) {
445 ExpressionStatement* use_asm = first_statement->AsExpressionStatement(); 523 ExpressionStatement* use_asm = first_statement->AsExpressionStatement();
446 if (use_asm == nullptr) { 524 if (use_asm == nullptr) {
447 return false; 525 return false;
448 } 526 }
449 527
450 Literal* use_asm_literal = use_asm->expression()->AsLiteral(); 528 Literal* use_asm_literal = use_asm->expression()->AsLiteral();
451 529
452 if (use_asm_literal == nullptr) { 530 if (use_asm_literal == nullptr) {
(...skipping 17 matching lines...) Expand all
470 if (assign->op() != Token::INIT) { 548 if (assign->op() != Token::INIT) {
471 // Done with initializers. 549 // Done with initializers.
472 return nullptr; 550 return nullptr;
473 } 551 }
474 return assign; 552 return assign;
475 } 553 }
476 554
477 } // namespace 555 } // namespace
478 556
479 // 6.1 ValidateModule 557 // 6.1 ValidateModule
480 namespace { 558 AsmType* AsmTyper::ValidateModuleBeforeFunctionsPhase(FunctionLiteral* fun) {
481 // SourceLayoutTracker keeps track of the start and end positions of each
482 // section in the asm.js source. The sections should not overlap, otherwise the
483 // asm.js source is invalid.
484 class SourceLayoutTracker {
485 public:
486 SourceLayoutTracker() = default;
487
488 bool IsValid() const {
489 const Section* kAllSections[] = {&use_asm_, &globals_, &functions_,
490 &tables_, &exports_};
491 for (size_t ii = 0; ii < arraysize(kAllSections); ++ii) {
492 const auto& curr_section = *kAllSections[ii];
493 for (size_t jj = ii + 1; jj < arraysize(kAllSections); ++jj) {
494 if (curr_section.OverlapsWith(*kAllSections[jj])) {
495 return false;
496 }
497 }
498 }
499 return true;
500 }
501
502 void AddUseAsm(const AstNode& node) { use_asm_.AddNewElement(node); }
503
504 void AddGlobal(const AstNode& node) { globals_.AddNewElement(node); }
505
506 void AddFunction(const AstNode& node) { functions_.AddNewElement(node); }
507
508 void AddTable(const AstNode& node) { tables_.AddNewElement(node); }
509
510 void AddExport(const AstNode& node) { exports_.AddNewElement(node); }
511
512 private:
513 class Section {
514 public:
515 Section() = default;
516 Section(const Section&) = default;
517 Section& operator=(const Section&) = default;
518
519 void AddNewElement(const AstNode& node) {
520 const int node_pos = node.position();
521 if (start_ == kNoSourcePosition) {
522 start_ = node_pos;
523 } else {
524 start_ = std::max(start_, node_pos);
525 }
526 if (end_ == kNoSourcePosition) {
527 end_ = node_pos;
528 } else {
529 end_ = std::max(end_, node_pos);
530 }
531 }
532
533 bool OverlapsWith(const Section& other) const {
534 if (start_ == kNoSourcePosition) {
535 DCHECK_EQ(end_, kNoSourcePosition);
536 return false;
537 }
538 if (other.start_ == kNoSourcePosition) {
539 DCHECK_EQ(other.end_, kNoSourcePosition);
540 return false;
541 }
542 return other.start_ < end_ || other.end_ < start_;
543 }
544
545 private:
546 int start_ = kNoSourcePosition;
547 int end_ = kNoSourcePosition;
548 };
549
550 Section use_asm_;
551 Section globals_;
552 Section functions_;
553 Section tables_;
554 Section exports_;
555
556 DISALLOW_COPY_AND_ASSIGN(SourceLayoutTracker);
557 };
558 } // namespace
559
560 AsmType* AsmTyper::ValidateModule(FunctionLiteral* fun) {
561 SourceLayoutTracker source_layout;
562
563 DeclarationScope* scope = fun->scope(); 559 DeclarationScope* scope = fun->scope();
564 if (!scope->is_function_scope()) FAIL(fun, "Not at function scope."); 560 if (!scope->is_function_scope()) FAIL(fun, "Not at function scope.");
565 if (!ValidAsmIdentifier(fun->name())) 561 if (!ValidAsmIdentifier(fun->name()))
566 FAIL(fun, "Invalid asm.js identifier in module name."); 562 FAIL(fun, "Invalid asm.js identifier in module name.");
567 module_name_ = fun->name(); 563 module_name_ = fun->name();
568 564
569 // Allowed parameters: Stdlib, FFI, Mem 565 // Allowed parameters: Stdlib, FFI, Mem
570 static const int MaxModuleParameters = 3; 566 static const int MaxModuleParameters = 3;
571 if (scope->num_parameters() > MaxModuleParameters) { 567 if (scope->num_parameters() > MaxModuleParameters) {
572 FAIL(fun, "asm.js modules may not have more than three parameters."); 568 FAIL(fun, "asm.js modules may not have more than three parameters.");
(...skipping 14 matching lines...) Expand all
587 } 583 }
588 584
589 auto* param_info = VariableInfo::ForSpecialSymbol( 585 auto* param_info = VariableInfo::ForSpecialSymbol(
590 zone_, kModuleParamInfo[ii].standard_member); 586 zone_, kModuleParamInfo[ii].standard_member);
591 587
592 if (!AddGlobal(param, param_info)) { 588 if (!AddGlobal(param, param_info)) {
593 FAIL(fun, "Redeclared identifier in module parameter."); 589 FAIL(fun, "Redeclared identifier in module parameter.");
594 } 590 }
595 } 591 }
596 592
597 ZoneVector<Assignment*> function_pointer_tables(zone_);
598 FlattenedStatements iter(zone_, fun->body()); 593 FlattenedStatements iter(zone_, fun->body());
599 auto* use_asm_directive = iter.Next(); 594 auto* use_asm_directive = iter.Next();
600 if (use_asm_directive == nullptr) { 595 if (use_asm_directive == nullptr) {
601 FAIL(fun, "Missing \"use asm\"."); 596 FAIL(fun, "Missing \"use asm\".");
602 } 597 }
603 // Check for extra assignment inserted by the parser when in this form: 598 // Check for extra assignment inserted by the parser when in this form:
604 // (function Module(a, b, c) {... }) 599 // (function Module(a, b, c) {... })
605 ExpressionStatement* estatement = use_asm_directive->AsExpressionStatement(); 600 ExpressionStatement* estatement = use_asm_directive->AsExpressionStatement();
606 if (estatement != nullptr) { 601 if (estatement != nullptr) {
607 Assignment* assignment = estatement->expression()->AsAssignment(); 602 Assignment* assignment = estatement->expression()->AsAssignment();
608 if (assignment != nullptr && assignment->target()->IsVariableProxy() && 603 if (assignment != nullptr && assignment->target()->IsVariableProxy() &&
609 assignment->target() 604 assignment->target()
610 ->AsVariableProxy() 605 ->AsVariableProxy()
611 ->var() 606 ->var()
612 ->is_sloppy_function_name()) { 607 ->is_sloppy_function_name()) {
613 use_asm_directive = iter.Next(); 608 use_asm_directive = iter.Next();
614 } 609 }
615 } 610 }
616 if (!IsUseAsmDirective(use_asm_directive)) { 611 if (!IsUseAsmDirective(use_asm_directive)) {
617 FAIL(fun, "Missing \"use asm\"."); 612 FAIL(fun, "Missing \"use asm\".");
618 } 613 }
619 source_layout.AddUseAsm(*use_asm_directive); 614 source_layout_.AddUseAsm(*use_asm_directive);
620 ReturnStatement* module_return = nullptr; 615 module_return_ = nullptr;
621 616
622 // *VIOLATION* The spec states that globals should be followed by function 617 // *VIOLATION* The spec states that globals should be followed by function
623 // declarations, which should be followed by function pointer tables, followed 618 // declarations, which should be followed by function pointer tables, followed
624 // by the module export (return) statement. Our AST might be rearraged by the 619 // by the module export (return) statement. Our AST might be rearraged by the
625 // parser, so we can't rely on it being in source code order. 620 // parser, so we can't rely on it being in source code order.
626 while (Statement* current = iter.Next()) { 621 while (Statement* current = iter.Next()) {
627 if (auto* assign = ExtractInitializerExpression(current)) { 622 if (auto* assign = ExtractInitializerExpression(current)) {
628 if (assign->value()->IsArrayLiteral()) { 623 if (assign->value()->IsArrayLiteral()) {
629 // Save function tables for later validation. 624 // Save function tables for later validation.
630 function_pointer_tables.push_back(assign); 625 function_pointer_tables_.push_back(assign);
631 } else { 626 } else {
632 RECURSE(ValidateGlobalDeclaration(assign)); 627 RECURSE(ValidateGlobalDeclaration(assign));
633 source_layout.AddGlobal(*assign); 628 source_layout_.AddGlobal(*assign);
634 } 629 }
635 continue; 630 continue;
636 } 631 }
637 632
638 if (auto* current_as_return = current->AsReturnStatement()) { 633 if (auto* current_as_return = current->AsReturnStatement()) {
639 if (module_return != nullptr) { 634 if (module_return_ != nullptr) {
640 FAIL(fun, "Multiple export statements."); 635 FAIL(fun, "Multiple export statements.");
641 } 636 }
642 module_return = current_as_return; 637 module_return_ = current_as_return;
643 source_layout.AddExport(*module_return); 638 source_layout_.AddExport(*module_return_);
644 continue; 639 continue;
645 } 640 }
646 641
647 FAIL(current, "Invalid top-level statement in asm.js module."); 642 FAIL(current, "Invalid top-level statement in asm.js module.");
648 } 643 }
649 644
645 return AsmType::Int(); // Any type that is not AsmType::None();
646 }
647
648 AsmType* AsmTyper::ValidateModuleFunction(FunctionDeclaration* fun_decl) {
649 RECURSE(ValidateFunction(fun_decl));
650 source_layout_.AddFunction(*fun_decl);
651
652 return AsmType::Int(); // Any type that is not AsmType::None();
653 }
654
655 AsmType* AsmTyper::ValidateModuleFunctions(FunctionLiteral* fun) {
656 DeclarationScope* scope = fun->scope();
650 Declaration::List* decls = scope->declarations(); 657 Declaration::List* decls = scope->declarations();
651 for (Declaration* decl : *decls) { 658 for (Declaration* decl : *decls) {
652 if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) { 659 if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) {
653 RECURSE(ValidateFunction(fun_decl)); 660 RECURSE(ValidateModuleFunction(fun_decl));
654 source_layout.AddFunction(*fun_decl);
655 continue; 661 continue;
656 } 662 }
657 } 663 }
658 664
659 for (auto* function_table : function_pointer_tables) { 665 return AsmType::Int(); // Any type that is not AsmType::None();
666 }
667
668 AsmType* AsmTyper::ValidateModuleAfterFunctionsPhase(FunctionLiteral* fun) {
669 for (auto* function_table : function_pointer_tables_) {
660 RECURSE(ValidateFunctionTable(function_table)); 670 RECURSE(ValidateFunctionTable(function_table));
661 source_layout.AddTable(*function_table); 671 source_layout_.AddTable(*function_table);
662 } 672 }
663 673
674 DeclarationScope* scope = fun->scope();
675 Declaration::List* decls = scope->declarations();
664 for (Declaration* decl : *decls) { 676 for (Declaration* decl : *decls) {
665 if (decl->IsFunctionDeclaration()) { 677 if (decl->IsFunctionDeclaration()) {
666 continue; 678 continue;
667 } 679 }
668 680
669 VariableDeclaration* var_decl = decl->AsVariableDeclaration(); 681 VariableDeclaration* var_decl = decl->AsVariableDeclaration();
670 if (var_decl == nullptr) { 682 if (var_decl == nullptr) {
671 FAIL(decl, "Invalid asm.js declaration."); 683 FAIL(decl, "Invalid asm.js declaration.");
672 } 684 }
673 685
674 auto* var_proxy = var_decl->proxy(); 686 auto* var_proxy = var_decl->proxy();
675 if (var_proxy == nullptr) { 687 if (var_proxy == nullptr) {
676 FAIL(decl, "Invalid asm.js declaration."); 688 FAIL(decl, "Invalid asm.js declaration.");
677 } 689 }
678 690
679 if (Lookup(var_proxy->var()) == nullptr) { 691 if (Lookup(var_proxy->var()) == nullptr) {
680 FAIL(decl, "Global variable missing initializer in asm.js module."); 692 FAIL(decl, "Global variable missing initializer in asm.js module.");
681 } 693 }
682 } 694 }
683 695
684 // 6.2 ValidateExport 696 // 6.2 ValidateExport
685 if (module_return == nullptr) { 697 if (module_return_ == nullptr) {
686 FAIL(fun, "Missing asm.js module export."); 698 FAIL(fun, "Missing asm.js module export.");
687 } 699 }
688 700
689 for (auto* forward_def : forward_definitions_) { 701 for (auto* forward_def : forward_definitions_) {
690 if (forward_def->missing_definition()) { 702 if (forward_def->missing_definition()) {
691 FAIL(forward_def->first_forward_use(), 703 FAIL(forward_def->first_forward_use(),
692 "Missing definition for forward declared identifier."); 704 "Missing definition for forward declared identifier.");
693 } 705 }
694 } 706 }
695 707
696 RECURSE(ValidateExport(module_return)); 708 RECURSE(ValidateExport(module_return_));
697 709
698 if (!source_layout.IsValid()) { 710 if (!source_layout_.IsValid()) {
699 FAIL(fun, "Invalid asm.js source code layout."); 711 FAIL(fun, "Invalid asm.js source code layout.");
700 } 712 }
701 713
702 return AsmType::Int(); // Any type that is not AsmType::None(); 714 return AsmType::Int(); // Any type that is not AsmType::None();
703 } 715 }
704 716
705 namespace { 717 namespace {
706 bool IsDoubleAnnotation(BinaryOperation* binop) { 718 bool IsDoubleAnnotation(BinaryOperation* binop) {
707 // *VIOLATION* The parser replaces uses of +x with x*1.0. 719 // *VIOLATION* The parser replaces uses of +x with x*1.0.
708 if (binop->op() != Token::MUL) { 720 if (binop->op() != Token::MUL) {
(...skipping 2148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2857 return true; 2869 return true;
2858 } 2870 }
2859 2871
2860 *error_message = typer.error_message(); 2872 *error_message = typer.error_message();
2861 return false; 2873 return false;
2862 } 2874 }
2863 2875
2864 } // namespace wasm 2876 } // namespace wasm
2865 } // namespace internal 2877 } // namespace internal
2866 } // namespace v8 2878 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698