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

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: Fix DCHECKS 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 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/asmjs/switch-logic.h" 15 #include "src/asmjs/switch-logic.h"
16 16
17 #include "src/wasm/wasm-macro-gen.h" 17 #include "src/wasm/wasm-macro-gen.h"
18 #include "src/wasm/wasm-opcodes.h" 18 #include "src/wasm/wasm-opcodes.h"
19 19
20 #include "src/ast/ast.h" 20 #include "src/ast/ast.h"
21 #include "src/ast/scopes.h" 21 #include "src/ast/scopes.h"
22 #include "src/codegen.h"
23 #include "src/compiler.h"
24 #include "src/isolate.h"
25 #include "src/parsing/parse-info.h"
22 26
23 namespace v8 { 27 namespace v8 {
24 namespace internal { 28 namespace internal {
25 namespace wasm { 29 namespace wasm {
26 30
27 #define RECURSE(call) \ 31 #define RECURSE(call) \
28 do { \ 32 do { \
29 DCHECK(!HasStackOverflow()); \ 33 DCHECK(!HasStackOverflow()); \
30 call; \ 34 call; \
31 if (HasStackOverflow()) return; \ 35 if (HasStackOverflow()) return; \
32 } while (false) 36 } while (false)
33 37
34 enum AsmScope { kModuleScope, kInitScope, kFuncScope, kExportScope }; 38 enum AsmScope { kModuleScope, kInitScope, kFuncScope, kExportScope };
35 enum ValueFate { kDrop, kLeaveOnStack }; 39 enum ValueFate { kDrop, kLeaveOnStack };
36 40
37 struct ForeignVariable { 41 struct ForeignVariable {
38 Handle<Name> name; 42 Handle<Name> name;
39 Variable* var; 43 Variable* var;
40 LocalType type; 44 LocalType type;
41 }; 45 };
42 46
43 class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> { 47 class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
44 public: 48 public:
45 AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, FunctionLiteral* literal, 49 AsmWasmBuilderImpl(Isolate* isolate, Zone* zone,
46 AsmTyper* typer) 50 AstValueFactory* ast_value_factory, Script* script,
51 FunctionLiteral* literal, AsmTyper* typer)
47 : local_variables_(ZoneHashMap::kDefaultHashMapCapacity, 52 : local_variables_(ZoneHashMap::kDefaultHashMapCapacity,
48 ZoneAllocationPolicy(zone)), 53 ZoneAllocationPolicy(zone)),
49 functions_(ZoneHashMap::kDefaultHashMapCapacity, 54 functions_(ZoneHashMap::kDefaultHashMapCapacity,
50 ZoneAllocationPolicy(zone)), 55 ZoneAllocationPolicy(zone)),
51 global_variables_(ZoneHashMap::kDefaultHashMapCapacity, 56 global_variables_(ZoneHashMap::kDefaultHashMapCapacity,
52 ZoneAllocationPolicy(zone)), 57 ZoneAllocationPolicy(zone)),
53 scope_(kModuleScope), 58 scope_(kModuleScope),
54 builder_(new (zone) WasmModuleBuilder(zone)), 59 builder_(new (zone) WasmModuleBuilder(zone)),
55 current_function_builder_(nullptr), 60 current_function_builder_(nullptr),
56 literal_(literal), 61 literal_(literal),
57 isolate_(isolate), 62 isolate_(isolate),
58 zone_(zone), 63 zone_(zone),
64 ast_value_factory_(ast_value_factory),
65 script_(script),
59 typer_(typer), 66 typer_(typer),
67 typer_failed_(false),
60 breakable_blocks_(zone), 68 breakable_blocks_(zone),
61 foreign_variables_(zone), 69 foreign_variables_(zone),
62 init_function_(nullptr), 70 init_function_(nullptr),
63 foreign_init_function_(nullptr), 71 foreign_init_function_(nullptr),
64 next_table_index_(0),
65 function_tables_(ZoneHashMap::kDefaultHashMapCapacity, 72 function_tables_(ZoneHashMap::kDefaultHashMapCapacity,
66 ZoneAllocationPolicy(zone)), 73 ZoneAllocationPolicy(zone)),
67 imported_function_table_(this) { 74 imported_function_table_(this) {
68 InitializeAstVisitor(isolate); 75 InitializeAstVisitor(isolate);
69 } 76 }
70 77
71 void InitializeInitFunction() { 78 void InitializeInitFunction() {
72 FunctionSig::Builder b(zone(), 0, 0); 79 FunctionSig::Builder b(zone(), 0, 0);
73 init_function_ = builder_->AddFunction(b.Build()); 80 init_function_ = builder_->AddFunction(b.Build());
74 builder_->MarkStartFunction(init_function_); 81 builder_->MarkStartFunction(init_function_);
(...skipping 20 matching lines...) Expand all
95 i::Handle<i::FixedArray> GetForeignArgs() { 102 i::Handle<i::FixedArray> GetForeignArgs() {
96 i::Handle<FixedArray> ret = isolate_->factory()->NewFixedArray( 103 i::Handle<FixedArray> ret = isolate_->factory()->NewFixedArray(
97 static_cast<int>(foreign_variables_.size())); 104 static_cast<int>(foreign_variables_.size()));
98 for (size_t i = 0; i < foreign_variables_.size(); ++i) { 105 for (size_t i = 0; i < foreign_variables_.size(); ++i) {
99 ForeignVariable* fv = &foreign_variables_[i]; 106 ForeignVariable* fv = &foreign_variables_[i];
100 ret->set(static_cast<int>(i), *fv->name); 107 ret->set(static_cast<int>(i), *fv->name);
101 } 108 }
102 return ret; 109 return ret;
103 } 110 }
104 111
105 void Build() { 112 bool Build() {
106 InitializeInitFunction(); 113 InitializeInitFunction();
107 RECURSE(VisitFunctionLiteral(literal_)); 114 if (!typer_->ValidateBeforeFunctionsPhase()) {
115 return false;
116 }
117 DCHECK(!HasStackOverflow());
118 VisitFunctionLiteral(literal_);
119 if (HasStackOverflow()) {
120 return false;
121 }
122 if (typer_failed_) {
123 return false;
124 }
108 BuildForeignInitFunction(); 125 BuildForeignInitFunction();
126 return true;
109 } 127 }
110 128
111 void VisitVariableDeclaration(VariableDeclaration* decl) {} 129 void VisitVariableDeclaration(VariableDeclaration* decl) {}
112 130
113 void VisitFunctionDeclaration(FunctionDeclaration* decl) { 131 void VisitFunctionDeclaration(FunctionDeclaration* decl) {
114 DCHECK_EQ(kModuleScope, scope_); 132 DCHECK_EQ(kModuleScope, scope_);
115 DCHECK_NULL(current_function_builder_); 133 DCHECK_NULL(current_function_builder_);
134 FunctionLiteral* old_func = decl->fun();
135 i::Zone zone(isolate_->allocator(), ZONE_NAME);
titzer 2016/11/29 14:57:37 Can you leave off the i:: prefix, since we really
bradn 2016/11/29 22:09:06 Done.
136 DeclarationScope* new_func_scope = nullptr;
137 if (decl->fun()->body() == nullptr) {
138 // TODO(bradnelson): Refactor parser so we don't need a
139 // SharedFunctionInfo to parse a single function,
140 // or squirrel away the SharedFunctionInfo to use later.
141 Handle<SharedFunctionInfo> shared =
142 isolate_->factory()->NewSharedFunctionInfoForLiteral(
143 decl->fun(), handle(script_, isolate_));
144 shared->set_is_toplevel(false);
145 i::ParseInfo info(&zone, handle(script_, isolate_));
146 info.set_shared_info(shared);
147 info.set_toplevel(false);
148 info.set_language_mode(decl->fun()->scope()->language_mode());
149 info.set_allow_lazy_parsing(false);
150 info.set_function_literal_id(shared->function_literal_id());
151 info.set_ast_value_factory(ast_value_factory_);
152 info.set_ast_value_factory_owned(false);
153 // Create fresh function scope to use to parse the function in.
154 new_func_scope = new (info.zone()) DeclarationScope(
155 info.zone(), decl->fun()->scope()->outer_scope(), FUNCTION_SCOPE);
156 info.set_asm_function_scope(new_func_scope);
157 if (!i::Compiler::ParseAndAnalyze(&info)) {
158 typer_failed_ = true;
159 return;
160 }
161 FunctionLiteral* func = info.literal();
162 DCHECK_NOT_NULL(func);
163 decl->set_fun(func);
164 }
165 if (!typer_->ValidateInnerFunction(decl)) {
166 typer_failed_ = true;
167 decl->set_fun(old_func);
168 if (new_func_scope != nullptr) {
169 DCHECK_EQ(new_func_scope, decl->scope()->inner_scope());
170 if (!decl->scope()->RemoveInnerScope(new_func_scope)) {
171 UNREACHABLE();
172 }
173 }
174 return;
175 }
116 current_function_builder_ = LookupOrInsertFunction(decl->proxy()->var()); 176 current_function_builder_ = LookupOrInsertFunction(decl->proxy()->var());
117 scope_ = kFuncScope; 177 scope_ = kFuncScope;
118 RECURSE(Visit(decl->fun())); 178 RECURSE(Visit(decl->fun()));
179 decl->set_fun(old_func);
180 if (new_func_scope != nullptr) {
181 DCHECK_EQ(new_func_scope, decl->scope()->inner_scope());
182 if (!decl->scope()->RemoveInnerScope(new_func_scope)) {
183 UNREACHABLE();
184 }
185 }
119 scope_ = kModuleScope; 186 scope_ = kModuleScope;
120 current_function_builder_ = nullptr; 187 current_function_builder_ = nullptr;
121 local_variables_.Clear(); 188 local_variables_.Clear();
189 typer_->ClearFunctionNodeTypes();
122 } 190 }
123 191
124 void VisitStatements(ZoneList<Statement*>* stmts) { 192 void VisitStatements(ZoneList<Statement*>* stmts) {
125 for (int i = 0; i < stmts->length(); ++i) { 193 for (int i = 0; i < stmts->length(); ++i) {
126 Statement* stmt = stmts->at(i); 194 Statement* stmt = stmts->at(i);
127 ExpressionStatement* e = stmt->AsExpressionStatement(); 195 ExpressionStatement* e = stmt->AsExpressionStatement();
128 if (e != nullptr && e->expression()->IsUndefinedLiteral()) { 196 if (e != nullptr && e->expression()->IsUndefinedLiteral()) {
129 continue; 197 continue;
130 } 198 }
131 RECURSE(Visit(stmt)); 199 RECURSE(Visit(stmt));
200 if (typer_failed_) break;
132 if (stmt->IsJump()) break; 201 if (stmt->IsJump()) break;
133 } 202 }
134 } 203 }
135 204
136 void VisitBlock(Block* stmt) { 205 void VisitBlock(Block* stmt) {
137 if (stmt->statements()->length() == 1) { 206 if (stmt->statements()->length() == 1) {
138 ExpressionStatement* expr = 207 ExpressionStatement* expr =
139 stmt->statements()->at(0)->AsExpressionStatement(); 208 stmt->statements()->at(0)->AsExpressionStatement();
140 if (expr != nullptr) { 209 if (expr != nullptr) {
141 if (expr->expression()->IsAssignment()) { 210 if (expr->expression()->IsAssignment()) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 void VisitContinueStatement(ContinueStatement* stmt) { 307 void VisitContinueStatement(ContinueStatement* stmt) {
239 DoBreakOrContinue(stmt->target(), true); 308 DoBreakOrContinue(stmt->target(), true);
240 } 309 }
241 310
242 void VisitBreakStatement(BreakStatement* stmt) { 311 void VisitBreakStatement(BreakStatement* stmt) {
243 DoBreakOrContinue(stmt->target(), false); 312 DoBreakOrContinue(stmt->target(), false);
244 } 313 }
245 314
246 void VisitReturnStatement(ReturnStatement* stmt) { 315 void VisitReturnStatement(ReturnStatement* stmt) {
247 if (scope_ == kModuleScope) { 316 if (scope_ == kModuleScope) {
317 if (!typer_->ValidateAfterFunctionsPhase()) {
318 typer_failed_ = true;
319 return;
320 }
248 scope_ = kExportScope; 321 scope_ = kExportScope;
249 RECURSE(Visit(stmt->expression())); 322 RECURSE(Visit(stmt->expression()));
250 scope_ = kModuleScope; 323 scope_ = kModuleScope;
251 } else if (scope_ == kFuncScope) { 324 } else if (scope_ == kFuncScope) {
252 RECURSE(Visit(stmt->expression())); 325 RECURSE(Visit(stmt->expression()));
253 current_function_builder_->Emit(kExprReturn); 326 current_function_builder_->Emit(kExprReturn);
254 } else { 327 } else {
255 UNREACHABLE(); 328 UNREACHABLE();
256 } 329 }
257 } 330 }
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 const auto& arguments = func_type->Arguments(); 514 const auto& arguments = func_type->Arguments();
442 for (int i = 0; i < expr->parameter_count(); ++i) { 515 for (int i = 0; i < expr->parameter_count(); ++i) {
443 LocalType type = TypeFrom(arguments[i]); 516 LocalType type = TypeFrom(arguments[i]);
444 DCHECK_NE(kAstStmt, type); 517 DCHECK_NE(kAstStmt, type);
445 InsertParameter(scope->parameter(i), type, i); 518 InsertParameter(scope->parameter(i), type, i);
446 } 519 }
447 } else { 520 } else {
448 UNREACHABLE(); 521 UNREACHABLE();
449 } 522 }
450 } 523 }
524 RECURSE(VisitDeclarations(scope->declarations()));
525 if (typer_failed_) return;
451 RECURSE(VisitStatements(expr->body())); 526 RECURSE(VisitStatements(expr->body()));
452 RECURSE(VisitDeclarations(scope->declarations()));
453 } 527 }
454 528
455 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 529 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
456 UNREACHABLE(); 530 UNREACHABLE();
457 } 531 }
458 532
459 void VisitConditional(Conditional* expr) { 533 void VisitConditional(Conditional* expr) {
460 DCHECK_EQ(kFuncScope, scope_); 534 DCHECK_EQ(kFuncScope, scope_);
461 RECURSE(Visit(expr->condition())); 535 RECURSE(Visit(expr->condition()));
462 // WASM ifs come with implicit blocks for both arms. 536 // WASM ifs come with implicit blocks for both arms.
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 void LoadInitFunction() { 727 void LoadInitFunction() {
654 current_function_builder_ = init_function_; 728 current_function_builder_ = init_function_;
655 scope_ = kInitScope; 729 scope_ = kInitScope;
656 } 730 }
657 731
658 void UnLoadInitFunction() { 732 void UnLoadInitFunction() {
659 scope_ = kModuleScope; 733 scope_ = kModuleScope;
660 current_function_builder_ = nullptr; 734 current_function_builder_ = nullptr;
661 } 735 }
662 736
663 void AddFunctionTable(VariableProxy* table, ArrayLiteral* funcs) { 737 struct FunctionTableIndices : public ZoneObject {
664 auto* func_tbl_type = typer_->TypeOf(funcs)->AsFunctionTableType(); 738 uint32_t start_index;
665 DCHECK_NOT_NULL(func_tbl_type); 739 uint32_t signature_index;
666 auto* func_type = func_tbl_type->signature()->AsFunctionType(); 740 };
741
742 FunctionTableIndices* LookupOrAddFunctionTable(VariableProxy* table,
743 Property* p) {
744 FunctionTableIndices* indices = LookupFunctionTable(table->var());
745 if (indices != nullptr) {
746 // Already setup.
747 return indices;
748 }
749 indices = new (zone()) FunctionTableIndices();
750 auto* func_type = typer_->TypeOf(p)->AsFunctionType();
751 auto* func_table_type = typer_->TypeOf(p->obj()->AsVariableProxy()->var())
752 ->AsFunctionTableType();
667 const auto& arguments = func_type->Arguments(); 753 const auto& arguments = func_type->Arguments();
668 LocalType return_type = TypeFrom(func_type->ReturnType()); 754 LocalType return_type = TypeFrom(func_type->ReturnType());
669 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, 755 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
670 arguments.size()); 756 arguments.size());
671 if (return_type != kAstStmt) { 757 if (return_type != kAstStmt) {
672 sig.AddReturn(return_type); 758 sig.AddReturn(return_type);
673 } 759 }
674 for (auto* arg : arguments) { 760 for (auto* arg : arguments) {
675 sig.AddParam(TypeFrom(arg)); 761 sig.AddParam(TypeFrom(arg));
676 } 762 }
677 uint32_t signature_index = builder_->AddSignature(sig.Build()); 763 uint32_t signature_index = builder_->AddSignature(sig.Build());
678 InsertFunctionTable(table->var(), next_table_index_, signature_index); 764 indices->start_index = builder_->AllocateIndirectFunctions(
679 next_table_index_ += funcs->values()->length(); 765 static_cast<uint32_t>(func_table_type->length()));
680 for (int i = 0; i < funcs->values()->length(); ++i) { 766 indices->signature_index = signature_index;
681 VariableProxy* func = funcs->values()->at(i)->AsVariableProxy();
682 DCHECK_NOT_NULL(func);
683 builder_->AddIndirectFunction(
684 LookupOrInsertFunction(func->var())->func_index());
685 }
686 }
687
688 struct FunctionTableIndices : public ZoneObject {
689 uint32_t start_index;
690 uint32_t signature_index;
691 };
692
693 void InsertFunctionTable(Variable* v, uint32_t start_index,
694 uint32_t signature_index) {
695 FunctionTableIndices* container = new (zone()) FunctionTableIndices();
696 container->start_index = start_index;
697 container->signature_index = signature_index;
698 ZoneHashMap::Entry* entry = function_tables_.LookupOrInsert( 767 ZoneHashMap::Entry* entry = function_tables_.LookupOrInsert(
699 v, ComputePointerHash(v), ZoneAllocationPolicy(zone())); 768 table->var(), ComputePointerHash(table->var()),
700 entry->value = container; 769 ZoneAllocationPolicy(zone()));
770 entry->value = indices;
771 return indices;
701 } 772 }
702 773
703 FunctionTableIndices* LookupFunctionTable(Variable* v) { 774 FunctionTableIndices* LookupFunctionTable(Variable* v) {
704 ZoneHashMap::Entry* entry = 775 ZoneHashMap::Entry* entry =
705 function_tables_.Lookup(v, ComputePointerHash(v)); 776 function_tables_.Lookup(v, ComputePointerHash(v));
706 DCHECK_NOT_NULL(entry); 777 if (entry == nullptr) {
778 return nullptr;
779 }
707 return reinterpret_cast<FunctionTableIndices*>(entry->value); 780 return reinterpret_cast<FunctionTableIndices*>(entry->value);
708 } 781 }
709 782
783 void PopulateFunctionTable(VariableProxy* table, ArrayLiteral* funcs) {
784 FunctionTableIndices* indices = LookupFunctionTable(table->var());
785 DCHECK_NOT_NULL(indices);
786 for (int i = 0; i < funcs->values()->length(); ++i) {
787 VariableProxy* func = funcs->values()->at(i)->AsVariableProxy();
788 DCHECK_NOT_NULL(func);
789 builder_->SetIndirectFunction(
790 indices->start_index + i,
791 LookupOrInsertFunction(func->var())->func_index());
792 }
793 }
794
710 class ImportedFunctionTable { 795 class ImportedFunctionTable {
711 private: 796 private:
712 class ImportedFunctionIndices : public ZoneObject { 797 class ImportedFunctionIndices : public ZoneObject {
713 public: 798 public:
714 const char* name_; 799 const char* name_;
715 int name_length_; 800 int name_length_;
716 WasmModuleBuilder::SignatureMap signature_to_index_; 801 WasmModuleBuilder::SignatureMap signature_to_index_;
717 802
718 ImportedFunctionIndices(const char* name, int name_length, Zone* zone) 803 ImportedFunctionIndices(const char* name, int name_length, Zone* zone)
719 : name_(name), name_length_(name_length), signature_to_index_(zone) {} 804 : name_(name), name_length_(name_length), signature_to_index_(zone) {}
720 }; 805 };
721 ZoneHashMap table_; 806 ZoneHashMap table_;
722 AsmWasmBuilderImpl* builder_; 807 AsmWasmBuilderImpl* builder_;
723 808
724 public: 809 public:
725 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder) 810 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder)
726 : table_(ZoneHashMap::kDefaultHashMapCapacity, 811 : table_(ZoneHashMap::kDefaultHashMapCapacity,
727 ZoneAllocationPolicy(builder->zone())), 812 ZoneAllocationPolicy(builder->zone())),
728 builder_(builder) {} 813 builder_(builder) {}
729 814
730 void AddImport(Variable* v, const char* name, int name_length) { 815 ImportedFunctionIndices* LookupOrInsertImport(Variable* v) {
731 ImportedFunctionIndices* indices = new (builder_->zone())
732 ImportedFunctionIndices(name, name_length, builder_->zone());
733 auto* entry = table_.LookupOrInsert( 816 auto* entry = table_.LookupOrInsert(
734 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone())); 817 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone()));
735 entry->value = indices; 818 ImportedFunctionIndices* indices;
819 if (entry->value == nullptr) {
820 indices = new (builder_->zone())
821 ImportedFunctionIndices(nullptr, 0, builder_->zone());
822 entry->value = indices;
823 } else {
824 indices = reinterpret_cast<ImportedFunctionIndices*>(entry->value);
825 }
826 return indices;
827 }
828
829 void SetImportName(Variable* v, const char* name, int name_length) {
830 auto* indices = LookupOrInsertImport(v);
831 indices->name_ = name;
832 indices->name_length_ = name_length;
833 for (auto i : indices->signature_to_index_) {
834 builder_->builder_->SetImportName(i.second, indices->name_,
835 indices->name_length_);
836 }
736 } 837 }
737 838
738 // Get a function's index (or allocate if new). 839 // Get a function's index (or allocate if new).
739 uint32_t LookupOrInsertImport(Variable* v, FunctionSig* sig) { 840 uint32_t LookupOrInsertImportUse(Variable* v, FunctionSig* sig) {
740 ZoneHashMap::Entry* entry = table_.Lookup(v, ComputePointerHash(v)); 841 auto* indices = LookupOrInsertImport(v);
741 DCHECK_NOT_NULL(entry);
742 ImportedFunctionIndices* indices =
743 reinterpret_cast<ImportedFunctionIndices*>(entry->value);
744 WasmModuleBuilder::SignatureMap::iterator pos = 842 WasmModuleBuilder::SignatureMap::iterator pos =
745 indices->signature_to_index_.find(sig); 843 indices->signature_to_index_.find(sig);
746 if (pos != indices->signature_to_index_.end()) { 844 if (pos != indices->signature_to_index_.end()) {
747 return pos->second; 845 return pos->second;
748 } else { 846 } else {
749 uint32_t index = builder_->builder_->AddImport( 847 uint32_t index = builder_->builder_->AddImport(
750 indices->name_, indices->name_length_, sig); 848 indices->name_, indices->name_length_, sig);
751 indices->signature_to_index_[sig] = index; 849 indices->signature_to_index_[sig] = index;
752 return index; 850 return index;
753 } 851 }
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 } 992 }
895 Property* prop = expr->value()->AsProperty(); 993 Property* prop = expr->value()->AsProperty();
896 if (prop != nullptr) { 994 if (prop != nullptr) {
897 VariableProxy* vp = prop->obj()->AsVariableProxy(); 995 VariableProxy* vp = prop->obj()->AsVariableProxy();
898 if (vp != nullptr && vp->var()->IsParameter() && 996 if (vp != nullptr && vp->var()->IsParameter() &&
899 vp->var()->index() == 1) { 997 vp->var()->index() == 1) {
900 VariableProxy* target = expr->target()->AsVariableProxy(); 998 VariableProxy* target = expr->target()->AsVariableProxy();
901 if (typer_->TypeOf(target)->AsFFIType() != nullptr) { 999 if (typer_->TypeOf(target)->AsFFIType() != nullptr) {
902 const AstRawString* name = 1000 const AstRawString* name =
903 prop->key()->AsLiteral()->AsRawPropertyName(); 1001 prop->key()->AsLiteral()->AsRawPropertyName();
904 imported_function_table_.AddImport( 1002 imported_function_table_.SetImportName(
905 target->var(), reinterpret_cast<const char*>(name->raw_data()), 1003 target->var(), reinterpret_cast<const char*>(name->raw_data()),
906 name->length()); 1004 name->length());
907 } 1005 }
908 } 1006 }
909 // Property values in module scope don't emit code, so return. 1007 // Property values in module scope don't emit code, so return.
910 return; 1008 return;
911 } 1009 }
912 ArrayLiteral* funcs = expr->value()->AsArrayLiteral(); 1010 ArrayLiteral* funcs = expr->value()->AsArrayLiteral();
913 if (funcs != nullptr && 1011 if (funcs != nullptr) {
914 typer_->TypeOf(funcs)
915 ->AsFunctionTableType()
916 ->signature()
917 ->AsFunctionType()) {
918 VariableProxy* target = expr->target()->AsVariableProxy(); 1012 VariableProxy* target = expr->target()->AsVariableProxy();
919 DCHECK_NOT_NULL(target); 1013 DCHECK_NOT_NULL(target);
920 AddFunctionTable(target, funcs); 1014 PopulateFunctionTable(target, funcs);
921 // Only add to the function table. No init needed. 1015 // Only add to the function table. No init needed.
922 return; 1016 return;
923 } 1017 }
924 if (expr->value()->IsCallNew()) { 1018 if (expr->value()->IsCallNew()) {
925 // No init code to emit for CallNew nodes. 1019 // No init code to emit for CallNew nodes.
926 return; 1020 return;
927 } 1021 }
928 as_init = true; 1022 as_init = true;
929 } 1023 }
930 1024
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, 1412 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
1319 args->length()); 1413 args->length());
1320 if (return_type != kAstStmt) { 1414 if (return_type != kAstStmt) {
1321 sig.AddReturn(return_type); 1415 sig.AddReturn(return_type);
1322 } else { 1416 } else {
1323 returns_value = false; 1417 returns_value = false;
1324 } 1418 }
1325 for (int i = 0; i < args->length(); ++i) { 1419 for (int i = 0; i < args->length(); ++i) {
1326 sig.AddParam(TypeOf(args->at(i))); 1420 sig.AddParam(TypeOf(args->at(i)));
1327 } 1421 }
1328 uint32_t index = imported_function_table_.LookupOrInsertImport( 1422 uint32_t index = imported_function_table_.LookupOrInsertImportUse(
1329 vp->var(), sig.Build()); 1423 vp->var(), sig.Build());
1330 VisitCallArgs(expr); 1424 VisitCallArgs(expr);
1331 current_function_builder_->AddAsmWasmOffset(expr->position()); 1425 current_function_builder_->AddAsmWasmOffset(expr->position());
1332 current_function_builder_->Emit(kExprCallFunction); 1426 current_function_builder_->Emit(kExprCallFunction);
1333 current_function_builder_->EmitVarInt(index); 1427 current_function_builder_->EmitVarInt(index);
1334 } else { 1428 } else {
1335 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var()); 1429 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var());
1336 VisitCallArgs(expr); 1430 VisitCallArgs(expr);
1337 current_function_builder_->AddAsmWasmOffset(expr->position()); 1431 current_function_builder_->AddAsmWasmOffset(expr->position());
1338 current_function_builder_->Emit(kExprCallFunction); 1432 current_function_builder_->Emit(kExprCallFunction);
1339 current_function_builder_->EmitDirectCallIndex( 1433 current_function_builder_->EmitDirectCallIndex(
1340 function->func_index()); 1434 function->func_index());
1341 returns_value = function->signature()->return_count() > 0; 1435 returns_value = function->signature()->return_count() > 0;
1342 } 1436 }
1343 break; 1437 break;
1344 } 1438 }
1345 case Call::KEYED_PROPERTY_CALL: { 1439 case Call::KEYED_PROPERTY_CALL: {
1346 DCHECK_EQ(kFuncScope, scope_); 1440 DCHECK_EQ(kFuncScope, scope_);
1347 Property* p = expr->expression()->AsProperty(); 1441 Property* p = expr->expression()->AsProperty();
1348 DCHECK_NOT_NULL(p); 1442 DCHECK_NOT_NULL(p);
1349 VariableProxy* var = p->obj()->AsVariableProxy(); 1443 VariableProxy* var = p->obj()->AsVariableProxy();
1350 DCHECK_NOT_NULL(var); 1444 DCHECK_NOT_NULL(var);
1351 FunctionTableIndices* indices = LookupFunctionTable(var->var()); 1445 FunctionTableIndices* indices = LookupOrAddFunctionTable(var, p);
1352 Visit(p->key()); // TODO(titzer): should use RECURSE() 1446 Visit(p->key()); // TODO(titzer): should use RECURSE()
1353 1447
1354 // We have to use a temporary for the correct order of evaluation. 1448 // We have to use a temporary for the correct order of evaluation.
1355 current_function_builder_->EmitI32Const(indices->start_index); 1449 current_function_builder_->EmitI32Const(indices->start_index);
1356 current_function_builder_->Emit(kExprI32Add); 1450 current_function_builder_->Emit(kExprI32Add);
1357 WasmTemporary tmp(current_function_builder_, kAstI32); 1451 WasmTemporary tmp(current_function_builder_, kAstI32);
1358 current_function_builder_->EmitSetLocal(tmp.index()); 1452 current_function_builder_->EmitSetLocal(tmp.index());
1359 1453
1360 VisitCallArgs(expr); 1454 VisitCallArgs(expr);
1361 1455
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 #undef CASE 1781 #undef CASE
1688 #undef NON_SIGNED_INT 1782 #undef NON_SIGNED_INT
1689 #undef SIGNED 1783 #undef SIGNED
1690 #undef NON_SIGNED 1784 #undef NON_SIGNED
1691 1785
1692 void VisitThisFunction(ThisFunction* expr) { UNREACHABLE(); } 1786 void VisitThisFunction(ThisFunction* expr) { UNREACHABLE(); }
1693 1787
1694 void VisitDeclarations(Declaration::List* decls) { 1788 void VisitDeclarations(Declaration::List* decls) {
1695 for (Declaration* decl : *decls) { 1789 for (Declaration* decl : *decls) {
1696 RECURSE(Visit(decl)); 1790 RECURSE(Visit(decl));
1791 if (typer_failed_) {
1792 return;
1793 }
1697 } 1794 }
1698 } 1795 }
1699 1796
1700 void VisitClassLiteral(ClassLiteral* expr) { UNREACHABLE(); } 1797 void VisitClassLiteral(ClassLiteral* expr) { UNREACHABLE(); }
1701 1798
1702 void VisitSpread(Spread* expr) { UNREACHABLE(); } 1799 void VisitSpread(Spread* expr) { UNREACHABLE(); }
1703 1800
1704 void VisitSuperPropertyReference(SuperPropertyReference* expr) { 1801 void VisitSuperPropertyReference(SuperPropertyReference* expr) {
1705 UNREACHABLE(); 1802 UNREACHABLE();
1706 } 1803 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1814 1911
1815 ZoneHashMap local_variables_; 1912 ZoneHashMap local_variables_;
1816 ZoneHashMap functions_; 1913 ZoneHashMap functions_;
1817 ZoneHashMap global_variables_; 1914 ZoneHashMap global_variables_;
1818 AsmScope scope_; 1915 AsmScope scope_;
1819 WasmModuleBuilder* builder_; 1916 WasmModuleBuilder* builder_;
1820 WasmFunctionBuilder* current_function_builder_; 1917 WasmFunctionBuilder* current_function_builder_;
1821 FunctionLiteral* literal_; 1918 FunctionLiteral* literal_;
1822 Isolate* isolate_; 1919 Isolate* isolate_;
1823 Zone* zone_; 1920 Zone* zone_;
1921 AstValueFactory* ast_value_factory_;
1922 Script* script_;
1824 AsmTyper* typer_; 1923 AsmTyper* typer_;
1924 bool typer_failed_;
1825 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; 1925 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
1826 ZoneVector<ForeignVariable> foreign_variables_; 1926 ZoneVector<ForeignVariable> foreign_variables_;
1827 WasmFunctionBuilder* init_function_; 1927 WasmFunctionBuilder* init_function_;
1828 WasmFunctionBuilder* foreign_init_function_; 1928 WasmFunctionBuilder* foreign_init_function_;
1829 uint32_t next_table_index_; 1929 uint32_t next_table_index_;
1830 ZoneHashMap function_tables_; 1930 ZoneHashMap function_tables_;
1831 ImportedFunctionTable imported_function_table_; 1931 ImportedFunctionTable imported_function_table_;
1832 1932
1833 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 1933 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
1834 1934
1835 private: 1935 private:
1836 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); 1936 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl);
1837 }; 1937 };
1838 1938
1839 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, 1939 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone,
1840 FunctionLiteral* literal, AsmTyper* typer) 1940 AstValueFactory* ast_value_factory,
1841 : isolate_(isolate), zone_(zone), literal_(literal), typer_(typer) {} 1941 Script* script, FunctionLiteral* literal)
1942 : isolate_(isolate),
1943 zone_(zone),
1944 ast_value_factory_(ast_value_factory),
1945 script_(script),
1946 literal_(literal),
1947 typer_(isolate, zone, script, literal) {}
1842 1948
1843 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so 1949 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so
1844 // that zone in constructor may be thrown away once wasm module is written. 1950 // that zone in constructor may be thrown away once wasm module is written.
1845 AsmWasmBuilder::Result AsmWasmBuilder::Run( 1951 AsmWasmBuilder::Result AsmWasmBuilder::Run(
1846 i::Handle<i::FixedArray>* foreign_args) { 1952 i::Handle<i::FixedArray>* foreign_args) {
1847 AsmWasmBuilderImpl impl(isolate_, zone_, literal_, typer_); 1953 AsmWasmBuilderImpl impl(isolate_, zone_, ast_value_factory_, script_,
1848 impl.Build(); 1954 literal_, &typer_);
1955 bool success = impl.Build();
1849 *foreign_args = impl.GetForeignArgs(); 1956 *foreign_args = impl.GetForeignArgs();
1850 ZoneBuffer* module_buffer = new (zone_) ZoneBuffer(zone_); 1957 ZoneBuffer* module_buffer = new (zone_) ZoneBuffer(zone_);
1851 impl.builder_->WriteTo(*module_buffer); 1958 impl.builder_->WriteTo(*module_buffer);
1852 ZoneBuffer* asm_offsets_buffer = new (zone_) ZoneBuffer(zone_); 1959 ZoneBuffer* asm_offsets_buffer = new (zone_) ZoneBuffer(zone_);
1853 impl.builder_->WriteAsmJsOffsetTable(*asm_offsets_buffer); 1960 impl.builder_->WriteAsmJsOffsetTable(*asm_offsets_buffer);
1854 return {module_buffer, asm_offsets_buffer}; 1961 return {module_buffer, asm_offsets_buffer, success};
1855 } 1962 }
1856 1963
1857 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__"; 1964 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__";
1858 const char* AsmWasmBuilder::single_function_name = "__single_function__"; 1965 const char* AsmWasmBuilder::single_function_name = "__single_function__";
1859 1966
1860 } // namespace wasm 1967 } // namespace wasm
1861 } // namespace internal 1968 } // namespace internal
1862 } // namespace v8 1969 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698