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 module_(module_object->compiled_module()->module()), |
1127 thrower_(thrower), | 1128 thrower_(thrower), |
1128 module_object_(module_object), | 1129 module_object_(module_object), |
1129 ffi_(ffi), | 1130 ffi_(ffi), |
1130 memory_(memory) {} | 1131 memory_(memory) {} |
1131 | 1132 |
1132 // Build an instance, in all of its glory. | 1133 // Build an instance, in all of its glory. |
1133 MaybeHandle<WasmInstanceObject> Build() { | 1134 MaybeHandle<WasmInstanceObject> Build() { |
1134 MaybeHandle<WasmInstanceObject> nothing; | 1135 MaybeHandle<WasmInstanceObject> nothing; |
| 1136 |
| 1137 // Check that an imports argument was provided, if the module requires it. |
| 1138 // No point in continuing otherwise. |
| 1139 if (!module_->import_table.empty() && 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 30 matching lines...) Expand all Loading... |
1199 RecordStats(isolate_, code_table); | 1208 RecordStats(isolate_, code_table); |
1200 } else { | 1209 } else { |
1201 // There was no owner, so we can reuse the original. | 1210 // There was no owner, so we can reuse the original. |
1202 compiled_module_ = original; | 1211 compiled_module_ = original; |
1203 TRACE("Reusing existing instance %d\n", | 1212 TRACE("Reusing existing instance %d\n", |
1204 compiled_module_->instance_id()); | 1213 compiled_module_->instance_id()); |
1205 } | 1214 } |
1206 compiled_module_->set_code_table(code_table); | 1215 compiled_module_->set_code_table(code_table); |
1207 compiled_module_->set_native_context(isolate_->native_context()); | 1216 compiled_module_->set_native_context(isolate_->native_context()); |
1208 } | 1217 } |
1209 module_ = compiled_module_->module(); | |
1210 | 1218 |
1211 //-------------------------------------------------------------------------- | 1219 //-------------------------------------------------------------------------- |
1212 // Allocate the instance object. | 1220 // Allocate the instance object. |
1213 //-------------------------------------------------------------------------- | 1221 //-------------------------------------------------------------------------- |
1214 Handle<WasmInstanceObject> instance = | 1222 Handle<WasmInstanceObject> instance = |
1215 WasmInstanceObject::New(isolate_, compiled_module_); | 1223 WasmInstanceObject::New(isolate_, compiled_module_); |
1216 | 1224 |
1217 //-------------------------------------------------------------------------- | 1225 //-------------------------------------------------------------------------- |
1218 // Set up the globals for the new instance. | 1226 // Set up the globals for the new instance. |
1219 //-------------------------------------------------------------------------- | 1227 //-------------------------------------------------------------------------- |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 // It's unfortunate that the new instance is already linked in the | 1443 // It's unfortunate that the new instance is already linked in the |
1436 // chain. However, we need to set up everything before executing the | 1444 // chain. However, we need to set up everything before executing the |
1437 // start function, such that stack trace information can be generated | 1445 // start function, such that stack trace information can be generated |
1438 // correctly already in the start function. | 1446 // correctly already in the start function. |
1439 return nothing; | 1447 return nothing; |
1440 } | 1448 } |
1441 } | 1449 } |
1442 | 1450 |
1443 DCHECK(!isolate_->has_pending_exception()); | 1451 DCHECK(!isolate_->has_pending_exception()); |
1444 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); | 1452 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); |
1445 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); | 1453 TRACE_CHAIN(module_object_->compiled_module()); |
1446 return instance; | 1454 return instance; |
1447 } | 1455 } |
1448 | 1456 |
1449 private: | 1457 private: |
1450 // Represents the initialized state of a table. | 1458 // Represents the initialized state of a table. |
1451 struct TableInstance { | 1459 struct TableInstance { |
1452 Handle<WasmTableObject> table_object; // WebAssembly.Table instance | 1460 Handle<WasmTableObject> table_object; // WebAssembly.Table instance |
1453 Handle<FixedArray> js_wrappers; // JSFunctions exported | 1461 Handle<FixedArray> js_wrappers; // JSFunctions exported |
1454 Handle<FixedArray> function_table; // internal code array | 1462 Handle<FixedArray> function_table; // internal code array |
1455 Handle<FixedArray> signature_table; // internal sig array | 1463 Handle<FixedArray> signature_table; // internal sig array |
1456 }; | 1464 }; |
1457 | 1465 |
1458 Isolate* isolate_; | 1466 Isolate* isolate_; |
1459 WasmModule* module_; | 1467 WasmModule* const module_; |
1460 ErrorThrower* thrower_; | 1468 ErrorThrower* thrower_; |
1461 Handle<JSObject> module_object_; | 1469 Handle<WasmModuleObject> module_object_; |
1462 Handle<JSReceiver> ffi_; | 1470 Handle<JSReceiver> ffi_; |
1463 Handle<JSArrayBuffer> memory_; | 1471 Handle<JSArrayBuffer> memory_; |
1464 Handle<JSArrayBuffer> globals_; | 1472 Handle<JSArrayBuffer> globals_; |
1465 Handle<WasmCompiledModule> compiled_module_; | 1473 Handle<WasmCompiledModule> compiled_module_; |
1466 std::vector<TableInstance> table_instances_; | 1474 std::vector<TableInstance> table_instances_; |
1467 std::vector<Handle<JSFunction>> js_wrappers_; | 1475 std::vector<Handle<JSFunction>> js_wrappers_; |
1468 | 1476 |
1469 // Helper routines to print out errors with imports. | 1477 // Helper routines to print out errors with imports. |
1470 void ReportLinkError(const char* error, uint32_t index, | 1478 void ReportLinkError(const char* error, uint32_t index, |
1471 Handle<String> module_name, Handle<String> import_name) { | 1479 Handle<String> module_name, Handle<String> import_name) { |
1472 thrower_->LinkError( | 1480 thrower_->LinkError( |
1473 "Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", index, | 1481 "Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", index, |
1474 module_name->length(), module_name->ToCString().get(), | 1482 module_name->length(), module_name->ToCString().get(), |
1475 import_name->length(), import_name->ToCString().get(), error); | 1483 import_name->length(), import_name->ToCString().get(), error); |
1476 } | 1484 } |
1477 | 1485 |
1478 MaybeHandle<Object> ReportTypeError(const char* error, uint32_t index, | 1486 MaybeHandle<Object> ReportLinkError(const char* error, uint32_t index, |
1479 Handle<String> module_name) { | 1487 Handle<String> module_name) { |
1480 thrower_->TypeError("Import #%d module=\"%.*s\" error: %s", index, | 1488 thrower_->LinkError("Import #%d module=\"%.*s\" error: %s", index, |
1481 module_name->length(), module_name->ToCString().get(), | 1489 module_name->length(), module_name->ToCString().get(), |
1482 error); | 1490 error); |
1483 return MaybeHandle<Object>(); | 1491 return MaybeHandle<Object>(); |
1484 } | 1492 } |
1485 | 1493 |
1486 // Look up an import value in the {ffi_} object. | 1494 // Look up an import value in the {ffi_} object. |
1487 MaybeHandle<Object> LookupImport(uint32_t index, Handle<String> module_name, | 1495 MaybeHandle<Object> LookupImport(uint32_t index, Handle<String> module_name, |
1488 Handle<String> import_name) { | 1496 Handle<String> import_name) { |
1489 if (ffi_.is_null()) { | 1497 // 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); | 1498 // a JSObject, if the module has imports. |
1491 } | 1499 DCHECK(!ffi_.is_null()); |
1492 | 1500 |
1493 // Look up the module first. | 1501 // Look up the module first. |
1494 MaybeHandle<Object> result = | 1502 MaybeHandle<Object> result = |
1495 Object::GetPropertyOrElement(ffi_, module_name); | 1503 Object::GetPropertyOrElement(ffi_, module_name); |
1496 if (result.is_null()) { | 1504 if (result.is_null()) { |
1497 return ReportTypeError("module not found", index, module_name); | 1505 return ReportLinkError("module not found", index, module_name); |
1498 } | 1506 } |
1499 | 1507 |
1500 Handle<Object> module = result.ToHandleChecked(); | 1508 Handle<Object> module = result.ToHandleChecked(); |
1501 | 1509 |
1502 // Look up the value in the module. | 1510 // Look up the value in the module. |
1503 if (!module->IsJSReceiver()) { | 1511 if (!module->IsJSReceiver()) { |
1504 return ReportTypeError("module is not an object or function", index, | 1512 return ReportLinkError("module is not an object or function", index, |
1505 module_name); | 1513 module_name); |
1506 } | 1514 } |
1507 | 1515 |
1508 result = Object::GetPropertyOrElement(module, import_name); | 1516 result = Object::GetPropertyOrElement(module, import_name); |
1509 if (result.is_null()) { | 1517 if (result.is_null()) { |
1510 ReportLinkError("import not found", index, module_name, import_name); | 1518 ReportLinkError("import not found", index, module_name, import_name); |
1511 return MaybeHandle<JSFunction>(); | 1519 return MaybeHandle<JSFunction>(); |
1512 } | 1520 } |
1513 | 1521 |
1514 return result; | 1522 return result; |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2075 } | 2083 } |
2076 } | 2084 } |
2077 compiled_module_->set_function_tables(new_function_tables); | 2085 compiled_module_->set_function_tables(new_function_tables); |
2078 compiled_module_->set_signature_tables(new_signature_tables); | 2086 compiled_module_->set_signature_tables(new_signature_tables); |
2079 } | 2087 } |
2080 }; | 2088 }; |
2081 | 2089 |
2082 // Instantiates a WASM module, creating a WebAssembly.Instance from a | 2090 // Instantiates a WASM module, creating a WebAssembly.Instance from a |
2083 // WebAssembly.Module. | 2091 // WebAssembly.Module. |
2084 MaybeHandle<WasmInstanceObject> WasmModule::Instantiate( | 2092 MaybeHandle<WasmInstanceObject> WasmModule::Instantiate( |
2085 Isolate* isolate, ErrorThrower* thrower, Handle<JSObject> wasm_module, | 2093 Isolate* isolate, ErrorThrower* thrower, |
2086 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) { | 2094 Handle<WasmModuleObject> wasm_module, Handle<JSReceiver> ffi, |
| 2095 Handle<JSArrayBuffer> memory) { |
2087 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); | 2096 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); |
2088 return builder.Build(); | 2097 return builder.Build(); |
2089 } | 2098 } |
2090 | 2099 |
2091 bool wasm::IsWasmInstance(Object* object) { | 2100 bool wasm::IsWasmInstance(Object* object) { |
2092 return WasmInstanceObject::IsWasmInstanceObject(object); | 2101 return WasmInstanceObject::IsWasmInstanceObject(object); |
2093 } | 2102 } |
2094 | 2103 |
2095 Handle<Script> wasm::GetScript(Handle<JSObject> instance) { | 2104 Handle<Script> wasm::GetScript(Handle<JSObject> instance) { |
2096 WasmCompiledModule* compiled_module = | 2105 WasmCompiledModule* compiled_module = |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2487 | 2496 |
2488 JSObject::AddProperty(entry, name_string, export_name.ToHandleChecked(), | 2497 JSObject::AddProperty(entry, name_string, export_name.ToHandleChecked(), |
2489 NONE); | 2498 NONE); |
2490 JSObject::AddProperty(entry, kind_string, export_kind, NONE); | 2499 JSObject::AddProperty(entry, kind_string, export_kind, NONE); |
2491 | 2500 |
2492 storage->set(index, *entry); | 2501 storage->set(index, *entry); |
2493 } | 2502 } |
2494 | 2503 |
2495 return array_object; | 2504 return array_object; |
2496 } | 2505 } |
OLD | NEW |