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

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

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

Powered by Google App Engine
This is Rietveld 408576698