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

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

Issue 1765843002: wasm: use strings for section names (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Silence compiler warning Created 4 years, 9 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 | « src/wasm/decoder.h ('k') | 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
11 #include "src/wasm/ast-decoder.h" 11 #include "src/wasm/ast-decoder.h"
12 #include "src/wasm/encoder.h" 12 #include "src/wasm/encoder.h"
13 #include "src/wasm/wasm-macro-gen.h" 13 #include "src/wasm/wasm-macro-gen.h"
14 #include "src/wasm/wasm-module.h" 14 #include "src/wasm/wasm-module.h"
15 #include "src/wasm/wasm-opcodes.h" 15 #include "src/wasm/wasm-opcodes.h"
16 16
17 #include "src/v8memory.h" 17 #include "src/v8memory.h"
18 18
19 #if DEBUG
20 #define TRACE(...) \
21 do { \
22 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \
23 } while (false)
24 #else
25 #define TRACE(...)
26 #endif
27
19 namespace v8 { 28 namespace v8 {
20 namespace internal { 29 namespace internal {
21 namespace wasm { 30 namespace wasm {
22 31
23 /*TODO: add error cases for adding too many locals, too many functions and bad 32 /*TODO: add error cases for adding too many locals, too many functions and bad
24 indices in body */ 33 indices in body */
25 34
26 namespace { 35 namespace {
27 void EmitUint8(byte** b, uint8_t x) { 36 void EmitUint8(byte** b, uint8_t x) {
28 Memory::uint8_at(*b) = x; 37 Memory::uint8_at(*b) = x;
29 *b += 1; 38 *b += 1;
30 } 39 }
31 40
32 41
33 void EmitUint16(byte** b, uint16_t x) { 42 void EmitUint16(byte** b, uint16_t x) {
34 WriteUnalignedUInt16(*b, x); 43 WriteUnalignedUInt16(*b, x);
35 *b += 2; 44 *b += 2;
36 } 45 }
37 46
38 47
39 void EmitUint32(byte** b, uint32_t x) { 48 void EmitUint32(byte** b, uint32_t x) {
40 WriteUnalignedUInt32(*b, x); 49 WriteUnalignedUInt32(*b, x);
41 *b += 4; 50 *b += 4;
42 } 51 }
43 52
53 // Sections all start with a size, but it's unknown at the start.
54 // We generate a large varint which we then fixup later when the size is known.
55 //
56 // TODO(jfb) Not strictly necessary since sizes are calculated ahead of time.
57 const size_t padded_varint = 5;
44 58
45 void EmitVarInt(byte** b, size_t val) { 59 void EmitVarInt(byte** b, size_t val) {
46 while (true) { 60 while (true) {
47 size_t next = val >> 7; 61 size_t next = val >> 7;
48 byte out = static_cast<byte>(val & 0x7f); 62 byte out = static_cast<byte>(val & 0x7f);
49 if (next) { 63 if (next) {
50 *((*b)++) = 0x80 | out; 64 *((*b)++) = 0x80 | out;
51 val = next; 65 val = next;
52 } else { 66 } else {
53 *((*b)++) = out; 67 *((*b)++) = out;
54 break; 68 break;
55 } 69 }
56 } 70 }
57 } 71 }
58 72
59 size_t SizeOfVarInt(size_t value) { 73 size_t SizeOfVarInt(size_t value) {
60 size_t size = 0; 74 size_t size = 0;
61 do { 75 do {
62 size++; 76 size++;
63 value = value >> 7; 77 value = value >> 7;
64 } while (value > 0); 78 } while (value > 0);
65 return size; 79 return size;
66 } 80 }
67 81
82 void FixupSection(byte* start, byte* end) {
83 // Same as EmitVarInt, but fixed-width with zeroes in the MSBs.
84 size_t val = end - start - padded_varint;
85 TRACE(" fixup %u\n", (unsigned)val);
86 for (size_t pos = 0; pos != padded_varint; ++pos) {
87 size_t next = val >> 7;
88 byte out = static_cast<byte>(val & 0x7f);
89 if (pos != padded_varint - 1) {
90 *(start++) = 0x80 | out;
91 val = next;
92 } else {
93 *(start++) = out;
94 // TODO(jfb) check that the pre-allocated fixup size isn't overflowed.
95 }
96 }
97 }
98
99 // Returns the start of the section, where the section VarInt size is.
100 byte* EmitSection(WasmSection::Code code, byte** b) {
101 byte* start = *b;
102 const char* name = WasmSection::getName(code);
103 size_t length = WasmSection::getNameLength(code);
104 TRACE("emit section: %s\n", name);
105 for (size_t padding = 0; padding != padded_varint; ++padding) {
106 EmitUint8(b, 0xff); // Will get fixed up later.
107 }
108 EmitVarInt(b, length); // Section name string size.
109 for (size_t i = 0; i != length; ++i) EmitUint8(b, name[i]);
110 return start;
111 }
68 } // namespace 112 } // namespace
69 113
70
71 struct WasmFunctionBuilder::Type { 114 struct WasmFunctionBuilder::Type {
72 bool param_; 115 bool param_;
73 LocalType type_; 116 LocalType type_;
74 }; 117 };
75 118
76 119
77 WasmFunctionBuilder::WasmFunctionBuilder(Zone* zone) 120 WasmFunctionBuilder::WasmFunctionBuilder(Zone* zone)
78 : return_type_(kAstI32), 121 : return_type_(kAstI32),
79 locals_(zone), 122 locals_(zone),
80 exported_(0), 123 exported_(0),
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 size_t header_size; 534 size_t header_size;
492 size_t body_size; 535 size_t body_size;
493 536
494 size_t total() { return header_size + body_size; } 537 size_t total() { return header_size + body_size; }
495 538
496 void Add(size_t header, size_t body) { 539 void Add(size_t header, size_t body) {
497 header_size += header; 540 header_size += header;
498 body_size += body; 541 body_size += body;
499 } 542 }
500 543
501 void AddSection(size_t size) { 544 void AddSection(WasmSection::Code code, size_t other_size) {
502 if (size > 0) { 545 Add(padded_varint + SizeOfVarInt(WasmSection::getNameLength(code)) +
503 Add(1, 0); 546 WasmSection::getNameLength(code),
504 Add(SizeOfVarInt(size), 0); 547 0);
505 } 548 if (other_size) Add(SizeOfVarInt(other_size), 0);
506 } 549 }
507 }; 550 };
508 551
509
510 WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const { 552 WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const {
511 Sizes sizes = {0, 0}; 553 Sizes sizes = {0, 0};
512 554
513 sizes.Add(2 * sizeof(uint32_t), 0); // header 555 sizes.Add(2 * sizeof(uint32_t), 0); // header
514 556
515 sizes.Add(1, 0); 557 sizes.AddSection(WasmSection::Code::Memory, 0);
516 sizes.Add(kDeclMemorySize, 0); 558 sizes.Add(kDeclMemorySize, 0);
559 TRACE("Size after memory: %u, %u\n", (unsigned)sizes.header_size,
560 (unsigned)sizes.body_size);
517 561
518 sizes.AddSection(signatures_.size()); 562 if (globals_.size() > 0) {
519 for (auto sig : signatures_) { 563 sizes.AddSection(WasmSection::Code::Globals, globals_.size());
520 sizes.Add(1 + SizeOfVarInt(sig->parameter_count()) + sig->parameter_count(), 564 /* These globals never have names, so are always 3 bytes. */
521 0); 565 sizes.Add(3 * globals_.size(), 0);
566 TRACE("Size after globals: %u, %u\n", (unsigned)sizes.header_size,
567 (unsigned)sizes.body_size);
522 } 568 }
523 569
524 sizes.AddSection(globals_.size()); 570 if (signatures_.size() > 0) {
525 if (globals_.size() > 0) { 571 sizes.AddSection(WasmSection::Code::Signatures, signatures_.size());
526 /* These globals never have names, so are always 3 bytes. */ 572 for (auto sig : signatures_) {
527 sizes.Add(3 * globals_.size(), 0); 573 sizes.Add(
574 1 + SizeOfVarInt(sig->parameter_count()) + sig->parameter_count(), 0);
575 }
576 TRACE("Size after signatures: %u, %u\n", (unsigned)sizes.header_size,
577 (unsigned)sizes.body_size);
528 } 578 }
529 579
530 sizes.AddSection(functions_.size()); 580 if (functions_.size() > 0) {
531 for (auto function : functions_) { 581 sizes.AddSection(WasmSection::Code::Functions, functions_.size());
532 sizes.Add(function->HeaderSize() + function->BodySize(), 582 for (auto function : functions_) {
533 function->NameSize()); 583 sizes.Add(function->HeaderSize() + function->BodySize(),
584 function->NameSize());
585 }
586 TRACE("Size after functions: %u, %u\n", (unsigned)sizes.header_size,
587 (unsigned)sizes.body_size);
534 } 588 }
535 589
536 if (start_function_index_ >= 0) { 590 if (start_function_index_ >= 0) {
537 sizes.Add(1, 0); 591 sizes.AddSection(WasmSection::Code::StartFunction, 0);
538 sizes.Add(SizeOfVarInt(start_function_index_), 0); 592 sizes.Add(SizeOfVarInt(start_function_index_), 0);
593 TRACE("Size after start: %u, %u\n", (unsigned)sizes.header_size,
594 (unsigned)sizes.body_size);
539 } 595 }
540 596
541 sizes.AddSection(data_segments_.size()); 597 if (data_segments_.size() > 0) {
542 for (auto segment : data_segments_) { 598 sizes.AddSection(WasmSection::Code::DataSegments, data_segments_.size());
543 sizes.Add(segment->HeaderSize(), segment->BodySize()); 599 for (auto segment : data_segments_) {
600 sizes.Add(segment->HeaderSize(), segment->BodySize());
601 }
602 TRACE("Size after data segments: %u, %u\n", (unsigned)sizes.header_size,
603 (unsigned)sizes.body_size);
544 } 604 }
545 605
546 sizes.AddSection(indirect_functions_.size()); 606 if (indirect_functions_.size() > 0) {
547 for (auto function_index : indirect_functions_) { 607 sizes.AddSection(WasmSection::Code::FunctionTable,
548 sizes.Add(SizeOfVarInt(function_index), 0); 608 indirect_functions_.size());
609 for (auto function_index : indirect_functions_) {
610 sizes.Add(SizeOfVarInt(function_index), 0);
611 }
612 TRACE("Size after indirect functions: %u, %u\n",
613 (unsigned)sizes.header_size, (unsigned)sizes.body_size);
549 } 614 }
550 615
551 if (sizes.body_size > 0) sizes.Add(1, 0); 616 if (sizes.body_size > 0) {
617 sizes.AddSection(WasmSection::Code::End, 0);
618 TRACE("Size after end: %u, %u\n", (unsigned)sizes.header_size,
619 (unsigned)sizes.body_size);
620 }
552 621
553 ZoneVector<uint8_t> buffer_vector(sizes.total(), zone); 622 ZoneVector<uint8_t> buffer_vector(sizes.total(), zone);
554 byte* buffer = &buffer_vector[0]; 623 byte* buffer = &buffer_vector[0];
555 byte* header = buffer; 624 byte* header = buffer;
556 byte* body = buffer + sizes.header_size; 625 byte* body = buffer + sizes.header_size;
557 626
558 // -- emit magic ------------------------------------------------------------- 627 // -- emit magic -------------------------------------------------------------
628 TRACE("emit magic\n");
559 EmitUint32(&header, kWasmMagic); 629 EmitUint32(&header, kWasmMagic);
560 EmitUint32(&header, kWasmVersion); 630 EmitUint32(&header, kWasmVersion);
561 631
562 // -- emit memory declaration ------------------------------------------------ 632 // -- emit memory declaration ------------------------------------------------
563 EmitUint8(&header, kDeclMemory); 633 {
564 EmitVarInt(&header, 16); // min memory size 634 byte* section = EmitSection(WasmSection::Code::Memory, &header);
565 EmitVarInt(&header, 16); // max memory size 635 EmitVarInt(&header, 16); // min memory size
566 EmitUint8(&header, 0); // memory export 636 EmitVarInt(&header, 16); // max memory size
637 EmitUint8(&header, 0); // memory export
638 static_assert(kDeclMemorySize == 3, "memory size must match emit above");
639 FixupSection(section, header);
640 }
567 641
568 // -- emit globals ----------------------------------------------------------- 642 // -- emit globals -----------------------------------------------------------
569 if (globals_.size() > 0) { 643 if (globals_.size() > 0) {
570 EmitUint8(&header, kDeclGlobals); 644 byte* section = EmitSection(WasmSection::Code::Globals, &header);
571 EmitVarInt(&header, globals_.size()); 645 EmitVarInt(&header, globals_.size());
572 646
573 for (auto global : globals_) { 647 for (auto global : globals_) {
574 EmitVarInt(&header, 0); // Length of the global name. 648 EmitVarInt(&header, 0); // Length of the global name.
575 EmitUint8(&header, WasmOpcodes::MemTypeCodeFor(global.first)); 649 EmitUint8(&header, WasmOpcodes::MemTypeCodeFor(global.first));
576 EmitUint8(&header, global.second); 650 EmitUint8(&header, global.second);
577 } 651 }
652 FixupSection(section, header);
578 } 653 }
579 654
580 // -- emit signatures -------------------------------------------------------- 655 // -- emit signatures --------------------------------------------------------
581 if (signatures_.size() > 0) { 656 if (signatures_.size() > 0) {
582 EmitUint8(&header, kDeclSignatures); 657 byte* section = EmitSection(WasmSection::Code::Signatures, &header);
583 EmitVarInt(&header, signatures_.size()); 658 EmitVarInt(&header, signatures_.size());
584 659
585 for (FunctionSig* sig : signatures_) { 660 for (FunctionSig* sig : signatures_) {
586 EmitVarInt(&header, sig->parameter_count()); 661 EmitVarInt(&header, sig->parameter_count());
587 if (sig->return_count() > 0) { 662 if (sig->return_count() > 0) {
588 EmitUint8(&header, WasmOpcodes::LocalTypeCodeFor(sig->GetReturn())); 663 EmitUint8(&header, WasmOpcodes::LocalTypeCodeFor(sig->GetReturn()));
589 } else { 664 } else {
590 EmitUint8(&header, kLocalVoid); 665 EmitUint8(&header, kLocalVoid);
591 } 666 }
592 for (size_t j = 0; j < sig->parameter_count(); j++) { 667 for (size_t j = 0; j < sig->parameter_count(); j++) {
593 EmitUint8(&header, WasmOpcodes::LocalTypeCodeFor(sig->GetParam(j))); 668 EmitUint8(&header, WasmOpcodes::LocalTypeCodeFor(sig->GetParam(j)));
594 } 669 }
595 } 670 }
671 FixupSection(section, header);
596 } 672 }
597 673
598 // -- emit functions --------------------------------------------------------- 674 // -- emit functions ---------------------------------------------------------
599 if (functions_.size() > 0) { 675 if (functions_.size() > 0) {
600 EmitUint8(&header, kDeclFunctions); 676 byte* section = EmitSection(WasmSection::Code::Functions, &header);
601 EmitVarInt(&header, functions_.size()); 677 EmitVarInt(&header, functions_.size());
602 678
603 for (auto func : functions_) { 679 for (auto func : functions_) {
604 func->Serialize(buffer, &header, &body); 680 func->Serialize(buffer, &header, &body);
605 } 681 }
682 FixupSection(section, header);
606 } 683 }
607 684
608 // -- emit start function index ---------------------------------------------- 685 // -- emit start function index ----------------------------------------------
609 if (start_function_index_ >= 0) { 686 if (start_function_index_ >= 0) {
610 EmitUint8(&header, kDeclStartFunction); 687 byte* section = EmitSection(WasmSection::Code::StartFunction, &header);
611 EmitVarInt(&header, start_function_index_); 688 EmitVarInt(&header, start_function_index_);
689 FixupSection(section, header);
612 } 690 }
613 691
614 // -- emit data segments ----------------------------------------------------- 692 // -- emit data segments -----------------------------------------------------
615 if (data_segments_.size() > 0) { 693 if (data_segments_.size() > 0) {
616 EmitUint8(&header, kDeclDataSegments); 694 byte* section = EmitSection(WasmSection::Code::DataSegments, &header);
617 EmitVarInt(&header, data_segments_.size()); 695 EmitVarInt(&header, data_segments_.size());
618 696
619 for (auto segment : data_segments_) { 697 for (auto segment : data_segments_) {
620 segment->Serialize(buffer, &header, &body); 698 segment->Serialize(buffer, &header, &body);
621 } 699 }
700 FixupSection(section, header);
622 } 701 }
623 702
624 // -- emit function table ---------------------------------------------------- 703 // -- emit function table ----------------------------------------------------
625 if (indirect_functions_.size() > 0) { 704 if (indirect_functions_.size() > 0) {
626 EmitUint8(&header, kDeclFunctionTable); 705 byte* section = EmitSection(WasmSection::Code::FunctionTable, &header);
627 EmitVarInt(&header, indirect_functions_.size()); 706 EmitVarInt(&header, indirect_functions_.size());
628 707
629 for (auto index : indirect_functions_) { 708 for (auto index : indirect_functions_) {
630 EmitVarInt(&header, index); 709 EmitVarInt(&header, index);
631 } 710 }
711 FixupSection(section, header);
632 } 712 }
633 713
634 if (sizes.body_size > 0) EmitUint8(&header, kDeclEnd); 714 if (sizes.body_size > 0) {
715 byte* section = EmitSection(WasmSection::Code::End, &header);
716 FixupSection(section, header);
717 }
635 718
636 return new (zone) WasmModuleIndex(buffer, buffer + sizes.total()); 719 return new (zone) WasmModuleIndex(buffer, buffer + sizes.total());
637 } 720 }
638 721
639 722
640 std::vector<uint8_t> UnsignedLEB128From(uint32_t result) { 723 std::vector<uint8_t> UnsignedLEB128From(uint32_t result) {
641 std::vector<uint8_t> output; 724 std::vector<uint8_t> output;
642 uint8_t next = 0; 725 uint8_t next = 0;
643 int shift = 0; 726 int shift = 0;
644 do { 727 do {
645 next = static_cast<uint8_t>(result >> shift); 728 next = static_cast<uint8_t>(result >> shift);
646 if (((result >> shift) & 0xFFFFFF80) != 0) { 729 if (((result >> shift) & 0xFFFFFF80) != 0) {
647 next = next | 0x80; 730 next = next | 0x80;
648 } 731 }
649 output.push_back(next); 732 output.push_back(next);
650 shift += 7; 733 shift += 7;
651 } while ((next & 0x80) != 0); 734 } while ((next & 0x80) != 0);
652 return output; 735 return output;
653 } 736 }
654 } // namespace wasm 737 } // namespace wasm
655 } // namespace internal 738 } // namespace internal
656 } // namespace v8 739 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/decoder.h ('k') | src/wasm/module-decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698