| 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 <memory> | 5 #include <memory> |
| 6 | 6 |
| 7 #include "src/base/atomic-utils.h" | 7 #include "src/base/atomic-utils.h" |
| 8 #include "src/macro-assembler.h" | 8 #include "src/macro-assembler.h" |
| 9 #include "src/objects.h" | 9 #include "src/objects.h" |
| 10 #include "src/property-descriptor.h" | 10 #include "src/property-descriptor.h" |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 kTable, // FixedArray of indirect function table | 197 kTable, // FixedArray of indirect function table |
| 198 kWasmIndirectFunctionTableMetadataSize // Sentinel value. | 198 kWasmIndirectFunctionTableMetadataSize // Sentinel value. |
| 199 }; | 199 }; |
| 200 | 200 |
| 201 uint32_t GetMinModuleMemSize(const WasmModule* module) { | 201 uint32_t GetMinModuleMemSize(const WasmModule* module) { |
| 202 return WasmModule::kPageSize * module->min_mem_pages; | 202 return WasmModule::kPageSize * module->min_mem_pages; |
| 203 } | 203 } |
| 204 | 204 |
| 205 void LoadDataSegments(Handle<FixedArray> compiled_module, Address mem_addr, | 205 void LoadDataSegments(Handle<FixedArray> compiled_module, Address mem_addr, |
| 206 size_t mem_size) { | 206 size_t mem_size) { |
| 207 Isolate* isolate = compiled_module->GetIsolate(); |
| 207 MaybeHandle<ByteArray> maybe_data = | 208 MaybeHandle<ByteArray> maybe_data = |
| 208 compiled_module->GetValue<ByteArray>(kDataSegments); | 209 compiled_module->GetValue<ByteArray>(isolate, kDataSegments); |
| 209 MaybeHandle<FixedArray> maybe_segments = | 210 MaybeHandle<FixedArray> maybe_segments = |
| 210 compiled_module->GetValue<FixedArray>(kDataSegmentsInfo); | 211 compiled_module->GetValue<FixedArray>(isolate, kDataSegmentsInfo); |
| 211 | 212 |
| 212 // We either have both or neither. | 213 // We either have both or neither. |
| 213 CHECK(maybe_data.is_null() == maybe_segments.is_null()); | 214 CHECK(maybe_data.is_null() == maybe_segments.is_null()); |
| 214 // If we have neither, we're done. | 215 // If we have neither, we're done. |
| 215 if (maybe_data.is_null()) return; | 216 if (maybe_data.is_null()) return; |
| 216 | 217 |
| 217 Handle<ByteArray> data = maybe_data.ToHandleChecked(); | 218 Handle<ByteArray> data = maybe_data.ToHandleChecked(); |
| 218 Handle<FixedArray> segments = maybe_segments.ToHandleChecked(); | 219 Handle<FixedArray> segments = maybe_segments.ToHandleChecked(); |
| 219 | 220 |
| 220 uint32_t last_extraction_pos = 0; | 221 uint32_t last_extraction_pos = 0; |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 void LinkImports(Isolate* isolate, std::vector<Handle<Code>>& functions, | 411 void LinkImports(Isolate* isolate, std::vector<Handle<Code>>& functions, |
| 411 const std::vector<Handle<Code>>& imports) { | 412 const std::vector<Handle<Code>>& imports) { |
| 412 for (uint32_t i = 0; i < functions.size(); ++i) { | 413 for (uint32_t i = 0; i < functions.size(); ++i) { |
| 413 Handle<Code> code = functions[i]; | 414 Handle<Code> code = functions[i]; |
| 414 LinkFunction(code, imports, Code::WASM_TO_JS_FUNCTION); | 415 LinkFunction(code, imports, Code::WASM_TO_JS_FUNCTION); |
| 415 } | 416 } |
| 416 } | 417 } |
| 417 | 418 |
| 418 void FlushAssemblyCache(Isolate* isolate, Handle<FixedArray> functions) { | 419 void FlushAssemblyCache(Isolate* isolate, Handle<FixedArray> functions) { |
| 419 for (int i = 0; i < functions->length(); ++i) { | 420 for (int i = 0; i < functions->length(); ++i) { |
| 420 Handle<Code> code = functions->GetValueChecked<Code>(i); | 421 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i); |
| 421 Assembler::FlushICache(isolate, code->instruction_start(), | 422 Assembler::FlushICache(isolate, code->instruction_start(), |
| 422 code->instruction_size()); | 423 code->instruction_size()); |
| 423 } | 424 } |
| 424 } | 425 } |
| 425 | 426 |
| 426 } // namespace | 427 } // namespace |
| 427 | 428 |
| 428 WasmModule::WasmModule(byte* module_start) | 429 WasmModule::WasmModule(byte* module_start) |
| 429 : module_start(module_start), | 430 : module_start(module_start), |
| 430 module_end(nullptr), | 431 module_end(nullptr), |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 | 621 |
| 621 bool CompileWrappersToImportedFunctions(Isolate* isolate, | 622 bool CompileWrappersToImportedFunctions(Isolate* isolate, |
| 622 const Handle<JSReceiver> ffi, | 623 const Handle<JSReceiver> ffi, |
| 623 std::vector<Handle<Code>>& imports, | 624 std::vector<Handle<Code>>& imports, |
| 624 Handle<FixedArray> import_data, | 625 Handle<FixedArray> import_data, |
| 625 ErrorThrower* thrower) { | 626 ErrorThrower* thrower) { |
| 626 uint32_t import_count = static_cast<uint32_t>(import_data->length()); | 627 uint32_t import_count = static_cast<uint32_t>(import_data->length()); |
| 627 if (import_count > 0) { | 628 if (import_count > 0) { |
| 628 imports.reserve(import_count); | 629 imports.reserve(import_count); |
| 629 for (uint32_t index = 0; index < import_count; ++index) { | 630 for (uint32_t index = 0; index < import_count; ++index) { |
| 630 Handle<FixedArray> data = import_data->GetValueChecked<FixedArray>(index); | 631 Handle<FixedArray> data = |
| 631 Handle<String> module_name = data->GetValueChecked<String>(kModuleName); | 632 import_data->GetValueChecked<FixedArray>(isolate, index); |
| 632 MaybeHandle<String> function_name = data->GetValue<String>(kFunctionName); | 633 Handle<String> module_name = |
| 634 data->GetValueChecked<String>(isolate, kModuleName); |
| 635 MaybeHandle<String> function_name = |
| 636 data->GetValue<String>(isolate, kFunctionName); |
| 633 | 637 |
| 634 // TODO(mtrofin): this is an uint32_t, actually. We should rationalize | 638 // TODO(mtrofin): this is an uint32_t, actually. We should rationalize |
| 635 // it when we rationalize signed/unsigned stuff. | 639 // it when we rationalize signed/unsigned stuff. |
| 636 int ret_count = Smi::cast(data->get(kOutputCount))->value(); | 640 int ret_count = Smi::cast(data->get(kOutputCount))->value(); |
| 637 CHECK(ret_count >= 0); | 641 CHECK(ret_count >= 0); |
| 638 Handle<ByteArray> sig_data = data->GetValueChecked<ByteArray>(kSignature); | 642 Handle<ByteArray> sig_data = |
| 643 data->GetValueChecked<ByteArray>(isolate, kSignature); |
| 639 int sig_data_size = sig_data->length(); | 644 int sig_data_size = sig_data->length(); |
| 640 int param_count = sig_data_size - ret_count; | 645 int param_count = sig_data_size - ret_count; |
| 641 CHECK(param_count >= 0); | 646 CHECK(param_count >= 0); |
| 642 | 647 |
| 643 MaybeHandle<JSFunction> function = LookupFunction( | 648 MaybeHandle<JSFunction> function = LookupFunction( |
| 644 *thrower, isolate->factory(), ffi, index, module_name, function_name); | 649 *thrower, isolate->factory(), ffi, index, module_name, function_name); |
| 645 if (function.is_null()) return false; | 650 if (function.is_null()) return false; |
| 646 | 651 |
| 647 { | 652 { |
| 648 // Copy the signature to avoid a raw pointer into a heap object when | 653 // Copy the signature to avoid a raw pointer into a heap object when |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 str.start()); | 818 str.start()); |
| 814 break; | 819 break; |
| 815 } | 820 } |
| 816 // Install the code into the linker table. | 821 // Install the code into the linker table. |
| 817 functions[i] = code; | 822 functions[i] = code; |
| 818 } | 823 } |
| 819 } | 824 } |
| 820 | 825 |
| 821 void SetDebugSupport(Factory* factory, Handle<FixedArray> compiled_module, | 826 void SetDebugSupport(Factory* factory, Handle<FixedArray> compiled_module, |
| 822 Handle<JSObject> js_object) { | 827 Handle<JSObject> js_object) { |
| 828 Isolate* isolate = compiled_module->GetIsolate(); |
| 823 MaybeHandle<String> module_bytes_string = | 829 MaybeHandle<String> module_bytes_string = |
| 824 compiled_module->GetValue<String>(kModuleBytes); | 830 compiled_module->GetValue<String>(isolate, kModuleBytes); |
| 825 if (!module_bytes_string.is_null()) { | 831 if (!module_bytes_string.is_null()) { |
| 826 js_object->SetInternalField(kWasmModuleBytesString, | 832 js_object->SetInternalField(kWasmModuleBytesString, |
| 827 *module_bytes_string.ToHandleChecked()); | 833 *module_bytes_string.ToHandleChecked()); |
| 828 } | 834 } |
| 829 Handle<FixedArray> functions = Handle<FixedArray>( | 835 Handle<FixedArray> functions = Handle<FixedArray>( |
| 830 FixedArray::cast(js_object->GetInternalField(kWasmModuleCodeTable))); | 836 FixedArray::cast(js_object->GetInternalField(kWasmModuleCodeTable))); |
| 831 | 837 |
| 832 for (int i = FLAG_skip_compiling_wasm_funcs; i < functions->length(); ++i) { | 838 for (int i = FLAG_skip_compiling_wasm_funcs; i < functions->length(); ++i) { |
| 833 Handle<Code> code = functions->GetValueChecked<Code>(i); | 839 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i); |
| 834 DCHECK(code->deoptimization_data() == nullptr || | 840 DCHECK(code->deoptimization_data() == nullptr || |
| 835 code->deoptimization_data()->length() == 0); | 841 code->deoptimization_data()->length() == 0); |
| 836 Handle<FixedArray> deopt_data = factory->NewFixedArray(2, TENURED); | 842 Handle<FixedArray> deopt_data = factory->NewFixedArray(2, TENURED); |
| 837 if (!js_object.is_null()) { | 843 if (!js_object.is_null()) { |
| 838 deopt_data->set(0, *js_object); | 844 deopt_data->set(0, *js_object); |
| 839 } | 845 } |
| 840 deopt_data->set(1, Smi::FromInt(static_cast<int>(i))); | 846 deopt_data->set(1, Smi::FromInt(static_cast<int>(i))); |
| 841 deopt_data->set_length(2); | 847 deopt_data->set_length(2); |
| 842 code->set_deoptimization_data(*deopt_data); | 848 code->set_deoptimization_data(*deopt_data); |
| 843 } | 849 } |
| 844 | 850 |
| 845 MaybeHandle<ByteArray> function_name_table = | 851 MaybeHandle<ByteArray> function_name_table = |
| 846 compiled_module->GetValue<ByteArray>(kFunctionNameTable); | 852 compiled_module->GetValue<ByteArray>(isolate, kFunctionNameTable); |
| 847 if (!function_name_table.is_null()) { | 853 if (!function_name_table.is_null()) { |
| 848 js_object->SetInternalField(kWasmFunctionNamesArray, | 854 js_object->SetInternalField(kWasmFunctionNamesArray, |
| 849 *function_name_table.ToHandleChecked()); | 855 *function_name_table.ToHandleChecked()); |
| 850 } | 856 } |
| 851 } | 857 } |
| 852 | 858 |
| 853 bool SetupGlobals(Isolate* isolate, Handle<FixedArray> compiled_module, | 859 bool SetupGlobals(Isolate* isolate, Handle<FixedArray> compiled_module, |
| 854 Handle<JSObject> instance, ErrorThrower* thrower) { | 860 Handle<JSObject> instance, ErrorThrower* thrower) { |
| 855 uint32_t globals_size = static_cast<uint32_t>( | 861 uint32_t globals_size = static_cast<uint32_t>( |
| 856 Smi::cast(compiled_module->get(kGlobalsSize))->value()); | 862 Smi::cast(compiled_module->get(kGlobalsSize))->value()); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 } | 901 } |
| 896 | 902 |
| 897 bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module, | 903 bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module, |
| 898 Handle<JSObject> instance, ErrorThrower* thrower, | 904 Handle<JSObject> instance, ErrorThrower* thrower, |
| 899 Handle<JSReceiver> ffi) { | 905 Handle<JSReceiver> ffi) { |
| 900 //------------------------------------------------------------------------- | 906 //------------------------------------------------------------------------- |
| 901 // Compile wrappers to imported functions. | 907 // Compile wrappers to imported functions. |
| 902 //------------------------------------------------------------------------- | 908 //------------------------------------------------------------------------- |
| 903 std::vector<Handle<Code>> import_code; | 909 std::vector<Handle<Code>> import_code; |
| 904 MaybeHandle<FixedArray> maybe_import_data = | 910 MaybeHandle<FixedArray> maybe_import_data = |
| 905 compiled_module->GetValue<FixedArray>(kImportData); | 911 compiled_module->GetValue<FixedArray>(isolate, kImportData); |
| 906 Handle<FixedArray> import_data; | 912 Handle<FixedArray> import_data; |
| 907 if (maybe_import_data.ToHandle(&import_data)) { | 913 if (maybe_import_data.ToHandle(&import_data)) { |
| 908 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code, | 914 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code, |
| 909 import_data, thrower)) { | 915 import_data, thrower)) { |
| 910 return false; | 916 return false; |
| 911 } | 917 } |
| 912 } | 918 } |
| 913 | 919 |
| 914 RecordStats(isolate, import_code); | 920 RecordStats(isolate, import_code); |
| 915 | 921 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 929 | 935 |
| 930 bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate, | 936 bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate, |
| 931 Handle<JSObject> instance, ErrorThrower* thrower) { | 937 Handle<JSObject> instance, ErrorThrower* thrower) { |
| 932 Factory* factory = isolate->factory(); | 938 Factory* factory = isolate->factory(); |
| 933 bool mem_export = | 939 bool mem_export = |
| 934 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value()); | 940 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value()); |
| 935 ModuleOrigin origin = static_cast<ModuleOrigin>( | 941 ModuleOrigin origin = static_cast<ModuleOrigin>( |
| 936 Smi::cast(compiled_module->get(kOrigin))->value()); | 942 Smi::cast(compiled_module->get(kOrigin))->value()); |
| 937 | 943 |
| 938 MaybeHandle<FixedArray> maybe_exports = | 944 MaybeHandle<FixedArray> maybe_exports = |
| 939 compiled_module->GetValue<FixedArray>(kExports); | 945 compiled_module->GetValue<FixedArray>(isolate, kExports); |
| 940 if (!maybe_exports.is_null() || mem_export) { | 946 if (!maybe_exports.is_null() || mem_export) { |
| 941 PropertyDescriptor desc; | 947 PropertyDescriptor desc; |
| 942 desc.set_writable(false); | 948 desc.set_writable(false); |
| 943 | 949 |
| 944 Handle<JSObject> exports_object = instance; | 950 Handle<JSObject> exports_object = instance; |
| 945 if (origin == kWasmOrigin) { | 951 if (origin == kWasmOrigin) { |
| 946 // Create the "exports" object. | 952 // Create the "exports" object. |
| 947 Handle<JSFunction> object_function = Handle<JSFunction>( | 953 Handle<JSFunction> object_function = Handle<JSFunction>( |
| 948 isolate->native_context()->object_function(), isolate); | 954 isolate->native_context()->object_function(), isolate); |
| 949 exports_object = factory->NewJSObject(object_function, TENURED); | 955 exports_object = factory->NewJSObject(object_function, TENURED); |
| 950 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); | 956 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); |
| 951 JSObject::AddProperty(instance, exports_name, exports_object, READ_ONLY); | 957 JSObject::AddProperty(instance, exports_name, exports_object, READ_ONLY); |
| 952 } | 958 } |
| 953 Handle<FixedArray> exports; | 959 Handle<FixedArray> exports; |
| 954 if (maybe_exports.ToHandle(&exports)) { | 960 if (maybe_exports.ToHandle(&exports)) { |
| 955 int exports_size = exports->length(); | 961 int exports_size = exports->length(); |
| 956 for (int i = 0; i < exports_size; ++i) { | 962 for (int i = 0; i < exports_size; ++i) { |
| 957 if (thrower->error()) return false; | 963 if (thrower->error()) return false; |
| 958 Handle<FixedArray> export_metadata = | 964 Handle<FixedArray> export_metadata = |
| 959 exports->GetValueChecked<FixedArray>(i); | 965 exports->GetValueChecked<FixedArray>(isolate, i); |
| 960 Handle<Code> export_code = | 966 Handle<Code> export_code = |
| 961 export_metadata->GetValueChecked<Code>(kExportCode); | 967 export_metadata->GetValueChecked<Code>(isolate, kExportCode); |
| 962 RecordStats(isolate, *export_code); | 968 RecordStats(isolate, *export_code); |
| 963 Handle<String> name = | 969 Handle<String> name = |
| 964 export_metadata->GetValueChecked<String>(kExportName); | 970 export_metadata->GetValueChecked<String>(isolate, kExportName); |
| 965 int arity = Smi::cast(export_metadata->get(kExportArity))->value(); | 971 int arity = Smi::cast(export_metadata->get(kExportArity))->value(); |
| 966 Handle<JSFunction> function = WrapExportCodeAsJSFunction( | 972 Handle<JSFunction> function = WrapExportCodeAsJSFunction( |
| 967 isolate, export_code, name, arity, instance); | 973 isolate, export_code, name, arity, instance); |
| 968 desc.set_value(function); | 974 desc.set_value(function); |
| 969 Maybe<bool> status = JSReceiver::DefineOwnProperty( | 975 Maybe<bool> status = JSReceiver::DefineOwnProperty( |
| 970 isolate, exports_object, name, &desc, Object::THROW_ON_ERROR); | 976 isolate, exports_object, name, &desc, Object::THROW_ON_ERROR); |
| 971 if (!status.IsJust()) { | 977 if (!status.IsJust()) { |
| 972 thrower->Error("export of %.*s failed.", name->length(), | 978 thrower->Error("export of %.*s failed.", name->length(), |
| 973 name->ToCString().get()); | 979 name->ToCString().get()); |
| 974 return false; | 980 return false; |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 } | 1164 } |
| 1159 | 1165 |
| 1160 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate, | 1166 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate, |
| 1161 Handle<FixedArray> original) { | 1167 Handle<FixedArray> original) { |
| 1162 Factory* factory = isolate->factory(); | 1168 Factory* factory = isolate->factory(); |
| 1163 Handle<FixedArray> clone = factory->CopyFixedArray(original); | 1169 Handle<FixedArray> clone = factory->CopyFixedArray(original); |
| 1164 | 1170 |
| 1165 // Copy the outer table, each WasmIndirectFunctionTableMetadata table, and the | 1171 // Copy the outer table, each WasmIndirectFunctionTableMetadata table, and the |
| 1166 // inner kTable. | 1172 // inner kTable. |
| 1167 MaybeHandle<FixedArray> maybe_indirect_tables = | 1173 MaybeHandle<FixedArray> maybe_indirect_tables = |
| 1168 original->GetValue<FixedArray>(kTableOfIndirectFunctionTables); | 1174 original->GetValue<FixedArray>(isolate, kTableOfIndirectFunctionTables); |
| 1169 Handle<FixedArray> indirect_tables, clone_indirect_tables; | 1175 Handle<FixedArray> indirect_tables, clone_indirect_tables; |
| 1170 if (maybe_indirect_tables.ToHandle(&indirect_tables)) { | 1176 if (maybe_indirect_tables.ToHandle(&indirect_tables)) { |
| 1171 clone_indirect_tables = factory->CopyFixedArray(indirect_tables); | 1177 clone_indirect_tables = factory->CopyFixedArray(indirect_tables); |
| 1172 clone->set(kTableOfIndirectFunctionTables, *clone_indirect_tables); | 1178 clone->set(kTableOfIndirectFunctionTables, *clone_indirect_tables); |
| 1173 for (int i = 0; i < clone_indirect_tables->length(); ++i) { | 1179 for (int i = 0; i < clone_indirect_tables->length(); ++i) { |
| 1174 Handle<FixedArray> orig_metadata = | 1180 Handle<FixedArray> orig_metadata = |
| 1175 clone_indirect_tables->GetValueChecked<FixedArray>(i); | 1181 clone_indirect_tables->GetValueChecked<FixedArray>(isolate, i); |
| 1176 Handle<FixedArray> clone_metadata = | 1182 Handle<FixedArray> clone_metadata = |
| 1177 factory->CopyFixedArray(orig_metadata); | 1183 factory->CopyFixedArray(orig_metadata); |
| 1178 clone_indirect_tables->set(i, *clone_metadata); | 1184 clone_indirect_tables->set(i, *clone_metadata); |
| 1179 | 1185 |
| 1180 Handle<FixedArray> orig_table = | 1186 Handle<FixedArray> orig_table = |
| 1181 clone_metadata->GetValueChecked<FixedArray>(kTable); | 1187 clone_metadata->GetValueChecked<FixedArray>(isolate, kTable); |
| 1182 Handle<FixedArray> clone_table = factory->CopyFixedArray(orig_table); | 1188 Handle<FixedArray> clone_table = factory->CopyFixedArray(orig_table); |
| 1183 clone_metadata->set(kTable, *clone_table); | 1189 clone_metadata->set(kTable, *clone_table); |
| 1184 } | 1190 } |
| 1185 } | 1191 } |
| 1186 | 1192 |
| 1187 // Clone each code, then if indirect tables are used, patch the cloned code to | 1193 // Clone each code, then if indirect tables are used, patch the cloned code to |
| 1188 // refer to the cloned kTable. | 1194 // refer to the cloned kTable. |
| 1189 Handle<FixedArray> orig_wasm_functions = | 1195 Handle<FixedArray> orig_wasm_functions = |
| 1190 original->GetValueChecked<FixedArray>(kFunctions); | 1196 original->GetValueChecked<FixedArray>(isolate, kFunctions); |
| 1191 Handle<FixedArray> clone_wasm_functions = | 1197 Handle<FixedArray> clone_wasm_functions = |
| 1192 factory->CopyFixedArray(orig_wasm_functions); | 1198 factory->CopyFixedArray(orig_wasm_functions); |
| 1193 clone->set(kFunctions, *clone_wasm_functions); | 1199 clone->set(kFunctions, *clone_wasm_functions); |
| 1194 for (int i = 0; i < clone_wasm_functions->length(); ++i) { | 1200 for (int i = 0; i < clone_wasm_functions->length(); ++i) { |
| 1195 Handle<Code> orig_code = clone_wasm_functions->GetValueChecked<Code>(i); | 1201 Handle<Code> orig_code = |
| 1202 clone_wasm_functions->GetValueChecked<Code>(isolate, i); |
| 1196 Handle<Code> cloned_code = factory->CopyCode(orig_code); | 1203 Handle<Code> cloned_code = factory->CopyCode(orig_code); |
| 1197 clone_wasm_functions->set(i, *cloned_code); | 1204 clone_wasm_functions->set(i, *cloned_code); |
| 1198 | 1205 |
| 1199 if (!clone_indirect_tables.is_null()) { | 1206 if (!clone_indirect_tables.is_null()) { |
| 1200 for (int j = 0; j < clone_indirect_tables->length(); ++j) { | 1207 for (int j = 0; j < clone_indirect_tables->length(); ++j) { |
| 1201 Handle<FixedArray> orig_metadata = | 1208 Handle<FixedArray> orig_metadata = |
| 1202 indirect_tables->GetValueChecked<FixedArray>(j); | 1209 indirect_tables->GetValueChecked<FixedArray>(isolate, j); |
| 1203 Handle<FixedArray> orig_table = | 1210 Handle<FixedArray> orig_table = |
| 1204 orig_metadata->GetValueChecked<FixedArray>(kTable); | 1211 orig_metadata->GetValueChecked<FixedArray>(isolate, kTable); |
| 1205 | 1212 |
| 1206 Handle<FixedArray> clone_metadata = | 1213 Handle<FixedArray> clone_metadata = |
| 1207 clone_indirect_tables->GetValueChecked<FixedArray>(j); | 1214 clone_indirect_tables->GetValueChecked<FixedArray>(isolate, j); |
| 1208 Handle<FixedArray> clone_table = | 1215 Handle<FixedArray> clone_table = |
| 1209 clone_metadata->GetValueChecked<FixedArray>(kTable); | 1216 clone_metadata->GetValueChecked<FixedArray>(isolate, kTable); |
| 1210 | 1217 |
| 1211 PatchFunctionTable(cloned_code, orig_table, clone_table); | 1218 PatchFunctionTable(cloned_code, orig_table, clone_table); |
| 1212 } | 1219 } |
| 1213 } | 1220 } |
| 1214 } | 1221 } |
| 1215 | 1222 |
| 1216 MaybeHandle<FixedArray> maybe_orig_exports = | 1223 MaybeHandle<FixedArray> maybe_orig_exports = |
| 1217 original->GetValue<FixedArray>(kExports); | 1224 original->GetValue<FixedArray>(isolate, kExports); |
| 1218 Handle<FixedArray> orig_exports; | 1225 Handle<FixedArray> orig_exports; |
| 1219 if (maybe_orig_exports.ToHandle(&orig_exports)) { | 1226 if (maybe_orig_exports.ToHandle(&orig_exports)) { |
| 1220 Handle<FixedArray> cloned_exports = factory->CopyFixedArray(orig_exports); | 1227 Handle<FixedArray> cloned_exports = factory->CopyFixedArray(orig_exports); |
| 1221 clone->set(kExports, *cloned_exports); | 1228 clone->set(kExports, *cloned_exports); |
| 1222 for (int i = 0; i < orig_exports->length(); ++i) { | 1229 for (int i = 0; i < orig_exports->length(); ++i) { |
| 1223 Handle<FixedArray> export_metadata = | 1230 Handle<FixedArray> export_metadata = |
| 1224 orig_exports->GetValueChecked<FixedArray>(i); | 1231 orig_exports->GetValueChecked<FixedArray>(isolate, i); |
| 1225 Handle<FixedArray> clone_metadata = | 1232 Handle<FixedArray> clone_metadata = |
| 1226 factory->CopyFixedArray(export_metadata); | 1233 factory->CopyFixedArray(export_metadata); |
| 1227 cloned_exports->set(i, *clone_metadata); | 1234 cloned_exports->set(i, *clone_metadata); |
| 1228 Handle<Code> orig_code = | 1235 Handle<Code> orig_code = |
| 1229 export_metadata->GetValueChecked<Code>(kExportCode); | 1236 export_metadata->GetValueChecked<Code>(isolate, kExportCode); |
| 1230 Handle<Code> cloned_code = factory->CopyCode(orig_code); | 1237 Handle<Code> cloned_code = factory->CopyCode(orig_code); |
| 1231 clone_metadata->set(kExportCode, *cloned_code); | 1238 clone_metadata->set(kExportCode, *cloned_code); |
| 1232 // TODO(wasm): This is actually a uint32_t, but since FixedArray indexes | 1239 // TODO(wasm): This is actually a uint32_t, but since FixedArray indexes |
| 1233 // in int, we are taking the risk of invalid values. | 1240 // in int, we are taking the risk of invalid values. |
| 1234 int exported_fct_index = | 1241 int exported_fct_index = |
| 1235 Smi::cast(export_metadata->get(kExportedFunctionIndex))->value(); | 1242 Smi::cast(export_metadata->get(kExportedFunctionIndex))->value(); |
| 1236 CHECK_GE(exported_fct_index, 0); | 1243 CHECK_GE(exported_fct_index, 0); |
| 1237 CHECK_LT(exported_fct_index, clone_wasm_functions->length()); | 1244 CHECK_LT(exported_fct_index, clone_wasm_functions->length()); |
| 1238 Handle<Code> new_target = | 1245 Handle<Code> new_target = clone_wasm_functions->GetValueChecked<Code>( |
| 1239 clone_wasm_functions->GetValueChecked<Code>(exported_fct_index); | 1246 isolate, exported_fct_index); |
| 1240 PatchJSWrapper(isolate, cloned_code, new_target); | 1247 PatchJSWrapper(isolate, cloned_code, new_target); |
| 1241 } | 1248 } |
| 1242 } | 1249 } |
| 1243 | 1250 |
| 1244 MaybeHandle<FixedArray> maybe_startup = | 1251 MaybeHandle<FixedArray> maybe_startup = |
| 1245 original->GetValue<FixedArray>(kStartupFunction); | 1252 original->GetValue<FixedArray>(isolate, kStartupFunction); |
| 1246 if (!maybe_startup.is_null()) { | 1253 if (!maybe_startup.is_null()) { |
| 1247 Handle<FixedArray> startup_metadata = | 1254 Handle<FixedArray> startup_metadata = |
| 1248 factory->CopyFixedArray(maybe_startup.ToHandleChecked()); | 1255 factory->CopyFixedArray(maybe_startup.ToHandleChecked()); |
| 1249 Handle<Code> startup_fct_clone = | 1256 Handle<Code> startup_fct_clone = factory->CopyCode( |
| 1250 factory->CopyCode(startup_metadata->GetValueChecked<Code>(kExportCode)); | 1257 startup_metadata->GetValueChecked<Code>(isolate, kExportCode)); |
| 1251 startup_metadata->set(kExportCode, *startup_fct_clone); | 1258 startup_metadata->set(kExportCode, *startup_fct_clone); |
| 1252 clone->set(kStartupFunction, *startup_metadata); | 1259 clone->set(kStartupFunction, *startup_metadata); |
| 1253 // TODO(wasm): see todo above about int vs size_t indexing in FixedArray. | 1260 // TODO(wasm): see todo above about int vs size_t indexing in FixedArray. |
| 1254 int startup_fct_index = | 1261 int startup_fct_index = |
| 1255 Smi::cast(startup_metadata->get(kExportedFunctionIndex))->value(); | 1262 Smi::cast(startup_metadata->get(kExportedFunctionIndex))->value(); |
| 1256 CHECK_GE(startup_fct_index, 0); | 1263 CHECK_GE(startup_fct_index, 0); |
| 1257 CHECK_LT(startup_fct_index, clone_wasm_functions->length()); | 1264 CHECK_LT(startup_fct_index, clone_wasm_functions->length()); |
| 1258 Handle<Code> new_target = | 1265 Handle<Code> new_target = |
| 1259 clone_wasm_functions->GetValueChecked<Code>(startup_fct_index); | 1266 clone_wasm_functions->GetValueChecked<Code>(isolate, startup_fct_index); |
| 1260 PatchJSWrapper(isolate, startup_fct_clone, new_target); | 1267 PatchJSWrapper(isolate, startup_fct_clone, new_target); |
| 1261 } | 1268 } |
| 1262 return clone; | 1269 return clone; |
| 1263 } | 1270 } |
| 1264 | 1271 |
| 1265 // Instantiates a wasm module as a JSObject. | 1272 // Instantiates a wasm module as a JSObject. |
| 1266 // * allocates a backing store of {mem_size} bytes. | 1273 // * allocates a backing store of {mem_size} bytes. |
| 1267 // * installs a named property "memory" for that buffer if exported | 1274 // * installs a named property "memory" for that buffer if exported |
| 1268 // * installs named properties on the object for exported functions | 1275 // * installs named properties on the object for exported functions |
| 1269 // * compiles wasm code to machine code | 1276 // * compiles wasm code to machine code |
| 1270 MaybeHandle<JSObject> WasmModule::Instantiate( | 1277 MaybeHandle<JSObject> WasmModule::Instantiate( |
| 1271 Isolate* isolate, Handle<FixedArray> compiled_module, | 1278 Isolate* isolate, Handle<FixedArray> compiled_module, |
| 1272 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) { | 1279 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) { |
| 1273 HistogramTimerScope wasm_instantiate_module_time_scope( | 1280 HistogramTimerScope wasm_instantiate_module_time_scope( |
| 1274 isolate->counters()->wasm_instantiate_module_time()); | 1281 isolate->counters()->wasm_instantiate_module_time()); |
| 1275 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); | 1282 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); |
| 1276 Factory* factory = isolate->factory(); | 1283 Factory* factory = isolate->factory(); |
| 1277 | 1284 |
| 1278 compiled_module = CloneModuleForInstance(isolate, compiled_module); | 1285 compiled_module = CloneModuleForInstance(isolate, compiled_module); |
| 1279 | 1286 |
| 1280 // These fields are compulsory. | 1287 // These fields are compulsory. |
| 1281 Handle<FixedArray> code_table = | 1288 Handle<FixedArray> code_table = |
| 1282 compiled_module->GetValueChecked<FixedArray>(kFunctions); | 1289 compiled_module->GetValueChecked<FixedArray>(isolate, kFunctions); |
| 1283 | 1290 |
| 1284 std::vector<Handle<Code>> functions( | 1291 std::vector<Handle<Code>> functions( |
| 1285 static_cast<size_t>(code_table->length())); | 1292 static_cast<size_t>(code_table->length())); |
| 1286 for (int i = 0; i < code_table->length(); ++i) { | 1293 for (int i = 0; i < code_table->length(); ++i) { |
| 1287 functions[static_cast<size_t>(i)] = code_table->GetValueChecked<Code>(i); | 1294 functions[static_cast<size_t>(i)] = |
| 1295 code_table->GetValueChecked<Code>(isolate, i); |
| 1288 } | 1296 } |
| 1289 LinkModuleFunctions(isolate, functions); | 1297 LinkModuleFunctions(isolate, functions); |
| 1290 | 1298 |
| 1291 RecordStats(isolate, code_table); | 1299 RecordStats(isolate, code_table); |
| 1292 | 1300 |
| 1293 MaybeHandle<JSObject> nothing; | 1301 MaybeHandle<JSObject> nothing; |
| 1294 | 1302 |
| 1295 Handle<Map> map = factory->NewMap( | 1303 Handle<Map> map = factory->NewMap( |
| 1296 JS_OBJECT_TYPE, | 1304 JS_OBJECT_TYPE, |
| 1297 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); | 1305 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); |
| 1298 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED); | 1306 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED); |
| 1299 js_object->SetInternalField(kWasmModuleCodeTable, *code_table); | 1307 js_object->SetInternalField(kWasmModuleCodeTable, *code_table); |
| 1300 | 1308 |
| 1301 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory, | 1309 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory, |
| 1302 &thrower) && | 1310 &thrower) && |
| 1303 SetupGlobals(isolate, compiled_module, js_object, &thrower) && | 1311 SetupGlobals(isolate, compiled_module, js_object, &thrower) && |
| 1304 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) && | 1312 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) && |
| 1305 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) { | 1313 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) { |
| 1306 return nothing; | 1314 return nothing; |
| 1307 } | 1315 } |
| 1308 | 1316 |
| 1309 SetDebugSupport(factory, compiled_module, js_object); | 1317 SetDebugSupport(factory, compiled_module, js_object); |
| 1310 | 1318 |
| 1311 FlushAssemblyCache(isolate, code_table); | 1319 FlushAssemblyCache(isolate, code_table); |
| 1312 | 1320 |
| 1313 MaybeHandle<FixedArray> maybe_indirect_tables = | 1321 MaybeHandle<FixedArray> maybe_indirect_tables = |
| 1314 compiled_module->GetValue<FixedArray>(kTableOfIndirectFunctionTables); | 1322 compiled_module->GetValue<FixedArray>(isolate, |
| 1323 kTableOfIndirectFunctionTables); |
| 1315 Handle<FixedArray> indirect_tables; | 1324 Handle<FixedArray> indirect_tables; |
| 1316 if (maybe_indirect_tables.ToHandle(&indirect_tables)) { | 1325 if (maybe_indirect_tables.ToHandle(&indirect_tables)) { |
| 1317 for (int i = 0; i < indirect_tables->length(); ++i) { | 1326 for (int i = 0; i < indirect_tables->length(); ++i) { |
| 1318 Handle<FixedArray> metadata = | 1327 Handle<FixedArray> metadata = |
| 1319 indirect_tables->GetValueChecked<FixedArray>(i); | 1328 indirect_tables->GetValueChecked<FixedArray>(isolate, i); |
| 1320 uint32_t size = Smi::cast(metadata->get(kSize))->value(); | 1329 uint32_t size = Smi::cast(metadata->get(kSize))->value(); |
| 1321 Handle<FixedArray> table = metadata->GetValueChecked<FixedArray>(kTable); | 1330 Handle<FixedArray> table = |
| 1331 metadata->GetValueChecked<FixedArray>(isolate, kTable); |
| 1322 wasm::PopulateFunctionTable(table, size, &functions); | 1332 wasm::PopulateFunctionTable(table, size, &functions); |
| 1323 } | 1333 } |
| 1324 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables); | 1334 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables); |
| 1325 } | 1335 } |
| 1326 | 1336 |
| 1327 // Run the start function if one was specified. | 1337 // Run the start function if one was specified. |
| 1328 MaybeHandle<FixedArray> maybe_startup_fct = | 1338 MaybeHandle<FixedArray> maybe_startup_fct = |
| 1329 compiled_module->GetValue<FixedArray>(kStartupFunction); | 1339 compiled_module->GetValue<FixedArray>(isolate, kStartupFunction); |
| 1330 Handle<FixedArray> metadata; | 1340 Handle<FixedArray> metadata; |
| 1331 if (maybe_startup_fct.ToHandle(&metadata)) { | 1341 if (maybe_startup_fct.ToHandle(&metadata)) { |
| 1332 HandleScope scope(isolate); | 1342 HandleScope scope(isolate); |
| 1333 Handle<Code> startup_code = metadata->GetValueChecked<Code>(kExportCode); | 1343 Handle<Code> startup_code = |
| 1344 metadata->GetValueChecked<Code>(isolate, kExportCode); |
| 1334 int arity = Smi::cast(metadata->get(kExportArity))->value(); | 1345 int arity = Smi::cast(metadata->get(kExportArity))->value(); |
| 1335 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( | 1346 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( |
| 1336 isolate, startup_code, factory->InternalizeUtf8String("start"), arity, | 1347 isolate, startup_code, factory->InternalizeUtf8String("start"), arity, |
| 1337 js_object); | 1348 js_object); |
| 1338 RecordStats(isolate, *startup_code); | 1349 RecordStats(isolate, *startup_code); |
| 1339 // Call the JS function. | 1350 // Call the JS function. |
| 1340 Handle<Object> undefined = isolate->factory()->undefined_value(); | 1351 Handle<Object> undefined = isolate->factory()->undefined_value(); |
| 1341 MaybeHandle<Object> retval = | 1352 MaybeHandle<Object> retval = |
| 1342 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); | 1353 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); |
| 1343 | 1354 |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1585 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); | 1596 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); |
| 1586 } | 1597 } |
| 1587 thrower.Error("WASM.compileRun() failed: Return value should be number"); | 1598 thrower.Error("WASM.compileRun() failed: Return value should be number"); |
| 1588 return -1; | 1599 return -1; |
| 1589 } | 1600 } |
| 1590 | 1601 |
| 1591 } // namespace testing | 1602 } // namespace testing |
| 1592 } // namespace wasm | 1603 } // namespace wasm |
| 1593 } // namespace internal | 1604 } // namespace internal |
| 1594 } // namespace v8 | 1605 } // namespace v8 |
| OLD | NEW |