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