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

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

Powered by Google App Engine
This is Rietveld 408576698