| 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 |