| 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 "src/wasm/module-decoder.h" | 5 #include "src/wasm/module-decoder.h" |
| 6 | 6 |
| 7 #include "src/base/functional.h" | 7 #include "src/base/functional.h" |
| 8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
| 9 #include "src/flags.h" | 9 #include "src/flags.h" |
| 10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 // ===== Imported table ========================================== | 309 // ===== Imported table ========================================== |
| 310 import->index = | 310 import->index = |
| 311 static_cast<uint32_t>(module->function_tables.size()); | 311 static_cast<uint32_t>(module->function_tables.size()); |
| 312 module->function_tables.push_back({0, 0, false, | 312 module->function_tables.push_back({0, 0, false, |
| 313 std::vector<int32_t>(), true, | 313 std::vector<int32_t>(), true, |
| 314 false, SignatureMap()}); | 314 false, SignatureMap()}); |
| 315 expect_u8("element type", kWasmAnyFunctionTypeForm); | 315 expect_u8("element type", kWasmAnyFunctionTypeForm); |
| 316 WasmIndirectFunctionTable* table = &module->function_tables.back(); | 316 WasmIndirectFunctionTable* table = &module->function_tables.back(); |
| 317 consume_resizable_limits( | 317 consume_resizable_limits( |
| 318 "element count", "elements", WasmModule::kV8MaxTableSize, | 318 "element count", "elements", WasmModule::kV8MaxTableSize, |
| 319 &table->min_size, &table->has_max, &table->max_size); | 319 &table->min_size, &table->has_max, WasmModule::kV8MaxTableSize, |
| 320 &table->max_size); |
| 320 break; | 321 break; |
| 321 } | 322 } |
| 322 case kExternalMemory: { | 323 case kExternalMemory: { |
| 323 // ===== Imported memory ========================================= | 324 // ===== Imported memory ========================================= |
| 324 bool has_max = false; | 325 bool has_max = false; |
| 325 consume_resizable_limits("memory", "pages", WasmModule::kV8MaxPages, | 326 consume_resizable_limits("memory", "pages", WasmModule::kV8MaxPages, |
| 326 &module->min_mem_pages, &has_max, | 327 &module->min_mem_pages, &has_max, |
| 328 WasmModule::kSpecMaxPages, |
| 327 &module->max_mem_pages); | 329 &module->max_mem_pages); |
| 328 break; | 330 break; |
| 329 } | 331 } |
| 330 case kExternalGlobal: { | 332 case kExternalGlobal: { |
| 331 // ===== Imported global ========================================= | 333 // ===== Imported global ========================================= |
| 332 import->index = static_cast<uint32_t>(module->globals.size()); | 334 import->index = static_cast<uint32_t>(module->globals.size()); |
| 333 module->globals.push_back( | 335 module->globals.push_back( |
| 334 {kAstStmt, false, WasmInitExpr(), 0, true, false}); | 336 {kAstStmt, false, WasmInitExpr(), 0, true, false}); |
| 335 WasmGlobal* global = &module->globals.back(); | 337 WasmGlobal* global = &module->globals.back(); |
| 336 global->type = consume_value_type(); | 338 global->type = consume_value_type(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 if (module->function_tables.size() < 1) { | 380 if (module->function_tables.size() < 1) { |
| 379 module->function_tables.push_back({0, 0, false, std::vector<int32_t>(), | 381 module->function_tables.push_back({0, 0, false, std::vector<int32_t>(), |
| 380 false, false, SignatureMap()}); | 382 false, false, SignatureMap()}); |
| 381 } | 383 } |
| 382 | 384 |
| 383 for (uint32_t i = 0; ok() && i < table_count; i++) { | 385 for (uint32_t i = 0; ok() && i < table_count; i++) { |
| 384 WasmIndirectFunctionTable* table = &module->function_tables.back(); | 386 WasmIndirectFunctionTable* table = &module->function_tables.back(); |
| 385 expect_u8("table type", kWasmAnyFunctionTypeForm); | 387 expect_u8("table type", kWasmAnyFunctionTypeForm); |
| 386 consume_resizable_limits("table elements", "elements", | 388 consume_resizable_limits("table elements", "elements", |
| 387 WasmModule::kV8MaxTableSize, &table->min_size, | 389 WasmModule::kV8MaxTableSize, &table->min_size, |
| 388 &table->has_max, &table->max_size); | 390 &table->has_max, WasmModule::kV8MaxTableSize, |
| 391 &table->max_size); |
| 389 } | 392 } |
| 390 section_iter.advance(); | 393 section_iter.advance(); |
| 391 } | 394 } |
| 392 | 395 |
| 393 // ===== Memory section ================================================== | 396 // ===== Memory section ================================================== |
| 394 if (section_iter.section_code() == kMemorySectionCode) { | 397 if (section_iter.section_code() == kMemorySectionCode) { |
| 395 const byte* pos = pc_; | 398 const byte* pos = pc_; |
| 396 uint32_t memory_count = consume_u32v("memory count"); | 399 uint32_t memory_count = consume_u32v("memory count"); |
| 397 // Require at most one memory for now. | 400 // Require at most one memory for now. |
| 398 if (memory_count > 1) { | 401 if (memory_count > 1) { |
| 399 error(pos, pos, "invalid memory count %d, maximum 1", memory_count); | 402 error(pos, pos, "invalid memory count %d, maximum 1", memory_count); |
| 400 } | 403 } |
| 401 | 404 |
| 402 for (uint32_t i = 0; ok() && i < memory_count; i++) { | 405 for (uint32_t i = 0; ok() && i < memory_count; i++) { |
| 403 bool has_max = false; | 406 bool has_max = false; |
| 404 consume_resizable_limits("memory", "pages", WasmModule::kV8MaxPages, | 407 consume_resizable_limits( |
| 405 &module->min_mem_pages, &has_max, | 408 "memory", "pages", WasmModule::kV8MaxPages, &module->min_mem_pages, |
| 406 &module->max_mem_pages); | 409 &has_max, WasmModule::kSpecMaxPages, &module->max_mem_pages); |
| 407 } | 410 } |
| 408 section_iter.advance(); | 411 section_iter.advance(); |
| 409 } | 412 } |
| 410 | 413 |
| 411 // ===== Global section ================================================== | 414 // ===== Global section ================================================== |
| 412 if (section_iter.section_code() == kGlobalSectionCode) { | 415 if (section_iter.section_code() == kGlobalSectionCode) { |
| 413 uint32_t globals_count = consume_u32v("globals count"); | 416 uint32_t globals_count = consume_u32v("globals count"); |
| 414 uint32_t imported_globals = static_cast<uint32_t>(module->globals.size()); | 417 uint32_t imported_globals = static_cast<uint32_t>(module->globals.size()); |
| 415 if (!IsWithinLimit(std::numeric_limits<int32_t>::max(), globals_count, | 418 if (!IsWithinLimit(std::numeric_limits<int32_t>::max(), globals_count, |
| 416 imported_globals)) { | 419 imported_globals)) { |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 error(pos, pos, "%s %u out of bounds (%d entries)", name, index, | 839 error(pos, pos, "%s %u out of bounds (%d entries)", name, index, |
| 837 static_cast<int>(vector.size())); | 840 static_cast<int>(vector.size())); |
| 838 *ptr = nullptr; | 841 *ptr = nullptr; |
| 839 return 0; | 842 return 0; |
| 840 } | 843 } |
| 841 *ptr = &vector[index]; | 844 *ptr = &vector[index]; |
| 842 return index; | 845 return index; |
| 843 } | 846 } |
| 844 | 847 |
| 845 void consume_resizable_limits(const char* name, const char* units, | 848 void consume_resizable_limits(const char* name, const char* units, |
| 846 uint32_t max_value, uint32_t* initial, | 849 uint32_t max_initial, uint32_t* initial, |
| 847 bool* has_max, uint32_t* maximum) { | 850 bool* has_max, uint32_t max_maximum, |
| 851 uint32_t* maximum) { |
| 848 uint32_t flags = consume_u32v("resizable limits flags"); | 852 uint32_t flags = consume_u32v("resizable limits flags"); |
| 849 const byte* pos = pc(); | 853 const byte* pos = pc(); |
| 850 *initial = consume_u32v("initial size"); | 854 *initial = consume_u32v("initial size"); |
| 851 *has_max = false; | 855 *has_max = false; |
| 852 if (*initial > max_value) { | 856 if (*initial > max_initial) { |
| 853 error(pos, pos, | 857 error(pos, pos, |
| 854 "initial %s size (%u %s) is larger than implementation limit (%u)", | 858 "initial %s size (%u %s) is larger than implementation limit (%u)", |
| 855 name, *initial, units, max_value); | 859 name, *initial, units, max_initial); |
| 856 } | 860 } |
| 857 if (flags & 1) { | 861 if (flags & 1) { |
| 858 *has_max = true; | 862 *has_max = true; |
| 859 pos = pc(); | 863 pos = pc(); |
| 860 *maximum = consume_u32v("maximum size"); | 864 *maximum = consume_u32v("maximum size"); |
| 861 if (*maximum > max_value) { | 865 if (*maximum > max_maximum) { |
| 862 error( | 866 error( |
| 863 pos, pos, | 867 pos, pos, |
| 864 "maximum %s size (%u %s) is larger than implementation limit (%u)", | 868 "maximum %s size (%u %s) is larger than implementation limit (%u)", |
| 865 name, *maximum, units, max_value); | 869 name, *maximum, units, max_maximum); |
| 866 } | 870 } |
| 867 if (*maximum < *initial) { | 871 if (*maximum < *initial) { |
| 868 error(pos, pos, "maximum %s size (%u %s) is less than initial (%u %s)", | 872 error(pos, pos, "maximum %s size (%u %s) is less than initial (%u %s)", |
| 869 name, *maximum, units, *initial, units); | 873 name, *maximum, units, *initial, units); |
| 870 } | 874 } |
| 871 } else { | 875 } else { |
| 872 *has_max = false; | 876 *has_max = false; |
| 873 *maximum = max_value; | 877 *maximum = max_initial; |
| 874 } | 878 } |
| 875 } | 879 } |
| 876 | 880 |
| 877 bool expect_u8(const char* name, uint8_t expected) { | 881 bool expect_u8(const char* name, uint8_t expected) { |
| 878 const byte* pos = pc(); | 882 const byte* pos = pc(); |
| 879 uint8_t value = consume_u8(name); | 883 uint8_t value = consume_u8(name); |
| 880 if (value != expected) { | 884 if (value != expected) { |
| 881 error(pos, pos, "expected %s 0x%02x, got 0x%02x", name, expected, value); | 885 error(pos, pos, "expected %s 0x%02x, got 0x%02x", name, expected, value); |
| 882 return false; | 886 return false; |
| 883 } | 887 } |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 table.push_back(std::move(func_asm_offsets)); | 1200 table.push_back(std::move(func_asm_offsets)); |
| 1197 } | 1201 } |
| 1198 if (decoder.more()) decoder.error("unexpected additional bytes"); | 1202 if (decoder.more()) decoder.error("unexpected additional bytes"); |
| 1199 | 1203 |
| 1200 return decoder.toResult(std::move(table)); | 1204 return decoder.toResult(std::move(table)); |
| 1201 } | 1205 } |
| 1202 | 1206 |
| 1203 } // namespace wasm | 1207 } // namespace wasm |
| 1204 } // namespace internal | 1208 } // namespace internal |
| 1205 } // namespace v8 | 1209 } // namespace v8 |
| OLD | NEW |