# All files / src/semantics/map-function declaration.js

97.5% Statements 39/40
89.66% Branches 26/29
100% Functions 6/6
97.5% Lines 39/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
    91
    21x
    21x
    21x

    21x
    4x

    4x

    21x
    184x

    21x
    184x
    184x
    184x
    184x
    184x
    184x
    184x
    16x
    168x
    2x

    166x

    184x

    184x

    21x
    162x
    162x
    162x

    162x

    162x
    162x
    4x
    4x
    4x

    21x
    30x
    30x
    22x
    22x

    22x

    8x

     // @flow
    import Syntax from "../../Syntax";
    import curry from "curry";
    import {
      CLOSURE_TYPE,
      TYPE_ARRAY,
      TYPE_CONST,
      TYPE_INDEX,
      LOCAL_INDEX,
      GLOBAL_INDEX,
    } from "../metadata";

    const getTypeSize = typeString => {
      switch (typeString) {
        case "i64":
        case "f64":
          return 8;
        case "i32":
        case "f32":
        default:
          return 4;
      }
    };

    const isClosureType = (types, type): boolean => {
      return types[type] != null && !!types[type].meta[CLOSURE_TYPE];
    };
    const parse = (isConst, { types, scope }, declaration) => {
      const index = Object.keys(scope).length;
      const typeString = declaration.type;
      const modifier = declaration.type.slice(-2);
      const isArray = modifier === "[]";
      const isClosure = isClosureType(types, typeString);
      const type = (() => {
        if (isArray) {
          return "i32";
        } else if (isClosure) {
          return "i64";
        }
        return declaration.type;
      })();
      const meta = {
        [TYPE_ARRAY]: isArray ? typeString.slice(0, -2) : null,
        [CLOSURE_TYPE]: isClosure || null,
        [TYPE_CONST]: isConst || null,
        [TYPE_INDEX]: isClosure ? Object.keys(types).indexOf(typeString) : null,
      };

      return [type, meta, index];
    };

    export const parseDeclaration = curry((isConst, options, declaration) => {
      const { locals: scope, closures } = options;
      Eif (scope[declaration.value] == null) {
        const [type, meta, index] = parse(
          isConst,
          { ...options, scope },
          declaration
        );
        scope[declaration.value] = {
          ...declaration,
          type,
          meta: { ...meta, [LOCAL_INDEX]: index },
          Type: Syntax.Declaration,
        };

        const { variables } = closures;
        if (variables[declaration.value] != null && declaration.params[0]) {
          const { offsets } = closures;
          offsets[declaration.value] = closures.envSize;
          closures.envSize += getTypeSize(declaration.type);
        }
      }
    });

    export const parseGlobalDeclaration = curry((isConst, options, node) => {
      const { globals: scope } = options;
      if (node.type !== "Table" && node.type !== "Memory") {
        const [type, meta, index] = parse(isConst, { ...options, scope }, node);
        scope[node.value] = {
          ...node,
          meta: { ...meta, [GLOBAL_INDEX]: index },
          type,
          Type: Syntax.Declaration,
        };

        return scope[node.value];
      }
      return { ...node, meta: { [GLOBAL_INDEX]: -1 } };
    });