HOME


Mini Shell 1.0
Redirecting to https://devs.lapieza.net/iniciar-sesion Redirecting to https://devs.lapieza.net/iniciar-sesion.
DIR: /proc/self/root/usr/share/nodejs/webassemblyjs/lib/interpreter/kernel/
Upload File :
Current File : //proc/self/root/usr/share/nodejs/webassemblyjs/lib/interpreter/kernel/exec.js
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.executeStackFrame = executeStackFrame;

var _long = _interopRequireDefault(require("@xtuc/long"));

var _memory2 = require("../runtime/values/memory");

var _errors = require("../../errors");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }

var _require = require("./instruction/binop"),
    binopi32 = _require.binopi32,
    binopi64 = _require.binopi64,
    binopf32 = _require.binopf32,
    binopf64 = _require.binopf64;

var _require2 = require("./instruction/unop"),
    unopi32 = _require2.unopi32,
    unopi64 = _require2.unopi64,
    unopf32 = _require2.unopf32,
    unopf64 = _require2.unopf64;

var _require3 = require("../runtime/castIntoStackLocalOfType"),
    castIntoStackLocalOfType = _require3.castIntoStackLocalOfType;

var i32 = require("../runtime/values/i32");

var i64 = require("../runtime/values/i64");

var f32 = require("../runtime/values/f32");

var f64 = require("../runtime/values/f64");

var label = require("../runtime/values/label");

var _require4 = require("./signals"),
    createTrap = _require4.createTrap;

var _require5 = require("./instruction/comparison"),
    compare = _require5.compare;

