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

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

Issue 2164273002: V8. ASM-2-WASM. Enforces source code layout. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Adds new entry to the new cctests. Created 4 years, 5 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 | « no previous file | 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 <limits> 8 #include <limits>
8 #include <string> 9 #include <string>
9 10
10 #include "src/v8.h" 11 #include "src/v8.h"
11 12
12 #include "src/asmjs/asm-types.h" 13 #include "src/asmjs/asm-types.h"
13 #include "src/ast/ast.h" 14 #include "src/ast/ast.h"
14 #include "src/ast/scopes.h" 15 #include "src/ast/scopes.h"
15 #include "src/base/bits.h" 16 #include "src/base/bits.h"
16 #include "src/codegen.h" 17 #include "src/codegen.h"
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 if (assign->op() != Token::INIT) { 460 if (assign->op() != Token::INIT) {
460 // Done with initializers. 461 // Done with initializers.
461 return nullptr; 462 return nullptr;
462 } 463 }
463 return assign; 464 return assign;
464 } 465 }
465 466
466 } // namespace 467 } // namespace
467 468
468 // 6.1 ValidateModule 469 // 6.1 ValidateModule
470 namespace {
471 // SourceLayoutTracker keeps track of the start and end positions of each
472 // section in the asm.js source. The sections should not overlap, otherwise the
473 // asm.js source is invalid.
474 class SourceLayoutTracker {
475 public:
476 SourceLayoutTracker() = default;
477
478 bool IsValid() const {
479 const Section* kAllSections[] = {&use_asm_, &globals_, &functions_,
480 &tables_, &exports_};
481 for (size_t ii = 0; ii < arraysize(kAllSections); ++ii) {
482 const auto& curr_section = *kAllSections[ii];
483 for (size_t jj = ii + 1; jj < arraysize(kAllSections); ++jj) {
484 if (curr_section.OverlapsWith(*kAllSections[jj])) {
485 return false;
486 }
487 }
488 }
489 return true;
490 }
491
492 void AddUseAsm(const AstNode& node) { use_asm_.AddNewElement(node); }
493
494 void AddGlobal(const AstNode& node) { globals_.AddNewElement(node); }
495
496 void AddFunction(const AstNode& node) { functions_.AddNewElement(node); }
497
498 void AddTable(const AstNode& node) { tables_.AddNewElement(node); }
499
500 void AddExport(const AstNode& node) { exports_.AddNewElement(node); }
501
502 private:
503 class Section {
504 public:
505 Section() = default;
506 Section(const Section&) = default;
507 Section& operator=(const Section&) = default;
508
509 void AddNewElement(const AstNode& node) {
510 const int node_pos = node.position();
511 if (start_ == kNoSourcePosition) {
512 start_ = node_pos;
513 } else {
514 start_ = std::max(start_, node_pos);
515 }
516 if (end_ == kNoSourcePosition) {
517 end_ = node_pos;
518 } else {
519 end_ = std::max(end_, node_pos);
520 }
521 }
522
523 bool OverlapsWith(const Section& other) const {
524 if (start_ == kNoSourcePosition) {
525 DCHECK_EQ(end_, kNoSourcePosition);
526 return false;
527 }
528 if (other.start_ == kNoSourcePosition) {
529 DCHECK_EQ(other.end_, kNoSourcePosition);
530 return false;
531 }
532 return other.start_ < end_ || other.end_ < start_;
533 }
534
535 private:
536 int start_ = kNoSourcePosition;
537 int end_ = kNoSourcePosition;
538 };
539
540 Section use_asm_;
541 Section globals_;
542 Section functions_;
543 Section tables_;
544 Section exports_;
545
546 DISALLOW_COPY_AND_ASSIGN(SourceLayoutTracker);
547 };
548 } // namespace
549
469 AsmType* AsmTyper::ValidateModule(FunctionLiteral* fun) { 550 AsmType* AsmTyper::ValidateModule(FunctionLiteral* fun) {
551 SourceLayoutTracker source_layout;
552
470 Scope* scope = fun->scope(); 553 Scope* scope = fun->scope();
471 if (!scope->is_function_scope()) FAIL(fun, "Not at function scope."); 554 if (!scope->is_function_scope()) FAIL(fun, "Not at function scope.");
472 if (!ValidAsmIdentifier(fun->name())) 555 if (!ValidAsmIdentifier(fun->name()))
473 FAIL(fun, "Invalid asm.js identifier in module name."); 556 FAIL(fun, "Invalid asm.js identifier in module name.");
474 module_name_ = fun->name(); 557 module_name_ = fun->name();
475 558
476 // Allowed parameters: Stdlib, FFI, Mem 559 // Allowed parameters: Stdlib, FFI, Mem
477 static const uint32_t MaxModuleParameters = 3; 560 static const uint32_t MaxModuleParameters = 3;
478 if (scope->num_parameters() > MaxModuleParameters) { 561 if (scope->num_parameters() > MaxModuleParameters) {
479 FAIL(fun, "asm.js modules may not have more than three parameters."); 562 FAIL(fun, "asm.js modules may not have more than three parameters.");
(...skipping 20 matching lines...) Expand all
500 FAIL(fun, "Redeclared identifier in module parameter."); 583 FAIL(fun, "Redeclared identifier in module parameter.");
501 } 584 }
502 } 585 }
503 586
504 ZoneVector<Assignment*> function_pointer_tables(zone_); 587 ZoneVector<Assignment*> function_pointer_tables(zone_);
505 FlattenedStatements iter(zone_, fun->body()); 588 FlattenedStatements iter(zone_, fun->body());
506 auto* use_asm_directive = iter.Next(); 589 auto* use_asm_directive = iter.Next();
507 if (use_asm_directive == nullptr || !IsUseAsmDirective(use_asm_directive)) { 590 if (use_asm_directive == nullptr || !IsUseAsmDirective(use_asm_directive)) {
508 FAIL(fun, "Missing \"use asm\"."); 591 FAIL(fun, "Missing \"use asm\".");
509 } 592 }
593 source_layout.AddUseAsm(*use_asm_directive);
510 ReturnStatement* module_return = nullptr; 594 ReturnStatement* module_return = nullptr;
511 595
512 // *VIOLATION* The spec states that globals should be followed by function 596 // *VIOLATION* The spec states that globals should be followed by function
513 // declarations, which should be followed by function pointer tables, followed 597 // declarations, which should be followed by function pointer tables, followed
514 // by the module export (return) statement. Our AST might be rearraged by the 598 // by the module export (return) statement. Our AST might be rearraged by the
515 // parser, so we can't rely on it being in source code order. 599 // parser, so we can't rely on it being in source code order.
516 while (Statement* current = iter.Next()) { 600 while (Statement* current = iter.Next()) {
517 if (auto* assign = ExtractInitializerExpression(current)) { 601 if (auto* assign = ExtractInitializerExpression(current)) {
518 if (assign->value()->IsArrayLiteral()) { 602 if (assign->value()->IsArrayLiteral()) {
519 // Save function tables for later validation. 603 // Save function tables for later validation.
520 function_pointer_tables.push_back(assign); 604 function_pointer_tables.push_back(assign);
521 } else { 605 } else {
522 RECURSE(ValidateGlobalDeclaration(assign)); 606 RECURSE(ValidateGlobalDeclaration(assign));
607 source_layout.AddGlobal(*assign);
523 } 608 }
524 continue; 609 continue;
525 } 610 }
526 611
527 if (auto* current_as_return = current->AsReturnStatement()) { 612 if (auto* current_as_return = current->AsReturnStatement()) {
528 if (module_return != nullptr) { 613 if (module_return != nullptr) {
529 FAIL(fun, "Multiple export statements."); 614 FAIL(fun, "Multiple export statements.");
530 } 615 }
531 module_return = current_as_return; 616 module_return = current_as_return;
617 source_layout.AddExport(*module_return);
532 continue; 618 continue;
533 } 619 }
534 620
535 FAIL(current, "Invalid top-level statement in asm.js module."); 621 FAIL(current, "Invalid top-level statement in asm.js module.");
536 } 622 }
537 623
538 ZoneList<Declaration*>* decls = scope->declarations(); 624 ZoneList<Declaration*>* decls = scope->declarations();
539 625
540 for (int ii = 0; ii < decls->length(); ++ii) { 626 for (int ii = 0; ii < decls->length(); ++ii) {
541 Declaration* decl = decls->at(ii); 627 Declaration* decl = decls->at(ii);
542 628
543 if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) { 629 if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) {
544 RECURSE(ValidateFunction(fun_decl)); 630 RECURSE(ValidateFunction(fun_decl));
631 source_layout.AddFunction(*fun_decl);
545 continue; 632 continue;
546 } 633 }
547 } 634 }
548 635
549 for (auto* function_table : function_pointer_tables) { 636 for (auto* function_table : function_pointer_tables) {
550 RECURSE(ValidateFunctionTable(function_table)); 637 RECURSE(ValidateFunctionTable(function_table));
638 source_layout.AddTable(*function_table);
551 } 639 }
552 640
553 for (int ii = 0; ii < decls->length(); ++ii) { 641 for (int ii = 0; ii < decls->length(); ++ii) {
554 Declaration* decl = decls->at(ii); 642 Declaration* decl = decls->at(ii);
555 643
556 if (decl->IsFunctionDeclaration()) { 644 if (decl->IsFunctionDeclaration()) {
557 continue; 645 continue;
558 } 646 }
559 647
560 VariableDeclaration* var_decl = decl->AsVariableDeclaration(); 648 VariableDeclaration* var_decl = decl->AsVariableDeclaration();
(...skipping 18 matching lines...) Expand all
579 667
580 for (auto* forward_def : forward_definitions_) { 668 for (auto* forward_def : forward_definitions_) {
581 if (forward_def->missing_definition()) { 669 if (forward_def->missing_definition()) {
582 FAIL(forward_def->first_forward_use(), 670 FAIL(forward_def->first_forward_use(),
583 "Missing definition for forward declared identifier."); 671 "Missing definition for forward declared identifier.");
584 } 672 }
585 } 673 }
586 674
587 RECURSE(ValidateExport(module_return)); 675 RECURSE(ValidateExport(module_return));
588 676
677 if (!source_layout.IsValid()) {
678 FAIL(fun, "Invalid asm.js source code layout.");
679 }
680
589 return AsmType::Int(); // Any type that is not AsmType::None(); 681 return AsmType::Int(); // Any type that is not AsmType::None();
590 } 682 }
591 683
592 namespace { 684 namespace {
593 bool IsDoubleAnnotation(BinaryOperation* binop) { 685 bool IsDoubleAnnotation(BinaryOperation* binop) {
594 // *VIOLATION* The parser replaces uses of +x with x*1.0. 686 // *VIOLATION* The parser replaces uses of +x with x*1.0.
595 if (binop->op() != Token::MUL) { 687 if (binop->op() != Token::MUL) {
596 return false; 688 return false;
597 } 689 }
598 690
(...skipping 2036 matching lines...) Expand 10 before | Expand all | Expand 10 after
2635 return true; 2727 return true;
2636 } 2728 }
2637 2729
2638 *error_message = typer.error_message(); 2730 *error_message = typer.error_message();
2639 return false; 2731 return false;
2640 } 2732 }
2641 2733
2642 } // namespace wasm 2734 } // namespace wasm
2643 } // namespace internal 2735 } // namespace internal
2644 } // namespace v8 2736 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/cctest/asmjs/test-asm-typer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698