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

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: clear function node each time Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 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);
136 if (decl->fun()->body() == nullptr) {
137 // TODO(bradnelson): Refactor parser so we don't need a
138 // SharedFunctionInfo to parse a single function,
139 // or squirrel away the SharedFunctionInfo to use later.
140 Handle<SharedFunctionInfo> shared =
141 isolate_->factory()->NewSharedFunctionInfoForLiteral(
142 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_toplevel(false);
147 info.set_language_mode(decl->fun()->scope()->language_mode());
148 info.set_allow_lazy_parsing(false);
149 info.set_ast_value_factory(ast_value_factory_);
150 info.set_ast_value_factory_owned(false);
151 // Create fresh function scope to use to parse the function in.
152 DeclarationScope* new_func_scope = new (info.zone()) DeclarationScope(
153 info.zone(), decl->fun()->scope()->outer_scope(), FUNCTION_SCOPE);
154 info.set_asm_function_scope(new_func_scope);
155 if (!i::Compiler::ParseAndAnalyze(&info)) {
156 typer_failed_ = true;
157 return;
158 }
159 FunctionLiteral* func = info.literal();
160 DCHECK_NOT_NULL(func);
161 decl->set_fun(func);
162 }
163 if (!typer_->ValidateInnerFunction(decl)) {
164 typer_failed_ = true;
165 decl->set_fun(old_func);
166 decl->scope()->RemoveInnerScope(decl->scope()->inner_scope());
marja 2016/11/29 10:20:04 This RemoveInnerScope stuff looks a bit scary. Th
bradn 2016/11/29 10:43:36 Done.
167 return;
168 }
116 current_function_builder_ = LookupOrInsertFunction(decl->proxy()->var()); 169 current_function_builder_ = LookupOrInsertFunction(decl->proxy()->var());
117 scope_ = kFuncScope; 170 scope_ = kFuncScope;
118 RECURSE(Visit(decl->fun())); 171 RECURSE(Visit(decl->fun()));
172 decl->set_fun(old_func);
173 decl->scope()->RemoveInnerScope(decl->scope()->inner_scope());
119 scope_ = kModuleScope; 174 scope_ = kModuleScope;
120 current_function_builder_ = nullptr; 175 current_function_builder_ = nullptr;
121 local_variables_.Clear(); 176 local_variables_.Clear();
177 typer_->ClearFunctionNodeTypes();
122 } 178 }
123 179
124 void VisitStatements(ZoneList<Statement*>* stmts) { 180 void VisitStatements(ZoneList<Statement*>* stmts) {
125 for (int i = 0; i < stmts->length(); ++i) { 181 for (int i = 0; i < stmts->length(); ++i) {
126 Statement* stmt = stmts->at(i); 182 Statement* stmt = stmts->at(i);
127 ExpressionStatement* e = stmt->AsExpressionStatement(); 183 ExpressionStatement* e = stmt->AsExpressionStatement();
128 if (e != nullptr && e->expression()->IsUndefinedLiteral()) { 184 if (e != nullptr && e->expression()->IsUndefinedLiteral()) {
129 continue; 185 continue;
130 } 186 }
131 RECURSE(Visit(stmt)); 187 RECURSE(Visit(stmt));
188 if (typer_failed_) break;
132 if (stmt->IsJump()) break; 189 if (stmt->IsJump()) break;
133 } 190 }
134 } 191 }
135 192
136 void VisitBlock(Block* stmt) { 193 void VisitBlock(Block* stmt) {
137 if (stmt->statements()->length() == 1) { 194 if (stmt->statements()->length() == 1) {
138 ExpressionStatement* expr = 195 ExpressionStatement* expr =
139 stmt->statements()->at(0)->AsExpressionStatement(); 196 stmt->statements()->at(0)->AsExpressionStatement();
140 if (expr != nullptr) { 197 if (expr != nullptr) {
141 if (expr->expression()->IsAssignment()) { 198 if (expr->expression()->IsAssignment()) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 void VisitContinueStatement(ContinueStatement* stmt) { 295 void VisitContinueStatement(ContinueStatement* stmt) {
239 DoBreakOrContinue(stmt->target(), true); 296 DoBreakOrContinue(stmt->target(), true);
240 } 297 }
241 298
242 void VisitBreakStatement(BreakStatement* stmt) { 299 void VisitBreakStatement(BreakStatement* stmt) {
243 DoBreakOrContinue(stmt->target(), false); 300 DoBreakOrContinue(stmt->target(), false);
244 } 301 }
245 302
246 void VisitReturnStatement(ReturnStatement* stmt) { 303 void VisitReturnStatement(ReturnStatement* stmt) {
247 if (scope_ == kModuleScope) { 304 if (scope_ == kModuleScope) {
305 if (!typer_->ValidateAfterFunctionsPhase()) {
306 typer_failed_ = true;
307 return;
308 }
248 scope_ = kExportScope; 309 scope_ = kExportScope;
249 RECURSE(Visit(stmt->expression())); 310 RECURSE(Visit(stmt->expression()));
250 scope_ = kModuleScope; 311 scope_ = kModuleScope;
251 } else if (scope_ == kFuncScope) { 312 } else if (scope_ == kFuncScope) {
252 RECURSE(Visit(stmt->expression())); 313 RECURSE(Visit(stmt->expression()));
253 current_function_builder_->Emit(kExprReturn); 314 current_function_builder_->Emit(kExprReturn);
254 } else { 315 } else {
255 UNREACHABLE(); 316 UNREACHABLE();
256 } 317 }
257 } 318 }
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 const auto& arguments = func_type->Arguments(); 502 const auto& arguments = func_type->Arguments();
442 for (int i = 0; i < expr->parameter_count(); ++i) { 503 for (int i = 0; i < expr->parameter_count(); ++i) {
443 LocalType type = TypeFrom(arguments[i]); 504 LocalType type = TypeFrom(arguments[i]);
444 DCHECK_NE(kAstStmt, type); 505 DCHECK_NE(kAstStmt, type);
445 InsertParameter(scope->parameter(i), type, i); 506 InsertParameter(scope->parameter(i), type, i);
446 } 507 }
447 } else { 508 } else {
448 UNREACHABLE(); 509 UNREACHABLE();
449 } 510 }
450 } 511 }
512 RECURSE(VisitDeclarations(scope->declarations()));
513 if (typer_failed_) return;
451 RECURSE(VisitStatements(expr->body())); 514 RECURSE(VisitStatements(expr->body()));
452 RECURSE(VisitDeclarations(scope->declarations()));
453 } 515 }
454 516
455 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 517 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
456 UNREACHABLE(); 518 UNREACHABLE();
457 } 519 }
458 520
459 void VisitConditional(Conditional* expr) { 521 void VisitConditional(Conditional* expr) {
460 DCHECK_EQ(kFuncScope, scope_); 522 DCHECK_EQ(kFuncScope, scope_);
461 RECURSE(Visit(expr->condition())); 523 RECURSE(Visit(expr->condition()));
462 // WASM ifs come with implicit blocks for both arms. 524 // WASM ifs come with implicit blocks for both arms.
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 void LoadInitFunction() { 715 void LoadInitFunction() {
654 current_function_builder_ = init_function_; 716 current_function_builder_ = init_function_;
655 scope_ = kInitScope; 717 scope_ = kInitScope;
656 } 718 }
657 719
658 void UnLoadInitFunction() { 720 void UnLoadInitFunction() {
659 scope_ = kModuleScope; 721 scope_ = kModuleScope;
660 current_function_builder_ = nullptr; 722 current_function_builder_ = nullptr;
661 } 723 }
662 724
663 void AddFunctionTable(VariableProxy* table, ArrayLiteral* funcs) { 725 struct FunctionTableIndices : public ZoneObject {
664 auto* func_tbl_type = typer_->TypeOf(funcs)->AsFunctionTableType(); 726 uint32_t start_index;
665 DCHECK_NOT_NULL(func_tbl_type); 727 uint32_t signature_index;
666 auto* func_type = func_tbl_type->signature()->AsFunctionType(); 728 };
729
730 FunctionTableIndices* LookupOrAddFunctionTable(VariableProxy* table,
731 Property* p) {
732 FunctionTableIndices* indices = LookupFunctionTable(table->var());
733 if (indices != nullptr) {
734 // Already setup.
735 return indices;
736 }
737 indices = new (zone()) FunctionTableIndices();
738 auto* func_type = typer_->TypeOf(p)->AsFunctionType();
739 auto* func_table_type = typer_->TypeOf(p->obj()->AsVariableProxy()->var())
740 ->AsFunctionTableType();
667 const auto& arguments = func_type->Arguments(); 741 const auto& arguments = func_type->Arguments();
668 LocalType return_type = TypeFrom(func_type->ReturnType()); 742 LocalType return_type = TypeFrom(func_type->ReturnType());
669 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, 743 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
670 arguments.size()); 744 arguments.size());
671 if (return_type != kAstStmt) { 745 if (return_type != kAstStmt) {
672 sig.AddReturn(return_type); 746 sig.AddReturn(return_type);
673 } 747 }
674 for (auto* arg : arguments) { 748 for (auto* arg : arguments) {
675 sig.AddParam(TypeFrom(arg)); 749 sig.AddParam(TypeFrom(arg));
676 } 750 }
677 uint32_t signature_index = builder_->AddSignature(sig.Build()); 751 uint32_t signature_index = builder_->AddSignature(sig.Build());
678 InsertFunctionTable(table->var(), next_table_index_, signature_index); 752 indices->start_index = builder_->AllocateIndirectFunctions(
679 next_table_index_ += funcs->values()->length(); 753 static_cast<uint32_t>(func_table_type->length()));
680 for (int i = 0; i < funcs->values()->length(); ++i) { 754 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( 755 ZoneHashMap::Entry* entry = function_tables_.LookupOrInsert(
699 v, ComputePointerHash(v), ZoneAllocationPolicy(zone())); 756 table->var(), ComputePointerHash(table->var()),
700 entry->value = container; 757 ZoneAllocationPolicy(zone()));
758 entry->value = indices;
759 return indices;
701 } 760 }
702 761
703 FunctionTableIndices* LookupFunctionTable(Variable* v) { 762 FunctionTableIndices* LookupFunctionTable(Variable* v) {
704 ZoneHashMap::Entry* entry = 763 ZoneHashMap::Entry* entry =
705 function_tables_.Lookup(v, ComputePointerHash(v)); 764 function_tables_.Lookup(v, ComputePointerHash(v));
706 DCHECK_NOT_NULL(entry); 765 if (entry == nullptr) {
766 return nullptr;
767 }
707 return reinterpret_cast<FunctionTableIndices*>(entry->value); 768 return reinterpret_cast<FunctionTableIndices*>(entry->value);
708 } 769 }
709 770
771 void PopulateFunctionTable(VariableProxy* table, ArrayLiteral* funcs) {
772 FunctionTableIndices* indices = LookupFunctionTable(table->var());
773 DCHECK_NOT_NULL(indices);
774 for (int i = 0; i < funcs->values()->length(); ++i) {
775 VariableProxy* func = funcs->values()->at(i)->AsVariableProxy();
776 DCHECK_NOT_NULL(func);
777 builder_->SetIndirectFunction(
778 indices->start_index + i,
779 LookupOrInsertFunction(func->var())->func_index());
780 }
781 }
782
710 class ImportedFunctionTable { 783 class ImportedFunctionTable {
711 private: 784 private:
712 class ImportedFunctionIndices : public ZoneObject { 785 class ImportedFunctionIndices : public ZoneObject {
713 public: 786 public:
714 const char* name_; 787 const char* name_;
715 int name_length_; 788 int name_length_;
716 WasmModuleBuilder::SignatureMap signature_to_index_; 789 WasmModuleBuilder::SignatureMap signature_to_index_;
717 790
718 ImportedFunctionIndices(const char* name, int name_length, Zone* zone) 791 ImportedFunctionIndices(const char* name, int name_length, Zone* zone)
719 : name_(name), name_length_(name_length), signature_to_index_(zone) {} 792 : name_(name), name_length_(name_length), signature_to_index_(zone) {}
720 }; 793 };
721 ZoneHashMap table_; 794 ZoneHashMap table_;
722 AsmWasmBuilderImpl* builder_; 795 AsmWasmBuilderImpl* builder_;
723 796
724 public: 797 public:
725 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder) 798 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder)
726 : table_(ZoneHashMap::kDefaultHashMapCapacity, 799 : table_(ZoneHashMap::kDefaultHashMapCapacity,
727 ZoneAllocationPolicy(builder->zone())), 800 ZoneAllocationPolicy(builder->zone())),
728 builder_(builder) {} 801 builder_(builder) {}
729 802
730 void AddImport(Variable* v, const char* name, int name_length) { 803 ImportedFunctionIndices* LookupOrInsertImport(Variable* v) {
731 ImportedFunctionIndices* indices = new (builder_->zone())
732 ImportedFunctionIndices(name, name_length, builder_->zone());
733 auto* entry = table_.LookupOrInsert( 804 auto* entry = table_.LookupOrInsert(
734 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone())); 805 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone()));
735 entry->value = indices; 806 ImportedFunctionIndices* indices;
807 if (entry->value == nullptr) {
808 indices = new (builder_->zone())
809 ImportedFunctionIndices(nullptr, 0, builder_->zone());
810 entry->value = indices;
811 } else {
812 indices = reinterpret_cast<ImportedFunctionIndices*>(entry->value);
813 }
814 return indices;
815 }
816
817 void SetImportName(Variable* v, const char* name, int name_length) {
818 auto* indices = LookupOrInsertImport(v);
819 indices->name_ = name;
820 indices->name_length_ = name_length;
821 for (auto i : indices->signature_to_index_) {
822 builder_->builder_->SetImportName(i.second, indices->name_,
823 indices->name_length_);
824 }
736 } 825 }
737 826
738 // Get a function's index (or allocate if new). 827 // Get a function's index (or allocate if new).
739 uint32_t LookupOrInsertImport(Variable* v, FunctionSig* sig) { 828 uint32_t LookupOrInsertImportUse(Variable* v, FunctionSig* sig) {
740 ZoneHashMap::Entry* entry = table_.Lookup(v, ComputePointerHash(v)); 829 auto* indices = LookupOrInsertImport(v);
741 DCHECK_NOT_NULL(entry);
742 ImportedFunctionIndices* indices =
743 reinterpret_cast<ImportedFunctionIndices*>(entry->value);
744 WasmModuleBuilder::SignatureMap::iterator pos = 830 WasmModuleBuilder::SignatureMap::iterator pos =
745 indices->signature_to_index_.find(sig); 831 indices->signature_to_index_.find(sig);
746 if (pos != indices->signature_to_index_.end()) { 832 if (pos != indices->signature_to_index_.end()) {
747 return pos->second; 833 return pos->second;
748 } else { 834 } else {
749 uint32_t index = builder_->builder_->AddImport( 835 uint32_t index = builder_->builder_->AddImport(
750 indices->name_, indices->name_length_, sig); 836 indices->name_, indices->name_length_, sig);
751 indices->signature_to_index_[sig] = index; 837 indices->signature_to_index_[sig] = index;
752 return index; 838 return index;
753 } 839 }
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 } 980 }
895 Property* prop = expr->value()->AsProperty(); 981 Property* prop = expr->value()->AsProperty();
896 if (prop != nullptr) { 982 if (prop != nullptr) {
897 VariableProxy* vp = prop->obj()->AsVariableProxy(); 983 VariableProxy* vp = prop->obj()->AsVariableProxy();
898 if (vp != nullptr && vp->var()->IsParameter() && 984 if (vp != nullptr && vp->var()->IsParameter() &&
899 vp->var()->index() == 1) { 985 vp->var()->index() == 1) {
900 VariableProxy* target = expr->target()->AsVariableProxy(); 986 VariableProxy* target = expr->target()->AsVariableProxy();
901 if (typer_->TypeOf(target)->AsFFIType() != nullptr) { 987 if (typer_->TypeOf(target)->AsFFIType() != nullptr) {
902 const AstRawString* name = 988 const AstRawString* name =
903 prop->key()->AsLiteral()->AsRawPropertyName(); 989 prop->key()->AsLiteral()->AsRawPropertyName();
904 imported_function_table_.AddImport( 990 imported_function_table_.SetImportName(
905 target->var(), reinterpret_cast<const char*>(name->raw_data()), 991 target->var(), reinterpret_cast<const char*>(name->raw_data()),
906 name->length()); 992 name->length());
907 } 993 }
908 } 994 }
909 // Property values in module scope don't emit code, so return. 995 // Property values in module scope don't emit code, so return.
910 return; 996 return;
911 } 997 }
912 ArrayLiteral* funcs = expr->value()->AsArrayLiteral(); 998 ArrayLiteral* funcs = expr->value()->AsArrayLiteral();
913 if (funcs != nullptr && 999 if (funcs != nullptr) {
914 typer_->TypeOf(funcs)
915 ->AsFunctionTableType()
916 ->signature()
917 ->AsFunctionType()) {
918 VariableProxy* target = expr->target()->AsVariableProxy(); 1000 VariableProxy* target = expr->target()->AsVariableProxy();
919 DCHECK_NOT_NULL(target); 1001 DCHECK_NOT_NULL(target);
920 AddFunctionTable(target, funcs); 1002 PopulateFunctionTable(target, funcs);
921 // Only add to the function table. No init needed. 1003 // Only add to the function table. No init needed.
922 return; 1004 return;
923 } 1005 }
924 if (expr->value()->IsCallNew()) { 1006 if (expr->value()->IsCallNew()) {
925 // No init code to emit for CallNew nodes. 1007 // No init code to emit for CallNew nodes.
926 return; 1008 return;
927 } 1009 }
928 as_init = true; 1010 as_init = true;
929 } 1011 }
930 1012
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, 1400 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
1319 args->length()); 1401 args->length());
1320 if (return_type != kAstStmt) { 1402 if (return_type != kAstStmt) {
1321 sig.AddReturn(return_type); 1403 sig.AddReturn(return_type);
1322 } else { 1404 } else {
1323 returns_value = false; 1405 returns_value = false;
1324 } 1406 }
1325 for (int i = 0; i < args->length(); ++i) { 1407 for (int i = 0; i < args->length(); ++i) {
1326 sig.AddParam(TypeOf(args->at(i))); 1408 sig.AddParam(TypeOf(args->at(i)));
1327 } 1409 }
1328 uint32_t index = imported_function_table_.LookupOrInsertImport( 1410 uint32_t index = imported_function_table_.LookupOrInsertImportUse(
1329 vp->var(), sig.Build()); 1411 vp->var(), sig.Build());
1330 VisitCallArgs(expr); 1412 VisitCallArgs(expr);
1331 current_function_builder_->AddAsmWasmOffset(expr->position()); 1413 current_function_builder_->AddAsmWasmOffset(expr->position());
1332 current_function_builder_->Emit(kExprCallFunction); 1414 current_function_builder_->Emit(kExprCallFunction);
1333 current_function_builder_->EmitVarInt(index); 1415 current_function_builder_->EmitVarInt(index);
1334 } else { 1416 } else {
1335 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var()); 1417 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var());
1336 VisitCallArgs(expr); 1418 VisitCallArgs(expr);
1337 current_function_builder_->AddAsmWasmOffset(expr->position()); 1419 current_function_builder_->AddAsmWasmOffset(expr->position());
1338 current_function_builder_->Emit(kExprCallFunction); 1420 current_function_builder_->Emit(kExprCallFunction);
1339 current_function_builder_->EmitDirectCallIndex( 1421 current_function_builder_->EmitDirectCallIndex(
1340 function->func_index()); 1422 function->func_index());
1341 returns_value = function->signature()->return_count() > 0; 1423 returns_value = function->signature()->return_count() > 0;
1342 } 1424 }
1343 break; 1425 break;
1344 } 1426 }
1345 case Call::KEYED_PROPERTY_CALL: { 1427 case Call::KEYED_PROPERTY_CALL: {
1346 DCHECK_EQ(kFuncScope, scope_); 1428 DCHECK_EQ(kFuncScope, scope_);
1347 Property* p = expr->expression()->AsProperty(); 1429 Property* p = expr->expression()->AsProperty();
1348 DCHECK_NOT_NULL(p); 1430 DCHECK_NOT_NULL(p);
1349 VariableProxy* var = p->obj()->AsVariableProxy(); 1431 VariableProxy* var = p->obj()->AsVariableProxy();
1350 DCHECK_NOT_NULL(var); 1432 DCHECK_NOT_NULL(var);
1351 FunctionTableIndices* indices = LookupFunctionTable(var->var()); 1433 FunctionTableIndices* indices = LookupOrAddFunctionTable(var, p);
1352 Visit(p->key()); // TODO(titzer): should use RECURSE() 1434 Visit(p->key()); // TODO(titzer): should use RECURSE()
1353 1435
1354 // We have to use a temporary for the correct order of evaluation. 1436 // We have to use a temporary for the correct order of evaluation.
1355 current_function_builder_->EmitI32Const(indices->start_index); 1437 current_function_builder_->EmitI32Const(indices->start_index);
1356 current_function_builder_->Emit(kExprI32Add); 1438 current_function_builder_->Emit(kExprI32Add);
1357 WasmTemporary tmp(current_function_builder_, kAstI32); 1439 WasmTemporary tmp(current_function_builder_, kAstI32);
1358 current_function_builder_->EmitSetLocal(tmp.index()); 1440 current_function_builder_->EmitSetLocal(tmp.index());
1359 1441
1360 VisitCallArgs(expr); 1442 VisitCallArgs(expr);
1361 1443
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 #undef CASE 1769 #undef CASE
1688 #undef NON_SIGNED_INT 1770 #undef NON_SIGNED_INT
1689 #undef SIGNED 1771 #undef SIGNED
1690 #undef NON_SIGNED 1772 #undef NON_SIGNED
1691 1773
1692 void VisitThisFunction(ThisFunction* expr) { UNREACHABLE(); } 1774 void VisitThisFunction(ThisFunction* expr) { UNREACHABLE(); }
1693 1775
1694 void VisitDeclarations(Declaration::List* decls) { 1776 void VisitDeclarations(Declaration::List* decls) {
1695 for (Declaration* decl : *decls) { 1777 for (Declaration* decl : *decls) {
1696 RECURSE(Visit(decl)); 1778 RECURSE(Visit(decl));
1779 if (typer_failed_) {
1780 return;
1781 }
1697 } 1782 }
1698 } 1783 }
1699 1784
1700 void VisitClassLiteral(ClassLiteral* expr) { UNREACHABLE(); } 1785 void VisitClassLiteral(ClassLiteral* expr) { UNREACHABLE(); }
1701 1786
1702 void VisitSpread(Spread* expr) { UNREACHABLE(); } 1787 void VisitSpread(Spread* expr) { UNREACHABLE(); }
1703 1788
1704 void VisitSuperPropertyReference(SuperPropertyReference* expr) { 1789 void VisitSuperPropertyReference(SuperPropertyReference* expr) {
1705 UNREACHABLE(); 1790 UNREACHABLE();
1706 } 1791 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1814 1899
1815 ZoneHashMap local_variables_; 1900 ZoneHashMap local_variables_;
1816 ZoneHashMap functions_; 1901 ZoneHashMap functions_;
1817 ZoneHashMap global_variables_; 1902 ZoneHashMap global_variables_;
1818 AsmScope scope_; 1903 AsmScope scope_;
1819 WasmModuleBuilder* builder_; 1904 WasmModuleBuilder* builder_;
1820 WasmFunctionBuilder* current_function_builder_; 1905 WasmFunctionBuilder* current_function_builder_;
1821 FunctionLiteral* literal_; 1906 FunctionLiteral* literal_;
1822 Isolate* isolate_; 1907 Isolate* isolate_;
1823 Zone* zone_; 1908 Zone* zone_;
1909 AstValueFactory* ast_value_factory_;
1910 Script* script_;
1824 AsmTyper* typer_; 1911 AsmTyper* typer_;
1912 bool typer_failed_;
1825 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; 1913 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
1826 ZoneVector<ForeignVariable> foreign_variables_; 1914 ZoneVector<ForeignVariable> foreign_variables_;
1827 WasmFunctionBuilder* init_function_; 1915 WasmFunctionBuilder* init_function_;
1828 WasmFunctionBuilder* foreign_init_function_; 1916 WasmFunctionBuilder* foreign_init_function_;
1829 uint32_t next_table_index_; 1917 uint32_t next_table_index_;
1830 ZoneHashMap function_tables_; 1918 ZoneHashMap function_tables_;
1831 ImportedFunctionTable imported_function_table_; 1919 ImportedFunctionTable imported_function_table_;
1832 1920
1833 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 1921 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
1834 1922
1835 private: 1923 private:
1836 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); 1924 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl);
1837 }; 1925 };
1838 1926
1839 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, 1927 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone,
1840 FunctionLiteral* literal, AsmTyper* typer) 1928 AstValueFactory* ast_value_factory,
1841 : isolate_(isolate), zone_(zone), literal_(literal), typer_(typer) {} 1929 Script* script, FunctionLiteral* literal)
1930 : isolate_(isolate),
1931 zone_(zone),
1932 ast_value_factory_(ast_value_factory),
1933 script_(script),
1934 literal_(literal),
1935 typer_(isolate, zone, script, literal) {}
1842 1936
1843 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so 1937 // 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. 1938 // that zone in constructor may be thrown away once wasm module is written.
1845 AsmWasmBuilder::Result AsmWasmBuilder::Run( 1939 AsmWasmBuilder::Result AsmWasmBuilder::Run(
1846 i::Handle<i::FixedArray>* foreign_args) { 1940 i::Handle<i::FixedArray>* foreign_args) {
1847 AsmWasmBuilderImpl impl(isolate_, zone_, literal_, typer_); 1941 AsmWasmBuilderImpl impl(isolate_, zone_, ast_value_factory_, script_,
1848 impl.Build(); 1942 literal_, &typer_);
1943 bool success = impl.Build();
1849 *foreign_args = impl.GetForeignArgs(); 1944 *foreign_args = impl.GetForeignArgs();
1850 ZoneBuffer* module_buffer = new (zone_) ZoneBuffer(zone_); 1945 ZoneBuffer* module_buffer = new (zone_) ZoneBuffer(zone_);
1851 impl.builder_->WriteTo(*module_buffer); 1946 impl.builder_->WriteTo(*module_buffer);
1852 ZoneBuffer* asm_offsets_buffer = new (zone_) ZoneBuffer(zone_); 1947 ZoneBuffer* asm_offsets_buffer = new (zone_) ZoneBuffer(zone_);
1853 impl.builder_->WriteAsmJsOffsetTable(*asm_offsets_buffer); 1948 impl.builder_->WriteAsmJsOffsetTable(*asm_offsets_buffer);
1854 return {module_buffer, asm_offsets_buffer}; 1949 return {module_buffer, asm_offsets_buffer, success};
1855 } 1950 }
1856 1951
1857 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__"; 1952 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__";
1858 const char* AsmWasmBuilder::single_function_name = "__single_function__"; 1953 const char* AsmWasmBuilder::single_function_name = "__single_function__";
1859 1954
1860 } // namespace wasm 1955 } // namespace wasm
1861 } // namespace internal 1956 } // namespace internal
1862 } // namespace v8 1957 } // namespace v8
OLDNEW
« no previous file with comments | « src/asmjs/asm-wasm-builder.h ('k') | src/ast/scopes.h » ('j') | src/ast/scopes.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698