function executeStackFrame(_ref, offset, firstFrame) {
  var program = _ref.program;

  if (!(_typeof(program) === "object")) {
    throw new _errors.RuntimeError('typeof program === "object"' + " error: " + (undefined || "unknown"));
  }

  var callStack = [firstFrame]; // because it's used a macros
  // eslint-disable-next-line prefer-const

  var framepointer = 0;

  function getLocalByIndex(frame, index) {
    var local = frame.locals[index];

    if (typeof local === "undefined") {
      throw newRuntimeError("Assertion error: no local value at index " + index);
    }

    frame.values.push(local);
  }

  function setLocalByIndex(frame, index, value) {
    if (!(typeof index === "number")) {
      throw new _errors.RuntimeError('typeof index === "number"' + " error: " + (undefined || "unknown"));
    }

    frame.locals[index] = value;
  }

  function pushResult(frame, res) {
    if (typeof res === "undefined") {
      return;
    }

    frame.values.push(res);
  }

  function popArrayOfValTypes(frame, types) {
    if (frame.values.length < types.length) {
      throw new _errors.RuntimeError("Assertion error: expected " + JSON.stringify(types.length) + " on the stack, found " + frame.values.length);
    }

    return types.map(function (type) {
      return pop1OfType(frame, type);
    });
  }

  function valueTypeEq(l, r) {
    // compatibility with our parser
    if (l === "u32") {
      l = "i32";
    }

    if (l === "u64") {
      l = "i64";
    }

    if (r === "u32") {
      r = "i32";
    }

    if (r === "u64") {
      r = "i64";
    }

    return l === r;
  }

  function pop1OfType(frame, type) {
    if (frame.values.length < 1) {
      throw new _errors.RuntimeError("Assertion error: expected " + JSON.stringify(1) + " on the stack, found " + frame.values.length);
    }

    var v = frame.values.pop();

    if (typeof type === "string" && valueTypeEq(v.type, type) === false) {
      throw newRuntimeError("Internal failure: expected value of type " + type + " on top of the stack, type given: " + v.type);
    }

    return v;
  }

  function pop1(frame) {
    if (frame.values.length < 1) {
      throw new _errors.RuntimeError("Assertion error: expected " + JSON.stringify(1) + " on the stack, found " + frame.values.length);
    }

    return frame.values.pop();
  }

  function pop2(frame, type1, type2) {
    if (frame.values.length < 2) {
      throw new _errors.RuntimeError("Assertion error: expected " + JSON.stringify(2) + " on the stack, found " + frame.values.length);
    }

    var c2 = frame.values.pop();
    var c1 = frame.values.pop();

    if (valueTypeEq(c2.type, type2) === false) {
      throw newRuntimeError("Internal failure: expected c2 value of type " + type2 + " on top of the stack, given type: " + c2.type);
    }

    if (valueTypeEq(c1.type, type1) === false) {
      throw newRuntimeError("Internal failure: expected c1 value of type " + type1 + " on top of the stack, given type: " + c1.type);
    }

    return [c1, c2];
  }

  function getMemoryOffset(frame, instruction) {
    if (instruction.namedArgs && instruction.namedArgs.offset) {
      // $FlowIgnore
      var _offset = instruction.namedArgs.offset.value;

      if (_offset < 0) {
        throw newRuntimeError("offset must be positive");
      }

      if (_offset > 0xffffffff) {
        throw newRuntimeError("offset must be less than or equal to 0xffffffff");
      }

      return _offset;
    } else {
      return 0;
    }
  }

  function getMemory(frame) {
    if (frame.originatingModule.memaddrs.length !== 1) {
      throw newRuntimeError("unknown memory");
    }

    var memAddr = frame.originatingModule.memaddrs[0];
    return frame.allocator.get(memAddr);
  }

  function newRuntimeError(msg) {
    return new _errors.RuntimeError(msg);
  }

  function getActiveStackFrame() {
    if (!(framepointer > -1)) {
      throw new _errors.RuntimeError('framepointer > -1' + " error: " + ("call stack underflow" || "unknown"));
    }

    var frame = callStack[framepointer];

    if (!(frame !== undefined)) {
      throw new _errors.RuntimeError('frame !== undefined' + " error: " + ("no frame at " + framepointer || "unknown"));
    }

    return frame;
  }

  var offsets = Object.keys(program);
  var pc = offsets.indexOf(String(offset));

  while (true) {
    var frame = getActiveStackFrame();
    var instruction = program[parseInt(offsets[pc])];

    if (!(instruction !== undefined)) {
      throw new _errors.RuntimeError('instruction !== undefined' + " error: " + ("no instruction at pc ".concat(pc, " in frame ").concat(framepointer) || "unknown"));
    }

    if (typeof frame.trace === "function") {
      frame.trace(framepointer, pc, instruction, frame);
    }

    pc++;

    switch (instruction.type) {
      // $FlowIgnore
      case "InternalEndAndReturn":
        {
          if (frame.returnAddress !== -1) {
            pc = frame.returnAddress; // raw goto

            var activeFrame = getActiveStackFrame(); // pass the result of the previous call into the new active fame

            var res = void 0;

            if (activeFrame.values.length > 0) {
              res = pop1(activeFrame);
            } // Pop active frame from the stack


            callStack.pop();
            framepointer--;
            var newStackFrame = getActiveStackFrame();

            if (res !== undefined && newStackFrame !== undefined) {
              pushResult(newStackFrame, res);
            }

            break;
          } else {
            var activeFrame = getActiveStackFrame();

            if (activeFrame.values.length > 0) {
              return pop1(activeFrame);
            } else {
              return;
            }
          }
        }
      // $FlowIgnore

      case "InternalGoto":
        {
          var target = instruction.target;
          pc = offsets.indexOf(String(target));
          break;
        }
      // $FlowIgnore

      case "InternalCallExtern":
        {
          var _target = instruction.target; // 2. Assert: due to validation, F.module.funcaddrs[x] exists.

          var funcaddr = frame.originatingModule.funcaddrs[_target];

          if (typeof funcaddr === "undefined") {
            throw newRuntimeError("No function was found in module at address ".concat(_target));
          } // 3. Let a be the function address F.module.funcaddrs[x]


          var subroutine = frame.allocator.get(funcaddr);

          if (_typeof(subroutine) !== "object") {
            throw newRuntimeError("Cannot call function at address ".concat(funcaddr, ": not a function"));
          } // 4. Invoke the function instance at address a
          // FIXME(sven): assert that res has type of resultType


          var _subroutine$type = _slicedToArray(subroutine.type, 2),
              argTypes = _subroutine$type[0],
              resultType = _subroutine$type[1];

          var args = popArrayOfValTypes(frame, argTypes);

          if (!subroutine.isExternal) {
            throw new _errors.RuntimeError('subroutine.isExternal' + " error: " + (undefined || "unknown"));
          }

          var _res = subroutine.code(args.map(function (arg) {
            return arg.value;
          }));

          if (typeof _res !== "undefined") {
            pushResult(frame, castIntoStackLocalOfType(resultType, _res));
          }

          break;
        }
    }

    switch (instruction.id) {
      case "const":
        {
          // https://webassembly.github.io/spec/core/exec/instructions.html#exec-const
          // $FlowIgnore
          var n = instruction.args[0];

          if (typeof n === "undefined") {
            throw newRuntimeError("const requires one argument, none given.");
          }

          if (n.type !== "NumberLiteral" && n.type !== "LongNumberLiteral" && n.type !== "FloatLiteral") {
            throw newRuntimeError("const: unsupported value of type: " + n.type);
          }

          pushResult(frame, // $FlowIgnore
          castIntoStackLocalOfType(instruction.object, n.value));
          break;
        }

      /**
       * Control Instructions
       *
       * https://webassembly.github.io/spec/core/exec/instructions.html#control-instructions
       */

      case "nop":
        {
          // Do nothing
          // https://webassembly.github.io/spec/core/exec/instructions.html#exec-nop
          break;
        }

      case "drop":
        {
          // https://webassembly.github.io/spec/core/exec/instructions.html#exec-drop
          // 1. Assert: due to validation, a value is on the top of the stack.
          if (frame.values.length < 1) {
            throw new _errors.RuntimeError("Assertion error: expected " + JSON.stringify(1) + " on the stack, found " + frame.values.length);
          }

          // 2. Pop the value valval from the stack.
          pop1(frame);
          break;
        }

      case "call":
        {
          // FIXME(sven): check spec compliancy
          // $FlowIgnore
          var index = instruction.index.value;

          var stackframe = require("./stackframe");

          var activeFrame = getActiveStackFrame();
          var newStackFrame = stackframe.createChildStackFrame(activeFrame, pc); // move active frame

          framepointer++;

          if (framepointer >= 300) {
            throw new _errors.RuntimeError("Maximum call stack depth reached");
          } // Push the frame on top of the stack


          callStack[framepointer] = newStackFrame;
          pc = offsets.indexOf(String(index));
          break;
        }

      case "end":
        {
          // 3. Assert: due to validation, the label L is now on the top of the stack.
          // 4. Pop the label from the stack.
          var found = false;
          var index = frame.values.slice(0).reverse().findIndex(function (_ref2) {
            var type = _ref2.type;
            return type === "label";
          }); // some expression like inittializer don't have labels currently, so this is
          // guarantee to fail
          // assertRuntimeError(index !== -1, "POP_LABEL: label not found")

          if (index !== -1) {
            var initialOrderIndex = frame.values.length - 1 - index;
            frame.values.splice(initialOrderIndex, 1);
          }

          break;
        }

      case "loop":
      case "block":
        {
          // https://webassembly.github.io/spec/core/exec/instructions.html#blocks
          // FIXME(sven): check spec compliancy
          var block = instruction; // 2. Enter the block instr∗ with label

          frame.labels.push({
            value: block,
            arity: 0,
            // $FlowIgnore
            id: block.label
          }); // $FlowIgnore

          pushResult(frame, label.createValue(block.label.value)); // $FlowIgnore

          break;
        }

      case "br":
        {
          // FIXME(sven): check spec compliancy
          // $FlowIgnore
          var _label = instruction.args[0]; // $FlowIgnore

          pc = offsets.indexOf(String(_label.value));
          break;
        }

      case "br_if":
        {
          // $FlowIgnore
          var _label2 = instruction.args[0]; // 1. Assert: due to validation, a value of type i32 is on the top of the stack.
          // 2. Pop the value ci32.const c from the stack.

          var c = pop1OfType(frame, "i32");

          if (c.value.eqz().isTrue() === false) {
            // 3. If c is non-zero, then
            // 3. a. Execute the instruction (br l).
            // $FlowIgnore
            pc = offsets.indexOf(String(_label2.value));
          } else {// 4. Else:
            // 4. a. Do nothing.
          }

          break;
        }

      /**
       * Administrative Instructions
       *
       * https://webassembly.github.io/spec/core/exec/runtime.html#administrative-instructions
       */

      case "unreachable": // https://webassembly.github.io/spec/core/exec/instructions.html#exec-unreachable

      case "trap":
        {
          // signalling abrupt termination
          // https://webassembly.github.io/spec/core/exec/runtime.html#syntax-trap
          throw createTrap();
        }

      case "local":
        {
          // $FlowIgnore
          var _instruction$args = _slicedToArray(instruction.args, 1),
              valtype = _instruction$args[0];

          if (valtype.name === "i64") {
            var init = castIntoStackLocalOfType(valtype.name, new _long["default"](0, 0));
            frame.locals.push(init);
          } else {
            // $FlowIgnore
            var _init = castIntoStackLocalOfType(valtype.name, 0);

            frame.locals.push(_init);
          } // $FlowIgnore


          break;
        }

      /**
       * Memory Instructions
       *
       * https://webassembly.github.io/spec/core/exec/instructions.html#memory-instructions
       */

      case "get_local":
        {
          // https://webassembly.github.io/spec/core/exec/instructions.html#exec-get-local
          // $FlowIgnore
          var _index = instruction.args[0];

          if (typeof _index === "undefined") {
            throw newRuntimeError("get_local requires one argument, none given.");
          }

          if (_index.type === "NumberLiteral" || _index.type === "FloatLiteral") {
            getLocalByIndex(frame, _index.value);
          } else {
            throw newRuntimeError("get_local: unsupported index of type: " + _index.type);
          }

          break;
        }

      case "set_local":
        {
          // https://webassembly.github.io/spec/core/exec/instructions.html#exec-set-local
          // $FlowIgnore
          var _index2 = instruction.args[0];

          if (_index2.type === "NumberLiteral") {
            // WASM
            // 4. Pop the value val from the stack
            var val = pop1(frame); // 5. Replace F.locals[x] with the value val

            setLocalByIndex(frame, _index2.value, val);
          } else {
            throw newRuntimeError("set_local: unsupported index of type: " + _index2.type);
          }

          break;
        }

      case "tee_local":
        {
          // https://webassembly.github.io/spec/core/exec/instructions.html#exec-tee-local
          // $FlowIgnore
          var _index3 = instruction.args[0];

          if (_index3.type === "NumberLiteral") {
            // 1. Assert: due to validation, a value is on the top of the stack.
            // 2. Pop the value val from the stack.
            var _val = pop1(frame); // 3. Push the value valval to the stack.


            pushResult(frame, _val); // 4. Push the value valval to the stack.

            pushResult(frame, _val); // 5. Execute the instruction (set_local x).
            // 5. 4. Pop the value val from the stack

            var val2 = pop1(frame); // 5. 5. Replace F.locals[x] with the value val

            setLocalByIndex(frame, _index3.value, val2);
          } else {
            throw newRuntimeError("tee_local: unsupported index of type: " + _index3.type);
          }

          break;
        }

      case "set_global":
        {
          // https://webassembly.github.io/spec/core/exec/instructions.html#exec-set-global
          // $FlowIgnore
          var _index4 = instruction.args[0]; // 2. Assert: due to validation, F.module.globaladdrs[x] exists.
          // $FlowIgnore

          var globaladdr = frame.originatingModule.globaladdrs[_index4.value];

          if (typeof globaladdr === "undefined") {
            // $FlowIgnore
            throw newRuntimeError("Global address ".concat(_index4.value, " not found"));
          } // 4. Assert: due to validation, S.globals[a] exists.


          var globalinst = frame.allocator.get(globaladdr);

          if (_typeof(globalinst) !== "object") {
            throw newRuntimeError("Unexpected data for global at ".concat(globaladdr.toString()));
          } // 7. Pop the value val from the stack.


          var _val2 = pop1(frame); // 8. Replace glob.value with the value val.


          globalinst.value = _val2.value;
          frame.allocator.set(globaladdr, globalinst);
          break;
        }

      case "get_global":
        {
          // https://webassembly.github.io/spec/core/exec/instructions.html#exec-get-global
          // $FlowIgnore
          var _index5 = instruction.args[0]; // 2. Assert: due to validation, F.module.globaladdrs[x] exists.
          // $FlowIgnore

          var _globaladdr = frame.originatingModule.globaladdrs[_index5.value];

          if (typeof _globaladdr === "undefined") {
            throw newRuntimeError( // $FlowIgnore
            "Unknown global at index: ".concat(_index5.value.toString()));
          } // 4. Assert: due to validation, S.globals[a] exists.


          var _globalinst = frame.allocator.get(_globaladdr);

          if (_typeof(_globalinst) !== "object") {
            throw newRuntimeError("Unexpected data for global at ".concat(_globaladdr.toString()));
          } // 7. Pop the value val from the stack.


          pushResult(frame, _globalinst);
          break;
        }

      /**
       * Memory operations
       */
      // https://webassembly.github.io/spec/core/exec/instructions.html#exec-storen

      case "store":
      case "store8":
      case "store16":
      case "store32":
        {
          // $FlowIgnore
          var id = instruction.id,
              object = instruction.object;
          var memory = getMemory(frame); // $FlowIgnore

          var _pop = pop2(frame, "i32", object),
              _pop2 = _slicedToArray(_pop, 2),
              c1 = _pop2[0],
              c2 = _pop2[1];

          var ptr = c1.value.toNumber() + getMemoryOffset(frame, instruction);
          var valueBuffer = c2.value.toByteArray();

          switch (id) {
            case "store":
              break;

            case "store8":
              valueBuffer = valueBuffer.slice(0, 1);
              break;

            case "store16":
              valueBuffer = valueBuffer.slice(0, 2);
              break;

            case "store32":
              valueBuffer = valueBuffer.slice(0, 4);
              break;

            default:
              throw newRuntimeError("illegal operation: " + id);
          }

          if (ptr + valueBuffer.length > memory.buffer.byteLength) {
            throw newRuntimeError("memory access out of bounds");
          }

          var memoryBuffer = new Uint8Array(memory.buffer); // load / store use little-endian order

          for (var ptrOffset = 0; ptrOffset < valueBuffer.length; ptrOffset++) {
            memoryBuffer[ptr + ptrOffset] = valueBuffer[ptrOffset];
          }

          break;
        }
      // https://webassembly.github.io/spec/core/exec/instructions.html#and

      case "load":
      case "load16_s":
      case "load16_u":
      case "load8_s":
      case "load8_u":
      case "load32_s":
      case "load32_u":
        {
          // $FlowIgnore
          var _id = instruction.id,
              _object = instruction.object;

          var _memory = getMemory(frame);

          var _ptr = pop1OfType(frame, "i32").value.toNumber() + getMemoryOffset(frame, instruction); // for i32 / i64 ops, handle extended load


          var extend = 0; // for i64 values, increase the bitshift by 4 bytes

          var extendOffset = _object === "i32" ? 0 : 32;
          var signed = false;

          switch (_id) {
            case "load16_s":
              extend = 16 + extendOffset;
              signed = true;
              break;

            case "load16_u":
              extend = 16 + extendOffset;
              signed = false;
              break;

            case "load8_s":
              extend = 24 + extendOffset;
              signed = true;
              break;

            case "load8_u":
              extend = 24 + extendOffset;
              signed = false;
              break;

            case "load32_u":
              extend = 0 + extendOffset;
              signed = false;
              break;

            case "load32_s":
              extend = 0 + extendOffset;
              signed = true;
              break;
          } // check for memory access out of bounds


          switch (_object) {
            case "u32":
            case "i32":
            case "f32":
              {
                if (_ptr + 4 > _memory.buffer.byteLength) {
                  throw newRuntimeError("memory access out of bounds");
                }

                break;
              }

            case "i64":
            case "f64":
              {
                if (_ptr + 8 > _memory.buffer.byteLength) {
                  throw newRuntimeError("memory access out of bounds");
                }

                break;
              }

            default:
              // $FlowIgnore
              throw new _errors.RuntimeError("Unsupported " + _object + " load");
          }

          switch (_object) {
            case "i32":
            case "u32":
              pushResult(frame, i32.createValueFromArrayBuffer(_memory.buffer, _ptr, extend, signed));
              break;

            case "i64":
              pushResult(frame, i64.createValueFromArrayBuffer(_memory.buffer, _ptr, extend, signed));
              break;

            case "f32":
              pushResult(frame, f32.createValueFromArrayBuffer(_memory.buffer, _ptr));
              break;

            case "f64":
              pushResult(frame, f64.createValueFromArrayBuffer(_memory.buffer, _ptr));
              break;

            default:
              throw new _errors.RuntimeError("Unsupported " + _object + " load");
          }

          break;
        }

      /**
       * Binary operations
       */

      case "add":
      case "mul":
      case "sub":
      /**
       * There are two seperated operation for both signed and unsigned integer,
       * but since the host environment will handle that, we don't have too :)
       */

      case "div_s":
      case "div_u":
      case "rem_s":
      case "rem_u":
      case "shl":
      case "shr_s":
      case "shr_u":
      case "rotl":
      case "rotr":
      case "div":
      case "min":
      case "max":
      case "copysign":
      case "or":
      case "xor":
      case "and":
        {
          var binopFn = void 0; // $FlowIgnore

          switch (instruction.object) {
            case "i32":
              binopFn = binopi32;
              break;

            case "i64":
              binopFn = binopi64;
              break;

            case "f32":
              binopFn = binopf32;
              break;

            case "f64":
              binopFn = binopf64;
              break;

            default:
              throw createTrap("Unsupported operation " + instruction.id + " on " + // $FlowIgnore
              instruction.object);
          }

          var _pop3 = pop2(frame, instruction.object, instruction.object),
              _pop4 = _slicedToArray(_pop3, 2),
              _c = _pop4[0],
              _c2 = _pop4[1]; // $FlowIgnore


          pushResult(frame, binopFn(_c, _c2, instruction.id));
          break;
        }

      /**
       * Comparison operations
       */

      case "eq":
      case "ne":
      case "lt_s":
      case "lt_u":
      case "le_s":
      case "le_u":
      case "gt":
      case "gt_s":
      case "gt_u":
      case "ge_s":
      case "ge_u":
        {
          // $FlowIgnore
          var _pop5 = pop2(frame, instruction.object, instruction.object),
              _pop6 = _slicedToArray(_pop5, 2),
              _c3 = _pop6[0],
              _c4 = _pop6[1]; // $FlowIgnore


          pushResult(frame, compare(_c3, _c4, instruction.id));
          break;
        }

      /**
       * Unary operations
       */

      case "abs":
      case "neg":
      case "clz":
      case "ctz":
      case "popcnt":
      case "eqz":
      case "reinterpret/f32":
      case "reinterpret/f64":
        {
          var unopFn = void 0; // for conversion operations, the operand type appears after the forward-slash
          // e.g. with i32.reinterpret/f32, the oprand is f32, and the resultant is i32

          var opType = instruction.id.indexOf("/") !== -1 ? // $FlowIgnore
          instruction.id.split("/")[1] : // $FlowIgnore
          instruction.object;

          switch (opType) {
            case "i32":
              unopFn = unopi32;
              break;

            case "i64":
              unopFn = unopi64;
              break;

            case "f32":
              unopFn = unopf32;
              break;

            case "f64":
              unopFn = unopf64;
              break;

            default:
              throw createTrap( // $FlowIgnore
              "Unsupported operation " + instruction.id + " on " + opType);
          }

          var _c5 = pop1OfType(frame, opType); // $FlowIgnore


          pushResult(frame, unopFn(_c5, instruction.id));
          break;
        }

      case "return":
        {
          if (frame.returnAddress !== -1) {
            pc = frame.returnAddress; // raw goto

            var activeFrame = getActiveStackFrame(); // pass the result of the previous call into the new active fame

            var res = void 0;

            if (activeFrame.values.length > 0) {
              res = pop1(activeFrame);
            } // Pop active frame from the stack


            callStack.pop();
            framepointer--;
            var newStackFrame = getActiveStackFrame();

            if (res !== undefined && newStackFrame !== undefined) {
              pushResult(newStackFrame, res);
            }
          }

          var activeFrame = getActiveStackFrame();

          if (activeFrame.values.length > 0) {
            return pop1(activeFrame);
          } else {
            return;
          }
        }
    }
  }
}