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/assembler-inl.h" | 7 #include "src/assembler-inl.h" |
8 #include "src/base/adapters.h" | 8 #include "src/base/adapters.h" |
9 #include "src/base/atomic-utils.h" | 9 #include "src/base/atomic-utils.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1114 UnwrapImportWrapper(function)); | 1114 UnwrapImportWrapper(function)); |
1115 } | 1115 } |
1116 } | 1116 } |
1117 | 1117 |
1118 // A helper class to simplify instantiating a module from a compiled module. | 1118 // A helper class to simplify instantiating a module from a compiled module. |
1119 // It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule}, | 1119 // It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule}, |
1120 // etc. | 1120 // etc. |
1121 class WasmInstanceBuilder { | 1121 class WasmInstanceBuilder { |
1122 public: | 1122 public: |
1123 WasmInstanceBuilder(Isolate* isolate, ErrorThrower* thrower, | 1123 WasmInstanceBuilder(Isolate* isolate, ErrorThrower* thrower, |
1124 Handle<JSObject> module_object, Handle<JSReceiver> ffi, | 1124 Handle<WasmModuleObject> module_object, |
1125 Handle<JSArrayBuffer> memory) | 1125 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) |
1126 : isolate_(isolate), | 1126 : isolate_(isolate), |
1127 thrower_(thrower), | 1127 thrower_(thrower), |
1128 module_object_(module_object), | 1128 module_object_(module_object), |
1129 ffi_(ffi), | 1129 ffi_(ffi), |
1130 memory_(memory) {} | 1130 memory_(memory) {} |
1131 | 1131 |
1132 // Build an instance, in all of its glory. | 1132 // Build an instance, in all of its glory. |
1133 MaybeHandle<WasmInstanceObject> Build() { | 1133 MaybeHandle<WasmInstanceObject> Build() { |
1134 MaybeHandle<WasmInstanceObject> nothing; | 1134 MaybeHandle<WasmInstanceObject> nothing; |
1135 | |
1136 // Check that an imports argument was provided, if the module requires it. | |
1137 // No point in continuing otherwise. | |
1138 if (!module_object_->compiled_module()->module()->import_table.empty() && | |
titzer
2017/01/13 17:20:43
Can you do this check after we extract the module_
Mircea Trofin
2017/01/13 20:17:18
we can actually initialize module_ at construction
| |
1139 ffi_.is_null()) { | |
1140 thrower_->TypeError( | |
1141 "Imports argument must be present and must be an object"); | |
1142 return nothing; | |
1143 } | |
1144 | |
1135 HistogramTimerScope wasm_instantiate_module_time_scope( | 1145 HistogramTimerScope wasm_instantiate_module_time_scope( |
1136 isolate_->counters()->wasm_instantiate_module_time()); | 1146 isolate_->counters()->wasm_instantiate_module_time()); |
1137 Factory* factory = isolate_->factory(); | 1147 Factory* factory = isolate_->factory(); |
1138 | 1148 |
1139 //-------------------------------------------------------------------------- | 1149 //-------------------------------------------------------------------------- |
1140 // Reuse the compiled module (if no owner), otherwise clone. | 1150 // Reuse the compiled module (if no owner), otherwise clone. |
1141 //-------------------------------------------------------------------------- | 1151 //-------------------------------------------------------------------------- |
1142 Handle<FixedArray> code_table; | 1152 Handle<FixedArray> code_table; |
1143 Handle<FixedArray> old_code_table; | 1153 Handle<FixedArray> old_code_table; |
1144 MaybeHandle<WasmInstanceObject> owner; | 1154 MaybeHandle<WasmInstanceObject> owner; |
1145 | 1155 |
1146 TRACE("Starting new module instantiation\n"); | 1156 TRACE("Starting new module instantiation\n"); |
1147 { | 1157 { |
1148 // Root the owner, if any, before doing any allocations, which | 1158 // Root the owner, if any, before doing any allocations, which |
1149 // may trigger GC. | 1159 // may trigger GC. |
1150 // Both owner and original template need to be in sync. Even | 1160 // Both owner and original template need to be in sync. Even |
1151 // after we lose the original template handle, the code | 1161 // after we lose the original template handle, the code |
1152 // objects we copied from it have data relative to the | 1162 // objects we copied from it have data relative to the |
1153 // instance - such as globals addresses. | 1163 // instance - such as globals addresses. |
1154 Handle<WasmCompiledModule> original; | 1164 Handle<WasmCompiledModule> original; |
1155 { | 1165 { |
1156 DisallowHeapAllocation no_gc; | 1166 DisallowHeapAllocation no_gc; |
1157 original = handle( | 1167 original = handle(module_object_->compiled_module()); |
1158 WasmCompiledModule::cast(module_object_->GetInternalField(0))); | |
1159 if (original->has_weak_owning_instance()) { | 1168 if (original->has_weak_owning_instance()) { |
1160 owner = handle(WasmInstanceObject::cast( | 1169 owner = handle(WasmInstanceObject::cast( |
1161 original->weak_owning_instance()->value())); | 1170 original->weak_owning_instance()->value())); |
1162 } | 1171 } |
1163 } | 1172 } |
1164 DCHECK(!original.is_null()); | 1173 DCHECK(!original.is_null()); |
1165 // Always make a new copy of the code_table, since the old_code_table | 1174 // Always make a new copy of the code_table, since the old_code_table |
1166 // may still have placeholders for imports. | 1175 // may still have placeholders for imports. |
1167 old_code_table = original->code_table(); | 1176 old_code_table = original->code_table(); |
1168 code_table = factory->CopyFixedArray(old_code_table); | 1177 code_table = factory->CopyFixedArray(old_code_table); |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1435 // It's unfortunate that the new instance is already linked in the | 1444 // It's unfortunate that the new instance is already linked in the |
1436 // chain. However, we need to set up everything before executing the | 1445 // chain. However, we need to set up everything before executing the |
1437 // start function, such that stack trace information can be generated | 1446 // start function, such that stack trace information can be generated |
1438 // correctly already in the start function. | 1447 // correctly already in the start function. |
1439 return nothing; | 1448 return nothing; |
1440 } | 1449 } |
1441 } | 1450 } |
1442 | 1451 |
1443 DCHECK(!isolate_->has_pending_exception()); | 1452 DCHECK(!isolate_->has_pending_exception()); |
1444 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); | 1453 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); |
1445 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); | 1454 TRACE_CHAIN(module_object_->compiled_module()); |
1446 return instance; | 1455 return instance; |
1447 } | 1456 } |
1448 | 1457 |
1449 private: | 1458 private: |
1450 // Represents the initialized state of a table. | 1459 // Represents the initialized state of a table. |
1451 struct TableInstance { | 1460 struct TableInstance { |
1452 Handle<WasmTableObject> table_object; // WebAssembly.Table instance | 1461 Handle<WasmTableObject> table_object; // WebAssembly.Table instance |
1453 Handle<FixedArray> js_wrappers; // JSFunctions exported | 1462 Handle<FixedArray> js_wrappers; // JSFunctions exported |
1454 Handle<FixedArray> function_table; // internal code array | 1463 Handle<FixedArray> function_table; // internal code array |
1455 Handle<FixedArray> signature_table; // internal sig array | 1464 Handle<FixedArray> signature_table; // internal sig array |
1456 }; | 1465 }; |
1457 | 1466 |
1458 Isolate* isolate_; | 1467 Isolate* isolate_; |
1459 WasmModule* module_; | 1468 WasmModule* module_; |
1460 ErrorThrower* thrower_; | 1469 ErrorThrower* thrower_; |
1461 Handle<JSObject> module_object_; | 1470 Handle<WasmModuleObject> module_object_; |
1462 Handle<JSReceiver> ffi_; | 1471 Handle<JSReceiver> ffi_; |
1463 Handle<JSArrayBuffer> memory_; | 1472 Handle<JSArrayBuffer> memory_; |
1464 Handle<JSArrayBuffer> globals_; | 1473 Handle<JSArrayBuffer> globals_; |
1465 Handle<WasmCompiledModule> compiled_module_; | 1474 Handle<WasmCompiledModule> compiled_module_; |
1466 std::vector<TableInstance> table_instances_; | 1475 std::vector<TableInstance> table_instances_; |
1467 std::vector<Handle<JSFunction>> js_wrappers_; | 1476 std::vector<Handle<JSFunction>> js_wrappers_; |
1468 | 1477 |
1469 // Helper routines to print out errors with imports. | 1478 // Helper routines to print out errors with imports. |
1470 void ReportLinkError(const char* error, uint32_t index, | 1479 void ReportLinkError(const char* error, uint32_t index, |
1471 Handle<String> module_name, Handle<String> import_name) { | 1480 Handle<String> module_name, Handle<String> import_name) { |
1472 thrower_->LinkError( | 1481 thrower_->LinkError( |
1473 "Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", index, | 1482 "Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", index, |
1474 module_name->length(), module_name->ToCString().get(), | 1483 module_name->length(), module_name->ToCString().get(), |
1475 import_name->length(), import_name->ToCString().get(), error); | 1484 import_name->length(), import_name->ToCString().get(), error); |
1476 } | 1485 } |
1477 | 1486 |
1478 MaybeHandle<Object> ReportTypeError(const char* error, uint32_t index, | 1487 MaybeHandle<Object> ReportLinkError(const char* error, uint32_t index, |
1479 Handle<String> module_name) { | 1488 Handle<String> module_name) { |
1480 thrower_->TypeError("Import #%d module=\"%.*s\" error: %s", index, | 1489 thrower_->LinkError("Import #%d module=\"%.*s\" error: %s", index, |
1481 module_name->length(), module_name->ToCString().get(), | 1490 module_name->length(), module_name->ToCString().get(), |
1482 error); | 1491 error); |
1483 return MaybeHandle<Object>(); | 1492 return MaybeHandle<Object>(); |
1484 } | 1493 } |
1485 | 1494 |
1486 // Look up an import value in the {ffi_} object. | 1495 // Look up an import value in the {ffi_} object. |
1487 MaybeHandle<Object> LookupImport(uint32_t index, Handle<String> module_name, | 1496 MaybeHandle<Object> LookupImport(uint32_t index, Handle<String> module_name, |
1488 Handle<String> import_name) { | 1497 Handle<String> import_name) { |
1489 if (ffi_.is_null()) { | 1498 // We pre-validated in the js-api layer that the ffi object is present, and |
1490 return ReportTypeError("FFI is not an object", index, module_name); | 1499 // a JSObject, if the module has imports. |
1491 } | 1500 DCHECK(!ffi_.is_null()); |
1492 | 1501 |
1493 // Look up the module first. | 1502 // Look up the module first. |
1494 MaybeHandle<Object> result = | 1503 MaybeHandle<Object> result = |
1495 Object::GetPropertyOrElement(ffi_, module_name); | 1504 Object::GetPropertyOrElement(ffi_, module_name); |
1496 if (result.is_null()) { | 1505 if (result.is_null()) { |
1497 return ReportTypeError("module not found", index, module_name); | 1506 return ReportLinkError("module not found", index, module_name); |
1498 } | 1507 } |
1499 | 1508 |
1500 Handle<Object> module = result.ToHandleChecked(); | 1509 Handle<Object> module = result.ToHandleChecked(); |
1501 | 1510 |
1502 // Look up the value in the module. | 1511 // Look up the value in the module. |
1503 if (!module->IsJSReceiver()) { | 1512 if (!module->IsJSReceiver()) { |
1504 return ReportTypeError("module is not an object or function", index, | 1513 return ReportLinkError("module is not an object or function", index, |
1505 module_name); | 1514 module_name); |
1506 } | 1515 } |
1507 | 1516 |
1508 result = Object::GetPropertyOrElement(module, import_name); | 1517 result = Object::GetPropertyOrElement(module, import_name); |
1509 if (result.is_null()) { | 1518 if (result.is_null()) { |
1510 ReportLinkError("import not found", index, module_name, import_name); | 1519 ReportLinkError("import not found", index, module_name, import_name); |
1511 return MaybeHandle<JSFunction>(); | 1520 return MaybeHandle<JSFunction>(); |
1512 } | 1521 } |
1513 | 1522 |
1514 return result; | 1523 return result; |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2075 } | 2084 } |
2076 } | 2085 } |
2077 compiled_module_->set_function_tables(new_function_tables); | 2086 compiled_module_->set_function_tables(new_function_tables); |
2078 compiled_module_->set_signature_tables(new_signature_tables); | 2087 compiled_module_->set_signature_tables(new_signature_tables); |
2079 } | 2088 } |
2080 }; | 2089 }; |
2081 | 2090 |
2082 // Instantiates a WASM module, creating a WebAssembly.Instance from a | 2091 // Instantiates a WASM module, creating a WebAssembly.Instance from a |
2083 // WebAssembly.Module. | 2092 // WebAssembly.Module. |
2084 MaybeHandle<WasmInstanceObject> WasmModule::Instantiate( | 2093 MaybeHandle<WasmInstanceObject> WasmModule::Instantiate( |
2085 Isolate* isolate, ErrorThrower* thrower, Handle<JSObject> wasm_module, | 2094 Isolate* isolate, ErrorThrower* thrower, |
2086 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) { | 2095 Handle<WasmModuleObject> wasm_module, Handle<JSReceiver> ffi, |
2096 Handle<JSArrayBuffer> memory) { | |
2087 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); | 2097 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); |
2088 return builder.Build(); | 2098 return builder.Build(); |
2089 } | 2099 } |
2090 | 2100 |
2091 bool wasm::IsWasmInstance(Object* object) { | 2101 bool wasm::IsWasmInstance(Object* object) { |
2092 return WasmInstanceObject::IsWasmInstanceObject(object); | 2102 return WasmInstanceObject::IsWasmInstanceObject(object); |
2093 } | 2103 } |
2094 | 2104 |
2095 Handle<Script> wasm::GetScript(Handle<JSObject> instance) { | 2105 Handle<Script> wasm::GetScript(Handle<JSObject> instance) { |
2096 WasmCompiledModule* compiled_module = | 2106 WasmCompiledModule* compiled_module = |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2487 | 2497 |
2488 JSObject::AddProperty(entry, name_string, export_name.ToHandleChecked(), | 2498 JSObject::AddProperty(entry, name_string, export_name.ToHandleChecked(), |
2489 NONE); | 2499 NONE); |
2490 JSObject::AddProperty(entry, kind_string, export_kind, NONE); | 2500 JSObject::AddProperty(entry, kind_string, export_kind, NONE); |
2491 | 2501 |
2492 storage->set(index, *entry); | 2502 storage->set(index, *entry); |
2493 } | 2503 } |
2494 | 2504 |
2495 return array_object; | 2505 return array_object; |
2496 } | 2506 } |
OLD | NEW |