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

Side by Side Diff: src/wasm/wasm-module.cc

Issue 2134593002: [wasm] cloning compiled module before instantiation (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: [wasm] cloning compiled module before instantiation Created 4 years, 5 months 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
« no previous file with comments | « src/wasm/wasm-module.h ('k') | test/cctest/wasm/wasm-run-utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/base/atomic-utils.h" 5 #include "src/base/atomic-utils.h"
6 #include "src/macro-assembler.h" 6 #include "src/macro-assembler.h"
7 #include "src/objects.h" 7 #include "src/objects.h"
8 #include "src/property-descriptor.h" 8 #include "src/property-descriptor.h"
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 os.write(name.start(), name.length()); 105 os.write(name.start(), name.length());
106 } else { 106 } else {
107 os << "+" << pair.function_->func_index; 107 os << "+" << pair.function_->func_index;
108 } 108 }
109 } else { 109 } else {
110 os << "?"; 110 os << "?";
111 } 111 }
112 return os; 112 return os;
113 } 113 }
114 114
115 Handle<JSFunction> WrapExportCodeAsJSFunction(
116 Isolate* isolate, Handle<Code> export_code, Handle<String> name, int arity,
117 Handle<JSObject> module_instance) {
118 Handle<SharedFunctionInfo> shared =
119 isolate->factory()->NewSharedFunctionInfo(name, export_code, false);
120 shared->set_length(arity);
121 shared->set_internal_formal_parameter_count(arity);
122 Handle<JSFunction> function = isolate->factory()->NewFunction(
123 isolate->wasm_function_map(), name, export_code);
124 function->set_shared(*shared);
125
126 function->SetInternalField(0, *module_instance);
127 return function;
128 }
129
115 namespace { 130 namespace {
116 // Internal constants for the layout of the module object. 131 // Internal constants for the layout of the module object.
117 const int kWasmModuleFunctionTable = 0; 132 const int kWasmModuleFunctionTable = 0;
118 const int kWasmModuleCodeTable = 1; 133 const int kWasmModuleCodeTable = 1;
119 const int kWasmMemArrayBuffer = 2; 134 const int kWasmMemArrayBuffer = 2;
120 const int kWasmGlobalsArrayBuffer = 3; 135 const int kWasmGlobalsArrayBuffer = 3;
121 // TODO(clemensh): Remove function name array, extract names from module bytes. 136 // TODO(clemensh): Remove function name array, extract names from module bytes.
122 const int kWasmFunctionNamesArray = 4; 137 const int kWasmFunctionNamesArray = 4;
123 const int kWasmModuleBytesString = 5; 138 const int kWasmModuleBytesString = 5;
124 const int kWasmDebugInfo = 6; 139 const int kWasmDebugInfo = 6;
125 const int kWasmModuleInternalFieldCount = 7; 140 const int kWasmModuleInternalFieldCount = 7;
126 141
127 // TODO(mtrofin): Unnecessary once we stop using JS Heap for wasm code. 142 // TODO(mtrofin): Unnecessary once we stop using JS Heap for wasm code.
128 // For now, each field is expected to have the type commented by its side. 143 // For now, each field is expected to have the type commented by its side.
129 // The elements typed as "maybe" are optional. The others are mandatory. Since 144 // The elements typed as "maybe" are optional. The others are mandatory. Since
130 // the compiled module is either obtained from the current v8 instance, or from 145 // the compiled module is either obtained from the current v8 instance, or from
131 // a snapshot produced by a compatible (==identical) v8 instance, we simply 146 // a snapshot produced by a compatible (==identical) v8 instance, we simply
132 // fail at instantiation time, in the face of invalid data. 147 // fail at instantiation time, in the face of invalid data.
133 enum CompiledWasmObjectFields { 148 enum CompiledWasmObjectFields {
134 kFunctions, // FixedArray of Code 149 kFunctions, // FixedArray of Code
135 kImportData, // maybe FixedArray of FixedArray respecting the 150 kImportData, // maybe FixedArray of FixedArray respecting the
136 // WasmImportMetadata structure. 151 // WasmImportMetadata structure.
137 kExports, // maybe FixedArray of JSFunction 152 kExports, // maybe FixedArray of FixedArray of WasmExportMetadata
138 kStartupFunction, // maybe JSFunction 153 // structure
139 kModuleBytes, // maybe String 154 kStartupFunction, // maybe FixedArray of WasmExportMetadata structure
140 kFunctionNameTable, // maybe ByteArray 155 kIndirectFunctionTableSize, // Smi. Size of indirect function table.
141 kMinRequiredMemory, // Smi. an uint32_t 156 kIndirectFunctionTablePrototype, // maybe FixedArray
157 kModuleBytes, // maybe String
158 kFunctionNameTable, // maybe ByteArray
159 kMinRequiredMemory, // Smi. an uint32_t
142 // The following 2 are either together present or absent: 160 // The following 2 are either together present or absent:
143 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the 161 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the
144 // WasmSegmentInfo structure 162 // WasmSegmentInfo structure
145 kDataSegments, // maybe ByteArray. 163 kDataSegments, // maybe ByteArray.
146 164
147 kGlobalsSize, // Smi. an uint32_t 165 kGlobalsSize, // Smi. an uint32_t
148 kExportMem, // Smi. bool 166 kExportMem, // Smi. bool
149 kOrigin, // Smi. ModuleOrigin 167 kOrigin, // Smi. ModuleOrigin
150 kCompiledWasmObjectTableSize // Sentinel value. 168 kCompiledWasmObjectTableSize // Sentinel value.
151 }; 169 };
152 170
153 enum WasmImportMetadata { 171 enum WasmImportMetadata {
154 kModuleName, // String 172 kModuleName, // String
155 kFunctionName, // maybe String 173 kFunctionName, // maybe String
156 kOutputCount, // Smi. an uint32_t 174 kOutputCount, // Smi. an uint32_t
157 kSignature, // ByteArray. A copy of the data in FunctionSig 175 kSignature, // ByteArray. A copy of the data in FunctionSig
158 kWasmImportDataTableSize // Sentinel value. 176 kWasmImportDataTableSize // Sentinel value.
159 }; 177 };
160 178
179 enum WasmExportMetadata {
180 kExportCode, // Code
181 kExportName, // String
182 kExportArity, // Smi, an int
183 kExportedFunctionIndex, // Smi, an uint32_t
184 kWasmExportMetadataTableSize // Sentinel value.
185 };
186
161 enum WasmSegmentInfo { 187 enum WasmSegmentInfo {
162 kDestAddr, // Smi. an uint32_t 188 kDestAddr, // Smi. an uint32_t
163 kSourceSize, // Smi. an uint32_t 189 kSourceSize, // Smi. an uint32_t
164 kWasmSegmentInfoSize // Sentinel value. 190 kWasmSegmentInfoSize // Sentinel value.
165 }; 191 };
166 192
167 uint32_t GetMinModuleMemSize(const WasmModule* module) { 193 uint32_t GetMinModuleMemSize(const WasmModule* module) {
168 return WasmModule::kPageSize * module->min_mem_pages; 194 return WasmModule::kPageSize * module->min_mem_pages;
169 } 195 }
170 196
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 segments->set(i, *js_segment); 248 segments->set(i, *js_segment);
223 data->copy_in(last_insertion_pos, 249 data->copy_in(last_insertion_pos,
224 module->module_start + segment.source_offset, 250 module->module_start + segment.source_offset,
225 segment.source_size); 251 segment.source_size);
226 last_insertion_pos += segment.source_size; 252 last_insertion_pos += segment.source_size;
227 } 253 }
228 compiled_module->set(kDataSegmentsInfo, *segments); 254 compiled_module->set(kDataSegmentsInfo, *segments);
229 compiled_module->set(kDataSegments, *data); 255 compiled_module->set(kDataSegments, *data);
230 } 256 }
231 257
232 Handle<FixedArray> BuildFunctionTable(Isolate* isolate, 258 MaybeHandle<FixedArray> BuildFunctionTable(Isolate* isolate,
233 const WasmModule* module) { 259 const WasmModule* module) {
234 // Compute the size of the indirect function table 260 // Compute the size of the indirect function table
235 uint32_t table_size = module->FunctionTableSize(); 261 uint32_t table_size = module->FunctionTableSize();
236 if (table_size == 0) { 262 if (table_size == 0) {
237 return Handle<FixedArray>::null(); 263 return MaybeHandle<FixedArray>();
238 } 264 }
239 265
266 DCHECK_GE(table_size, module->function_table.size());
267
240 Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size); 268 Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size);
241 for (uint32_t i = 0; 269 for (uint32_t i = 0; i < module->function_table.size(); ++i) {
242 i < static_cast<uint32_t>(module->function_table.size());
243 ++i) {
244 const WasmFunction* function = 270 const WasmFunction* function =
245 &module->functions[module->function_table[i]]; 271 &module->functions[module->function_table[i]];
246 fixed->set(i, Smi::FromInt(function->sig_index)); 272 int fixed_array_index = static_cast<int>(i);
273 fixed->set(fixed_array_index, Smi::FromInt(function->sig_index));
274 fixed->set(fixed_array_index + table_size,
275 Smi::FromInt(module->function_table[fixed_array_index]));
247 } 276 }
277
248 // Set the remaining elements to -1 (instead of "undefined"). These 278 // Set the remaining elements to -1 (instead of "undefined"). These
249 // elements are accessed directly as SMIs (without a check). On 64-bit 279 // elements are accessed directly as SMIs (without a check). On 64-bit
250 // platforms, it is possible to have the top bits of "undefined" take 280 // platforms, it is possible to have the top bits of "undefined" take
251 // small integer values (or zero), which are more likely to be equal to 281 // small integer values (or zero), which are more likely to be equal to
252 // the signature index we check against. 282 // the signature index we check against.
253 for (uint32_t i = static_cast<uint32_t>(module->function_table.size()); 283 for (uint32_t i = static_cast<uint32_t>(module->function_table.size());
254 i < table_size; 284 i < table_size;
255 ++i) { 285 ++i) {
256 fixed->set(i, Smi::FromInt(-1)); 286 fixed->set(i, Smi::FromInt(-1));
257 } 287 }
258 return fixed; 288 return fixed;
259 } 289 }
260 290
291 void PatchFunctionTable(Handle<Code> code,
292 Handle<FixedArray> old_indirect_table,
293 Handle<FixedArray> new_indirect_table) {
294 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done();
295 it.next()) {
296 if (it.rinfo()->target_object() == *old_indirect_table) {
297 it.rinfo()->set_target_object(*new_indirect_table);
298 }
299 }
300 }
301
261 Handle<JSArrayBuffer> NewArrayBuffer(Isolate* isolate, size_t size) { 302 Handle<JSArrayBuffer> NewArrayBuffer(Isolate* isolate, size_t size) {
262 if (size > (WasmModule::kMaxMemPages * WasmModule::kPageSize)) { 303 if (size > (WasmModule::kMaxMemPages * WasmModule::kPageSize)) {
263 // TODO(titzer): lift restriction on maximum memory allocated here. 304 // TODO(titzer): lift restriction on maximum memory allocated here.
264 return Handle<JSArrayBuffer>::null(); 305 return Handle<JSArrayBuffer>::null();
265 } 306 }
266 void* memory = isolate->array_buffer_allocator()->Allocate(size); 307 void* memory = isolate->array_buffer_allocator()->Allocate(size);
267 if (memory == nullptr) { 308 if (memory == nullptr) {
268 return Handle<JSArrayBuffer>::null(); 309 return Handle<JSArrayBuffer>::null();
269 } 310 }
270 311
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 } 420 }
380 } 421 }
381 } 422 }
382 return modified; 423 return modified;
383 } 424 }
384 425
385 void LinkModuleFunctions(Isolate* isolate, 426 void LinkModuleFunctions(Isolate* isolate,
386 std::vector<Handle<Code>>& functions) { 427 std::vector<Handle<Code>>& functions) {
387 for (size_t i = 0; i < functions.size(); ++i) { 428 for (size_t i = 0; i < functions.size(); ++i) {
388 Handle<Code> code = functions[i]; 429 Handle<Code> code = functions[i];
389 bool modified = LinkFunction(code, functions, Code::WASM_FUNCTION); 430 LinkFunction(code, functions, Code::WASM_FUNCTION);
390 if (modified) {
391 Assembler::FlushICache(isolate, code->instruction_start(),
392 code->instruction_size());
393 }
394 } 431 }
395 } 432 }
396 433
397 void LinkImports(Isolate* isolate, std::vector<Handle<Code>>& functions, 434 void LinkImports(Isolate* isolate, std::vector<Handle<Code>>& functions,
398 const std::vector<Handle<Code>>& imports) { 435 const std::vector<Handle<Code>>& imports) {
399 for (uint32_t i = 0; i < functions.size(); ++i) { 436 for (uint32_t i = 0; i < functions.size(); ++i) {
400 Handle<Code> code = functions[i]; 437 Handle<Code> code = functions[i];
401 bool modified = LinkFunction(code, imports, Code::WASM_TO_JS_FUNCTION); 438 LinkFunction(code, imports, Code::WASM_TO_JS_FUNCTION);
402 if (modified) {
403 Assembler::FlushICache(isolate, code->instruction_start(),
404 code->instruction_size());
405 }
406 } 439 }
407 } 440 }
408 441
442 void FlushAssemblyCache(Isolate* isolate, Handle<FixedArray> functions) {
443 for (int i = 0; i < functions->length(); ++i) {
444 Handle<Code> code = functions->GetValueChecked<Code>(i);
445 Assembler::FlushICache(isolate, code->instruction_start(),
446 code->instruction_size());
447 }
448 }
449
409 } // namespace 450 } // namespace
410 451
411 WasmModule::WasmModule() 452 WasmModule::WasmModule()
412 : module_start(nullptr), 453 : module_start(nullptr),
413 module_end(nullptr), 454 module_end(nullptr),
414 min_mem_pages(0), 455 min_mem_pages(0),
415 max_mem_pages(0), 456 max_mem_pages(0),
416 mem_export(false), 457 mem_export(false),
417 mem_external(false), 458 mem_external(false),
418 start_function_index(-1), 459 start_function_index(-1),
419 origin(kWasmOrigin), 460 origin(kWasmOrigin),
420 globals_size(0), 461 globals_size(0),
421 indirect_table_size(0), 462 indirect_table_size(0),
422 pending_tasks(new base::Semaphore(0)) {} 463 pending_tasks(new base::Semaphore(0)) {}
423 464
424 static MaybeHandle<JSFunction> ReportFFIError( 465 static MaybeHandle<JSFunction> ReportFFIError(
425 ErrorThrower& thrower, const char* error, uint32_t index, 466 ErrorThrower& thrower, const char* error, uint32_t index,
426 Handle<String> module_name, MaybeHandle<String> function_name) { 467 Handle<String> module_name, MaybeHandle<String> function_name) {
427 if (!function_name.is_null()) { 468 Handle<String> function_name_handle;
428 Handle<String> function_name_handle = function_name.ToHandleChecked(); 469 if (function_name.ToHandle(&function_name_handle)) {
429 thrower.Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", 470 thrower.Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s",
430 index, module_name->length(), module_name->ToCString().get(), 471 index, module_name->length(), module_name->ToCString().get(),
431 function_name_handle->length(), 472 function_name_handle->length(),
432 function_name_handle->ToCString().get(), error); 473 function_name_handle->ToCString().get(), error);
433 } else { 474 } else {
434 thrower.Error("Import #%d module=\"%.*s\" error: %s", index, 475 thrower.Error("Import #%d module=\"%.*s\" error: %s", index,
435 module_name->length(), module_name->ToCString().get(), error); 476 module_name->length(), module_name->ToCString().get(), error);
436 } 477 }
437 thrower.Error("Import "); 478 thrower.Error("Import ");
438 return MaybeHandle<JSFunction>(); 479 return MaybeHandle<JSFunction>();
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 if (code.is_null()) { 836 if (code.is_null()) {
796 thrower->Error("Compilation of #%d:%.*s failed.", i, str.length(), 837 thrower->Error("Compilation of #%d:%.*s failed.", i, str.length(),
797 str.start()); 838 str.start());
798 break; 839 break;
799 } 840 }
800 // Install the code into the linker table. 841 // Install the code into the linker table.
801 functions[i] = code; 842 functions[i] = code;
802 } 843 }
803 } 844 }
804 845
805 void PopulateFunctionTable(WasmModuleInstance* instance) {
806 if (!instance->function_table.is_null()) {
807 uint32_t table_size = instance->module->FunctionTableSize();
808 DCHECK_EQ(table_size * 2, instance->function_table->length());
809 uint32_t populated_table_size =
810 static_cast<uint32_t>(instance->module->function_table.size());
811 for (uint32_t i = 0; i < populated_table_size; ++i) {
812 instance->function_table->set(
813 i + table_size,
814 *instance->function_code[instance->module->function_table[i]]);
815 }
816 }
817 }
818
819 void SetDebugSupport(Factory* factory, Handle<FixedArray> compiled_module, 846 void SetDebugSupport(Factory* factory, Handle<FixedArray> compiled_module,
820 Handle<JSObject> js_object) { 847 Handle<JSObject> js_object) {
821 MaybeHandle<String> module_bytes_string = 848 MaybeHandle<String> module_bytes_string =
822 compiled_module->GetValue<String>(kModuleBytes); 849 compiled_module->GetValue<String>(kModuleBytes);
823 if (!module_bytes_string.is_null()) { 850 if (!module_bytes_string.is_null()) {
824 js_object->SetInternalField(kWasmModuleBytesString, 851 js_object->SetInternalField(kWasmModuleBytesString,
825 *module_bytes_string.ToHandleChecked()); 852 *module_bytes_string.ToHandleChecked());
826 } 853 }
827 Handle<FixedArray> functions = Handle<FixedArray>( 854 Handle<FixedArray> functions = Handle<FixedArray>(
828 FixedArray::cast(js_object->GetInternalField(kWasmModuleCodeTable))); 855 FixedArray::cast(js_object->GetInternalField(kWasmModuleCodeTable)));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 921
895 bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module, 922 bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module,
896 Handle<JSObject> instance, ErrorThrower* thrower, 923 Handle<JSObject> instance, ErrorThrower* thrower,
897 Handle<JSReceiver> ffi) { 924 Handle<JSReceiver> ffi) {
898 //------------------------------------------------------------------------- 925 //-------------------------------------------------------------------------
899 // Compile wrappers to imported functions. 926 // Compile wrappers to imported functions.
900 //------------------------------------------------------------------------- 927 //-------------------------------------------------------------------------
901 std::vector<Handle<Code>> import_code; 928 std::vector<Handle<Code>> import_code;
902 MaybeHandle<FixedArray> maybe_import_data = 929 MaybeHandle<FixedArray> maybe_import_data =
903 compiled_module->GetValue<FixedArray>(kImportData); 930 compiled_module->GetValue<FixedArray>(kImportData);
904 if (!maybe_import_data.is_null()) { 931 Handle<FixedArray> import_data;
905 Handle<FixedArray> import_data = maybe_import_data.ToHandleChecked(); 932 if (maybe_import_data.ToHandle(&import_data)) {
906 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code, 933 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code,
907 import_data, thrower)) { 934 import_data, thrower)) {
908 return false; 935 return false;
909 } 936 }
910 } 937 }
911 938
912 RecordStats(isolate, import_code); 939 RecordStats(isolate, import_code);
913 940
914 Handle<FixedArray> code_table = Handle<FixedArray>( 941 Handle<FixedArray> code_table = Handle<FixedArray>(
915 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); 942 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable)));
916 // TODO(mtrofin): get the code off std::vector and on FixedArray, for 943 // TODO(mtrofin): get the code off std::vector and on FixedArray, for
917 // consistency. 944 // consistency.
918 std::vector<Handle<Code>> function_code(code_table->length()); 945 std::vector<Handle<Code>> function_code(code_table->length());
919 for (int i = 0; i < code_table->length(); ++i) { 946 for (int i = 0; i < code_table->length(); ++i) {
920 Handle<Code> code = Handle<Code>(Code::cast(code_table->get(i))); 947 Handle<Code> code = Handle<Code>(Code::cast(code_table->get(i)));
921 function_code[i] = code; 948 function_code[i] = code;
922 } 949 }
923 950
924 instance->SetInternalField(kWasmModuleFunctionTable, Smi::FromInt(0));
925 LinkImports(isolate, function_code, import_code); 951 LinkImports(isolate, function_code, import_code);
926 return true; 952 return true;
927 } 953 }
928 954
929 bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate, 955 bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate,
930 Handle<JSObject> instance, ErrorThrower* thrower) { 956 Handle<JSObject> instance, ErrorThrower* thrower) {
931 Factory* factory = isolate->factory(); 957 Factory* factory = isolate->factory();
932 bool mem_export = 958 bool mem_export =
933 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value()); 959 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value());
934 ModuleOrigin origin = static_cast<ModuleOrigin>( 960 ModuleOrigin origin = static_cast<ModuleOrigin>(
935 Smi::cast(compiled_module->get(kOrigin))->value()); 961 Smi::cast(compiled_module->get(kOrigin))->value());
936 962
937 MaybeHandle<FixedArray> maybe_exports = 963 MaybeHandle<FixedArray> maybe_exports =
938 compiled_module->GetValue<FixedArray>(kExports); 964 compiled_module->GetValue<FixedArray>(kExports);
939 if (!maybe_exports.is_null() || mem_export) { 965 if (!maybe_exports.is_null() || mem_export) {
940 PropertyDescriptor desc; 966 PropertyDescriptor desc;
941 desc.set_writable(false); 967 desc.set_writable(false);
942 968
943 Handle<JSObject> exports_object = instance; 969 Handle<JSObject> exports_object = instance;
944 if (origin == kWasmOrigin) { 970 if (origin == kWasmOrigin) {
945 // Create the "exports" object. 971 // Create the "exports" object.
946 Handle<JSFunction> object_function = Handle<JSFunction>( 972 Handle<JSFunction> object_function = Handle<JSFunction>(
947 isolate->native_context()->object_function(), isolate); 973 isolate->native_context()->object_function(), isolate);
948 exports_object = factory->NewJSObject(object_function, TENURED); 974 exports_object = factory->NewJSObject(object_function, TENURED);
949 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); 975 Handle<String> exports_name = factory->InternalizeUtf8String("exports");
950 JSObject::AddProperty(instance, exports_name, exports_object, READ_ONLY); 976 JSObject::AddProperty(instance, exports_name, exports_object, READ_ONLY);
951 } 977 }
952 if (!maybe_exports.is_null()) { 978 Handle<FixedArray> exports;
953 Handle<FixedArray> exports = maybe_exports.ToHandleChecked(); 979 if (maybe_exports.ToHandle(&exports)) {
954
955 int exports_size = exports->length(); 980 int exports_size = exports->length();
956 for (int i = 0; i < exports_size; ++i) { 981 for (int i = 0; i < exports_size; ++i) {
957 if (thrower->error()) return false; 982 if (thrower->error()) return false;
958 Handle<JSFunction> function = exports->GetValueChecked<JSFunction>(i); 983 Handle<FixedArray> export_metadata =
959 RecordStats(isolate, function->code()); 984 exports->GetValueChecked<FixedArray>(i);
985 Handle<Code> export_code =
986 export_metadata->GetValueChecked<Code>(kExportCode);
987 RecordStats(isolate, *export_code);
960 Handle<String> name = 988 Handle<String> name =
961 Handle<String>(String::cast(function->shared()->name())); 989 export_metadata->GetValueChecked<String>(kExportName);
962 function->SetInternalField(0, *instance); 990 int arity = Smi::cast(export_metadata->get(kExportArity))->value();
963 991 Handle<JSFunction> function = WrapExportCodeAsJSFunction(
992 isolate, export_code, name, arity, instance);
964 desc.set_value(function); 993 desc.set_value(function);
965 Maybe<bool> status = JSReceiver::DefineOwnProperty( 994 Maybe<bool> status = JSReceiver::DefineOwnProperty(
966 isolate, exports_object, name, &desc, Object::THROW_ON_ERROR); 995 isolate, exports_object, name, &desc, Object::THROW_ON_ERROR);
967 if (!status.IsJust()) { 996 if (!status.IsJust()) {
968 thrower->Error("export of %.*s failed.", name->length(), 997 thrower->Error("export of %.*s failed.", name->length(),
969 name->ToCString().get()); 998 name->ToCString().get());
970 return false; 999 return false;
971 } 1000 }
972 } 1001 }
973 } 1002 }
(...skipping 10 matching lines...) Expand all
984 1013
985 } // namespace 1014 } // namespace
986 1015
987 MaybeHandle<FixedArray> WasmModule::CompileFunctions(Isolate* isolate) const { 1016 MaybeHandle<FixedArray> WasmModule::CompileFunctions(Isolate* isolate) const {
988 Factory* factory = isolate->factory(); 1017 Factory* factory = isolate->factory();
989 ErrorThrower thrower(isolate, "WasmModule::CompileFunctions()"); 1018 ErrorThrower thrower(isolate, "WasmModule::CompileFunctions()");
990 1019
991 MaybeHandle<FixedArray> nothing; 1020 MaybeHandle<FixedArray> nothing;
992 1021
993 WasmModuleInstance temp_instance_for_compilation(this); 1022 WasmModuleInstance temp_instance_for_compilation(this);
994 temp_instance_for_compilation.function_table =
995 BuildFunctionTable(isolate, this);
996 temp_instance_for_compilation.context = isolate->native_context(); 1023 temp_instance_for_compilation.context = isolate->native_context();
997 temp_instance_for_compilation.mem_size = GetMinModuleMemSize(this); 1024 temp_instance_for_compilation.mem_size = GetMinModuleMemSize(this);
998 temp_instance_for_compilation.mem_start = nullptr; 1025 temp_instance_for_compilation.mem_start = nullptr;
999 temp_instance_for_compilation.globals_start = nullptr; 1026 temp_instance_for_compilation.globals_start = nullptr;
1000 1027
1028 MaybeHandle<FixedArray> indirect_table = BuildFunctionTable(isolate, this);
1029 if (!indirect_table.is_null()) {
1030 temp_instance_for_compilation.function_table =
1031 indirect_table.ToHandleChecked();
1032 }
1033
1001 HistogramTimerScope wasm_compile_module_time_scope( 1034 HistogramTimerScope wasm_compile_module_time_scope(
1002 isolate->counters()->wasm_compile_module_time()); 1035 isolate->counters()->wasm_compile_module_time());
1003 1036
1004 ModuleEnv module_env; 1037 ModuleEnv module_env;
1005 module_env.module = this; 1038 module_env.module = this;
1006 module_env.instance = &temp_instance_for_compilation; 1039 module_env.instance = &temp_instance_for_compilation;
1007 module_env.origin = origin; 1040 module_env.origin = origin;
1008 InitializePlaceholders(factory, &module_env.placeholders, functions.size()); 1041 InitializePlaceholders(factory, &module_env.placeholders, functions.size());
1009 1042
1010 Handle<FixedArray> compiled_functions = 1043 Handle<FixedArray> compiled_functions =
(...skipping 10 matching lines...) Expand all
1021 CompileInParallel(isolate, this, 1054 CompileInParallel(isolate, this,
1022 temp_instance_for_compilation.function_code, &thrower, 1055 temp_instance_for_compilation.function_code, &thrower,
1023 &module_env); 1056 &module_env);
1024 } else { 1057 } else {
1025 CompileSequentially(isolate, this, 1058 CompileSequentially(isolate, this,
1026 temp_instance_for_compilation.function_code, &thrower, 1059 temp_instance_for_compilation.function_code, &thrower,
1027 &module_env); 1060 &module_env);
1028 } 1061 }
1029 if (thrower.error()) return nothing; 1062 if (thrower.error()) return nothing;
1030 1063
1031 LinkModuleFunctions(isolate, temp_instance_for_compilation.function_code);
1032
1033 // At this point, compilation has completed. Update the code table. 1064 // At this point, compilation has completed. Update the code table.
1034 for (size_t i = FLAG_skip_compiling_wasm_funcs; 1065 for (size_t i = FLAG_skip_compiling_wasm_funcs;
1035 i < temp_instance_for_compilation.function_code.size(); ++i) { 1066 i < temp_instance_for_compilation.function_code.size(); ++i) {
1036 Code* code = *temp_instance_for_compilation.function_code[i]; 1067 Code* code = *temp_instance_for_compilation.function_code[i];
1037 compiled_functions->set(static_cast<int>(i), code); 1068 compiled_functions->set(static_cast<int>(i), code);
1038 } 1069 }
1039 1070
1040 PopulateFunctionTable(&temp_instance_for_compilation);
1041
1042 // Create the compiled module object, and populate with compiled functions 1071 // Create the compiled module object, and populate with compiled functions
1043 // and information needed at instantiation time. This object needs to be 1072 // and information needed at instantiation time. This object needs to be
1044 // serializable. Instantiation may occur off a deserialized version of this 1073 // serializable. Instantiation may occur off a deserialized version of this
1045 // object. 1074 // object.
1046 Handle<FixedArray> ret = 1075 Handle<FixedArray> ret =
1047 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED); 1076 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED);
1048 ret->set(kFunctions, *compiled_functions); 1077 ret->set(kFunctions, *compiled_functions);
1049 1078 ret->set(kIndirectFunctionTableSize,
1079 Smi::FromInt(static_cast<int>(function_table.size())));
1080 if (!indirect_table.is_null()) {
1081 ret->set(kIndirectFunctionTablePrototype,
1082 *indirect_table.ToHandleChecked());
1083 }
1050 Handle<FixedArray> import_data = GetImportsMetadata(factory, this); 1084 Handle<FixedArray> import_data = GetImportsMetadata(factory, this);
1051 ret->set(kImportData, *import_data); 1085 ret->set(kImportData, *import_data);
1052 1086
1053 // Compile export functions. 1087 // Compile export functions.
1054 int export_size = static_cast<int>(export_table.size()); 1088 int export_size = static_cast<int>(export_table.size());
1055 Handle<JSFunction> startup_fct; 1089 Handle<Code> startup_fct;
1056 if (export_size > 0) { 1090 if (export_size > 0) {
1057 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED); 1091 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED);
1058 for (int i = 0; i < export_size; ++i) { 1092 for (int i = 0; i < export_size; ++i) {
1093 Handle<FixedArray> export_metadata =
1094 factory->NewFixedArray(kWasmExportMetadataTableSize, TENURED);
1059 const WasmExport& exp = export_table[i]; 1095 const WasmExport& exp = export_table[i];
1060 WasmName str = GetName(exp.name_offset, exp.name_length); 1096 WasmName str = GetName(exp.name_offset, exp.name_length);
1061 Handle<String> name = factory->InternalizeUtf8String(str); 1097 Handle<String> name = factory->InternalizeUtf8String(str);
1062 Handle<Code> code = 1098 Handle<Code> code =
1063 temp_instance_for_compilation.function_code[exp.func_index]; 1099 temp_instance_for_compilation.function_code[exp.func_index];
1064 Handle<JSFunction> function = compiler::CompileJSToWasmWrapper( 1100 Handle<Code> export_code = compiler::CompileJSToWasmWrapper(
1065 isolate, &module_env, name, code, exp.func_index); 1101 isolate, &module_env, code, exp.func_index);
1066 if (thrower.error()) return nothing; 1102 if (thrower.error()) return nothing;
1067 exports->set(i, *function); 1103 export_metadata->set(kExportCode, *export_code);
1104 export_metadata->set(kExportName, *name);
1105 export_metadata->set(
1106 kExportArity, Smi::FromInt(static_cast<int>(
1107 functions[exp.func_index].sig->parameter_count())));
1108 export_metadata->set(kExportedFunctionIndex,
1109 Smi::FromInt(static_cast<int>(exp.func_index)));
1110 exports->set(i, *export_metadata);
1068 if (exp.func_index == start_function_index) { 1111 if (exp.func_index == start_function_index) {
1069 startup_fct = function; 1112 startup_fct = export_code;
1070 } 1113 }
1071 } 1114 }
1072 ret->set(kExports, *exports); 1115 ret->set(kExports, *exports);
1073 } 1116 }
1074 1117
1075 // Compile startup function, if we haven't already. 1118 // Compile startup function, if we haven't already.
1076 if (start_function_index >= 0) { 1119 if (start_function_index >= 0) {
1120 uint32_t index = static_cast<uint32_t>(start_function_index);
1077 HandleScope scope(isolate); 1121 HandleScope scope(isolate);
1078 if (startup_fct.is_null()) { 1122 if (startup_fct.is_null()) {
1079 uint32_t index = static_cast<uint32_t>(start_function_index);
1080 Handle<String> name = factory->NewStringFromStaticChars("start");
1081 Handle<Code> code = temp_instance_for_compilation.function_code[index]; 1123 Handle<Code> code = temp_instance_for_compilation.function_code[index];
1082 startup_fct = compiler::CompileJSToWasmWrapper(isolate, &module_env, name, 1124 DCHECK_EQ(0, functions[index].sig->parameter_count());
1083 code, index); 1125 startup_fct =
1126 compiler::CompileJSToWasmWrapper(isolate, &module_env, code, index);
1084 } 1127 }
1085 ret->set(kStartupFunction, *startup_fct); 1128 Handle<FixedArray> metadata =
1129 factory->NewFixedArray(kWasmExportMetadataTableSize, TENURED);
1130 metadata->set(kExportCode, *startup_fct);
1131 metadata->set(kExportArity, Smi::FromInt(0));
1132 metadata->set(kExportedFunctionIndex, Smi::FromInt(start_function_index));
1133 ret->set(kStartupFunction, *metadata);
1086 } 1134 }
1087 1135
1088 // TODO(wasm): saving the module bytes for debugging is wasteful. We should 1136 // TODO(wasm): saving the module bytes for debugging is wasteful. We should
1089 // consider downloading this on-demand. 1137 // consider downloading this on-demand.
1090 { 1138 {
1091 size_t module_bytes_len = module_end - module_start; 1139 size_t module_bytes_len = module_end - module_start;
1092 DCHECK_LE(module_bytes_len, static_cast<size_t>(kMaxInt)); 1140 DCHECK_LE(module_bytes_len, static_cast<size_t>(kMaxInt));
1093 Vector<const uint8_t> module_bytes_vec(module_start, 1141 Vector<const uint8_t> module_bytes_vec(module_start,
1094 static_cast<int>(module_bytes_len)); 1142 static_cast<int>(module_bytes_len));
1095 Handle<String> module_bytes_string = 1143 Handle<String> module_bytes_string =
1096 factory->NewStringFromOneByte(module_bytes_vec, TENURED) 1144 factory->NewStringFromOneByte(module_bytes_vec, TENURED)
1097 .ToHandleChecked(); 1145 .ToHandleChecked();
1098 ret->set(kModuleBytes, *module_bytes_string); 1146 ret->set(kModuleBytes, *module_bytes_string);
1099 } 1147 }
1100 1148
1101 Handle<ByteArray> function_name_table = 1149 Handle<ByteArray> function_name_table =
1102 BuildFunctionNamesTable(isolate, module_env.module); 1150 BuildFunctionNamesTable(isolate, module_env.module);
1103 ret->set(kFunctionNameTable, *function_name_table); 1151 ret->set(kFunctionNameTable, *function_name_table);
1104 ret->set(kMinRequiredMemory, Smi::FromInt(min_mem_pages)); 1152 ret->set(kMinRequiredMemory, Smi::FromInt(min_mem_pages));
1105 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret); 1153 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret);
1106 ret->set(kGlobalsSize, Smi::FromInt(globals_size)); 1154 ret->set(kGlobalsSize, Smi::FromInt(globals_size));
1107 ret->set(kExportMem, Smi::FromInt(mem_export)); 1155 ret->set(kExportMem, Smi::FromInt(mem_export));
1108 ret->set(kOrigin, Smi::FromInt(origin)); 1156 ret->set(kOrigin, Smi::FromInt(origin));
1109 return ret; 1157 return ret;
1110 } 1158 }
1111 1159
1160 void PatchJSWrapper(Isolate* isolate, Handle<Code> wrapper,
1161 Handle<Code> new_target) {
1162 AllowDeferredHandleDereference embedding_raw_address;
1163 bool seen = false;
1164 for (RelocIterator it(*wrapper, 1 << RelocInfo::CODE_TARGET); !it.done();
1165 it.next()) {
1166 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
1167 if (target->kind() == Code::WASM_FUNCTION) {
1168 DCHECK(!seen);
1169 seen = true;
1170 it.rinfo()->set_target_address(new_target->instruction_start(),
1171 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
1172 }
1173 }
1174 CHECK(seen);
1175 Assembler::FlushICache(isolate, wrapper->instruction_start(),
1176 wrapper->instruction_size());
1177 }
1178
1179 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate,
1180 Handle<FixedArray> original) {
1181 Factory* factory = isolate->factory();
1182 Handle<FixedArray> clone = factory->CopyFixedArray(original);
1183
1184 Handle<FixedArray> orig_wasm_functions =
1185 original->GetValueChecked<FixedArray>(kFunctions);
1186 Handle<FixedArray> clone_wasm_functions =
1187 factory->CopyFixedArray(orig_wasm_functions);
1188 clone->set(kFunctions, *clone_wasm_functions);
1189
1190 MaybeHandle<FixedArray> maybe_indirect_table =
1191 original->GetValue<FixedArray>(kIndirectFunctionTablePrototype);
1192
1193 Handle<FixedArray> indirect_table;
1194 Handle<FixedArray> old_table;
1195 if (maybe_indirect_table.ToHandle(&old_table)) {
1196 indirect_table = factory->CopyFixedArray(old_table);
1197 clone->set(kIndirectFunctionTablePrototype, *indirect_table);
1198 }
1199
1200 for (int i = 0; i < orig_wasm_functions->length(); ++i) {
1201 Handle<Code> orig_code = orig_wasm_functions->GetValueChecked<Code>(i);
1202 Handle<Code> cloned_code = factory->CopyCode(orig_code);
1203 clone_wasm_functions->set(i, *cloned_code);
1204 if (!maybe_indirect_table.is_null()) {
1205 PatchFunctionTable(cloned_code, old_table, indirect_table);
1206 }
1207 }
1208
1209 MaybeHandle<FixedArray> maybe_orig_exports =
1210 original->GetValue<FixedArray>(kExports);
1211 Handle<FixedArray> orig_exports;
1212 if (maybe_orig_exports.ToHandle(&orig_exports)) {
1213 Handle<FixedArray> cloned_exports = factory->CopyFixedArray(orig_exports);
1214 clone->set(kExports, *cloned_exports);
1215 for (int i = 0; i < orig_exports->length(); ++i) {
1216 Handle<FixedArray> export_metadata =
1217 orig_exports->GetValueChecked<FixedArray>(i);
1218 Handle<FixedArray> clone_metadata =
1219 factory->CopyFixedArray(export_metadata);
1220 cloned_exports->set(i, *clone_metadata);
1221 Handle<Code> orig_code =
1222 export_metadata->GetValueChecked<Code>(kExportCode);
1223 Handle<Code> cloned_code = factory->CopyCode(orig_code);
1224 clone_metadata->set(kExportCode, *cloned_code);
1225 // TODO(wasm): This is actually a uint32_t, but since FixedArray indexes
1226 // in int, we are taking the risk of invalid values.
1227 int exported_fct_index =
1228 Smi::cast(export_metadata->get(kExportedFunctionIndex))->value();
1229 CHECK_GE(exported_fct_index, 0);
1230 CHECK_LT(exported_fct_index, clone_wasm_functions->length());
1231 Handle<Code> new_target =
1232 clone_wasm_functions->GetValueChecked<Code>(exported_fct_index);
1233 PatchJSWrapper(isolate, cloned_code, new_target);
1234 }
1235 }
1236
1237 MaybeHandle<FixedArray> maybe_startup =
1238 original->GetValue<FixedArray>(kStartupFunction);
1239 if (!maybe_startup.is_null()) {
1240 Handle<FixedArray> startup_metadata =
1241 factory->CopyFixedArray(maybe_startup.ToHandleChecked());
1242 Handle<Code> startup_fct_clone =
1243 factory->CopyCode(startup_metadata->GetValueChecked<Code>(kExportCode));
1244 startup_metadata->set(kExportCode, *startup_fct_clone);
1245 clone->set(kStartupFunction, *startup_metadata);
1246 // TODO(wasm): see todo above about int vs size_t indexing in FixedArray.
1247 int startup_fct_index =
1248 Smi::cast(startup_metadata->get(kExportedFunctionIndex))->value();
1249 CHECK_GE(startup_fct_index, 0);
1250 CHECK_LT(startup_fct_index, clone_wasm_functions->length());
1251 Handle<Code> new_target =
1252 clone_wasm_functions->GetValueChecked<Code>(startup_fct_index);
1253 PatchJSWrapper(isolate, startup_fct_clone, new_target);
1254 }
1255 return clone;
1256 }
1257
1112 // Instantiates a wasm module as a JSObject. 1258 // Instantiates a wasm module as a JSObject.
1113 // * allocates a backing store of {mem_size} bytes. 1259 // * allocates a backing store of {mem_size} bytes.
1114 // * installs a named property "memory" for that buffer if exported 1260 // * installs a named property "memory" for that buffer if exported
1115 // * installs named properties on the object for exported functions 1261 // * installs named properties on the object for exported functions
1116 // * compiles wasm code to machine code 1262 // * compiles wasm code to machine code
1117 MaybeHandle<JSObject> WasmModule::Instantiate( 1263 MaybeHandle<JSObject> WasmModule::Instantiate(
1118 Isolate* isolate, Handle<FixedArray> compiled_module, 1264 Isolate* isolate, Handle<FixedArray> compiled_module,
1119 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) { 1265 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) {
1120 HistogramTimerScope wasm_instantiate_module_time_scope( 1266 HistogramTimerScope wasm_instantiate_module_time_scope(
1121 isolate->counters()->wasm_instantiate_module_time()); 1267 isolate->counters()->wasm_instantiate_module_time());
1122 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); 1268 ErrorThrower thrower(isolate, "WasmModule::Instantiate()");
1123 Factory* factory = isolate->factory(); 1269 Factory* factory = isolate->factory();
1124 1270
1271 compiled_module = CloneModuleForInstance(isolate, compiled_module);
1272
1125 // These fields are compulsory. 1273 // These fields are compulsory.
1126 Handle<FixedArray> code_table = 1274 Handle<FixedArray> code_table =
1127 compiled_module->GetValueChecked<FixedArray>(kFunctions); 1275 compiled_module->GetValueChecked<FixedArray>(kFunctions);
1128 1276
1277 {
1278 std::vector<Handle<Code>> functions(
1279 static_cast<size_t>(code_table->length()));
1280 for (int i = 0; i < code_table->length(); ++i) {
1281 functions[static_cast<size_t>(i)] = code_table->GetValueChecked<Code>(i);
1282 }
1283 LinkModuleFunctions(isolate, functions);
1284 }
1285
1129 RecordStats(isolate, code_table); 1286 RecordStats(isolate, code_table);
1130 1287
1131 MaybeHandle<JSObject> nothing; 1288 MaybeHandle<JSObject> nothing;
1132 1289
1133 Handle<Map> map = factory->NewMap( 1290 Handle<Map> map = factory->NewMap(
1134 JS_OBJECT_TYPE, 1291 JS_OBJECT_TYPE,
1135 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 1292 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
1136 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED); 1293 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED);
1137 js_object->SetInternalField(kWasmModuleCodeTable, *code_table); 1294 js_object->SetInternalField(kWasmModuleCodeTable, *code_table);
1138 1295
1139 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory, 1296 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory,
1140 &thrower) && 1297 &thrower) &&
1141 SetupGlobals(isolate, compiled_module, js_object, &thrower) && 1298 SetupGlobals(isolate, compiled_module, js_object, &thrower) &&
1142 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) && 1299 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) &&
1143 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) { 1300 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) {
1144 return nothing; 1301 return nothing;
1145 } 1302 }
1146 1303
1147 SetDebugSupport(factory, compiled_module, js_object); 1304 SetDebugSupport(factory, compiled_module, js_object);
1148 1305
1306 FlushAssemblyCache(isolate, code_table);
1307
1308 MaybeHandle<FixedArray> maybe_indirect_table =
1309 compiled_module->GetValue<FixedArray>(kIndirectFunctionTablePrototype);
1310 Handle<FixedArray> indirect_table;
1311 if (maybe_indirect_table.ToHandle(&indirect_table)) {
1312 int table_size =
1313 Smi::cast(compiled_module->get(kIndirectFunctionTableSize))->value();
1314 int half_point = indirect_table->length() / 2;
1315 for (int i = half_point; i < half_point + table_size; ++i) {
1316 int index = Smi::cast(indirect_table->get(i))->value();
1317 DCHECK_GE(index, 0);
1318 DCHECK_LT(index, code_table->length());
1319 indirect_table->set(i, code_table->get(index));
1320 }
1321 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_table);
1322 }
1323
1149 // Run the start function if one was specified. 1324 // Run the start function if one was specified.
1150 MaybeHandle<JSFunction> maybe_startup_fct = 1325 MaybeHandle<FixedArray> maybe_startup_fct =
1151 compiled_module->GetValue<JSFunction>(kStartupFunction); 1326 compiled_module->GetValue<FixedArray>(kStartupFunction);
1152 if (!maybe_startup_fct.is_null()) { 1327 Handle<FixedArray> metadata;
1328 if (maybe_startup_fct.ToHandle(&metadata)) {
1153 HandleScope scope(isolate); 1329 HandleScope scope(isolate);
1154 Handle<JSFunction> startup_fct = maybe_startup_fct.ToHandleChecked(); 1330 Handle<Code> startup_code = metadata->GetValueChecked<Code>(kExportCode);
1155 RecordStats(isolate, startup_fct->code()); 1331 int arity = Smi::cast(metadata->get(kExportArity))->value();
1156 startup_fct->SetInternalField(0, *js_object); 1332 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction(
1333 isolate, startup_code, factory->InternalizeUtf8String("start"), arity,
1334 js_object);
1335 RecordStats(isolate, *startup_code);
1157 // Call the JS function. 1336 // Call the JS function.
1158 Handle<Object> undefined = isolate->factory()->undefined_value(); 1337 Handle<Object> undefined = isolate->factory()->undefined_value();
1159 MaybeHandle<Object> retval = 1338 MaybeHandle<Object> retval =
1160 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); 1339 Execution::Call(isolate, startup_fct, undefined, 0, nullptr);
1161 1340
1162 if (retval.is_null()) { 1341 if (retval.is_null()) {
1163 thrower.Error("WASM.instantiateModule(): start function failed"); 1342 thrower.Error("WASM.instantiateModule(): start function failed");
1164 return nothing; 1343 return nothing;
1165 } 1344 }
1166 } 1345 }
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1327 } 1506 }
1328 if (module->export_table.size() == 0) { 1507 if (module->export_table.size() == 0) {
1329 thrower.Error("Not supported: module has no exports."); 1508 thrower.Error("Not supported: module has no exports.");
1330 } 1509 }
1331 1510
1332 if (thrower.error()) return -1; 1511 if (thrower.error()) return -1;
1333 MaybeHandle<FixedArray> compiled_module = module->CompileFunctions(isolate); 1512 MaybeHandle<FixedArray> compiled_module = module->CompileFunctions(isolate);
1334 1513
1335 if (compiled_module.is_null()) return -1; 1514 if (compiled_module.is_null()) return -1;
1336 Handle<JSObject> instance = 1515 Handle<JSObject> instance =
1337 module 1516 WasmModule::Instantiate(isolate, compiled_module.ToHandleChecked(),
1338 ->Instantiate(isolate, compiled_module.ToHandleChecked(), 1517 Handle<JSReceiver>::null(),
1339 Handle<JSReceiver>::null(), 1518 Handle<JSArrayBuffer>::null())
1340 Handle<JSArrayBuffer>::null())
1341 .ToHandleChecked(); 1519 .ToHandleChecked();
1342 1520
1343 Handle<Name> exports = isolate->factory()->InternalizeUtf8String("exports"); 1521 Handle<Name> exports = isolate->factory()->InternalizeUtf8String("exports");
1344 Handle<JSObject> exports_object = Handle<JSObject>::cast( 1522 Handle<JSObject> exports_object = Handle<JSObject>::cast(
1345 JSObject::GetProperty(instance, exports).ToHandleChecked()); 1523 JSObject::GetProperty(instance, exports).ToHandleChecked());
1346 Handle<Name> main_name = isolate->factory()->NewStringFromStaticChars("main"); 1524 Handle<Name> main_name = isolate->factory()->NewStringFromStaticChars("main");
1347 PropertyDescriptor desc; 1525 PropertyDescriptor desc;
1348 Maybe<bool> property_found = JSReceiver::GetOwnPropertyDescriptor( 1526 Maybe<bool> property_found = JSReceiver::GetOwnPropertyDescriptor(
1349 isolate, exports_object, main_name, &desc); 1527 isolate, exports_object, main_name, &desc);
1350 if (!property_found.FromMaybe(false)) return -1; 1528 if (!property_found.FromMaybe(false)) return -1;
(...skipping 18 matching lines...) Expand all
1369 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); 1547 return static_cast<int32_t>(HeapNumber::cast(*result)->value());
1370 } 1548 }
1371 thrower.Error("WASM.compileRun() failed: Return value should be number"); 1549 thrower.Error("WASM.compileRun() failed: Return value should be number");
1372 return -1; 1550 return -1;
1373 } 1551 }
1374 1552
1375 } // namespace testing 1553 } // namespace testing
1376 } // namespace wasm 1554 } // namespace wasm
1377 } // namespace internal 1555 } // namespace internal
1378 } // namespace v8 1556 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/wasm-module.h ('k') | test/cctest/wasm/wasm-run-utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698