OLD | NEW |
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 Loading... |
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 28 matching lines...) Expand all Loading... |
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 node_types_(zone_), |
141 fround_type_(AsmType::FroundType(zone_)), | 186 fround_type_(AsmType::FroundType(zone_)), |
142 ffi_type_(AsmType::FFIType(zone_)) { | 187 ffi_type_(AsmType::FFIType(zone_)), |
| 188 function_pointer_tables_(zone_) { |
143 InitializeStdlib(); | 189 InitializeStdlib(); |
144 } | 190 } |
145 | 191 |
146 namespace { | 192 namespace { |
147 bool ValidAsmIdentifier(Handle<String> name) { | 193 bool ValidAsmIdentifier(Handle<String> name) { |
148 static const char* kInvalidAsmNames[] = {"eval", "arguments"}; | 194 static const char* kInvalidAsmNames[] = {"eval", "arguments"}; |
149 | 195 |
150 for (size_t ii = 0; ii < arraysize(kInvalidAsmNames); ++ii) { | 196 for (size_t ii = 0; ii < arraysize(kInvalidAsmNames); ++ii) { |
151 if (strcmp(name->ToCString().get(), kInvalidAsmNames[ii]) == 0) { | 197 if (strcmp(name->ToCString().get(), kInvalidAsmNames[ii]) == 0) { |
152 return false; | 198 return false; |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(Variable* var) { | 473 AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(Variable* var) { |
428 auto* var_info = Lookup(var); | 474 auto* var_info = Lookup(var); |
429 if (var_info == nullptr) { | 475 if (var_info == nullptr) { |
430 return kNone; | 476 return kNone; |
431 } | 477 } |
432 StandardMember member = var_info->standard_member(); | 478 StandardMember member = var_info->standard_member(); |
433 return member; | 479 return member; |
434 } | 480 } |
435 | 481 |
436 bool AsmTyper::Validate() { | 482 bool AsmTyper::Validate() { |
437 if (!AsmType::None()->IsExactly(ValidateModule(root_))) { | 483 return ValidatePhase1of2() && |
| 484 !AsmType::None()->IsExactly(ValidateModuleFunctions(root_)) && |
| 485 ValidatePhase2of2(); |
| 486 } |
| 487 |
| 488 bool AsmTyper::ValidatePhase1of2() { |
| 489 if (!AsmType::None()->IsExactly(ValidateModulePhase1of2(root_))) { |
438 return true; | 490 return true; |
439 } | 491 } |
440 return false; | 492 return false; |
| 493 } |
| 494 |
| 495 bool AsmTyper::ValidateInnerFunction(FunctionDeclaration* fun_decl) { |
| 496 if (!AsmType::None()->IsExactly(ValidateModuleFunction(fun_decl))) { |
| 497 return true; |
| 498 } |
| 499 return false; |
| 500 } |
| 501 |
| 502 bool AsmTyper::ValidatePhase2of2() { |
| 503 if (!AsmType::None()->IsExactly(ValidateModulePhase2of2(root_))) { |
| 504 return true; |
| 505 } |
| 506 return false; |
441 } | 507 } |
442 | 508 |
443 namespace { | 509 namespace { |
444 bool IsUseAsmDirective(Statement* first_statement) { | 510 bool IsUseAsmDirective(Statement* first_statement) { |
445 ExpressionStatement* use_asm = first_statement->AsExpressionStatement(); | 511 ExpressionStatement* use_asm = first_statement->AsExpressionStatement(); |
446 if (use_asm == nullptr) { | 512 if (use_asm == nullptr) { |
447 return false; | 513 return false; |
448 } | 514 } |
449 | 515 |
450 Literal* use_asm_literal = use_asm->expression()->AsLiteral(); | 516 Literal* use_asm_literal = use_asm->expression()->AsLiteral(); |
(...skipping 19 matching lines...) Expand all Loading... |
470 if (assign->op() != Token::INIT) { | 536 if (assign->op() != Token::INIT) { |
471 // Done with initializers. | 537 // Done with initializers. |
472 return nullptr; | 538 return nullptr; |
473 } | 539 } |
474 return assign; | 540 return assign; |
475 } | 541 } |
476 | 542 |
477 } // namespace | 543 } // namespace |
478 | 544 |
479 // 6.1 ValidateModule | 545 // 6.1 ValidateModule |
480 namespace { | 546 AsmType* AsmTyper::ValidateModulePhase1of2(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(); | 547 DeclarationScope* scope = fun->scope(); |
564 if (!scope->is_function_scope()) FAIL(fun, "Not at function scope."); | 548 if (!scope->is_function_scope()) FAIL(fun, "Not at function scope."); |
565 if (!ValidAsmIdentifier(fun->name())) | 549 if (!ValidAsmIdentifier(fun->name())) |
566 FAIL(fun, "Invalid asm.js identifier in module name."); | 550 FAIL(fun, "Invalid asm.js identifier in module name."); |
567 module_name_ = fun->name(); | 551 module_name_ = fun->name(); |
568 | 552 |
569 // Allowed parameters: Stdlib, FFI, Mem | 553 // Allowed parameters: Stdlib, FFI, Mem |
570 static const uint32_t MaxModuleParameters = 3; | 554 static const uint32_t MaxModuleParameters = 3; |
571 if (scope->num_parameters() > MaxModuleParameters) { | 555 if (scope->num_parameters() > MaxModuleParameters) { |
572 FAIL(fun, "asm.js modules may not have more than three parameters."); | 556 FAIL(fun, "asm.js modules may not have more than three parameters."); |
(...skipping 14 matching lines...) Expand all Loading... |
587 } | 571 } |
588 | 572 |
589 auto* param_info = VariableInfo::ForSpecialSymbol( | 573 auto* param_info = VariableInfo::ForSpecialSymbol( |
590 zone_, kModuleParamInfo[ii].standard_member); | 574 zone_, kModuleParamInfo[ii].standard_member); |
591 | 575 |
592 if (!AddGlobal(param, param_info)) { | 576 if (!AddGlobal(param, param_info)) { |
593 FAIL(fun, "Redeclared identifier in module parameter."); | 577 FAIL(fun, "Redeclared identifier in module parameter."); |
594 } | 578 } |
595 } | 579 } |
596 | 580 |
597 ZoneVector<Assignment*> function_pointer_tables(zone_); | |
598 FlattenedStatements iter(zone_, fun->body()); | 581 FlattenedStatements iter(zone_, fun->body()); |
599 auto* use_asm_directive = iter.Next(); | 582 auto* use_asm_directive = iter.Next(); |
600 if (use_asm_directive == nullptr) { | 583 if (use_asm_directive == nullptr) { |
601 FAIL(fun, "Missing \"use asm\"."); | 584 FAIL(fun, "Missing \"use asm\"."); |
602 } | 585 } |
603 // Check for extra assignment inserted by the parser when in this form: | 586 // Check for extra assignment inserted by the parser when in this form: |
604 // (function Module(a, b, c) {... }) | 587 // (function Module(a, b, c) {... }) |
605 ExpressionStatement* estatement = use_asm_directive->AsExpressionStatement(); | 588 ExpressionStatement* estatement = use_asm_directive->AsExpressionStatement(); |
606 if (estatement != nullptr) { | 589 if (estatement != nullptr) { |
607 Assignment* assignment = estatement->expression()->AsAssignment(); | 590 Assignment* assignment = estatement->expression()->AsAssignment(); |
608 if (assignment != nullptr && assignment->target()->IsVariableProxy() && | 591 if (assignment != nullptr && assignment->target()->IsVariableProxy() && |
609 assignment->target() | 592 assignment->target() |
610 ->AsVariableProxy() | 593 ->AsVariableProxy() |
611 ->var() | 594 ->var() |
612 ->is_sloppy_function_name()) { | 595 ->is_sloppy_function_name()) { |
613 use_asm_directive = iter.Next(); | 596 use_asm_directive = iter.Next(); |
614 } | 597 } |
615 } | 598 } |
616 if (!IsUseAsmDirective(use_asm_directive)) { | 599 if (!IsUseAsmDirective(use_asm_directive)) { |
617 FAIL(fun, "Missing \"use asm\"."); | 600 FAIL(fun, "Missing \"use asm\"."); |
618 } | 601 } |
619 source_layout.AddUseAsm(*use_asm_directive); | 602 source_layout_.AddUseAsm(*use_asm_directive); |
620 ReturnStatement* module_return = nullptr; | 603 module_return_ = nullptr; |
621 | 604 |
622 // *VIOLATION* The spec states that globals should be followed by function | 605 // *VIOLATION* The spec states that globals should be followed by function |
623 // declarations, which should be followed by function pointer tables, followed | 606 // declarations, which should be followed by function pointer tables, followed |
624 // by the module export (return) statement. Our AST might be rearraged by the | 607 // 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. | 608 // parser, so we can't rely on it being in source code order. |
626 while (Statement* current = iter.Next()) { | 609 while (Statement* current = iter.Next()) { |
627 if (auto* assign = ExtractInitializerExpression(current)) { | 610 if (auto* assign = ExtractInitializerExpression(current)) { |
628 if (assign->value()->IsArrayLiteral()) { | 611 if (assign->value()->IsArrayLiteral()) { |
629 // Save function tables for later validation. | 612 // Save function tables for later validation. |
630 function_pointer_tables.push_back(assign); | 613 function_pointer_tables_.push_back(assign); |
631 } else { | 614 } else { |
632 RECURSE(ValidateGlobalDeclaration(assign)); | 615 RECURSE(ValidateGlobalDeclaration(assign)); |
633 source_layout.AddGlobal(*assign); | 616 source_layout_.AddGlobal(*assign); |
634 } | 617 } |
635 continue; | 618 continue; |
636 } | 619 } |
637 | 620 |
638 if (auto* current_as_return = current->AsReturnStatement()) { | 621 if (auto* current_as_return = current->AsReturnStatement()) { |
639 if (module_return != nullptr) { | 622 if (module_return_ != nullptr) { |
640 FAIL(fun, "Multiple export statements."); | 623 FAIL(fun, "Multiple export statements."); |
641 } | 624 } |
642 module_return = current_as_return; | 625 module_return_ = current_as_return; |
643 source_layout.AddExport(*module_return); | 626 source_layout_.AddExport(*module_return_); |
644 continue; | 627 continue; |
645 } | 628 } |
646 | 629 |
647 FAIL(current, "Invalid top-level statement in asm.js module."); | 630 FAIL(current, "Invalid top-level statement in asm.js module."); |
648 } | 631 } |
649 | 632 |
| 633 return AsmType::Int(); // Any type that is not AsmType::None(); |
| 634 } |
| 635 |
| 636 AsmType* AsmTyper::ValidateModuleFunction(FunctionDeclaration* fun_decl) { |
| 637 RECURSE(ValidateFunction(fun_decl)); |
| 638 source_layout_.AddFunction(*fun_decl); |
| 639 |
| 640 return AsmType::Int(); // Any type that is not AsmType::None(); |
| 641 } |
| 642 |
| 643 AsmType* AsmTyper::ValidateModuleFunctions(FunctionLiteral* fun) { |
| 644 DeclarationScope* scope = fun->scope(); |
650 ZoneList<Declaration*>* decls = scope->declarations(); | 645 ZoneList<Declaration*>* decls = scope->declarations(); |
651 | 646 |
652 for (int ii = 0; ii < decls->length(); ++ii) { | 647 for (int ii = 0; ii < decls->length(); ++ii) { |
653 Declaration* decl = decls->at(ii); | 648 Declaration* decl = decls->at(ii); |
654 | 649 |
655 if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) { | 650 if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) { |
656 RECURSE(ValidateFunction(fun_decl)); | 651 RECURSE(ValidateModuleFunction(fun_decl)); |
657 source_layout.AddFunction(*fun_decl); | |
658 continue; | 652 continue; |
659 } | 653 } |
660 } | 654 } |
661 | 655 |
662 for (auto* function_table : function_pointer_tables) { | 656 return AsmType::Int(); // Any type that is not AsmType::None(); |
| 657 } |
| 658 |
| 659 AsmType* AsmTyper::ValidateModulePhase2of2(FunctionLiteral* fun) { |
| 660 for (auto* function_table : function_pointer_tables_) { |
663 RECURSE(ValidateFunctionTable(function_table)); | 661 RECURSE(ValidateFunctionTable(function_table)); |
664 source_layout.AddTable(*function_table); | 662 source_layout_.AddTable(*function_table); |
665 } | 663 } |
666 | 664 |
| 665 DeclarationScope* scope = fun->scope(); |
| 666 ZoneList<Declaration*>* decls = scope->declarations(); |
667 for (int ii = 0; ii < decls->length(); ++ii) { | 667 for (int ii = 0; ii < decls->length(); ++ii) { |
668 Declaration* decl = decls->at(ii); | 668 Declaration* decl = decls->at(ii); |
669 | 669 |
670 if (decl->IsFunctionDeclaration()) { | 670 if (decl->IsFunctionDeclaration()) { |
671 continue; | 671 continue; |
672 } | 672 } |
673 | 673 |
674 VariableDeclaration* var_decl = decl->AsVariableDeclaration(); | 674 VariableDeclaration* var_decl = decl->AsVariableDeclaration(); |
675 if (var_decl == nullptr) { | 675 if (var_decl == nullptr) { |
676 FAIL(decl, "Invalid asm.js declaration."); | 676 FAIL(decl, "Invalid asm.js declaration."); |
677 } | 677 } |
678 | 678 |
679 auto* var_proxy = var_decl->proxy(); | 679 auto* var_proxy = var_decl->proxy(); |
680 if (var_proxy == nullptr) { | 680 if (var_proxy == nullptr) { |
681 FAIL(decl, "Invalid asm.js declaration."); | 681 FAIL(decl, "Invalid asm.js declaration."); |
682 } | 682 } |
683 | 683 |
684 if (Lookup(var_proxy->var()) == nullptr) { | 684 if (Lookup(var_proxy->var()) == nullptr) { |
685 FAIL(decl, "Global variable missing initializer in asm.js module."); | 685 FAIL(decl, "Global variable missing initializer in asm.js module."); |
686 } | 686 } |
687 } | 687 } |
688 | 688 |
689 // 6.2 ValidateExport | 689 // 6.2 ValidateExport |
690 if (module_return == nullptr) { | 690 if (module_return_ == nullptr) { |
691 FAIL(fun, "Missing asm.js module export."); | 691 FAIL(fun, "Missing asm.js module export."); |
692 } | 692 } |
693 | 693 |
694 for (auto* forward_def : forward_definitions_) { | 694 for (auto* forward_def : forward_definitions_) { |
695 if (forward_def->missing_definition()) { | 695 if (forward_def->missing_definition()) { |
696 FAIL(forward_def->first_forward_use(), | 696 FAIL(forward_def->first_forward_use(), |
697 "Missing definition for forward declared identifier."); | 697 "Missing definition for forward declared identifier."); |
698 } | 698 } |
699 } | 699 } |
700 | 700 |
701 RECURSE(ValidateExport(module_return)); | 701 RECURSE(ValidateExport(module_return_)); |
702 | 702 |
703 if (!source_layout.IsValid()) { | 703 if (!source_layout_.IsValid()) { |
704 FAIL(fun, "Invalid asm.js source code layout."); | 704 FAIL(fun, "Invalid asm.js source code layout."); |
705 } | 705 } |
706 | 706 |
707 return AsmType::Int(); // Any type that is not AsmType::None(); | 707 return AsmType::Int(); // Any type that is not AsmType::None(); |
708 } | 708 } |
709 | 709 |
710 namespace { | 710 namespace { |
711 bool IsDoubleAnnotation(BinaryOperation* binop) { | 711 bool IsDoubleAnnotation(BinaryOperation* binop) { |
712 // *VIOLATION* The parser replaces uses of +x with x*1.0. | 712 // *VIOLATION* The parser replaces uses of +x with x*1.0. |
713 if (binop->op() != Token::MUL) { | 713 if (binop->op() != Token::MUL) { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 } | 849 } |
850 SetTypeOf(assign, target_info->type()); | 850 SetTypeOf(assign, target_info->type()); |
851 SetTypeOf(target, target_info->type()); | 851 SetTypeOf(target, target_info->type()); |
852 return target_info->type(); | 852 return target_info->type(); |
853 } | 853 } |
854 | 854 |
855 // 6.2 ValidateExport | 855 // 6.2 ValidateExport |
856 AsmType* AsmTyper::ExportType(VariableProxy* fun_export) { | 856 AsmType* AsmTyper::ExportType(VariableProxy* fun_export) { |
857 auto* fun_info = Lookup(fun_export->var()); | 857 auto* fun_info = Lookup(fun_export->var()); |
858 if (fun_info == nullptr) { | 858 if (fun_info == nullptr) { |
| 859 UNREACHABLE(); |
859 FAIL(fun_export, "Undefined identifier in asm.js module export."); | 860 FAIL(fun_export, "Undefined identifier in asm.js module export."); |
860 } | 861 } |
861 | 862 |
862 if (fun_info->standard_member() != kNone) { | 863 if (fun_info->standard_member() != kNone) { |
863 FAIL(fun_export, "Module cannot export standard library functions."); | 864 FAIL(fun_export, "Module cannot export standard library functions."); |
864 } | 865 } |
865 | 866 |
866 auto* type = fun_info->type(); | 867 auto* type = fun_info->type(); |
867 if (type->AsFFIType() != nullptr) { | 868 if (type->AsFFIType() != nullptr) { |
868 FAIL(fun_export, "Module cannot export foreign functions."); | 869 FAIL(fun_export, "Module cannot export foreign functions."); |
(...skipping 1914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2783 return true; | 2784 return true; |
2784 } | 2785 } |
2785 | 2786 |
2786 *error_message = typer.error_message(); | 2787 *error_message = typer.error_message(); |
2787 return false; | 2788 return false; |
2788 } | 2789 } |
2789 | 2790 |
2790 } // namespace wasm | 2791 } // namespace wasm |
2791 } // namespace internal | 2792 } // namespace internal |
2792 } // namespace v8 | 2793 } // namespace v8 |
OLD | NEW |