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

Side by Side Diff: src/asmjs/asm-wasm-builder.cc

Issue 2398023002: [wasm] asm.js - Parse and convert asm.js to wasm a function at a time. (Closed)
Patch Set: 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/v8.h" 5 #include "src/v8.h"
6 6
7 // Required to get M_E etc. in MSVC. 7 // Required to get M_E etc. in MSVC.
8 #if defined(_WIN32) 8 #if defined(_WIN32)
9 #define _USE_MATH_DEFINES 9 #define _USE_MATH_DEFINES
10 #endif 10 #endif
11 #include <math.h> 11 #include <math.h>
12 12
13 #include "src/asmjs/asm-types.h" 13 #include "src/asmjs/asm-types.h"
14 #include "src/asmjs/asm-wasm-builder.h" 14 #include "src/asmjs/asm-wasm-builder.h"
15 #include "src/wasm/switch-logic.h" 15 #include "src/wasm/switch-logic.h"
16 #include "src/wasm/wasm-macro-gen.h" 16 #include "src/wasm/wasm-macro-gen.h"
17 #include "src/wasm/wasm-opcodes.h" 17 #include "src/wasm/wasm-opcodes.h"
18 18
19 #include "src/ast/ast.h" 19 #include "src/ast/ast.h"
20 #include "src/ast/scopes.h" 20 #include "src/ast/scopes.h"
21 #include "src/codegen.h" 21 #include "src/codegen.h"
22 #include "src/compiler.h"
23 #include "src/isolate.h"
24 #include "src/parsing/parse-info.h"
22 25
23 namespace v8 { 26 namespace v8 {
24 namespace internal { 27 namespace internal {
25 namespace wasm { 28 namespace wasm {
26 29
27 #define RECURSE(call) \ 30 #define RECURSE(call) \
28 do { \ 31 do { \
29 DCHECK(!HasStackOverflow()); \ 32 DCHECK(!HasStackOverflow()); \
30 call; \ 33 call; \
31 if (HasStackOverflow()) return; \ 34 if (HasStackOverflow()) return; \
32 } while (false) 35 } while (false)
33 36
34 enum AsmScope { kModuleScope, kInitScope, kFuncScope, kExportScope }; 37 enum AsmScope { kModuleScope, kInitScope, kFuncScope, kExportScope };
35 enum ValueFate { kDrop, kLeaveOnStack }; 38 enum ValueFate { kDrop, kLeaveOnStack };
36 39
37 struct ForeignVariable { 40 struct ForeignVariable {
38 Handle<Name> name; 41 Handle<Name> name;
39 Variable* var; 42 Variable* var;
40 LocalType type; 43 LocalType type;
41 }; 44 };
42 45
43 class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> { 46 class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
44 public: 47 public:
45 AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, FunctionLiteral* literal, 48 AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, Script* script,
46 AsmTyper* typer) 49 FunctionLiteral* literal, AsmTyper* typer)
47 : local_variables_(ZoneHashMap::kDefaultHashMapCapacity, 50 : local_variables_(ZoneHashMap::kDefaultHashMapCapacity,
48 ZoneAllocationPolicy(zone)), 51 ZoneAllocationPolicy(zone)),
49 functions_(ZoneHashMap::kDefaultHashMapCapacity, 52 functions_(ZoneHashMap::kDefaultHashMapCapacity,
50 ZoneAllocationPolicy(zone)), 53 ZoneAllocationPolicy(zone)),
51 global_variables_(ZoneHashMap::kDefaultHashMapCapacity, 54 global_variables_(ZoneHashMap::kDefaultHashMapCapacity,
52 ZoneAllocationPolicy(zone)), 55 ZoneAllocationPolicy(zone)),
53 scope_(kModuleScope), 56 scope_(kModuleScope),
54 builder_(new (zone) WasmModuleBuilder(zone)), 57 builder_(new (zone) WasmModuleBuilder(zone)),
55 current_function_builder_(nullptr), 58 current_function_builder_(nullptr),
56 literal_(literal), 59 literal_(literal),
57 isolate_(isolate), 60 isolate_(isolate),
58 zone_(zone), 61 zone_(zone),
62 script_(script),
59 typer_(typer), 63 typer_(typer),
64 typer_failed_(false),
60 breakable_blocks_(zone), 65 breakable_blocks_(zone),
61 foreign_variables_(zone), 66 foreign_variables_(zone),
62 init_function_(nullptr), 67 init_function_(nullptr),
63 foreign_init_function_(nullptr), 68 foreign_init_function_(nullptr),
64 next_table_index_(0),
65 function_tables_(ZoneHashMap::kDefaultHashMapCapacity, 69 function_tables_(ZoneHashMap::kDefaultHashMapCapacity,
66 ZoneAllocationPolicy(zone)), 70 ZoneAllocationPolicy(zone)),
67 imported_function_table_(this) { 71 imported_function_table_(this) {
68 InitializeAstVisitor(isolate); 72 InitializeAstVisitor(isolate);
69 } 73 }
70 74
71 void InitializeInitFunction() { 75 void InitializeInitFunction() {
72 FunctionSig::Builder b(zone(), 0, 0); 76 FunctionSig::Builder b(zone(), 0, 0);
73 init_function_ = builder_->AddFunction(b.Build()); 77 init_function_ = builder_->AddFunction(b.Build());
74 builder_->MarkStartFunction(init_function_); 78 builder_->MarkStartFunction(init_function_);
(...skipping 26 matching lines...) Expand all
101 i::Handle<i::FixedArray> GetForeignArgs() { 105 i::Handle<i::FixedArray> GetForeignArgs() {
102 i::Handle<FixedArray> ret = isolate_->factory()->NewFixedArray( 106 i::Handle<FixedArray> ret = isolate_->factory()->NewFixedArray(
103 static_cast<int>(foreign_variables_.size())); 107 static_cast<int>(foreign_variables_.size()));
104 for (size_t i = 0; i < foreign_variables_.size(); ++i) { 108 for (size_t i = 0; i < foreign_variables_.size(); ++i) {
105 ForeignVariable* fv = &foreign_variables_[i]; 109 ForeignVariable* fv = &foreign_variables_[i];
106 ret->set(static_cast<int>(i), *fv->name); 110 ret->set(static_cast<int>(i), *fv->name);
107 } 111 }
108 return ret; 112 return ret;
109 } 113 }
110 114
111 void Build() { 115 bool Build() {
112 InitializeInitFunction(); 116 InitializeInitFunction();
113 RECURSE(VisitFunctionLiteral(literal_)); 117 if (!typer_->ValidatePhase1of2()) {
118 return false;
119 }
120 DCHECK(!HasStackOverflow());
121 VisitFunctionLiteral(literal_);
122 if (HasStackOverflow()) {
123 return false;
124 }
125 if (typer_failed_) {
126 return false;
127 }
114 BuildForeignInitFunction(); 128 BuildForeignInitFunction();
129 return true;
115 } 130 }
116 131
117 void VisitVariableDeclaration(VariableDeclaration* decl) {} 132 void VisitVariableDeclaration(VariableDeclaration* decl) {}
118 133
119 void VisitFunctionDeclaration(FunctionDeclaration* decl) { 134 void VisitFunctionDeclaration(FunctionDeclaration* decl) {
120 DCHECK_EQ(kModuleScope, scope_); 135 DCHECK_EQ(kModuleScope, scope_);
121 DCHECK_NULL(current_function_builder_); 136 DCHECK_NULL(current_function_builder_);
137 bool had_body;
138 i::Zone zone(isolate_->allocator());
139 if (decl->fun()->body() == nullptr) {
140 Handle<SharedFunctionInfo> shared =
titzer 2016/10/07 12:56:59 Do we really need a shared function info here? See
bradn 2016/11/25 09:19:36 A large number of places in the parser assume a Sh
141 i::Compiler::NewSharedFunctionInfoFromLiteral(
142 isolate_, decl->fun(), handle(script_, isolate_));
143 shared->set_is_toplevel(false);
144 i::ParseInfo info(&zone, handle(script_, isolate_));
145 info.set_shared_info(shared);
146 info.set_language_mode(decl->fun()->scope()->language_mode());
147 info.set_lazy(true);
148 info.set_allow_lazy_parsing(false);
149 info.set_script_scope(decl->fun()->scope());
150 if (!i::Compiler::ParseAndAnalyze(&info)) {
151 typer_failed_ = true;
152 return;
153 }
154 FunctionLiteral* func = info.literal();
155 DCHECK_NOT_NULL(func);
156 decl->fun()->set_body(func->body());
157 had_body = false;
158 } else {
159 had_body = true;
160 }
161 if (!typer_->ValidateInnerFunction(decl)) {
162 typer_failed_ = true;
163 return;
164 }
122 current_function_builder_ = LookupOrInsertFunction(decl->proxy()->var()); 165 current_function_builder_ = LookupOrInsertFunction(decl->proxy()->var());
123 scope_ = kFuncScope; 166 scope_ = kFuncScope;
124 RECURSE(Visit(decl->fun())); 167 RECURSE(Visit(decl->fun()));
168 if (!had_body) {
169 decl->fun()->set_body(nullptr);
170 }
125 scope_ = kModuleScope; 171 scope_ = kModuleScope;
126 current_function_builder_ = nullptr; 172 current_function_builder_ = nullptr;
127 local_variables_.Clear(); 173 local_variables_.Clear();
128 } 174 }
129 175
130 void VisitStatements(ZoneList<Statement*>* stmts) { 176 void VisitStatements(ZoneList<Statement*>* stmts) {
131 for (int i = 0; i < stmts->length(); ++i) { 177 for (int i = 0; i < stmts->length(); ++i) {
132 Statement* stmt = stmts->at(i); 178 Statement* stmt = stmts->at(i);
133 ExpressionStatement* e = stmt->AsExpressionStatement(); 179 ExpressionStatement* e = stmt->AsExpressionStatement();
134 if (e != nullptr && e->expression()->IsUndefinedLiteral()) { 180 if (e != nullptr && e->expression()->IsUndefinedLiteral()) {
135 continue; 181 continue;
136 } 182 }
137 RECURSE(Visit(stmt)); 183 RECURSE(Visit(stmt));
184 if (typer_failed_) break;
138 if (stmt->IsJump()) break; 185 if (stmt->IsJump()) break;
139 } 186 }
140 } 187 }
141 188
142 void VisitBlock(Block* stmt) { 189 void VisitBlock(Block* stmt) {
143 if (stmt->statements()->length() == 1) { 190 if (stmt->statements()->length() == 1) {
144 ExpressionStatement* expr = 191 ExpressionStatement* expr =
145 stmt->statements()->at(0)->AsExpressionStatement(); 192 stmt->statements()->at(0)->AsExpressionStatement();
146 if (expr != nullptr) { 193 if (expr != nullptr) {
147 if (expr->expression()->IsAssignment()) { 194 if (expr->expression()->IsAssignment()) {
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 const auto& arguments = func_type->Arguments(); 494 const auto& arguments = func_type->Arguments();
448 for (int i = 0; i < expr->parameter_count(); ++i) { 495 for (int i = 0; i < expr->parameter_count(); ++i) {
449 LocalType type = TypeFrom(arguments[i]); 496 LocalType type = TypeFrom(arguments[i]);
450 DCHECK_NE(kAstStmt, type); 497 DCHECK_NE(kAstStmt, type);
451 InsertParameter(scope->parameter(i), type, i); 498 InsertParameter(scope->parameter(i), type, i);
452 } 499 }
453 } else { 500 } else {
454 UNREACHABLE(); 501 UNREACHABLE();
455 } 502 }
456 } 503 }
457 RECURSE(VisitStatements(expr->body())); 504 if (scope_ == kFuncScope) {
titzer 2016/10/07 12:56:59 Why do we need to do the declarations after for a
bradn 2016/11/25 09:19:36 No good reason. Both should be declarations then s
458 RECURSE(VisitDeclarations(scope->declarations())); 505 RECURSE(VisitStatements(expr->body()));
506 RECURSE(VisitDeclarations(scope->declarations()));
507 } else {
508 RECURSE(VisitDeclarations(scope->declarations()));
509 RECURSE(VisitStatements(expr->body()));
510 }
459 } 511 }
460 512
461 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 513 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
462 UNREACHABLE(); 514 UNREACHABLE();
463 } 515 }
464 516
465 void VisitConditional(Conditional* expr) { 517 void VisitConditional(Conditional* expr) {
466 DCHECK_EQ(kFuncScope, scope_); 518 DCHECK_EQ(kFuncScope, scope_);
467 RECURSE(Visit(expr->condition())); 519 RECURSE(Visit(expr->condition()));
468 // WASM ifs come with implicit blocks for both arms. 520 // WASM ifs come with implicit blocks for both arms.
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 byte code[] = {WASM_F32(val)}; 682 byte code[] = {WASM_F32(val)};
631 current_function_builder_->EmitCode(code, sizeof(code)); 683 current_function_builder_->EmitCode(code, sizeof(code));
632 } else { 684 } else {
633 UNREACHABLE(); 685 UNREACHABLE();
634 } 686 }
635 } 687 }
636 688
637 void VisitRegExpLiteral(RegExpLiteral* expr) { UNREACHABLE(); } 689 void VisitRegExpLiteral(RegExpLiteral* expr) { UNREACHABLE(); }
638 690
639 void VisitObjectLiteral(ObjectLiteral* expr) { 691 void VisitObjectLiteral(ObjectLiteral* expr) {
692 if (!typer_->ValidatePhase2of2()) {
693 typer_failed_ = true;
694 return;
695 }
696
640 ZoneList<ObjectLiteralProperty*>* props = expr->properties(); 697 ZoneList<ObjectLiteralProperty*>* props = expr->properties();
641 for (int i = 0; i < props->length(); ++i) { 698 for (int i = 0; i < props->length(); ++i) {
642 ObjectLiteralProperty* prop = props->at(i); 699 ObjectLiteralProperty* prop = props->at(i);
643 DCHECK_EQ(kExportScope, scope_); 700 DCHECK_EQ(kExportScope, scope_);
644 VariableProxy* expr = prop->value()->AsVariableProxy(); 701 VariableProxy* expr = prop->value()->AsVariableProxy();
645 DCHECK_NOT_NULL(expr); 702 DCHECK_NOT_NULL(expr);
646 Variable* var = expr->var(); 703 Variable* var = expr->var();
647 Literal* name = prop->key()->AsLiteral(); 704 Literal* name = prop->key()->AsLiteral();
648 DCHECK_NOT_NULL(name); 705 DCHECK_NOT_NULL(name);
649 DCHECK(name->IsPropertyName()); 706 DCHECK(name->IsPropertyName());
(...skipping 12 matching lines...) Expand all
662 void LoadInitFunction() { 719 void LoadInitFunction() {
663 current_function_builder_ = init_function_; 720 current_function_builder_ = init_function_;
664 scope_ = kInitScope; 721 scope_ = kInitScope;
665 } 722 }
666 723
667 void UnLoadInitFunction() { 724 void UnLoadInitFunction() {
668 scope_ = kModuleScope; 725 scope_ = kModuleScope;
669 current_function_builder_ = nullptr; 726 current_function_builder_ = nullptr;
670 } 727 }
671 728
672 void AddFunctionTable(VariableProxy* table, ArrayLiteral* funcs) { 729 struct FunctionTableIndices : public ZoneObject {
673 auto* func_tbl_type = typer_->TypeOf(funcs)->AsFunctionTableType(); 730 uint32_t start_index;
674 DCHECK_NOT_NULL(func_tbl_type); 731 uint32_t signature_index;
675 auto* func_type = func_tbl_type->signature()->AsFunctionType(); 732 };
733
734 FunctionTableIndices* LookupOrAddFunctionTable(VariableProxy* table,
735 Property* p) {
736 FunctionTableIndices* indices = LookupFunctionTable(table->var());
737 if (indices != nullptr) {
738 // Already setup.
739 return indices;
740 }
741 indices = new (zone()) FunctionTableIndices();
742 auto* func_type = typer_->TypeOf(p)->AsFunctionType();
743 auto* func_table_type = typer_->TypeOf(p->obj()->AsVariableProxy()->var())
744 ->AsFunctionTableType();
676 const auto& arguments = func_type->Arguments(); 745 const auto& arguments = func_type->Arguments();
677 LocalType return_type = TypeFrom(func_type->ReturnType()); 746 LocalType return_type = TypeFrom(func_type->ReturnType());
678 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, 747 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
679 arguments.size()); 748 arguments.size());
680 if (return_type != kAstStmt) { 749 if (return_type != kAstStmt) {
681 sig.AddReturn(return_type); 750 sig.AddReturn(return_type);
682 } 751 }
683 for (auto* arg : arguments) { 752 for (auto* arg : arguments) {
684 sig.AddParam(TypeFrom(arg)); 753 sig.AddParam(TypeFrom(arg));
685 } 754 }
686 uint32_t signature_index = builder_->AddSignature(sig.Build()); 755 uint32_t signature_index = builder_->AddSignature(sig.Build());
687 InsertFunctionTable(table->var(), next_table_index_, signature_index); 756 indices->start_index =
688 next_table_index_ += funcs->values()->length(); 757 builder_->AllocateIndirectFunctions(func_table_type->length());
689 for (int i = 0; i < funcs->values()->length(); ++i) { 758 indices->signature_index = signature_index;
690 VariableProxy* func = funcs->values()->at(i)->AsVariableProxy();
691 DCHECK_NOT_NULL(func);
692 builder_->AddIndirectFunction(
693 LookupOrInsertFunction(func->var())->func_index());
694 }
695 }
696
697 struct FunctionTableIndices : public ZoneObject {
698 uint32_t start_index;
699 uint32_t signature_index;
700 };
701
702 void InsertFunctionTable(Variable* v, uint32_t start_index,
703 uint32_t signature_index) {
704 FunctionTableIndices* container = new (zone()) FunctionTableIndices();
705 container->start_index = start_index;
706 container->signature_index = signature_index;
707 ZoneHashMap::Entry* entry = function_tables_.LookupOrInsert( 759 ZoneHashMap::Entry* entry = function_tables_.LookupOrInsert(
708 v, ComputePointerHash(v), ZoneAllocationPolicy(zone())); 760 table->var(), ComputePointerHash(table->var()),
709 entry->value = container; 761 ZoneAllocationPolicy(zone()));
762 entry->value = indices;
763 return indices;
710 } 764 }
711 765
712 FunctionTableIndices* LookupFunctionTable(Variable* v) { 766 FunctionTableIndices* LookupFunctionTable(Variable* v) {
713 ZoneHashMap::Entry* entry = 767 ZoneHashMap::Entry* entry =
714 function_tables_.Lookup(v, ComputePointerHash(v)); 768 function_tables_.Lookup(v, ComputePointerHash(v));
715 DCHECK_NOT_NULL(entry); 769 if (entry == nullptr) {
770 return nullptr;
771 }
716 return reinterpret_cast<FunctionTableIndices*>(entry->value); 772 return reinterpret_cast<FunctionTableIndices*>(entry->value);
717 } 773 }
718 774
775 void PopulateFunctionTable(VariableProxy* table, ArrayLiteral* funcs) {
776 FunctionTableIndices* indices = LookupFunctionTable(table->var());
777 DCHECK_NOT_NULL(indices);
778 for (int i = 0; i < funcs->values()->length(); ++i) {
779 VariableProxy* func = funcs->values()->at(i)->AsVariableProxy();
780 DCHECK_NOT_NULL(func);
781 builder_->SetIndirectFunction(
782 indices->start_index + i,
783 LookupOrInsertFunction(func->var())->func_index());
784 }
785 }
786
719 class ImportedFunctionTable { 787 class ImportedFunctionTable {
720 private: 788 private:
721 class ImportedFunctionIndices : public ZoneObject { 789 class ImportedFunctionIndices : public ZoneObject {
722 public: 790 public:
723 const char* name_; 791 const char* name_;
724 int name_length_; 792 int name_length_;
725 WasmModuleBuilder::SignatureMap signature_to_index_; 793 WasmModuleBuilder::SignatureMap signature_to_index_;
726 794
727 ImportedFunctionIndices(const char* name, int name_length, Zone* zone) 795 ImportedFunctionIndices(const char* name, int name_length, Zone* zone)
728 : name_(name), name_length_(name_length), signature_to_index_(zone) {} 796 : name_(name), name_length_(name_length), signature_to_index_(zone) {}
729 }; 797 };
730 ZoneHashMap table_; 798 ZoneHashMap table_;
731 AsmWasmBuilderImpl* builder_; 799 AsmWasmBuilderImpl* builder_;
732 800
733 public: 801 public:
734 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder) 802 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder)
735 : table_(ZoneHashMap::kDefaultHashMapCapacity, 803 : table_(ZoneHashMap::kDefaultHashMapCapacity,
736 ZoneAllocationPolicy(builder->zone())), 804 ZoneAllocationPolicy(builder->zone())),
737 builder_(builder) {} 805 builder_(builder) {}
738 806
739 void AddImport(Variable* v, const char* name, int name_length) { 807 ImportedFunctionIndices* LookupOrInsertImport(Variable* v) {
740 ImportedFunctionIndices* indices = new (builder_->zone())
741 ImportedFunctionIndices(name, name_length, builder_->zone());
742 auto* entry = table_.LookupOrInsert( 808 auto* entry = table_.LookupOrInsert(
743 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone())); 809 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone()));
744 entry->value = indices; 810 ImportedFunctionIndices* indices;
811 if (entry->value == nullptr) {
812 indices = new (builder_->zone())
813 ImportedFunctionIndices(nullptr, 0, builder_->zone());
814 entry->value = indices;
815 } else {
816 indices = reinterpret_cast<ImportedFunctionIndices*>(entry->value);
817 }
818 return indices;
819 }
820
821 void SetImportName(Variable* v, const char* name, int name_length) {
822 auto* indices = LookupOrInsertImport(v);
823 indices->name_ = name;
824 indices->name_length_ = name_length;
825 for (auto i : indices->signature_to_index_) {
826 builder_->builder_->SetImportName(i.second, indices->name_,
827 indices->name_length_);
828 }
745 } 829 }
746 830
747 // Get a function's index (or allocate if new). 831 // Get a function's index (or allocate if new).
748 uint32_t LookupOrInsertImport(Variable* v, FunctionSig* sig) { 832 uint32_t LookupOrInsertImportUse(Variable* v, FunctionSig* sig) {
749 ZoneHashMap::Entry* entry = table_.Lookup(v, ComputePointerHash(v)); 833 auto* indices = LookupOrInsertImport(v);
750 DCHECK_NOT_NULL(entry);
751 ImportedFunctionIndices* indices =
752 reinterpret_cast<ImportedFunctionIndices*>(entry->value);
753 WasmModuleBuilder::SignatureMap::iterator pos = 834 WasmModuleBuilder::SignatureMap::iterator pos =
754 indices->signature_to_index_.find(sig); 835 indices->signature_to_index_.find(sig);
755 if (pos != indices->signature_to_index_.end()) { 836 if (pos != indices->signature_to_index_.end()) {
756 return pos->second; 837 return pos->second;
757 } else { 838 } else {
758 uint32_t index = builder_->builder_->AddImport( 839 uint32_t index = builder_->builder_->AddImport(
759 indices->name_, indices->name_length_, sig); 840 indices->name_, indices->name_length_, sig);
760 indices->signature_to_index_[sig] = index; 841 indices->signature_to_index_[sig] = index;
761 return index; 842 return index;
762 } 843 }
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 } 984 }
904 Property* prop = expr->value()->AsProperty(); 985 Property* prop = expr->value()->AsProperty();
905 if (prop != nullptr) { 986 if (prop != nullptr) {
906 VariableProxy* vp = prop->obj()->AsVariableProxy(); 987 VariableProxy* vp = prop->obj()->AsVariableProxy();
907 if (vp != nullptr && vp->var()->IsParameter() && 988 if (vp != nullptr && vp->var()->IsParameter() &&
908 vp->var()->index() == 1) { 989 vp->var()->index() == 1) {
909 VariableProxy* target = expr->target()->AsVariableProxy(); 990 VariableProxy* target = expr->target()->AsVariableProxy();
910 if (typer_->TypeOf(target)->AsFFIType() != nullptr) { 991 if (typer_->TypeOf(target)->AsFFIType() != nullptr) {
911 const AstRawString* name = 992 const AstRawString* name =
912 prop->key()->AsLiteral()->AsRawPropertyName(); 993 prop->key()->AsLiteral()->AsRawPropertyName();
913 imported_function_table_.AddImport( 994 imported_function_table_.SetImportName(
914 target->var(), reinterpret_cast<const char*>(name->raw_data()), 995 target->var(), reinterpret_cast<const char*>(name->raw_data()),
915 name->length()); 996 name->length());
916 } 997 }
917 } 998 }
918 // Property values in module scope don't emit code, so return. 999 // Property values in module scope don't emit code, so return.
919 return; 1000 return;
920 } 1001 }
921 ArrayLiteral* funcs = expr->value()->AsArrayLiteral(); 1002 ArrayLiteral* funcs = expr->value()->AsArrayLiteral();
922 if (funcs != nullptr && 1003 if (funcs != nullptr) {
923 typer_->TypeOf(funcs)
924 ->AsFunctionTableType()
925 ->signature()
926 ->AsFunctionType()) {
927 VariableProxy* target = expr->target()->AsVariableProxy(); 1004 VariableProxy* target = expr->target()->AsVariableProxy();
928 DCHECK_NOT_NULL(target); 1005 DCHECK_NOT_NULL(target);
929 AddFunctionTable(target, funcs); 1006 PopulateFunctionTable(target, funcs);
930 // Only add to the function table. No init needed. 1007 // Only add to the function table. No init needed.
931 return; 1008 return;
932 } 1009 }
933 if (expr->value()->IsCallNew()) { 1010 if (expr->value()->IsCallNew()) {
934 // No init code to emit for CallNew nodes. 1011 // No init code to emit for CallNew nodes.
935 return; 1012 return;
936 } 1013 }
937 as_init = true; 1014 as_init = true;
938 } 1015 }
939 1016
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
1354 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, 1431 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
1355 args->length()); 1432 args->length());
1356 if (return_type != kAstStmt) { 1433 if (return_type != kAstStmt) {
1357 sig.AddReturn(return_type); 1434 sig.AddReturn(return_type);
1358 } else { 1435 } else {
1359 returns_value = false; 1436 returns_value = false;
1360 } 1437 }
1361 for (int i = 0; i < args->length(); ++i) { 1438 for (int i = 0; i < args->length(); ++i) {
1362 sig.AddParam(TypeOf(args->at(i))); 1439 sig.AddParam(TypeOf(args->at(i)));
1363 } 1440 }
1364 uint32_t index = imported_function_table_.LookupOrInsertImport( 1441 uint32_t index = imported_function_table_.LookupOrInsertImportUse(
1365 vp->var(), sig.Build()); 1442 vp->var(), sig.Build());
1366 VisitCallArgs(expr); 1443 VisitCallArgs(expr);
1367 current_function_builder_->Emit(kExprCallFunction); 1444 current_function_builder_->Emit(kExprCallFunction);
1368 current_function_builder_->EmitVarInt(index); 1445 current_function_builder_->EmitVarInt(index);
1369 } else { 1446 } else {
1370 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var()); 1447 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var());
1371 VisitCallArgs(expr); 1448 VisitCallArgs(expr);
1372 current_function_builder_->Emit(kExprCallFunction); 1449 current_function_builder_->Emit(kExprCallFunction);
1373 current_function_builder_->EmitDirectCallIndex( 1450 current_function_builder_->EmitDirectCallIndex(
1374 function->func_index()); 1451 function->func_index());
1375 returns_value = function->signature()->return_count() > 0; 1452 returns_value = function->signature()->return_count() > 0;
1376 } 1453 }
1377 break; 1454 break;
1378 } 1455 }
1379 case Call::KEYED_PROPERTY_CALL: { 1456 case Call::KEYED_PROPERTY_CALL: {
1380 DCHECK_EQ(kFuncScope, scope_); 1457 DCHECK_EQ(kFuncScope, scope_);
1381 Property* p = expr->expression()->AsProperty(); 1458 Property* p = expr->expression()->AsProperty();
1382 DCHECK_NOT_NULL(p); 1459 DCHECK_NOT_NULL(p);
1383 VariableProxy* var = p->obj()->AsVariableProxy(); 1460 VariableProxy* var = p->obj()->AsVariableProxy();
1384 DCHECK_NOT_NULL(var); 1461 DCHECK_NOT_NULL(var);
1385 FunctionTableIndices* indices = LookupFunctionTable(var->var()); 1462 FunctionTableIndices* indices = LookupOrAddFunctionTable(var, p);
1386 Visit(p->key()); // TODO(titzer): should use RECURSE() 1463 Visit(p->key()); // TODO(titzer): should use RECURSE()
1387 1464
1388 // We have to use a temporary for the correct order of evaluation. 1465 // We have to use a temporary for the correct order of evaluation.
1389 current_function_builder_->EmitI32Const(indices->start_index); 1466 current_function_builder_->EmitI32Const(indices->start_index);
1390 current_function_builder_->Emit(kExprI32Add); 1467 current_function_builder_->Emit(kExprI32Add);
1391 WasmTemporary tmp(current_function_builder_, kAstI32); 1468 WasmTemporary tmp(current_function_builder_, kAstI32);
1392 current_function_builder_->EmitSetLocal(tmp.index()); 1469 current_function_builder_->EmitSetLocal(tmp.index());
1393 1470
1394 VisitCallArgs(expr); 1471 VisitCallArgs(expr);
1395 1472
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1720 #undef NON_SIGNED_INT 1797 #undef NON_SIGNED_INT
1721 #undef SIGNED 1798 #undef SIGNED
1722 #undef NON_SIGNED 1799 #undef NON_SIGNED
1723 1800
1724 void VisitThisFunction(ThisFunction* expr) { UNREACHABLE(); } 1801 void VisitThisFunction(ThisFunction* expr) { UNREACHABLE(); }
1725 1802
1726 void VisitDeclarations(ZoneList<Declaration*>* decls) { 1803 void VisitDeclarations(ZoneList<Declaration*>* decls) {
1727 for (int i = 0; i < decls->length(); ++i) { 1804 for (int i = 0; i < decls->length(); ++i) {
1728 Declaration* decl = decls->at(i); 1805 Declaration* decl = decls->at(i);
1729 RECURSE(Visit(decl)); 1806 RECURSE(Visit(decl));
1807 if (typer_failed_) {
1808 return;
1809 }
1730 } 1810 }
1731 } 1811 }
1732 1812
1733 void VisitClassLiteral(ClassLiteral* expr) { UNREACHABLE(); } 1813 void VisitClassLiteral(ClassLiteral* expr) { UNREACHABLE(); }
1734 1814
1735 void VisitSpread(Spread* expr) { UNREACHABLE(); } 1815 void VisitSpread(Spread* expr) { UNREACHABLE(); }
1736 1816
1737 void VisitSuperPropertyReference(SuperPropertyReference* expr) { 1817 void VisitSuperPropertyReference(SuperPropertyReference* expr) {
1738 UNREACHABLE(); 1818 UNREACHABLE();
1739 } 1819 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 1927
1848 ZoneHashMap local_variables_; 1928 ZoneHashMap local_variables_;
1849 ZoneHashMap functions_; 1929 ZoneHashMap functions_;
1850 ZoneHashMap global_variables_; 1930 ZoneHashMap global_variables_;
1851 AsmScope scope_; 1931 AsmScope scope_;
1852 WasmModuleBuilder* builder_; 1932 WasmModuleBuilder* builder_;
1853 WasmFunctionBuilder* current_function_builder_; 1933 WasmFunctionBuilder* current_function_builder_;
1854 FunctionLiteral* literal_; 1934 FunctionLiteral* literal_;
1855 Isolate* isolate_; 1935 Isolate* isolate_;
1856 Zone* zone_; 1936 Zone* zone_;
1937 Script* script_;
1857 AsmTyper* typer_; 1938 AsmTyper* typer_;
1939 bool typer_failed_;
1858 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; 1940 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
1859 ZoneVector<ForeignVariable> foreign_variables_; 1941 ZoneVector<ForeignVariable> foreign_variables_;
1860 WasmFunctionBuilder* init_function_; 1942 WasmFunctionBuilder* init_function_;
1861 WasmFunctionBuilder* foreign_init_function_; 1943 WasmFunctionBuilder* foreign_init_function_;
1862 uint32_t next_table_index_; 1944 uint32_t next_table_index_;
1863 ZoneHashMap function_tables_; 1945 ZoneHashMap function_tables_;
1864 ImportedFunctionTable imported_function_table_; 1946 ImportedFunctionTable imported_function_table_;
1865 1947
1866 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 1948 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
1867 1949
1868 private: 1950 private:
1869 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); 1951 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl);
1870 }; 1952 };
1871 1953
1872 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, 1954 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, Script* script,
1873 FunctionLiteral* literal, AsmTyper* typer) 1955 FunctionLiteral* literal)
1874 : isolate_(isolate), zone_(zone), literal_(literal), typer_(typer) {} 1956 : isolate_(isolate),
1957 zone_(zone),
1958 script_(script),
1959 literal_(literal),
1960 typer_(isolate, zone, script, literal) {}
1875 1961
1876 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so 1962 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so
1877 // that zone in constructor may be thrown away once wasm module is written. 1963 // that zone in constructor may be thrown away once wasm module is written.
1878 ZoneBuffer* AsmWasmBuilder::Run(i::Handle<i::FixedArray>* foreign_args) { 1964 ZoneBuffer* AsmWasmBuilder::Run(i::Handle<i::FixedArray>* foreign_args) {
1879 AsmWasmBuilderImpl impl(isolate_, zone_, literal_, typer_); 1965 AsmWasmBuilderImpl impl(isolate_, zone_, script_, literal_, &typer_);
1880 impl.Build(); 1966 if (!impl.Build()) {
1967 return nullptr;
1968 }
1881 *foreign_args = impl.GetForeignArgs(); 1969 *foreign_args = impl.GetForeignArgs();
1882 ZoneBuffer* buffer = new (zone_) ZoneBuffer(zone_); 1970 ZoneBuffer* buffer = new (zone_) ZoneBuffer(zone_);
1883 impl.builder_->WriteTo(*buffer); 1971 impl.builder_->WriteTo(*buffer);
1884 return buffer; 1972 return buffer;
1885 } 1973 }
1886 1974
1887 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__"; 1975 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__";
1888 const char* AsmWasmBuilder::single_function_name = "__single_function__"; 1976 const char* AsmWasmBuilder::single_function_name = "__single_function__";
1889 1977
1890 } // namespace wasm 1978 } // namespace wasm
1891 } // namespace internal 1979 } // namespace internal
1892 } // namespace v8 1980 } // namespace v8
OLDNEW
« src/asmjs/asm-typer.h ('K') | « src/asmjs/asm-wasm-builder.h ('k') | src/ast/ast.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698