| 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 1651 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1662                             module_name, import_name); | 1662                             module_name, import_name); | 
| 1663             return -1; | 1663             return -1; | 
| 1664           } | 1664           } | 
| 1665           WasmIndirectFunctionTable& table = | 1665           WasmIndirectFunctionTable& table = | 
| 1666               module_->function_tables[num_imported_tables]; | 1666               module_->function_tables[num_imported_tables]; | 
| 1667           TableInstance& table_instance = table_instances_[num_imported_tables]; | 1667           TableInstance& table_instance = table_instances_[num_imported_tables]; | 
| 1668           table_instance.table_object = Handle<WasmTableObject>::cast(value); | 1668           table_instance.table_object = Handle<WasmTableObject>::cast(value); | 
| 1669           table_instance.js_wrappers = Handle<FixedArray>( | 1669           table_instance.js_wrappers = Handle<FixedArray>( | 
| 1670               table_instance.table_object->functions(), isolate_); | 1670               table_instance.table_object->functions(), isolate_); | 
| 1671 | 1671 | 
| 1672           // TODO(titzer): import table size must match exactly for now. | 1672           int imported_cur_size = table_instance.js_wrappers->length(); | 
| 1673           int table_size = table_instance.js_wrappers->length(); | 1673           if (imported_cur_size < static_cast<int>(table.min_size)) { | 
| 1674           if (table_size != static_cast<int>(table.min_size)) { |  | 
| 1675             thrower_->LinkError( | 1674             thrower_->LinkError( | 
| 1676                 "table import %d is wrong size (%d), expected %u", index, | 1675                 "table import %d is smaller than minimum %d, got %u", index, | 
| 1677                 table_size, table.min_size); | 1676                 table.min_size, imported_cur_size); | 
| 1678             return -1; | 1677             return -1; | 
| 1679           } | 1678           } | 
| 1680 | 1679 | 
|  | 1680           if (table.has_max) { | 
|  | 1681             int64_t imported_max_size = | 
|  | 1682                 table_instance.table_object->maximum_length(); | 
|  | 1683             if (imported_max_size < 0) { | 
|  | 1684               thrower_->LinkError( | 
|  | 1685                   "table import %d has no maximum length, expected %d", index, | 
|  | 1686                   table.max_size); | 
|  | 1687               return -1; | 
|  | 1688             } | 
|  | 1689             if (imported_max_size > table.max_size) { | 
|  | 1690               thrower_->LinkError( | 
|  | 1691                   "table import %d has maximum larger than maximum %d, got %ld", | 
|  | 1692                   index, table.max_size, imported_max_size); | 
|  | 1693               return -1; | 
|  | 1694             } | 
|  | 1695           } | 
|  | 1696 | 
| 1681           // Allocate a new dispatch table and signature table. | 1697           // Allocate a new dispatch table and signature table. | 
|  | 1698           int table_size = imported_cur_size; | 
| 1682           table_instance.function_table = | 1699           table_instance.function_table = | 
| 1683               isolate_->factory()->NewFixedArray(table_size); | 1700               isolate_->factory()->NewFixedArray(table_size); | 
| 1684           table_instance.signature_table = | 1701           table_instance.signature_table = | 
| 1685               isolate_->factory()->NewFixedArray(table_size); | 1702               isolate_->factory()->NewFixedArray(table_size); | 
| 1686           for (int i = 0; i < table_size; ++i) { | 1703           for (int i = 0; i < table_size; ++i) { | 
| 1687             table_instance.signature_table->set(i, | 1704             table_instance.signature_table->set(i, | 
| 1688                                                 Smi::FromInt(kInvalidSigIndex)); | 1705                                                 Smi::FromInt(kInvalidSigIndex)); | 
| 1689           } | 1706           } | 
| 1690           // Initialize the dispatch table with the (foreign) JS functions | 1707           // Initialize the dispatch table with the (foreign) JS functions | 
| 1691           // that are already in the table. | 1708           // that are already in the table. | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 1713           DCHECK(!instance->has_memory_object()); | 1730           DCHECK(!instance->has_memory_object()); | 
| 1714           if (!WasmJs::IsWasmMemoryObject(isolate_, value)) { | 1731           if (!WasmJs::IsWasmMemoryObject(isolate_, value)) { | 
| 1715             ReportLinkError("memory import must be a WebAssembly.Memory object", | 1732             ReportLinkError("memory import must be a WebAssembly.Memory object", | 
| 1716                             index, module_name, import_name); | 1733                             index, module_name, import_name); | 
| 1717             return -1; | 1734             return -1; | 
| 1718           } | 1735           } | 
| 1719           auto memory = Handle<WasmMemoryObject>::cast(value); | 1736           auto memory = Handle<WasmMemoryObject>::cast(value); | 
| 1720           DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory)); | 1737           DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory)); | 
| 1721           instance->set_memory_object(*memory); | 1738           instance->set_memory_object(*memory); | 
| 1722           memory_ = Handle<JSArrayBuffer>(memory->buffer(), isolate_); | 1739           memory_ = Handle<JSArrayBuffer>(memory->buffer(), isolate_); | 
|  | 1740           uint32_t imported_cur_pages = static_cast<uint32_t>( | 
|  | 1741               memory_->byte_length()->Number() / WasmModule::kPageSize); | 
|  | 1742           if (imported_cur_pages < module_->min_mem_pages) { | 
|  | 1743             thrower_->LinkError( | 
|  | 1744                 "memory import %d is smaller than maximum %u, got %u", index, | 
|  | 1745                 module_->min_mem_pages, imported_cur_pages); | 
|  | 1746           } | 
|  | 1747           int32_t imported_max_pages = memory->maximum_pages(); | 
|  | 1748           if (module_->has_max_mem) { | 
|  | 1749             if (imported_max_pages < 0) { | 
|  | 1750               thrower_->LinkError( | 
|  | 1751                   "memory import %d has no maximum limit, expected at most %u", | 
|  | 1752                   index, imported_max_pages); | 
|  | 1753               return -1; | 
|  | 1754             } | 
|  | 1755             if (static_cast<uint32_t>(imported_max_pages) > | 
|  | 1756                 module_->max_mem_pages) { | 
|  | 1757               thrower_->LinkError( | 
|  | 1758                   "memory import %d has larger maximum than maximum %u, got %d", | 
|  | 1759                   index, module_->max_mem_pages, imported_max_pages); | 
|  | 1760               return -1; | 
|  | 1761             } | 
|  | 1762           } | 
| 1723           break; | 1763           break; | 
| 1724         } | 1764         } | 
| 1725         case kExternalGlobal: { | 1765         case kExternalGlobal: { | 
| 1726           // Global imports are converted to numbers and written into the | 1766           // Global imports are converted to numbers and written into the | 
| 1727           // {globals_} array buffer. | 1767           // {globals_} array buffer. | 
| 1728           if (!value->IsNumber()) { | 1768           if (!value->IsNumber()) { | 
| 1729             ReportLinkError("global import must be a number", index, | 1769             ReportLinkError("global import must be a number", index, | 
| 1730                             module_name, import_name); | 1770                             module_name, import_name); | 
| 1731             return -1; | 1771             return -1; | 
| 1732           } | 1772           } | 
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2205   MaybeHandle<JSArrayBuffer> maybe_mem_buffer = | 2245   MaybeHandle<JSArrayBuffer> maybe_mem_buffer = | 
| 2206       GetInstanceMemory(isolate, instance); | 2246       GetInstanceMemory(isolate, instance); | 
| 2207   Handle<JSArrayBuffer> buffer; | 2247   Handle<JSArrayBuffer> buffer; | 
| 2208   if (!maybe_mem_buffer.ToHandle(&buffer)) { | 2248   if (!maybe_mem_buffer.ToHandle(&buffer)) { | 
| 2209     return 0; | 2249     return 0; | 
| 2210   } else { | 2250   } else { | 
| 2211     return buffer->byte_length()->Number() / WasmModule::kPageSize; | 2251     return buffer->byte_length()->Number() / WasmModule::kPageSize; | 
| 2212   } | 2252   } | 
| 2213 } | 2253 } | 
| 2214 | 2254 | 
| 2215 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, | 2255 uint32_t GetMaxInstanceMemoryPages(Isolate* isolate, | 
| 2216                                   Handle<WasmInstanceObject> instance) { | 2256                                    Handle<WasmInstanceObject> instance) { | 
| 2217   if (instance->has_memory_object()) { | 2257   if (instance->has_memory_object()) { | 
| 2218     Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate); | 2258     Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate); | 
| 2219 | 2259     if (memory_object->has_maximum_pages()) { | 
| 2220     int maximum = memory_object->maximum_pages(); | 2260       uint32_t maximum = static_cast<uint32_t>(memory_object->maximum_pages()); | 
| 2221     if (maximum > 0) return static_cast<uint32_t>(maximum); | 2261       if (maximum < kV8MaxWasmMemoryPages) return maximum; | 
|  | 2262     } | 
| 2222   } | 2263   } | 
| 2223   uint32_t compiled_max_pages = instance->compiled_module()->max_mem_pages(); | 2264   uint32_t compiled_max_pages = instance->compiled_module()->max_mem_pages(); | 
| 2224   isolate->counters()->wasm_max_mem_pages_count()->AddSample( | 2265   isolate->counters()->wasm_max_mem_pages_count()->AddSample( | 
| 2225       compiled_max_pages); | 2266       compiled_max_pages); | 
| 2226   if (compiled_max_pages != 0) return compiled_max_pages; | 2267   if (compiled_max_pages != 0) return compiled_max_pages; | 
| 2227   return kV8MaxWasmMemoryPages; | 2268   return kV8MaxWasmMemoryPages; | 
| 2228 } | 2269 } | 
| 2229 | 2270 | 
| 2230 Handle<JSArrayBuffer> GrowMemoryBuffer(Isolate* isolate, | 2271 Handle<JSArrayBuffer> GrowMemoryBuffer(Isolate* isolate, | 
| 2231                                        MaybeHandle<JSArrayBuffer> buffer, | 2272                                        MaybeHandle<JSArrayBuffer> buffer, | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2287                                     uint32_t pages) { | 2328                                     uint32_t pages) { | 
| 2288   DCHECK(WasmJs::IsWasmMemoryObject(isolate, receiver)); | 2329   DCHECK(WasmJs::IsWasmMemoryObject(isolate, receiver)); | 
| 2289   Handle<WasmMemoryObject> memory_object = | 2330   Handle<WasmMemoryObject> memory_object = | 
| 2290       handle(WasmMemoryObject::cast(*receiver)); | 2331       handle(WasmMemoryObject::cast(*receiver)); | 
| 2291   Handle<WasmInstanceWrapper> instance_wrapper(memory_object->instances_link()); | 2332   Handle<WasmInstanceWrapper> instance_wrapper(memory_object->instances_link()); | 
| 2292   DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); | 2333   DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); | 
| 2293   DCHECK(instance_wrapper->has_instance()); | 2334   DCHECK(instance_wrapper->has_instance()); | 
| 2294   Handle<WasmInstanceObject> instance = instance_wrapper->instance_object(); | 2335   Handle<WasmInstanceObject> instance = instance_wrapper->instance_object(); | 
| 2295   DCHECK(IsWasmInstance(*instance)); | 2336   DCHECK(IsWasmInstance(*instance)); | 
| 2296   if (pages == 0) return GetInstanceMemorySize(isolate, instance); | 2337   if (pages == 0) return GetInstanceMemorySize(isolate, instance); | 
| 2297   uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); | 2338   uint32_t max_pages = GetMaxInstanceMemoryPages(isolate, instance); | 
| 2298 | 2339 | 
| 2299   // Grow memory object buffer and update instances associated with it. | 2340   // Grow memory object buffer and update instances associated with it. | 
| 2300   MaybeHandle<JSArrayBuffer> memory_buffer = handle(memory_object->buffer()); | 2341   MaybeHandle<JSArrayBuffer> memory_buffer = handle(memory_object->buffer()); | 
| 2301   Handle<JSArrayBuffer> old_buffer; | 2342   Handle<JSArrayBuffer> old_buffer; | 
| 2302   uint32_t old_size = 0; | 2343   uint32_t old_size = 0; | 
| 2303   Address old_mem_start = nullptr; | 2344   Address old_mem_start = nullptr; | 
| 2304   if (memory_buffer.ToHandle(&old_buffer) && | 2345   if (memory_buffer.ToHandle(&old_buffer) && | 
| 2305       old_buffer->backing_store() != nullptr) { | 2346       old_buffer->backing_store() != nullptr) { | 
| 2306     old_size = old_buffer->byte_length()->Number(); | 2347     old_size = old_buffer->byte_length()->Number(); | 
| 2307     old_mem_start = static_cast<Address>(old_buffer->backing_store()); | 2348     old_mem_start = static_cast<Address>(old_buffer->backing_store()); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 2335     MaybeHandle<JSArrayBuffer> instance_buffer = | 2376     MaybeHandle<JSArrayBuffer> instance_buffer = | 
| 2336         GetInstanceMemory(isolate, instance); | 2377         GetInstanceMemory(isolate, instance); | 
| 2337     Handle<JSArrayBuffer> old_buffer; | 2378     Handle<JSArrayBuffer> old_buffer; | 
| 2338     uint32_t old_size = 0; | 2379     uint32_t old_size = 0; | 
| 2339     Address old_mem_start = nullptr; | 2380     Address old_mem_start = nullptr; | 
| 2340     if (instance_buffer.ToHandle(&old_buffer) && | 2381     if (instance_buffer.ToHandle(&old_buffer) && | 
| 2341         old_buffer->backing_store() != nullptr) { | 2382         old_buffer->backing_store() != nullptr) { | 
| 2342       old_size = old_buffer->byte_length()->Number(); | 2383       old_size = old_buffer->byte_length()->Number(); | 
| 2343       old_mem_start = static_cast<Address>(old_buffer->backing_store()); | 2384       old_mem_start = static_cast<Address>(old_buffer->backing_store()); | 
| 2344     } | 2385     } | 
| 2345     uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance_obj); | 2386     uint32_t max_pages = GetMaxInstanceMemoryPages(isolate, instance_obj); | 
| 2346     Handle<JSArrayBuffer> buffer = | 2387     Handle<JSArrayBuffer> buffer = | 
| 2347         GrowMemoryBuffer(isolate, instance_buffer, pages, max_pages); | 2388         GrowMemoryBuffer(isolate, instance_buffer, pages, max_pages); | 
| 2348     if (buffer.is_null()) return -1; | 2389     if (buffer.is_null()) return -1; | 
| 2349     SetInstanceMemory(instance, *buffer); | 2390     SetInstanceMemory(instance, *buffer); | 
| 2350     UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); | 2391     UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); | 
| 2351     DCHECK(old_size % WasmModule::kPageSize == 0); | 2392     DCHECK(old_size % WasmModule::kPageSize == 0); | 
| 2352     return (old_size / WasmModule::kPageSize); | 2393     return (old_size / WasmModule::kPageSize); | 
| 2353   } else { | 2394   } else { | 
| 2354     return GrowWebAssemblyMemory(isolate, handle(instance_obj->memory_object()), | 2395     return GrowWebAssemblyMemory(isolate, handle(instance_obj->memory_object()), | 
| 2355                                  pages); | 2396                                  pages); | 
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2564 | 2605 | 
| 2565     JSObject::AddProperty(entry, name_string, export_name.ToHandleChecked(), | 2606     JSObject::AddProperty(entry, name_string, export_name.ToHandleChecked(), | 
| 2566                           NONE); | 2607                           NONE); | 
| 2567     JSObject::AddProperty(entry, kind_string, export_kind, NONE); | 2608     JSObject::AddProperty(entry, kind_string, export_kind, NONE); | 
| 2568 | 2609 | 
| 2569     storage->set(index, *entry); | 2610     storage->set(index, *entry); | 
| 2570   } | 2611   } | 
| 2571 | 2612 | 
| 2572   return array_object; | 2613   return array_object; | 
| 2573 } | 2614 } | 
| OLD | NEW | 
|---|