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

Side by Side Diff: src/wasm/encoder.cc

Issue 1900153002: [wasm] Enforce strict ordering of WASM module sections. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 8 months 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 | « no previous file | src/wasm/module-decoder.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/signature.h" 5 #include "src/signature.h"
6 6
7 #include "src/handles.h" 7 #include "src/handles.h"
8 #include "src/v8.h" 8 #include "src/v8.h"
9 #include "src/zone-containers.h" 9 #include "src/zone-containers.h"
10 10
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 } 52 }
53 53
54 void EmitVarInt(byte** b, size_t val) { 54 void EmitVarInt(byte** b, size_t val) {
55 LEBHelper::write_u32v(b, static_cast<uint32_t>(val)); 55 LEBHelper::write_u32v(b, static_cast<uint32_t>(val));
56 } 56 }
57 57
58 // Sections all start with a size, but it's unknown at the start. 58 // Sections all start with a size, but it's unknown at the start.
59 // We generate a large varint which we then fixup later when the size is known. 59 // We generate a large varint which we then fixup later when the size is known.
60 // 60 //
61 // TODO(jfb) Not strictly necessary since sizes are calculated ahead of time. 61 // TODO(jfb) Not strictly necessary since sizes are calculated ahead of time.
62 const size_t padded_varint = 5; 62 const size_t kPaddedVarintSize = 5;
63 63
64 void FixupSection(byte* start, byte* end) { 64 void FixupSection(byte* start, byte* end) {
65 // Same as LEBHelper::write_u32v, but fixed-width with zeroes in the MSBs. 65 // Same as LEBHelper::write_u32v, but fixed-width with zeroes in the MSBs.
66 size_t val = end - start - padded_varint; 66 size_t val = end - start - kPaddedVarintSize;
67 TRACE(" fixup %u\n", (unsigned)val); 67 TRACE(" fixup %u\n", (unsigned)val);
68 for (size_t pos = 0; pos != padded_varint; ++pos) { 68 for (size_t pos = 0; pos != kPaddedVarintSize; ++pos) {
69 size_t next = val >> 7; 69 size_t next = val >> 7;
70 byte out = static_cast<byte>(val & 0x7f); 70 byte out = static_cast<byte>(val & 0x7f);
71 if (pos != padded_varint - 1) { 71 if (pos != kPaddedVarintSize - 1) {
72 *(start++) = 0x80 | out; 72 *(start++) = 0x80 | out;
73 val = next; 73 val = next;
74 } else { 74 } else {
75 *(start++) = out; 75 *(start++) = out;
76 // TODO(jfb) check that the pre-allocated fixup size isn't overflowed. 76 // TODO(jfb) check that the pre-allocated fixup size isn't overflowed.
77 } 77 }
78 } 78 }
79 } 79 }
80 80
81 // Returns the start of the section, where the section VarInt size is. 81 // Returns the start of the section, where the section VarInt size is.
82 byte* EmitSection(WasmSection::Code code, byte** b) { 82 byte* EmitSection(WasmSection::Code code, byte** b) {
83 // Emit a placeholder for the length.
83 byte* start = *b; 84 byte* start = *b;
84 const char* name = WasmSection::getName(code); 85 for (size_t padding = 0; padding != kPaddedVarintSize; ++padding) {
85 size_t length = WasmSection::getNameLength(code);
86 TRACE("emit section: %s\n", name);
87 for (size_t padding = 0; padding != padded_varint; ++padding) {
88 EmitUint8(b, 0xff); // Will get fixed up later. 86 EmitUint8(b, 0xff); // Will get fixed up later.
89 } 87 }
88 // Emit the section name.
89 const char* name = WasmSection::getName(code);
90 TRACE("emit section: %s\n", name);
91 size_t length = WasmSection::getNameLength(code);
90 EmitVarInt(b, length); // Section name string size. 92 EmitVarInt(b, length); // Section name string size.
91 for (size_t i = 0; i != length; ++i) EmitUint8(b, name[i]); 93 for (size_t i = 0; i != length; ++i) EmitUint8(b, name[i]);
94
92 return start; 95 return start;
93 } 96 }
94 } // namespace 97 } // namespace
95 98
96 struct WasmFunctionBuilder::Type { 99 struct WasmFunctionBuilder::Type {
97 bool param_; 100 bool param_;
98 LocalType type_; 101 LocalType type_;
99 }; 102 };
100 103
101 104
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 size_t body_size; 544 size_t body_size;
542 545
543 size_t total() { return header_size + body_size; } 546 size_t total() { return header_size + body_size; }
544 547
545 void Add(size_t header, size_t body) { 548 void Add(size_t header, size_t body) {
546 header_size += header; 549 header_size += header;
547 body_size += body; 550 body_size += body;
548 } 551 }
549 552
550 void AddSection(WasmSection::Code code, size_t other_size) { 553 void AddSection(WasmSection::Code code, size_t other_size) {
551 Add(padded_varint + 554 Add(kPaddedVarintSize +
552 LEBHelper::sizeof_u32v(WasmSection::getNameLength(code)) + 555 LEBHelper::sizeof_u32v(WasmSection::getNameLength(code)) +
553 WasmSection::getNameLength(code), 556 WasmSection::getNameLength(code),
554 0); 557 0);
555 if (other_size) Add(LEBHelper::sizeof_u32v(other_size), 0); 558 if (other_size) Add(LEBHelper::sizeof_u32v(other_size), 0);
556 } 559 }
557 }; 560 };
558 561
559 WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const { 562 WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const {
560 Sizes sizes = {0, 0}; 563 Sizes sizes = {0, 0};
561 564
562 sizes.Add(2 * sizeof(uint32_t), 0); // header 565 sizes.Add(2 * sizeof(uint32_t), 0); // header
563 566
564 sizes.AddSection(WasmSection::Code::Memory, 0);
565 sizes.Add(kDeclMemorySize, 0);
566 TRACE("Size after memory: %u, %u\n", (unsigned)sizes.header_size,
567 (unsigned)sizes.body_size);
568
569 if (globals_.size() > 0) { 567 if (globals_.size() > 0) {
570 sizes.AddSection(WasmSection::Code::Globals, globals_.size()); 568 sizes.AddSection(WasmSection::Code::Globals, globals_.size());
571 /* These globals never have names, so are always 3 bytes. */ 569 /* These globals never have names, so are always 3 bytes. */
572 sizes.Add(3 * globals_.size(), 0); 570 sizes.Add(3 * globals_.size(), 0);
573 TRACE("Size after globals: %u, %u\n", (unsigned)sizes.header_size, 571 TRACE("Size after globals: %u, %u\n", (unsigned)sizes.header_size,
574 (unsigned)sizes.body_size); 572 (unsigned)sizes.body_size);
575 } 573 }
576 574
577 if (signatures_.size() > 0) { 575 if (signatures_.size() > 0) {
578 sizes.AddSection(WasmSection::Code::Signatures, signatures_.size()); 576 sizes.AddSection(WasmSection::Code::Signatures, signatures_.size());
579 for (auto sig : signatures_) { 577 for (auto sig : signatures_) {
580 sizes.Add(1 + LEBHelper::sizeof_u32v(sig->parameter_count()) + 578 sizes.Add(1 + LEBHelper::sizeof_u32v(sig->parameter_count()) +
581 sig->parameter_count(), 579 sig->parameter_count(),
582 0); 580 0);
583 } 581 }
584 TRACE("Size after signatures: %u, %u\n", (unsigned)sizes.header_size, 582 TRACE("Size after signatures: %u, %u\n", (unsigned)sizes.header_size,
585 (unsigned)sizes.body_size); 583 (unsigned)sizes.body_size);
586 } 584 }
587 585
588 if (functions_.size() > 0) { 586 if (functions_.size() > 0) {
589 sizes.AddSection(WasmSection::Code::Functions, functions_.size()); 587 sizes.AddSection(WasmSection::Code::Functions, functions_.size());
590 for (auto function : functions_) { 588 for (auto function : functions_) {
591 sizes.Add(function->HeaderSize() + function->BodySize(), 589 sizes.Add(function->HeaderSize() + function->BodySize(),
592 function->NameSize()); 590 function->NameSize());
593 } 591 }
594 TRACE("Size after functions: %u, %u\n", (unsigned)sizes.header_size, 592 TRACE("Size after functions: %u, %u\n", (unsigned)sizes.header_size,
595 (unsigned)sizes.body_size); 593 (unsigned)sizes.body_size);
596 } 594 }
597 595
596 if (indirect_functions_.size() > 0) {
597 sizes.AddSection(WasmSection::Code::FunctionTable,
598 indirect_functions_.size());
599 for (auto function_index : indirect_functions_) {
600 sizes.Add(LEBHelper::sizeof_u32v(function_index), 0);
601 }
602 TRACE("Size after indirect functions: %u, %u\n",
603 (unsigned)sizes.header_size, (unsigned)sizes.body_size);
604 }
605
606 sizes.AddSection(WasmSection::Code::Memory, 0);
607 sizes.Add(kDeclMemorySize, 0);
608 TRACE("Size after memory: %u, %u\n", (unsigned)sizes.header_size,
609 (unsigned)sizes.body_size);
610
598 if (start_function_index_ >= 0) { 611 if (start_function_index_ >= 0) {
599 sizes.AddSection(WasmSection::Code::StartFunction, 0); 612 sizes.AddSection(WasmSection::Code::StartFunction, 0);
600 sizes.Add(LEBHelper::sizeof_u32v(start_function_index_), 0); 613 sizes.Add(LEBHelper::sizeof_u32v(start_function_index_), 0);
601 TRACE("Size after start: %u, %u\n", (unsigned)sizes.header_size, 614 TRACE("Size after start: %u, %u\n", (unsigned)sizes.header_size,
602 (unsigned)sizes.body_size); 615 (unsigned)sizes.body_size);
603 } 616 }
604 617
605 if (data_segments_.size() > 0) { 618 if (data_segments_.size() > 0) {
606 sizes.AddSection(WasmSection::Code::DataSegments, data_segments_.size()); 619 sizes.AddSection(WasmSection::Code::DataSegments, data_segments_.size());
607 for (auto segment : data_segments_) { 620 for (auto segment : data_segments_) {
608 sizes.Add(segment->HeaderSize(), segment->BodySize()); 621 sizes.Add(segment->HeaderSize(), segment->BodySize());
609 } 622 }
610 TRACE("Size after data segments: %u, %u\n", (unsigned)sizes.header_size, 623 TRACE("Size after data segments: %u, %u\n", (unsigned)sizes.header_size,
611 (unsigned)sizes.body_size); 624 (unsigned)sizes.body_size);
612 } 625 }
613 626
614 if (indirect_functions_.size() > 0) {
615 sizes.AddSection(WasmSection::Code::FunctionTable,
616 indirect_functions_.size());
617 for (auto function_index : indirect_functions_) {
618 sizes.Add(LEBHelper::sizeof_u32v(function_index), 0);
619 }
620 TRACE("Size after indirect functions: %u, %u\n",
621 (unsigned)sizes.header_size, (unsigned)sizes.body_size);
622 }
623
624 if (sizes.body_size > 0) { 627 if (sizes.body_size > 0) {
625 sizes.AddSection(WasmSection::Code::End, 0); 628 sizes.AddSection(WasmSection::Code::End, 0);
626 TRACE("Size after end: %u, %u\n", (unsigned)sizes.header_size, 629 TRACE("Size after end: %u, %u\n", (unsigned)sizes.header_size,
627 (unsigned)sizes.body_size); 630 (unsigned)sizes.body_size);
628 } 631 }
629 632
630 ZoneVector<uint8_t> buffer_vector(sizes.total(), zone); 633 ZoneVector<uint8_t> buffer_vector(sizes.total(), zone);
631 byte* buffer = &buffer_vector[0]; 634 byte* buffer = &buffer_vector[0];
632 byte* header = buffer; 635 byte* header = buffer;
633 byte* body = buffer + sizes.header_size; 636 byte* body = buffer + sizes.header_size;
634 637
635 // -- emit magic ------------------------------------------------------------- 638 // -- emit magic -------------------------------------------------------------
636 TRACE("emit magic\n"); 639 TRACE("emit magic\n");
637 EmitUint32(&header, kWasmMagic); 640 EmitUint32(&header, kWasmMagic);
638 EmitUint32(&header, kWasmVersion); 641 EmitUint32(&header, kWasmVersion);
639 642
640 // -- emit memory declaration ------------------------------------------------
641 {
642 byte* section = EmitSection(WasmSection::Code::Memory, &header);
643 EmitVarInt(&header, 16); // min memory size
644 EmitVarInt(&header, 16); // max memory size
645 EmitUint8(&header, 0); // memory export
646 static_assert(kDeclMemorySize == 3, "memory size must match emit above");
647 FixupSection(section, header);
648 }
649
650 // -- emit globals ----------------------------------------------------------- 643 // -- emit globals -----------------------------------------------------------
651 if (globals_.size() > 0) { 644 if (globals_.size() > 0) {
652 byte* section = EmitSection(WasmSection::Code::Globals, &header); 645 byte* section = EmitSection(WasmSection::Code::Globals, &header);
653 EmitVarInt(&header, globals_.size()); 646 EmitVarInt(&header, globals_.size());
654 647
655 for (auto global : globals_) { 648 for (auto global : globals_) {
656 EmitVarInt(&header, 0); // Length of the global name. 649 EmitVarInt(&header, 0); // Length of the global name.
657 EmitUint8(&header, WasmOpcodes::MemTypeCodeFor(global.first)); 650 EmitUint8(&header, WasmOpcodes::MemTypeCodeFor(global.first));
658 EmitUint8(&header, global.second); 651 EmitUint8(&header, global.second);
659 } 652 }
(...skipping 23 matching lines...) Expand all
683 if (functions_.size() > 0) { 676 if (functions_.size() > 0) {
684 byte* section = EmitSection(WasmSection::Code::Functions, &header); 677 byte* section = EmitSection(WasmSection::Code::Functions, &header);
685 EmitVarInt(&header, functions_.size()); 678 EmitVarInt(&header, functions_.size());
686 679
687 for (auto func : functions_) { 680 for (auto func : functions_) {
688 func->Serialize(buffer, &header, &body); 681 func->Serialize(buffer, &header, &body);
689 } 682 }
690 FixupSection(section, header); 683 FixupSection(section, header);
691 } 684 }
692 685
686 // -- emit function table ----------------------------------------------------
687 if (indirect_functions_.size() > 0) {
688 byte* section = EmitSection(WasmSection::Code::FunctionTable, &header);
689 EmitVarInt(&header, indirect_functions_.size());
690
691 for (auto index : indirect_functions_) {
692 EmitVarInt(&header, index);
693 }
694 FixupSection(section, header);
695 }
696
697 // -- emit memory declaration ------------------------------------------------
698 {
699 byte* section = EmitSection(WasmSection::Code::Memory, &header);
700 EmitVarInt(&header, 16); // min memory size
701 EmitVarInt(&header, 16); // max memory size
702 EmitUint8(&header, 0); // memory export
703 static_assert(kDeclMemorySize == 3, "memory size must match emit above");
704 FixupSection(section, header);
705 }
706
693 // -- emit start function index ---------------------------------------------- 707 // -- emit start function index ----------------------------------------------
694 if (start_function_index_ >= 0) { 708 if (start_function_index_ >= 0) {
695 byte* section = EmitSection(WasmSection::Code::StartFunction, &header); 709 byte* section = EmitSection(WasmSection::Code::StartFunction, &header);
696 EmitVarInt(&header, start_function_index_); 710 EmitVarInt(&header, start_function_index_);
697 FixupSection(section, header); 711 FixupSection(section, header);
698 } 712 }
699 713
700 // -- emit data segments ----------------------------------------------------- 714 // -- emit data segments -----------------------------------------------------
701 if (data_segments_.size() > 0) { 715 if (data_segments_.size() > 0) {
702 byte* section = EmitSection(WasmSection::Code::DataSegments, &header); 716 byte* section = EmitSection(WasmSection::Code::DataSegments, &header);
703 EmitVarInt(&header, data_segments_.size()); 717 EmitVarInt(&header, data_segments_.size());
704 718
705 for (auto segment : data_segments_) { 719 for (auto segment : data_segments_) {
706 segment->Serialize(buffer, &header, &body); 720 segment->Serialize(buffer, &header, &body);
707 } 721 }
708 FixupSection(section, header); 722 FixupSection(section, header);
709 } 723 }
710 724
711 // -- emit function table ----------------------------------------------------
712 if (indirect_functions_.size() > 0) {
713 byte* section = EmitSection(WasmSection::Code::FunctionTable, &header);
714 EmitVarInt(&header, indirect_functions_.size());
715
716 for (auto index : indirect_functions_) {
717 EmitVarInt(&header, index);
718 }
719 FixupSection(section, header);
720 }
721
722 if (sizes.body_size > 0) { 725 if (sizes.body_size > 0) {
723 byte* section = EmitSection(WasmSection::Code::End, &header); 726 byte* section = EmitSection(WasmSection::Code::End, &header);
724 FixupSection(section, header); 727 FixupSection(section, header);
725 } 728 }
726 729
727 return new (zone) WasmModuleIndex(buffer, buffer + sizes.total()); 730 return new (zone) WasmModuleIndex(buffer, buffer + sizes.total());
728 } 731 }
729 } // namespace wasm 732 } // namespace wasm
730 } // namespace internal 733 } // namespace internal
731 } // namespace v8 734 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/wasm/module-decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698