Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(795)

Side by Side Diff: src/wasm/module-decoder.cc

Issue 2456193006: Revert of [wasm] Support for restricted table imports. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/wasm-compiler.cc ('k') | src/wasm/wasm-interpreter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 13 matching lines...) Expand all
24 } while (false) 24 } while (false)
25 #else 25 #else
26 #define TRACE(...) 26 #define TRACE(...)
27 #endif 27 #endif
28 28
29 namespace { 29 namespace {
30 30
31 const char* kNameString = "name"; 31 const char* kNameString = "name";
32 const size_t kNameStringLength = 4; 32 const size_t kNameStringLength = 4;
33 33
34 static const uint32_t kMaxTableSize = 1 << 28;
35
34 LocalType TypeOf(const WasmModule* module, const WasmInitExpr& expr) { 36 LocalType TypeOf(const WasmModule* module, const WasmInitExpr& expr) {
35 switch (expr.kind) { 37 switch (expr.kind) {
36 case WasmInitExpr::kNone: 38 case WasmInitExpr::kNone:
37 return kAstStmt; 39 return kAstStmt;
38 case WasmInitExpr::kGlobalIndex: 40 case WasmInitExpr::kGlobalIndex:
39 return expr.val.global_index < module->globals.size() 41 return expr.val.global_index < module->globals.size()
40 ? module->globals[expr.val.global_index].type 42 ? module->globals[expr.val.global_index].type
41 : kAstStmt; 43 : kAstStmt;
42 case WasmInitExpr::kI32Const: 44 case WasmInitExpr::kI32Const:
43 return kAstI32; 45 return kAstI32;
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 true, // imported 304 true, // imported
303 false}); // exported 305 false}); // exported
304 WasmFunction* function = &module->functions.back(); 306 WasmFunction* function = &module->functions.back();
305 function->sig_index = consume_sig_index(module, &function->sig); 307 function->sig_index = consume_sig_index(module, &function->sig);
306 break; 308 break;
307 } 309 }
308 case kExternalTable: { 310 case kExternalTable: {
309 // ===== Imported table ========================================== 311 // ===== Imported table ==========================================
310 import->index = 312 import->index =
311 static_cast<uint32_t>(module->function_tables.size()); 313 static_cast<uint32_t>(module->function_tables.size());
312 module->function_tables.push_back({0, 0, false, 314 module->function_tables.push_back(
313 std::vector<int32_t>(), true, 315 {0, 0, std::vector<int32_t>(), true, false, SignatureMap()});
314 false, SignatureMap()});
315 expect_u8("element type", kWasmAnyFunctionTypeForm); 316 expect_u8("element type", kWasmAnyFunctionTypeForm);
316 WasmIndirectFunctionTable* table = &module->function_tables.back(); 317 WasmIndirectFunctionTable* table = &module->function_tables.back();
317 consume_resizable_limits( 318 consume_resizable_limits("element count", "elements", kMaxTableSize,
318 "element count", "elements", WasmModule::kV8MaxTableSize, 319 &table->size, &table->max_size);
319 &table->min_size, &table->has_max, &table->max_size);
320 break; 320 break;
321 } 321 }
322 case kExternalMemory: { 322 case kExternalMemory: {
323 // ===== Imported memory ========================================= 323 // ===== Imported memory =========================================
324 bool has_max = false; 324 consume_resizable_limits(
325 consume_resizable_limits("memory", "pages", WasmModule::kV8MaxPages, 325 "memory", "pages", WasmModule::kMaxLegalPages,
326 &module->min_mem_pages, &has_max, 326 &module->min_mem_pages, &module->max_mem_pages);
327 &module->max_mem_pages);
328 break; 327 break;
329 } 328 }
330 case kExternalGlobal: { 329 case kExternalGlobal: {
331 // ===== Imported global ========================================= 330 // ===== Imported global =========================================
332 import->index = static_cast<uint32_t>(module->globals.size()); 331 import->index = static_cast<uint32_t>(module->globals.size());
333 module->globals.push_back( 332 module->globals.push_back(
334 {kAstStmt, false, WasmInitExpr(), 0, true, false}); 333 {kAstStmt, false, WasmInitExpr(), 0, true, false});
335 WasmGlobal* global = &module->globals.back(); 334 WasmGlobal* global = &module->globals.back();
336 global->type = consume_value_type(); 335 global->type = consume_value_type();
337 global->mutability = consume_u8("mutability") != 0; 336 global->mutability = consume_u8("mutability") != 0;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 368
370 // ===== Table section =================================================== 369 // ===== Table section ===================================================
371 if (section_iter.section_code() == kTableSectionCode) { 370 if (section_iter.section_code() == kTableSectionCode) {
372 const byte* pos = pc_; 371 const byte* pos = pc_;
373 uint32_t table_count = consume_u32v("table count"); 372 uint32_t table_count = consume_u32v("table count");
374 // Require at most one table for now. 373 // Require at most one table for now.
375 if (table_count > 1) { 374 if (table_count > 1) {
376 error(pos, pos, "invalid table count %d, maximum 1", table_count); 375 error(pos, pos, "invalid table count %d, maximum 1", table_count);
377 } 376 }
378 if (module->function_tables.size() < 1) { 377 if (module->function_tables.size() < 1) {
379 module->function_tables.push_back({0, 0, false, std::vector<int32_t>(), 378 module->function_tables.push_back(
380 false, false, SignatureMap()}); 379 {0, 0, std::vector<int32_t>(), false, false, SignatureMap()});
381 } 380 }
382 381
383 for (uint32_t i = 0; ok() && i < table_count; i++) { 382 for (uint32_t i = 0; ok() && i < table_count; i++) {
384 WasmIndirectFunctionTable* table = &module->function_tables.back(); 383 WasmIndirectFunctionTable* table = &module->function_tables.back();
385 expect_u8("table type", kWasmAnyFunctionTypeForm); 384 expect_u8("table type", kWasmAnyFunctionTypeForm);
386 consume_resizable_limits("table elements", "elements", 385 consume_resizable_limits("table elements", "elements", kMaxUInt32,
387 WasmModule::kV8MaxTableSize, &table->min_size, 386 &table->size, &table->max_size);
388 &table->has_max, &table->max_size);
389 } 387 }
390 section_iter.advance(); 388 section_iter.advance();
391 } 389 }
392 390
393 // ===== Memory section ================================================== 391 // ===== Memory section ==================================================
394 if (section_iter.section_code() == kMemorySectionCode) { 392 if (section_iter.section_code() == kMemorySectionCode) {
395 const byte* pos = pc_; 393 const byte* pos = pc_;
396 uint32_t memory_count = consume_u32v("memory count"); 394 uint32_t memory_count = consume_u32v("memory count");
397 // Require at most one memory for now. 395 // Require at most one memory for now.
398 if (memory_count > 1) { 396 if (memory_count > 1) {
399 error(pos, pos, "invalid memory count %d, maximum 1", memory_count); 397 error(pos, pos, "invalid memory count %d, maximum 1", memory_count);
400 } 398 }
401 399
402 for (uint32_t i = 0; ok() && i < memory_count; i++) { 400 for (uint32_t i = 0; ok() && i < memory_count; i++) {
403 bool has_max = false; 401 consume_resizable_limits("memory", "pages", WasmModule::kMaxLegalPages,
404 consume_resizable_limits("memory", "pages", WasmModule::kV8MaxPages, 402 &module->min_mem_pages,
405 &module->min_mem_pages, &has_max,
406 &module->max_mem_pages); 403 &module->max_mem_pages);
407 } 404 }
408 section_iter.advance(); 405 section_iter.advance();
409 } 406 }
410 407
411 // ===== Global section ================================================== 408 // ===== Global section ==================================================
412 if (section_iter.section_code() == kGlobalSectionCode) { 409 if (section_iter.section_code() == kGlobalSectionCode) {
413 uint32_t globals_count = consume_u32v("globals count"); 410 uint32_t globals_count = consume_u32v("globals count");
414 uint32_t imported_globals = static_cast<uint32_t>(module->globals.size()); 411 uint32_t imported_globals = static_cast<uint32_t>(module->globals.size());
415 if (!IsWithinLimit(std::numeric_limits<int32_t>::max(), globals_count, 412 if (!IsWithinLimit(std::numeric_limits<int32_t>::max(), globals_count,
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 } 616 }
620 617
621 // ===== Remaining sections ============================================== 618 // ===== Remaining sections ==============================================
622 if (section_iter.more() && ok()) { 619 if (section_iter.more() && ok()) {
623 error(pc(), pc(), "unexpected section: %s", 620 error(pc(), pc(), "unexpected section: %s",
624 SectionName(section_iter.section_code())); 621 SectionName(section_iter.section_code()));
625 } 622 }
626 623
627 if (ok()) { 624 if (ok()) {
628 CalculateGlobalOffsets(module); 625 CalculateGlobalOffsets(module);
626 PreinitializeIndirectFunctionTables(module);
629 } 627 }
630 const WasmModule* finished_module = module; 628 const WasmModule* finished_module = module;
631 ModuleResult result = toResult(finished_module); 629 ModuleResult result = toResult(finished_module);
632 if (FLAG_dump_wasm_module) DumpModule(module, result); 630 if (FLAG_dump_wasm_module) DumpModule(module, result);
633 return result; 631 return result;
634 } 632 }
635 633
636 uint32_t SafeReserve(uint32_t count) { 634 uint32_t SafeReserve(uint32_t count) {
637 // Avoid OOM by only reserving up to a certain size. 635 // Avoid OOM by only reserving up to a certain size.
638 const uint32_t kMaxReserve = 20000; 636 const uint32_t kMaxReserve = 20000;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 for (WasmGlobal& global : module->globals) { 742 for (WasmGlobal& global : module->globals) {
745 byte size = 743 byte size =
746 WasmOpcodes::MemSize(WasmOpcodes::MachineTypeFor(global.type)); 744 WasmOpcodes::MemSize(WasmOpcodes::MachineTypeFor(global.type));
747 offset = (offset + size - 1) & ~(size - 1); // align 745 offset = (offset + size - 1) & ~(size - 1); // align
748 global.offset = offset; 746 global.offset = offset;
749 offset += size; 747 offset += size;
750 } 748 }
751 module->globals_size = offset; 749 module->globals_size = offset;
752 } 750 }
753 751
752 // TODO(titzer): this only works without overlapping initializations from
753 // global bases for entries
754 void PreinitializeIndirectFunctionTables(WasmModule* module) {
755 // Fill all tables with invalid entries first.
756 for (WasmIndirectFunctionTable& table : module->function_tables) {
757 table.values.resize(table.size);
758 for (size_t i = 0; i < table.size; i++) {
759 table.values[i] = kInvalidFunctionIndex;
760 }
761 }
762 for (WasmTableInit& init : module->table_inits) {
763 if (init.offset.kind != WasmInitExpr::kI32Const) continue;
764 if (init.table_index >= module->function_tables.size()) continue;
765 WasmIndirectFunctionTable& table =
766 module->function_tables[init.table_index];
767 for (size_t i = 0; i < init.entries.size(); i++) {
768 size_t index = i + init.offset.val.i32_const;
769 if (index < table.values.size()) {
770 table.values[index] = init.entries[i];
771 }
772 }
773 }
774 }
775
754 // Verifies the body (code) of a given function. 776 // Verifies the body (code) of a given function.
755 void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv, 777 void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv,
756 WasmFunction* function) { 778 WasmFunction* function) {
757 if (FLAG_trace_wasm_decoder || FLAG_trace_wasm_decode_time) { 779 if (FLAG_trace_wasm_decoder || FLAG_trace_wasm_decode_time) {
758 OFStream os(stdout); 780 OFStream os(stdout);
759 os << "Verifying WASM function " << WasmFunctionName(function, menv) 781 os << "Verifying WASM function " << WasmFunctionName(function, menv)
760 << std::endl; 782 << std::endl;
761 } 783 }
762 FunctionBody body = {menv, function->sig, start_, 784 FunctionBody body = {menv, function->sig, start_,
763 start_ + function->code_start_offset, 785 start_ + function->code_start_offset,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 static_cast<int>(vector.size())); 859 static_cast<int>(vector.size()));
838 *ptr = nullptr; 860 *ptr = nullptr;
839 return 0; 861 return 0;
840 } 862 }
841 *ptr = &vector[index]; 863 *ptr = &vector[index];
842 return index; 864 return index;
843 } 865 }
844 866
845 void consume_resizable_limits(const char* name, const char* units, 867 void consume_resizable_limits(const char* name, const char* units,
846 uint32_t max_value, uint32_t* initial, 868 uint32_t max_value, uint32_t* initial,
847 bool* has_max, uint32_t* maximum) { 869 uint32_t* maximum) {
848 uint32_t flags = consume_u32v("resizable limits flags"); 870 uint32_t flags = consume_u32v("resizable limits flags");
849 const byte* pos = pc(); 871 const byte* pos = pc();
850 *initial = consume_u32v("initial size"); 872 *initial = consume_u32v("initial size");
851 *has_max = false;
852 if (*initial > max_value) { 873 if (*initial > max_value) {
853 error(pos, pos, 874 error(pos, pos,
854 "initial %s size (%u %s) is larger than implementation limit (%u)", 875 "initial %s size (%u %s) is larger than maximum allowable (%u)",
855 name, *initial, units, max_value); 876 name, *initial, units, max_value);
856 } 877 }
857 if (flags & 1) { 878 if (flags & 1) {
858 *has_max = true;
859 pos = pc(); 879 pos = pc();
860 *maximum = consume_u32v("maximum size"); 880 *maximum = consume_u32v("maximum size");
861 if (*maximum > max_value) { 881 if (*maximum > max_value) {
862 error( 882 error(pos, pos,
863 pos, pos, 883 "maximum %s size (%u %s) is larger than maximum allowable (%u)",
864 "maximum %s size (%u %s) is larger than implementation limit (%u)", 884 name, *maximum, units, max_value);
865 name, *maximum, units, max_value);
866 } 885 }
867 if (*maximum < *initial) { 886 if (*maximum < *initial) {
868 error(pos, pos, "maximum %s size (%u %s) is less than initial (%u %s)", 887 error(pos, pos, "maximum %s size (%u %s) is less than initial (%u %s)",
869 name, *maximum, units, *initial, units); 888 name, *maximum, units, *initial, units);
870 } 889 }
871 } else { 890 } else {
872 *has_max = false; 891 *maximum = 0;
873 *maximum = max_value;
874 } 892 }
875 } 893 }
876 894
877 bool expect_u8(const char* name, uint8_t expected) { 895 bool expect_u8(const char* name, uint8_t expected) {
878 const byte* pos = pc(); 896 const byte* pos = pc();
879 uint8_t value = consume_u8(name); 897 uint8_t value = consume_u8(name);
880 if (value != expected) { 898 if (value != expected) {
881 error(pos, pos, "expected %s 0x%02x, got 0x%02x", name, expected, value); 899 error(pos, pos, "expected %s 0x%02x, got 0x%02x", name, expected, value);
882 return false; 900 return false;
883 } 901 }
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 table.push_back(std::move(func_asm_offsets)); 1214 table.push_back(std::move(func_asm_offsets));
1197 } 1215 }
1198 if (decoder.more()) decoder.error("unexpected additional bytes"); 1216 if (decoder.more()) decoder.error("unexpected additional bytes");
1199 1217
1200 return decoder.toResult(std::move(table)); 1218 return decoder.toResult(std::move(table));
1201 } 1219 }
1202 1220
1203 } // namespace wasm 1221 } // namespace wasm
1204 } // namespace internal 1222 } // namespace internal
1205 } // namespace v8 1223 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/wasm-compiler.cc ('k') | src/wasm/wasm-interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698