# 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
    21x
    21x
    21x

    21x
    3x
    3x
    3x

    21x

    3x

    3x
    3x
    13x
    13x

    3x

    21x

    3x

    3x

    3x
    6x
    6x

    6x
    11x
    11x

    3x

    21x
    3x

    3x

    3x
    3x
    3x
    3x

    3x
    3x
    3x
    3x

    3x
    3x
    3x
    3x

    3x

     // @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;