text: /**
   * Copyright (c) 2014, Facebook, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the BSD-style license found in the
   * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
   * additional grant of patent rights can be found in the PATENTS file in
   * the same directory.
   */
  
  exports.FunctionEntry = FunctionEntry;
  exports.FinallyEntry  = FinallyEntry;
  exports.SwitchEntry   = SwitchEntry;
  exports.LeapManager   = LeapManager;
  exports.CatchEntry    = CatchEntry;
  exports.LoopEntry     = LoopEntry;
  exports.TryEntry      = TryEntry;
  
  var assert = require("assert");
  var util   = require("util");
  var t      = require("../../../types");
  
  var inherits = util.inherits;
  
  function Entry() {
    assert.ok(this instanceof Entry);
  }
  
  function FunctionEntry(returnLoc) {
    Entry.call(this);
  
    t.assertLiteral(returnLoc);
  
    this.returnLoc = returnLoc;
  }
  
  inherits(FunctionEntry, Entry);
  
  function LoopEntry(breakLoc, continueLoc, label) {
    Entry.call(this);
  
    t.assertLiteral(breakLoc);
    t.assertLiteral(continueLoc);
  
    if (label) {
      t.assertIdentifier(label);
    } else {
      label = null;
    }
  
    this.breakLoc = breakLoc;
    this.continueLoc = continueLoc;
    this.label = label;
  }
  
  inherits(LoopEntry, Entry);
  
  function SwitchEntry(breakLoc) {
    Entry.call(this);
  
    t.assertLiteral(breakLoc);
  
    this.breakLoc = breakLoc;
  }
  
  inherits(SwitchEntry, Entry);
  
  function TryEntry(firstLoc, catchEntry, finallyEntry) {
    Entry.call(this);
  
    t.assertLiteral(firstLoc);
  
    if (catchEntry) {
      assert.ok(catchEntry instanceof CatchEntry);
    } else {
      catchEntry = null;
    }
  
    if (finallyEntry) {
      assert.ok(finallyEntry instanceof FinallyEntry);
    } else {
      finallyEntry = null;
    }
  
    // Have to have one or the other (or both).
    assert.ok(catchEntry || finallyEntry);
  
    this.firstLoc = firstLoc;
    this.catchEntry = catchEntry;
    this.finallyEntry = finallyEntry;
  }
  
  inherits(TryEntry, Entry);
  
  function CatchEntry(firstLoc, paramId) {
    Entry.call(this);
  
    t.assertLiteral(firstLoc);
    t.assertIdentifier(paramId);
  
    this.firstLoc = firstLoc;
    this.paramId = paramId;
  }
  
  inherits(CatchEntry, Entry);
  
  function FinallyEntry(firstLoc) {
    Entry.call(this);
  
    t.assertLiteral(firstLoc);
  
    this.firstLoc = firstLoc;
  }
  
  inherits(FinallyEntry, Entry);
  
  function LeapManager(emitter) {
    assert.ok(this instanceof LeapManager);
  
    var Emitter = require("./emit").Emitter;
    assert.ok(emitter instanceof Emitter);
  
    this.emitter = emitter;
    this.entryStack = [new FunctionEntry(emitter.finalLoc)];
  }
  
  LeapManager.prototype.withEntry = function (entry, callback) {
    assert.ok(entry instanceof Entry);
    this.entryStack.push(entry);
    try {
      callback.call(this.emitter);
    } finally {
      var popped = this.entryStack.pop();
      assert.strictEqual(popped, entry);
    }
  };
  
  LeapManager.prototype._findLeapLocation = function (property, label) {
    for (var i = this.entryStack.length - 1; i >= 0; --i) {
      var entry = this.entryStack[i];
      var loc = entry[property];
      if (loc) {
        if (label) {
          if (entry.label &&
              entry.label.name === label.name) {
            return loc;
          }
        } else {
          return loc;
        }
      }
    }
  
    return null;
  };
  
  LeapManager.prototype.getBreakLoc = function (label) {
    return this._findLeapLocation("breakLoc", label);
  };
  
  LeapManager.prototype.getContinueLoc = function (label) {
    return this._findLeapLocation("continueLoc", label);
  };
  