OLD | NEW |
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 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 i::Handle<i::FixedArray> GetForeignArgs() { | 101 i::Handle<i::FixedArray> GetForeignArgs() { |
102 i::Handle<FixedArray> ret = isolate_->factory()->NewFixedArray( | 102 i::Handle<FixedArray> ret = isolate_->factory()->NewFixedArray( |
103 static_cast<int>(foreign_variables_.size())); | 103 static_cast<int>(foreign_variables_.size())); |
104 for (size_t i = 0; i < foreign_variables_.size(); ++i) { | 104 for (size_t i = 0; i < foreign_variables_.size(); ++i) { |
105 ForeignVariable* fv = &foreign_variables_[i]; | 105 ForeignVariable* fv = &foreign_variables_[i]; |
106 ret->set(static_cast<int>(i), *fv->name); | 106 ret->set(static_cast<int>(i), *fv->name); |
107 } | 107 } |
108 return ret; | 108 return ret; |
109 } | 109 } |
110 | 110 |
111 void BuildImports() { | |
112 for (const AsmTyper::FFIUseSignature& ffi : typer_->FFIUseSignatures()) { | |
113 size_t ret_count = ffi.return_type_ == AsmType::Void() ? 0 : 1; | |
114 FunctionSig::Builder b(zone_, ret_count, ffi.arg_types_.size()); | |
115 for (AsmType* arg : ffi.arg_types_) b.AddParam(TypeFrom(arg)); | |
116 if (ffi.return_type_ != AsmType::Void()) { | |
117 b.AddReturn(TypeFrom(ffi.return_type_)); | |
118 } | |
119 imported_function_table_.AddFunction(ffi.var, b.Build()); | |
120 } | |
121 } | |
122 | |
123 void Build() { | 111 void Build() { |
124 BuildImports(); | |
125 InitializeInitFunction(); | 112 InitializeInitFunction(); |
126 RECURSE(VisitFunctionLiteral(literal_)); | 113 RECURSE(VisitFunctionLiteral(literal_)); |
127 BuildForeignInitFunction(); | 114 BuildForeignInitFunction(); |
128 } | 115 } |
129 | 116 |
130 void VisitVariableDeclaration(VariableDeclaration* decl) {} | 117 void VisitVariableDeclaration(VariableDeclaration* decl) {} |
131 | 118 |
132 void VisitFunctionDeclaration(FunctionDeclaration* decl) { | 119 void VisitFunctionDeclaration(FunctionDeclaration* decl) { |
133 DCHECK_EQ(kModuleScope, scope_); | 120 DCHECK_EQ(kModuleScope, scope_); |
134 DCHECK_NULL(current_function_builder_); | 121 DCHECK_NULL(current_function_builder_); |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 ZoneHashMap::Entry* entry = | 713 ZoneHashMap::Entry* entry = |
727 function_tables_.Lookup(v, ComputePointerHash(v)); | 714 function_tables_.Lookup(v, ComputePointerHash(v)); |
728 DCHECK_NOT_NULL(entry); | 715 DCHECK_NOT_NULL(entry); |
729 return reinterpret_cast<FunctionTableIndices*>(entry->value); | 716 return reinterpret_cast<FunctionTableIndices*>(entry->value); |
730 } | 717 } |
731 | 718 |
732 class ImportedFunctionTable { | 719 class ImportedFunctionTable { |
733 private: | 720 private: |
734 class ImportedFunctionIndices : public ZoneObject { | 721 class ImportedFunctionIndices : public ZoneObject { |
735 public: | 722 public: |
736 bool has_name_; | 723 const char* name_; |
| 724 int name_length_; |
737 WasmModuleBuilder::SignatureMap signature_to_index_; | 725 WasmModuleBuilder::SignatureMap signature_to_index_; |
738 | 726 |
739 explicit ImportedFunctionIndices(Zone* zone) | 727 ImportedFunctionIndices(const char* name, int name_length, Zone* zone) |
740 : has_name_(false), signature_to_index_(zone) {} | 728 : name_(name), name_length_(name_length), signature_to_index_(zone) {} |
741 }; | 729 }; |
742 ZoneHashMap table_; | 730 ZoneHashMap table_; |
743 AsmWasmBuilderImpl* builder_; | 731 AsmWasmBuilderImpl* builder_; |
744 | 732 |
745 public: | 733 public: |
746 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder) | 734 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder) |
747 : table_(ZoneHashMap::kDefaultHashMapCapacity, | 735 : table_(ZoneHashMap::kDefaultHashMapCapacity, |
748 ZoneAllocationPolicy(builder->zone())), | 736 ZoneAllocationPolicy(builder->zone())), |
749 builder_(builder) {} | 737 builder_(builder) {} |
750 | 738 |
751 // Set the imported name of a variable. Must happen after all signatures | 739 void AddImport(Variable* v, const char* name, int name_length) { |
752 // (and thus import indices) are added for a given variable. | 740 ImportedFunctionIndices* indices = new (builder_->zone()) |
753 void SetImportName(Variable* v, const char* name, int name_length) { | 741 ImportedFunctionIndices(name, name_length, builder_->zone()); |
754 auto indices = GetEntry(v); | 742 auto* entry = table_.LookupOrInsert( |
755 if (indices) { | 743 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone())); |
756 for (auto entry : indices->signature_to_index_) { | 744 entry->value = indices; |
757 uint32_t index = entry.second; | |
758 builder_->builder_->SetImportName(index, name, name_length); | |
759 } | |
760 indices->has_name_ = true; | |
761 } | |
762 } | 745 } |
763 | 746 |
764 // Get a function's index. Does not insert new entries. | 747 // Get a function's index (or allocate if new). |
765 uint32_t GetFunctionIndex(Variable* v, FunctionSig* sig) { | 748 uint32_t LookupOrInsertImport(Variable* v, FunctionSig* sig) { |
766 auto indices = GetEntry(v); | 749 ZoneHashMap::Entry* entry = table_.Lookup(v, ComputePointerHash(v)); |
767 DCHECK_NOT_NULL(indices); | 750 DCHECK_NOT_NULL(entry); |
768 auto pos = indices->signature_to_index_.find(sig); | 751 ImportedFunctionIndices* indices = |
769 DCHECK(pos != indices->signature_to_index_.end()); | 752 reinterpret_cast<ImportedFunctionIndices*>(entry->value); |
770 return pos->second; | 753 WasmModuleBuilder::SignatureMap::iterator pos = |
771 } | 754 indices->signature_to_index_.find(sig); |
772 | 755 if (pos != indices->signature_to_index_.end()) { |
773 // Add a function and register it as an import with the builder. | 756 return pos->second; |
774 void AddFunction(Variable* v, FunctionSig* sig) { | 757 } else { |
775 auto entry = table_.LookupOrInsert( | 758 uint32_t index = builder_->builder_->AddImport( |
776 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone())); | 759 indices->name_, indices->name_length_, sig); |
777 if (entry->value == nullptr) { | 760 indices->signature_to_index_[sig] = index; |
778 entry->value = | 761 return index; |
779 new (builder_->zone()) ImportedFunctionIndices(builder_->zone()); | |
780 } | 762 } |
781 auto indices = reinterpret_cast<ImportedFunctionIndices*>(entry->value); | |
782 DCHECK(!indices->has_name_); | |
783 auto pos = indices->signature_to_index_.find(sig); | |
784 if (pos == indices->signature_to_index_.end()) { | |
785 // A new import. Name is not known up front. | |
786 uint32_t index = builder_->builder_->AddImport(nullptr, 0, sig); | |
787 indices->signature_to_index_[sig] = index; | |
788 } | |
789 } | |
790 | |
791 ImportedFunctionIndices* GetEntry(Variable* v) { | |
792 auto entry = table_.Lookup(v, ComputePointerHash(v)); | |
793 if (entry == nullptr) return nullptr; | |
794 return reinterpret_cast<ImportedFunctionIndices*>(entry->value); | |
795 } | 763 } |
796 }; | 764 }; |
797 | 765 |
798 void EmitAssignmentLhs(Expression* target, MachineType* mtype) { | 766 void EmitAssignmentLhs(Expression* target, MachineType* mtype) { |
799 // Match the left hand side of the assignment. | 767 // Match the left hand side of the assignment. |
800 VariableProxy* target_var = target->AsVariableProxy(); | 768 VariableProxy* target_var = target->AsVariableProxy(); |
801 if (target_var != nullptr) { | 769 if (target_var != nullptr) { |
802 // Left hand side is a local or a global variable, no code on LHS. | 770 // Left hand side is a local or a global variable, no code on LHS. |
803 return; | 771 return; |
804 } | 772 } |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 } | 903 } |
936 Property* prop = expr->value()->AsProperty(); | 904 Property* prop = expr->value()->AsProperty(); |
937 if (prop != nullptr) { | 905 if (prop != nullptr) { |
938 VariableProxy* vp = prop->obj()->AsVariableProxy(); | 906 VariableProxy* vp = prop->obj()->AsVariableProxy(); |
939 if (vp != nullptr && vp->var()->IsParameter() && | 907 if (vp != nullptr && vp->var()->IsParameter() && |
940 vp->var()->index() == 1) { | 908 vp->var()->index() == 1) { |
941 VariableProxy* target = expr->target()->AsVariableProxy(); | 909 VariableProxy* target = expr->target()->AsVariableProxy(); |
942 if (typer_->TypeOf(target)->AsFFIType() != nullptr) { | 910 if (typer_->TypeOf(target)->AsFFIType() != nullptr) { |
943 const AstRawString* name = | 911 const AstRawString* name = |
944 prop->key()->AsLiteral()->AsRawPropertyName(); | 912 prop->key()->AsLiteral()->AsRawPropertyName(); |
945 imported_function_table_.SetImportName( | 913 imported_function_table_.AddImport( |
946 target->var(), reinterpret_cast<const char*>(name->raw_data()), | 914 target->var(), reinterpret_cast<const char*>(name->raw_data()), |
947 name->length()); | 915 name->length()); |
948 } | 916 } |
949 } | 917 } |
950 // Property values in module scope don't emit code, so return. | 918 // Property values in module scope don't emit code, so return. |
951 return; | 919 return; |
952 } | 920 } |
953 ArrayLiteral* funcs = expr->value()->AsArrayLiteral(); | 921 ArrayLiteral* funcs = expr->value()->AsArrayLiteral(); |
954 if (funcs != nullptr && | 922 if (funcs != nullptr && |
955 typer_->TypeOf(funcs) | 923 typer_->TypeOf(funcs) |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, | 1354 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, |
1387 args->length()); | 1355 args->length()); |
1388 if (return_type != kAstStmt) { | 1356 if (return_type != kAstStmt) { |
1389 sig.AddReturn(return_type); | 1357 sig.AddReturn(return_type); |
1390 } else { | 1358 } else { |
1391 returns_value = false; | 1359 returns_value = false; |
1392 } | 1360 } |
1393 for (int i = 0; i < args->length(); ++i) { | 1361 for (int i = 0; i < args->length(); ++i) { |
1394 sig.AddParam(TypeOf(args->at(i))); | 1362 sig.AddParam(TypeOf(args->at(i))); |
1395 } | 1363 } |
1396 uint32_t index = | 1364 uint32_t index = imported_function_table_.LookupOrInsertImport( |
1397 imported_function_table_.GetFunctionIndex(vp->var(), sig.Build()); | 1365 vp->var(), sig.Build()); |
1398 VisitCallArgs(expr); | 1366 VisitCallArgs(expr); |
1399 current_function_builder_->Emit(kExprCallFunction); | 1367 current_function_builder_->Emit(kExprCallFunction); |
1400 current_function_builder_->EmitVarInt(index); | 1368 current_function_builder_->EmitVarInt(index); |
1401 } else { | 1369 } else { |
1402 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var()); | 1370 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var()); |
1403 VisitCallArgs(expr); | 1371 VisitCallArgs(expr); |
1404 current_function_builder_->Emit(kExprCallFunction); | 1372 current_function_builder_->Emit(kExprCallFunction); |
1405 current_function_builder_->EmitVarInt(function->func_index()); | 1373 current_function_builder_->EmitDirectCallIndex( |
| 1374 function->func_index()); |
1406 returns_value = function->signature()->return_count() > 0; | 1375 returns_value = function->signature()->return_count() > 0; |
1407 } | 1376 } |
1408 break; | 1377 break; |
1409 } | 1378 } |
1410 case Call::KEYED_PROPERTY_CALL: { | 1379 case Call::KEYED_PROPERTY_CALL: { |
1411 DCHECK_EQ(kFuncScope, scope_); | 1380 DCHECK_EQ(kFuncScope, scope_); |
1412 Property* p = expr->expression()->AsProperty(); | 1381 Property* p = expr->expression()->AsProperty(); |
1413 DCHECK_NOT_NULL(p); | 1382 DCHECK_NOT_NULL(p); |
1414 VariableProxy* var = p->obj()->AsVariableProxy(); | 1383 VariableProxy* var = p->obj()->AsVariableProxy(); |
1415 DCHECK_NOT_NULL(var); | 1384 DCHECK_NOT_NULL(var); |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1914 impl.builder_->WriteTo(*buffer); | 1883 impl.builder_->WriteTo(*buffer); |
1915 return buffer; | 1884 return buffer; |
1916 } | 1885 } |
1917 | 1886 |
1918 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__"; | 1887 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__"; |
1919 const char* AsmWasmBuilder::single_function_name = "__single_function__"; | 1888 const char* AsmWasmBuilder::single_function_name = "__single_function__"; |
1920 | 1889 |
1921 } // namespace wasm | 1890 } // namespace wasm |
1922 } // namespace internal | 1891 } // namespace internal |
1923 } // namespace v8 | 1892 } // namespace v8 |
OLD | NEW |