# All files / src/emitter/section name.js

100% Statements 40/40
100% Branches 0/0
100% Functions 7/7
100% Lines 40/40

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    23x
    23x
    23x

    23x
    5x
    5x
    5x

    23x

    5x

    5x
    5x
    41x
    41x

    5x

    23x

    5x

    5x

    5x
    28x
    28x

    28x
    77x
    77x

    5x

    23x
    5x

    5x

    5x
    5x
    5x
    5x

    5x
    5x
    5x
    5x

    5x
    5x
    5x
    5x

    5x

     // @flow
    import { varuint32, varuint7 } from "../numbers";
    import { emitString } from "../string";
    import OutputStream from "../../utils/output-stream";
    import type { NameSectionType } from "../../generator/flow/types";

    // Emit Module name subsection
    const emitModuleName = (name: string): OutputStream => {
      const moduleSubsection = new OutputStream();
      emitString(moduleSubsection, name, `name_len: ${name}`);
      return moduleSubsection;
    };

    // Emit Functions subsection
    const emitFunctionNames = (
      names: Array<{ index: number, name: string }>
    ): OutputStream => {
      const stream = new OutputStream();

      stream.push(varuint32, names.length, `count: ${String(names.length)}`);
      names.forEach(({ index, name }) => {
        stream.push(varuint32, index, `index: ${String(index)}`);
        emitString(stream, name, `name_len: ${name}`);
      });

      return stream;
    };

    // Emit Locals subsection
    const emitLocals = (
      localsMap: Array<{
        index: number,
        locals: Array<{ index: number, name: string }>,
      }>
    ): OutputStream => {
      const stream = new OutputStream();

      // WebAssembly Binary Encoding docs are not the best on how this should be encoded.
      // This is pretty much lifted from wabt C++ source code. First comes the number
      // or functions, where each function is a header of a u32 function index followed
      // by locals + params count with each local/param encoded as a name_map
      stream.push(
        varuint32,
        localsMap.length,
        `count: ${String(localsMap.length)}`
      );
      localsMap.forEach(({ index: funIndex, locals }) => {
        stream.push(varuint32, funIndex, `function index: ${String(funIndex)}`);
        stream.push(
          varuint32,
          locals.length,
          `number of params and locals ${locals.length}`
        );
        locals.forEach(({ index, name }) => {
          stream.push(varuint32, index, `index: ${String(index)}`);
          emitString(stream, name, `name_len: ${name}`);
        });
      });

      return stream;
    };

    // Emit the Name custom section.
    const emit = (nameSection: NameSectionType): OutputStream => {
      const stream = new OutputStream();
      // Name identifier/header as this is a custom section which requires a string id
      emitString(stream, "name", "name_len: name");

      // NOTE: Every subsection header is encoded here, not in the individual subsection
      // logic.
      const moduleSubsection = emitModuleName(nameSection.module);
      stream.push(varuint7, 0, "name_type: Module");
      stream.push(varuint32, moduleSubsection.size, "name_payload_len");
      stream.write(moduleSubsection);

      const functionSubsection = emitFunctionNames(nameSection.functions);
      stream.push(varuint7, 1, "name_type: Function");
      stream.push(varuint32, functionSubsection.size, "name_payload_len");
      stream.write(functionSubsection);

      const localsSubsection = emitLocals(nameSection.locals);
      stream.push(varuint7, 2, "name_type: Locals");
      stream.push(varuint32, localsSubsection.size, "name_payload_len");
      stream.write(localsSubsection);

      return stream;
    };

    export default emit;