From eebe6c89a27bfeaa4f4302ee6f4f67bd4857399e Mon Sep 17 00:00:00 2001 From: Robert Plummer Date: Thu, 20 Sep 2018 13:05:09 -0400 Subject: [PATCH] fix: TrainStream, CrossValidate, and Typescript Overhauled the internals of TrainStream and CrossValidate so they are decoupled from the networks themselves, as well as being able to restore or store CrossValidate from json. Added examples for CrossValidate and TrainStream, and as well one for learning math, to test the typescript type file. Too I added missing typescript configs and examples. * --- README.md | 47 +- browser.js | 32551 +++++++++-------- browser.min.js | 174 +- dist/cross-validate.js | 334 +- dist/cross-validate.js.map | 2 +- dist/index.js | 2 +- dist/index.js.map | 2 +- dist/neural-network-gpu.js.map | 2 +- dist/neural-network.js | 20 - dist/neural-network.js.map | 2 +- dist/recurrent/gru-time-step.js.map | 2 +- dist/recurrent/gru.js.map | 2 +- dist/recurrent/lstm-time-step.js.map | 2 +- dist/recurrent/lstm.js.map | 2 +- dist/recurrent/matrix/clone.js.map | 2 +- dist/recurrent/matrix/equation.js.map | 2 +- dist/recurrent/matrix/ones-matrix.js.map | 2 +- dist/recurrent/matrix/random-matrix.js.map | 2 +- dist/recurrent/matrix/random-n-matrix.js.map | 2 +- dist/recurrent/matrix/sample-i.js.map | 2 +- dist/recurrent/matrix/softmax.js.map | 2 +- dist/recurrent/rnn-time-step.js.map | 2 +- dist/recurrent/rnn.js.map | 2 +- dist/train-stream.js | 39 +- dist/train-stream.js.map | 2 +- examples-typescript/childrens-book.ts | 2 +- examples-typescript/cli/stream-example.ts | 41 - examples-typescript/cross-validate.ts | 56 + examples-typescript/learn-math.ts | 129 + examples-typescript/predict-numbers.ts | 22 + examples-typescript/stream-example.ts | 53 + examples-typescript/which-letter-simple.ts | 4 +- examples/childrens-book.js | 9 +- examples/cli/stream-example.js | 41 - examples/cross-validate.js | 56 + examples/learn-math.js | 129 + examples/predict-numbers.js | 23 + examples/stream-example.js | 54 + examples/which-letter-simple.js | 10 +- index.d.ts | 146 +- index.js | 4 +- package.json | 2 +- src/cross-validate.js | 295 +- src/index.js | 4 +- src/neural-network.js | 14 - src/train-stream.js | 23 +- test/base/stream-bitwise.js | 3 +- 47 files changed, 17821 insertions(+), 16502 deletions(-) delete mode 100644 examples-typescript/cli/stream-example.ts create mode 100644 examples-typescript/cross-validate.ts create mode 100644 examples-typescript/learn-math.ts create mode 100644 examples-typescript/predict-numbers.ts create mode 100644 examples-typescript/stream-example.ts delete mode 100644 examples/cli/stream-example.js create mode 100644 examples/cross-validate.js create mode 100644 examples/learn-math.js create mode 100644 examples/predict-numbers.js create mode 100644 examples/stream-example.js diff --git a/README.md b/README.md index 9d0e3ba4e..6ab18d2aa 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ + [For training with `RNN`, `LSTM` and `GRU`](#for-training-with-rnn-lstm-and-gru) + [Training Options](#training-options) + [Async Training](#async-training) + + [Cross Validation](#cross-validation) + + [Train Stream](#train-stream) - [Methods](#methods) + [train](#train) - [Failing](#failing) @@ -274,6 +276,49 @@ With multiple networks you can train in parallel like this: .catch(handleError); ``` +### Cross Validation +[Cross Validation](https://en.wikipedia.org/wiki/Cross-validation_(statistics)) can provide a less fragile way of training on larger data sets. The brain.js api provides Cross Validation in this example: +```js +const crossValidate = new CrossValidate(brain.NeuralNetwork); +const stats = crossValidate.train(data, networkOptions, trainingOptions, k); //note k (or KFolds) is optional +const net = crossValidate.toNetwork(); + + +// optionally later +const json = crossValidate.toJSON(); +const net = crossValidate.fromJSON(json); +``` + +An example of using cross validate can be found in [examples/cross-validate.js](examples/cross-validate.js) + +### Train Stream +Streams are a very powerful tool in node for massive data spread across processes and are provided via the brain.js api in the following way: +```js +const net = new brain.NeuralNetwork(); +const trainStream = new brain.TrainStream({ + neuralNetwork: net, + floodCallback: function() { + flood(trainStream, data); + }, + doneTrainingCallback: function(stats) { + // network is done training! What next? + } +}); + +// kick it off +readInputs(trainStream, data); + +function readInputs(stream, data) { + for (let i = 0; i < data.length; i++) { + stream.write(data[i]); + } + // let it know we've reached the end of the inputs + stream.endInputs(); +} +``` + +An example of using train stream can be found in [examples/stream-example.js](examples/stream-example.js) + # Methods ### train The output of `train()` is a hash of information about how the training went: @@ -341,7 +386,7 @@ The network now has a [WriteStream](http://nodejs.org/api/stream.html#stream_cla ### Example -Refer to [`stream-example.js`](./examples/cli/stream-example.js) for an example on how to train the network with a stream. +Refer to [`stream-example.js`](examples/stream-example.js) for an example on how to train the network with a stream. ### Initialization diff --git a/browser.js b/browser.js index f252ab510..c37083109 100644 --- a/browser.js +++ b/browser.js @@ -6,19 +6,19 @@ * license: MIT (http://opensource.org/licenses/MIT) * author: Heather Arthur * homepage: https://github.com/brainjs/brain.js#readme - * version: 1.2.8 + * version: 1.3.0 * * acorn: * license: MIT (http://opensource.org/licenses/MIT) - * maintainers: Marijn Haverbeke , Ingvar Stepanyan + * maintainers: Marijn Haverbeke , Ingvar Stepanyan , Adrian Heine * homepage: https://github.com/acornjs/acorn - * version: 5.5.3 + * version: 5.7.2 * * base64-js: * license: MIT (http://opensource.org/licenses/MIT) * author: T. Jameson Little * homepage: https://github.com/beatgammit/base64-js - * version: 1.2.3 + * version: 1.3.0 * * buffer: * license: MIT (http://opensource.org/licenses/MIT) @@ -41,13 +41,13 @@ * license: MIT (http://opensource.org/licenses/MIT) * author: The gpu.js Team * homepage: http://gpu.rocks/ - * version: 1.6.0 + * version: 1.6.2 * * ieee754: * license: BSD-3-Clause (http://opensource.org/licenses/BSD-3-Clause) * author: Feross Aboukhadijeh * contributors: Romain Beauxis - * version: 1.1.8 + * version: 1.1.12 * * inherits: * license: ISC (http://opensource.org/licenses/ISC) @@ -71,13 +71,13 @@ * * readable-stream: * license: MIT (http://opensource.org/licenses/MIT) - * version: 2.3.5 + * version: 2.3.6 * * safe-buffer: * license: MIT (http://opensource.org/licenses/MIT) * author: Feross Aboukhadijeh * homepage: https://github.com/feross/safe-buffer - * version: 5.1.1 + * version: 5.1.2 * * stream-browserify: * license: MIT (http://opensource.org/licenses/MIT) @@ -87,8 +87,8 @@ * * string_decoder: * license: MIT (http://opensource.org/licenses/MIT) - * homepage: https://github.com/rvagg/string_decoder - * version: 1.0.3 + * homepage: https://github.com/nodejs/string_decoder + * version: 1.1.1 * * thaw.js: * license: MIT (http://opensource.org/licenses/MIT) @@ -117,161 +117,209 @@ Object.defineProperty(exports, "__esModule", { value: true }); -exports.testPartition = testPartition; -exports.shuffleArray = shuffleArray; -exports.default = crossValidate; -/** - * - * @param {NeuralNetwork|constructor} Classifier - * @param {object} opts - * @param {object} trainOpts - * @param {object} trainSet - * @param {object} testSet - * @returns {void|*} - */ -function testPartition(Classifier, opts, trainOpts, trainSet, testSet) { - var classifier = new Classifier(opts); - var beginTrain = Date.now(); - var trainingStats = classifier.train(trainSet, trainOpts); - var beginTest = Date.now(); - var testStats = classifier.test(testSet); - var endTest = Date.now(); - var stats = Object.assign({}, testStats, { - trainTime: beginTest - beginTrain, - testTime: endTest - beginTest, - iterations: trainingStats.iterations, - trainError: trainingStats.error, - learningRate: trainOpts.learningRate, - hidden: classifier.hiddenSizes, - network: classifier.toJSON() - }); - return stats; -} +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -/** - * Randomize array element order in-place. - * Using Durstenfeld shuffle algorithm. - * source: http://stackoverflow.com/a/12646864/1324039 - */ -function shuffleArray(array) { - for (var i = array.length - 1; i > 0; i--) { - var j = Math.floor(Math.random() * (i + 1)); - var temp = array[i]; - array[i] = array[j]; - array[j] = temp; - } - return array; -} +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -/** - * - * @param {NeuralNetwork|constructor} Classifier - * @param {object} data - * @param {object} opts - * @param {object} trainOpts - * @param {number} k - * @returns { - * { - * avgs: { - * error: number, - * trainTime: number, - * testTime: number, - * iterations: number, - * trainError: number - * }, - * stats: { - * truePos: number, - * trueNeg: number, - * falsePos: number, - * falseNeg: number, - * total: number - * }, - * sets: Array, - * misclasses: Array - * } - * } - */ -function crossValidate(Classifier, data, opts, trainOpts, k) { - k = k || 4; - var size = data.length / k; +var CrossValidate = function () { - if (data.constructor === Array) { - shuffleArray(data); - } else { - var newData = {}; - shuffleArray(Object.keys(data)).forEach(function (key) { - newData[key] = data[key]; - }); - data = newData; + /** + * + * @param {NeuralNetwork|constructor} Classifier + */ + function CrossValidate(Classifier) { + _classCallCheck(this, CrossValidate); + + this.Classifier = Classifier; + this.json = null; } - var avgs = { - error: 0, - trainTime: 0, - testTime: 0, - iterations: 0, - trainError: 0 - }; + /** + * + * @param {object} options + * @param {object} trainOpts + * @param {object} trainSet + * @param {object} testSet + * @returns {void|*} + */ - var stats = { - truePos: 0, - trueNeg: 0, - falsePos: 0, - falseNeg: 0, - total: 0 - }; - var misclasses = []; - var results = []; - var stat = void 0; - var sum = void 0; - - for (var i = 0; i < k; i++) { - var dclone = data.slice(0); - var testSet = dclone.splice(i * size, size); - var trainSet = dclone; - var result = testPartition(Classifier, opts, trainOpts, trainSet, testSet); - for (stat in avgs) { - if (stat in avgs) { - sum = avgs[stat]; - avgs[stat] = sum + result[stat]; - } + _createClass(CrossValidate, [{ + key: "testPartition", + value: function testPartition(options, trainOpts, trainSet, testSet) { + var classifier = new this.Classifier(options); + var beginTrain = Date.now(); + var trainingStats = classifier.train(trainSet, trainOpts); + var beginTest = Date.now(); + var testStats = classifier.test(testSet); + var endTest = Date.now(); + var stats = Object.assign({}, testStats, { + trainTime: beginTest - beginTrain, + testTime: endTest - beginTest, + iterations: trainingStats.iterations, + trainError: trainingStats.error, + learningRate: trainOpts.learningRate, + hidden: classifier.hiddenSizes, + network: classifier.toJSON() + }); + + return stats; } - for (stat in stats) { - if (stat in stats) { - sum = stats[stat]; - stats[stat] = sum + result[stat]; + /** + * Randomize array element order in-place. + * Using Durstenfeld shuffle algorithm. + * source: http://stackoverflow.com/a/12646864/1324039 + */ + + }, { + key: "shuffleArray", + value: function shuffleArray(array) { + for (var i = array.length - 1; i > 0; i--) { + var j = Math.floor(Math.random() * (i + 1)); + var temp = array[i]; + array[i] = array[j]; + array[j] = temp; } + return array; } - misclasses.concat(results.misclasses); + /** + * + * @param {object} data + * @param {object} options + * @param {object} trainOpts + * @param {number} [k] + * @returns { + * { + * avgs: { + * error: number, + * trainTime: number, + * testTime: number, + * iterations: number, + * trainError: number + * }, + * stats: { + * truePos: number, + * trueNeg: number, + * falsePos: number, + * falseNeg: number, + * total: number + * }, + * sets: Array + * } + * } + */ - results.push(result); - } + }, { + key: "train", + value: function train(data, options, trainOpts, k) { + k = k || 4; + var size = data.length / k; - for (stat in avgs) { - if (stat in avgs) { - sum = avgs[stat]; - avgs[stat] = sum / k; - } - } + if (data.constructor === Array) { + this.shuffleArray(data); + } else { + var newData = {}; + this.shuffleArray(Object.keys(data)).forEach(function (key) { + newData[key] = data[key]; + }); + data = newData; + } - stats.precision = stats.truePos / (stats.truePos + stats.falsePos); - stats.recall = stats.truePos / (stats.truePos + stats.falseNeg); - stats.accuracy = (stats.trueNeg + stats.truePos) / stats.total; + var avgs = { + error: 0, + trainTime: 0, + testTime: 0, + iterations: 0, + trainError: 0 + }; - stats.testSize = size; - stats.trainSize = data.length - size; + var stats = { + truePos: 0, + trueNeg: 0, + falsePos: 0, + falseNeg: 0, + total: 0 + }; - return { - avgs: avgs, - stats: stats, - sets: results, - misclasses: misclasses - }; -} + var results = []; + var stat = void 0; + var sum = void 0; + + for (var i = 0; i < k; i++) { + var dclone = data.slice(0); + var testSet = dclone.splice(i * size, size); + var trainSet = dclone; + var result = this.testPartition(options, trainOpts, trainSet, testSet); + for (stat in avgs) { + if (stat in avgs) { + sum = avgs[stat]; + avgs[stat] = sum + result[stat]; + } + } + + for (stat in stats) { + if (stat in stats) { + sum = stats[stat]; + stats[stat] = sum + result[stat]; + } + } + + results.push(result); + } + + for (stat in avgs) { + if (stat in avgs) { + sum = avgs[stat]; + avgs[stat] = sum / k; + } + } + + stats.precision = stats.truePos / (stats.truePos + stats.falsePos); + stats.recall = stats.truePos / (stats.truePos + stats.falseNeg); + stats.accuracy = (stats.trueNeg + stats.truePos) / stats.total; + + stats.testSize = size; + stats.trainSize = data.length - size; + + this.json = { + avgs: avgs, + stats: stats, + sets: results + }; + } + }, { + key: "toNetwork", + value: function toNetwork() { + return this.fromJSON(this.json); + } + }, { + key: "toJSON", + value: function toJSON() { + return this.json; + } + }, { + key: "fromJSON", + value: function fromJSON(crossValidateJson) { + var Classifier = this.Classifier; + var json = crossValidateJson.sets.reduce(function (prev, cur) { + return prev.error < cur.error ? prev : cur; + }, { error: Infinity }).network; + if (Classifier.fromJSON) { + return Classifier.fromJSON(json); + } + var instance = new Classifier(); + instance.fromJSON(json); + return instance; + } + }]); + + return CrossValidate; +}(); + +exports.default = CrossValidate; },{}],2:[function(require,module,exports){ "use strict"; @@ -935,7 +983,7 @@ function mse(errors) { return sum / this.constants.size; } -},{"./lookup":3,"./neural-network":5,"gpu.js":85}],5:[function(require,module,exports){ +},{"./lookup":3,"./neural-network":5,"gpu.js":86}],5:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { @@ -948,10 +996,6 @@ var _lookup = require('./lookup'); var _lookup2 = _interopRequireDefault(_lookup); -var _trainStream = require('./train-stream'); - -var _trainStream2 = _interopRequireDefault(_trainStream); - var _max = require('./utilities/max'); var _max2 = _interopRequireDefault(_max); @@ -2008,22 +2052,6 @@ var NeuralNetwork = function () { } return new Function('input', 'return ' + result); } - - /** - * This will create a TrainStream (WriteStream) for us to send the training data to. - * @param opts training options - * @returns {TrainStream|*} - */ - - }, { - key: 'createTrainStream', - value: function createTrainStream(opts) { - opts = opts || {}; - opts.neuralNetwork = this; - this.setActivation(); - this.trainStream = new _trainStream2.default(opts); - return this.trainStream; - } }, { key: 'isRunnable', get: function get() { @@ -2051,7 +2079,7 @@ var NeuralNetwork = function () { exports.default = NeuralNetwork; -},{"./lookup":3,"./train-stream":36,"./utilities/max":38,"./utilities/mse":39,"./utilities/randos":43,"./utilities/range":44,"./utilities/to-array":45,"./utilities/zeros":46,"thaw.js":110}],6:[function(require,module,exports){ +},{"./lookup":3,"./utilities/max":38,"./utilities/mse":39,"./utilities/randos":43,"./utilities/range":44,"./utilities/to-array":45,"./utilities/zeros":46,"thaw.js":110}],6:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { @@ -4669,6 +4697,7 @@ var TrainStream = function (_Writable) { } _this.neuralNetwork = opts.neuralNetwork; + _this.hiddenSizes = opts.neuralNetwork.hiddenSizes; _this.dataFormatDetermined = false; _this.inputKeys = []; @@ -4693,17 +4722,22 @@ var TrainStream = function (_Writable) { return _ret = _this, _possibleConstructorReturn(_this, _ret); } - /** - * _write expects data to be in the form of a datum. ie. {input: {a: 1 b: 0}, output: {z: 0}} - * @param chunk - * @param enc - * @param next - * @returns {*} - * @private - */ + _createClass(TrainStream, [{ + key: 'endInputs', + value: function endInputs() { + this.write(false); + } + /** + * _write expects data to be in the form of a datum. ie. {input: {a: 1 b: 0}, output: {z: 0}} + * @param chunk + * @param enc + * @param next + * @returns {*} + * @private + */ - _createClass(TrainStream, [{ + }, { key: '_write', value: function _write(chunk, enc, next) { if (!chunk) { @@ -4722,7 +4756,7 @@ var TrainStream = function (_Writable) { this.count++; - var data = this.neuralNetwork.formatData(chunk); + var data = this.neuralNetwork._formatData(chunk); this.trainDatum(data[0]); // tell the Readable Stream that we are ready for more data @@ -4737,7 +4771,7 @@ var TrainStream = function (_Writable) { }, { key: 'trainDatum', value: function trainDatum(datum) { - var err = this.neuralNetwork.trainPattern(datum.input, datum.output); + var err = this.neuralNetwork._trainPattern(datum.input, datum.output, true); this.sum += err; } @@ -4760,11 +4794,11 @@ var TrainStream = function (_Writable) { this.neuralNetwork.outputLookup = _lookup2.default.lookupFromArray(this.outputKeys); } - var data = this.neuralNetwork.formatData(this.firstDatum); + var data = this.neuralNetwork._formatData(this.firstDatum); var sizes = []; var inputSize = data[0].input.length; var outputSize = data[0].output.length; - var hiddenSizes = this.hiddenSizes; + var hiddenSizes = this.neuralNetwork.hiddenSizes; if (!hiddenSizes) { sizes.push(Math.max(3, Math.floor(inputSize / 2))); } else { @@ -4777,7 +4811,8 @@ var TrainStream = function (_Writable) { sizes.push(outputSize); this.dataFormatDetermined = true; - this.neuralNetwork.initialize(sizes); + this.neuralNetwork.sizes = sizes; + this.neuralNetwork._initialize(); if (typeof this.floodCallback === 'function') { this.floodCallback(); @@ -4787,10 +4822,10 @@ var TrainStream = function (_Writable) { var error = this.sum / this.size; - if (this.log && this.i % this.logPeriod == 0) { + if (this.log && this.i % this.logPeriod === 0) { this.log('iterations:', this.i, 'training error:', error); } - if (this.callback && this.i % this.callbackPeriod == 0) { + if (this.callback && this.i % this.callbackPeriod === 0) { this.callback({ error: error, iterations: this.i @@ -5259,7 +5294,7 @@ function zeros(size) { } },{}],47:[function(require,module,exports){ -var crossValidate = require('./dist/cross-validate').default; +var CrossValidate = require('./dist/cross-validate').default; var likely = require('./dist/likely').default; var lookup = require('./dist/lookup').default; var NeuralNetwork = require('./dist/neural-network').default; @@ -5285,7 +5320,7 @@ var utilities = { }; var brain = { - crossValidate: crossValidate, + CrossValidate: CrossValidate, likely: likely, lookup: lookup, NeuralNetwork: NeuralNetwork, @@ -5313,14558 +5348,3041 @@ if (typeof module !== 'undefined') { } },{"./dist/cross-validate":1,"./dist/likely":2,"./dist/lookup":3,"./dist/neural-network":5,"./dist/neural-network-gpu":4,"./dist/recurrent/gru":7,"./dist/recurrent/gru-time-step":6,"./dist/recurrent/lstm":9,"./dist/recurrent/lstm-time-step":8,"./dist/recurrent/rnn":35,"./dist/recurrent/rnn-time-step":34,"./dist/train-stream":36,"./dist/utilities/data-formatter":37,"./dist/utilities/max":38,"./dist/utilities/mse":39,"./dist/utilities/ones":40,"./dist/utilities/random":42,"./dist/utilities/random-weight":41,"./dist/utilities/randos":43,"./dist/utilities/range":44,"./dist/utilities/to-array":45,"./dist/utilities/zeros":46}],48:[function(require,module,exports){ -'use strict' - -exports.byteLength = byteLength -exports.toByteArray = toByteArray -exports.fromByteArray = fromByteArray +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.acorn = {}))); +}(this, (function (exports) { 'use strict'; -var lookup = [] -var revLookup = [] -var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array +// Reserved word lists for various dialects of the language -var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' -for (var i = 0, len = code.length; i < len; ++i) { - lookup[i] = code[i] - revLookup[code.charCodeAt(i)] = i -} +var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" +}; -// Support decoding URL-safe base64 strings, as Node.js does. -// See: https://en.wikipedia.org/wiki/Base64#URL_applications -revLookup['-'.charCodeAt(0)] = 62 -revLookup['_'.charCodeAt(0)] = 63 +// And the keywords -function placeHoldersCount (b64) { - var len = b64.length - if (len % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } +var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"; - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 -} +var keywords = { + 5: ecma5AndLessKeywords, + 6: ecma5AndLessKeywords + " const class extends export import super" +}; -function byteLength (b64) { - // base64 is 4/3 + up to two characters of the original data - return (b64.length * 3 / 4) - placeHoldersCount(b64) -} +var keywordRelationalOperator = /^in(stanceof)?$/; -function toByteArray (b64) { - var i, l, tmp, placeHolders, arr - var len = b64.length - placeHolders = placeHoldersCount(b64) +// ## Character categories - arr = new Arr((len * 3 / 4) - placeHolders) +// Big ugly regular expressions that match characters in the +// whitespace, identifier, and identifier-start categories. These +// are only applied when a character is found to actually have a +// code point above 128. +// Generated by `bin/generate-identifier-regex.js`. - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? len - 4 : len +var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7b9\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; +var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; - var L = 0 +var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); +var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); - for (i = 0; i < l; i += 4) { - tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] - arr[L++] = (tmp >> 16) & 0xFF - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } +nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; - if (placeHolders === 2) { - tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) - arr[L++] = tmp & 0xFF - } else if (placeHolders === 1) { - tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } +// These are a run-length and offset encoded representation of the +// >0xffff code points that are a valid part of identifiers. The +// offset starts at 0x10000, and each pair of numbers represents an +// offset to the next range, and then a size of the range. They were +// generated by bin/generate-identifier-regex.js - return arr -} +// eslint-disable-next-line comma-spacing +var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,477,28,11,0,9,21,190,52,76,44,33,24,27,35,30,0,12,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,26,230,43,117,63,32,0,257,0,11,39,8,0,22,0,12,39,3,3,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,270,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,68,12,0,67,12,65,1,31,6129,15,754,9486,286,82,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,15,7472,3104,541]; -function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] -} +// eslint-disable-next-line comma-spacing +var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,280,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239]; -function encodeChunk (uint8, start, end) { - var tmp - var output = [] - for (var i = start; i < end; i += 3) { - tmp = ((uint8[i] << 16) & 0xFF0000) + ((uint8[i + 1] << 8) & 0xFF00) + (uint8[i + 2] & 0xFF) - output.push(tripletToBase64(tmp)) +// This has a complexity linear to the value of the code. The +// assumption is that looking up astral identifier characters is +// rare. +function isInAstralSet(code, set) { + var pos = 0x10000; + for (var i = 0; i < set.length; i += 2) { + pos += set[i]; + if (pos > code) { return false } + pos += set[i + 1]; + if (pos >= code) { return true } } - return output.join('') } -function fromByteArray (uint8) { - var tmp - var len = uint8.length - var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes - var output = '' - var parts = [] - var maxChunkLength = 16383 // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1] - output += lookup[tmp >> 2] - output += lookup[(tmp << 4) & 0x3F] - output += '==' - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) - output += lookup[tmp >> 10] - output += lookup[(tmp >> 4) & 0x3F] - output += lookup[(tmp << 2) & 0x3F] - output += '=' - } - - parts.push(output) +// Test whether a given character code starts an identifier. - return parts.join('') +function isIdentifierStart(code, astral) { + if (code < 65) { return code === 36 } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) } -},{}],49:[function(require,module,exports){ +// Test whether a given character is part of an identifier. -},{}],50:[function(require,module,exports){ -(function (global){ -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -/* eslint-disable no-proto */ +function isIdentifierChar(code, astral) { + if (code < 48) { return code === 36 } + if (code < 58) { return true } + if (code < 65) { return false } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) +} -'use strict' +// ## Token types -var base64 = require('base64-js') -var ieee754 = require('ieee754') -var isArray = require('isarray') +// The assignment of fine-grained, information-carrying type objects +// allows the tokenizer to store the information it has about a +// token in a way that is very cheap for the parser to look up. -exports.Buffer = Buffer -exports.SlowBuffer = SlowBuffer -exports.INSPECT_MAX_BYTES = 50 +// All token type variables start with an underscore, to make them +// easy to recognize. -/** - * If `Buffer.TYPED_ARRAY_SUPPORT`: - * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (most compatible, even IE6) - * - * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, - * Opera 11.6+, iOS 4.2+. - * - * Due to various browser bugs, sometimes the Object implementation will be used even - * when the browser supports typed arrays. - * - * Note: - * - * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, - * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. - * - * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. - * - * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of - * incorrect length in some situations. +// The `beforeExpr` property is used to disambiguate between regular +// expressions and divisions. It is set on all token types that can +// be followed by an expression (thus, a slash after them would be a +// regular expression). +// +// The `startsExpr` property is used to check if the token ends a +// `yield` expression. It is set on all token types that either can +// directly start an expression (like a quotation mark) or can +// continue an expression (like the body of a string). +// +// `isLoop` marks a keyword as starting a loop, which is important +// to know when parsing a label, in order to allow or disallow +// continue jumps to that label. - * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they - * get the Object implementation, which is slower but behaves correctly. - */ -Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined - ? global.TYPED_ARRAY_SUPPORT - : typedArraySupport() +var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; -/* - * Export kMaxLength after typed array support is determined. - */ -exports.kMaxLength = kMaxLength() + this.label = label; + this.keyword = conf.keyword; + this.beforeExpr = !!conf.beforeExpr; + this.startsExpr = !!conf.startsExpr; + this.isLoop = !!conf.isLoop; + this.isAssign = !!conf.isAssign; + this.prefix = !!conf.prefix; + this.postfix = !!conf.postfix; + this.binop = conf.binop || null; + this.updateContext = null; +}; -function typedArraySupport () { - try { - var arr = new Uint8Array(1) - arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} - return arr.foo() === 42 && // typed array instances can be augmented - typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` - arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` - } catch (e) { - return false - } +function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) } +var beforeExpr = {beforeExpr: true}; +var startsExpr = {startsExpr: true}; -function kMaxLength () { - return Buffer.TYPED_ARRAY_SUPPORT - ? 0x7fffffff - : 0x3fffffff -} +// Map keyword names to token types. -function createBuffer (that, length) { - if (kMaxLength() < length) { - throw new RangeError('Invalid typed array length') - } - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = new Uint8Array(length) - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - if (that === null) { - that = new Buffer(length) - } - that.length = length - } +var keywords$1 = {}; - return that +// Succinct definitions of keyword token types +function kw(name, options) { + if ( options === void 0 ) options = {}; + + options.keyword = name; + return keywords$1[name] = new TokenType(name, options) } -/** - * The Buffer constructor returns instances of `Uint8Array` that have their - * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of - * `Uint8Array`, so the returned instances will have all the node `Buffer` methods - * and the `Uint8Array` methods. Square bracket notation works as expected -- it - * returns a single octet. - * - * The `Uint8Array` prototype remains unmodified. - */ +var types = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + eof: new TokenType("eof"), -function Buffer (arg, encodingOrOffset, length) { - if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { - return new Buffer(arg, encodingOrOffset, length) - } + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + invalidTemplate: new TokenType("invalidTemplate"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), - // Common case. - if (typeof arg === 'number') { - if (typeof encodingOrOffset === 'string') { - throw new Error( - 'If encoding is specified then the first argument must be a string' - ) - } - return allocUnsafe(this, arg) - } - return from(this, arg, encodingOrOffset, length) -} + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. -Buffer.poolSize = 8192 // not used by this implementation + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=/===/!==", 6), + relational: binop("/<=/>=", 7), + bitShift: binop("<>/>>>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), -// TODO: Legacy, not needed anymore. Remove in next major version. -Buffer._augment = function (arr) { - arr.__proto__ = Buffer.prototype - return arr + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class", startsExpr), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import"), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) +}; + +// Matches a whole line break (where CRLF is considered a single +// line break). Used to count lines. + +var lineBreak = /\r\n?|\n|\u2028|\u2029/; +var lineBreakG = new RegExp(lineBreak.source, "g"); + +function isNewLine(code, ecma2019String) { + return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029)) } -function from (that, value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number') - } +var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - return fromArrayBuffer(that, value, encodingOrOffset, length) - } +var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; - if (typeof value === 'string') { - return fromString(that, value, encodingOrOffset) - } +var ref = Object.prototype; +var hasOwnProperty = ref.hasOwnProperty; +var toString = ref.toString; - return fromObject(that, value) -} +// Checks if an object has a property. -/** - * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError - * if value is a number. - * Buffer.from(str[, encoding]) - * Buffer.from(array) - * Buffer.from(buffer) - * Buffer.from(arrayBuffer[, byteOffset[, length]]) - **/ -Buffer.from = function (value, encodingOrOffset, length) { - return from(null, value, encodingOrOffset, length) +function has(obj, propName) { + return hasOwnProperty.call(obj, propName) } -if (Buffer.TYPED_ARRAY_SUPPORT) { - Buffer.prototype.__proto__ = Uint8Array.prototype - Buffer.__proto__ = Uint8Array - if (typeof Symbol !== 'undefined' && Symbol.species && - Buffer[Symbol.species] === Buffer) { - // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 - Object.defineProperty(Buffer, Symbol.species, { - value: null, - configurable: true - }) - } -} +var isArray = Array.isArray || (function (obj) { return ( + toString.call(obj) === "[object Array]" +); }); -function assertSize (size) { - if (typeof size !== 'number') { - throw new TypeError('"size" argument must be a number') - } else if (size < 0) { - throw new RangeError('"size" argument must not be negative') - } -} +// These are used when `options.locations` is on, for the +// `startLoc` and `endLoc` properties. -function alloc (that, size, fill, encoding) { - assertSize(size) - if (size <= 0) { - return createBuffer(that, size) - } - if (fill !== undefined) { - // Only pay attention to encoding if it's a string. This - // prevents accidentally sending in a number that would - // be interpretted as a start offset. - return typeof encoding === 'string' - ? createBuffer(that, size).fill(fill, encoding) - : createBuffer(that, size).fill(fill) - } - return createBuffer(that, size) -} +var Position = function Position(line, col) { + this.line = line; + this.column = col; +}; -/** - * Creates a new filled Buffer instance. - * alloc(size[, fill[, encoding]]) - **/ -Buffer.alloc = function (size, fill, encoding) { - return alloc(null, size, fill, encoding) -} +Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) +}; -function allocUnsafe (that, size) { - assertSize(size) - that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) { - for (var i = 0; i < size; ++i) { - that[i] = 0 +var SourceLocation = function SourceLocation(p, start, end) { + this.start = start; + this.end = end; + if (p.sourceFile !== null) { this.source = p.sourceFile; } +}; + +// The `getLineInfo` function is mostly useful when the +// `locations` option is off (for performance reasons) and you +// want to find the line/column position for a given character +// offset. `input` should be the code string that the offset refers +// into. + +function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + lineBreakG.lastIndex = cur; + var match = lineBreakG.exec(input); + if (match && match.index < offset) { + ++line; + cur = match.index + match[0].length; + } else { + return new Position(line, offset - cur) } } - return that } -/** - * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. - * */ -Buffer.allocUnsafe = function (size) { - return allocUnsafe(null, size) -} -/** - * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. - */ -Buffer.allocUnsafeSlow = function (size) { - return allocUnsafe(null, size) -} +// A second optional argument can be given to further configure +// the parser process. These options are recognized: -function fromString (that, string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8' - } +var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must + // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support + // for strict mode, the set of reserved words, and support for + // new syntax features. The default is 7. + ecmaVersion: 7, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"` or `"module"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // th position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program. + allowImportExportEverywhere: false, + // When enabled, await identifiers are allowed to appear at the top-level scope, + // but they are still not allowed in non-async functions. + allowAwaitOutsideFunction: false, + // When enabled, hashbang directive in the beginning of file + // is allowed and treated as a line comment. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false, + plugins: {} +}; - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('"encoding" must be a valid string encoding') - } +// Interpret and default an options object - var length = byteLength(string, encoding) | 0 - that = createBuffer(that, length) +function getOptions(opts) { + var options = {}; - var actual = that.write(string, encoding) + for (var opt in defaultOptions) + { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; } - if (actual !== length) { - // Writing a hex string, for example, that contains invalid characters will - // cause everything after the first invalid character to be ignored. (e.g. - // 'abxxcd' will be treated as 'ab') - that = that.slice(0, actual) + if (options.ecmaVersion >= 2015) + { options.ecmaVersion -= 2009; } + + if (options.allowReserved == null) + { options.allowReserved = options.ecmaVersion < 5; } + + if (isArray(options.onToken)) { + var tokens = options.onToken; + options.onToken = function (token) { return tokens.push(token); }; } + if (isArray(options.onComment)) + { options.onComment = pushComment(options, options.onComment); } - return that + return options } -function fromArrayLike (that, array) { - var length = array.length < 0 ? 0 : checked(array.length) | 0 - that = createBuffer(that, length) - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 +function pushComment(options, array) { + return function(block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? "Block" : "Line", + value: text, + start: start, + end: end + }; + if (options.locations) + { comment.loc = new SourceLocation(this, startLoc, endLoc); } + if (options.ranges) + { comment.range = [start, end]; } + array.push(comment); } - return that } -function fromArrayBuffer (that, array, byteOffset, length) { - array.byteLength // this throws if `array` is not a valid ArrayBuffer +// Registered plugins +var plugins = {}; - if (byteOffset < 0 || array.byteLength < byteOffset) { - throw new RangeError('\'offset\' is out of bounds') - } +function keywordRegexp(words) { + return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$") +} - if (array.byteLength < byteOffset + (length || 0)) { - throw new RangeError('\'length\' is out of bounds') +var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options); + this.sourceFile = options.sourceFile; + this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]); + var reserved = ""; + if (!options.allowReserved) { + for (var v = options.ecmaVersion;; v--) + { if (reserved = reservedWords[v]) { break } } + if (options.sourceType === "module") { reserved += " await"; } } + this.reservedWords = keywordRegexp(reserved); + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; + this.reservedWordsStrict = keywordRegexp(reservedStrict); + this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind); + this.input = String(input); - if (byteOffset === undefined && length === undefined) { - array = new Uint8Array(array) - } else if (length === undefined) { - array = new Uint8Array(array, byteOffset) - } else { - array = new Uint8Array(array, byteOffset, length) - } + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false; - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = array - that.__proto__ = Buffer.prototype + // Load plugins + this.loadPlugins(options.plugins); + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos; + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; } else { - // Fallback: Return an object instance of the Buffer class - that = fromArrayLike(that, array) + this.pos = this.lineStart = 0; + this.curLine = 1; } - return that -} -function fromObject (that, obj) { - if (Buffer.isBuffer(obj)) { - var len = checked(obj.length) | 0 - that = createBuffer(that, len) + // Properties of the current token: + // Its type + this.type = types.eof; + // For tokens that include more information than their type, the value + this.value = null; + // Its start and end offset + this.start = this.end = this.pos; + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition(); - if (that.length === 0) { - return that - } + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null; + this.lastTokStart = this.lastTokEnd = this.pos; - obj.copy(that, 0, 0, len) - return that - } + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext(); + this.exprAllowed = true; - if (obj) { - if ((typeof ArrayBuffer !== 'undefined' && - obj.buffer instanceof ArrayBuffer) || 'length' in obj) { - if (typeof obj.length !== 'number' || isnan(obj.length)) { - return createBuffer(that, 0) - } - return fromArrayLike(that, obj) - } + // Figure out if it's a module code. + this.inModule = options.sourceType === "module"; + this.strict = this.inModule || this.strictDirective(this.pos); - if (obj.type === 'Buffer' && isArray(obj.data)) { - return fromArrayLike(that, obj.data) - } - } + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1; - throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') -} + // Flags to track whether we are in a function, a generator, an async function. + this.inFunction = this.inGenerator = this.inAsync = false; + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = 0; + // Labels in scope. + this.labels = []; -function checked (length) { - // Note: cannot use `length < kMaxLength()` here because that fails when - // length is NaN (which is otherwise coerced to zero.) - if (length >= kMaxLength()) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + - 'size: 0x' + kMaxLength().toString(16) + ' bytes') - } - return length | 0 -} + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") + { this.skipLineComment(2); } -function SlowBuffer (length) { - if (+length != length) { // eslint-disable-line eqeqeq - length = 0 - } - return Buffer.alloc(+length) -} + // Scope tracking for duplicate variable names (see scope.js) + this.scopeStack = []; + this.enterFunctionScope(); -Buffer.isBuffer = function isBuffer (b) { - return !!(b != null && b._isBuffer) -} + // For RegExp validation + this.regexpState = null; +}; -Buffer.compare = function compare (a, b) { - if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { - throw new TypeError('Arguments must be Buffers') - } +// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them +Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) }; +Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) }; - if (a === b) return 0 +Parser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]); +}; - var x = a.length - var y = b.length +Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { + var this$1 = this; - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i] - y = b[i] - break - } + for (var name in pluginConfigs) { + var plugin = plugins[name]; + if (!plugin) { throw new Error("Plugin '" + name + "' not found") } + plugin(this$1, pluginConfigs[name]); } +}; - if (x < y) return -1 - if (y < x) return 1 - return 0 -} +Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode(); + this.nextToken(); + return this.parseTopLevel(node) +}; -Buffer.isEncoding = function isEncoding (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'latin1': - case 'binary': - case 'base64': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } -} +var pp = Parser.prototype; -Buffer.concat = function concat (list, length) { - if (!isArray(list)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } +// ## Parser utilities - if (list.length === 0) { - return Buffer.alloc(0) - } +var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/; +pp.strictDirective = function(start) { + var this$1 = this; - var i - if (length === undefined) { - length = 0 - for (i = 0; i < list.length; ++i) { - length += list[i].length - } + for (;;) { + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this$1.input)[0].length; + var match = literal.exec(this$1.input.slice(start)); + if (!match) { return false } + if ((match[1] || match[2]) === "use strict") { return true } + start += match[0].length; } +}; - var buffer = Buffer.allocUnsafe(length) - var pos = 0 - for (i = 0; i < list.length; ++i) { - var buf = list[i] - if (!Buffer.isBuffer(buf)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - buf.copy(buffer, pos) - pos += buf.length - } - return buffer -} +// Predicate that tests whether the next token is of the given +// type, and if yes, consumes it as a side effect. -function byteLength (string, encoding) { - if (Buffer.isBuffer(string)) { - return string.length - } - if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && - (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { - return string.byteLength - } - if (typeof string !== 'string') { - string = '' + string +pp.eat = function(type) { + if (this.type === type) { + this.next(); + return true + } else { + return false } +}; - var len = string.length - if (len === 0) return 0 - - // Use a for loop to avoid recursion - var loweredCase = false - for (;;) { - switch (encoding) { - case 'ascii': - case 'latin1': - case 'binary': - return len - case 'utf8': - case 'utf-8': - case undefined: - return utf8ToBytes(string).length - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return len * 2 - case 'hex': - return len >>> 1 - case 'base64': - return base64ToBytes(string).length - default: - if (loweredCase) return utf8ToBytes(string).length // assume utf8 - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} -Buffer.byteLength = byteLength +// Tests whether parsed token is a contextual keyword. -function slowToString (encoding, start, end) { - var loweredCase = false +pp.isContextual = function(name) { + return this.type === types.name && this.value === name && !this.containsEsc +}; - // No need to verify that "this.length <= MAX_UINT32" since it's a read-only - // property of a typed array. +// Consumes contextual keyword if possible. - // This behaves neither like String nor Uint8Array in that we set start/end - // to their upper/lower bounds if the value passed is out of range. - // undefined is handled specially as per ECMA-262 6th Edition, - // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. - if (start === undefined || start < 0) { - start = 0 - } - // Return early if start > this.length. Done here to prevent potential uint32 - // coercion fail below. - if (start > this.length) { - return '' - } +pp.eatContextual = function(name) { + if (!this.isContextual(name)) { return false } + this.next(); + return true +}; - if (end === undefined || end > this.length) { - end = this.length - } +// Asserts that following token is given contextual keyword. - if (end <= 0) { - return '' - } +pp.expectContextual = function(name) { + if (!this.eatContextual(name)) { this.unexpected(); } +}; - // Force coersion to uint32. This will also coerce falsey/NaN values to 0. - end >>>= 0 - start >>>= 0 +// Test whether a semicolon can be inserted at the current position. - if (end <= start) { - return '' +pp.canInsertSemicolon = function() { + return this.type === types.eof || + this.type === types.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +}; + +pp.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } + return true } +}; - if (!encoding) encoding = 'utf8' +// Consume a semicolon, or, failing that, see if we are allowed to +// pretend that there is a semicolon at this position. - while (true) { - switch (encoding) { - case 'hex': - return hexSlice(this, start, end) +pp.semicolon = function() { + if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); } +}; - case 'utf8': - case 'utf-8': - return utf8Slice(this, start, end) +pp.afterTrailingComma = function(tokType, notNext) { + if (this.type === tokType) { + if (this.options.onTrailingComma) + { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } + if (!notNext) + { this.next(); } + return true + } +}; - case 'ascii': - return asciiSlice(this, start, end) +// Expect a token of a given type. If found, consume it, otherwise, +// raise an unexpected token error. - case 'latin1': - case 'binary': - return latin1Slice(this, start, end) +pp.expect = function(type) { + this.eat(type) || this.unexpected(); +}; - case 'base64': - return base64Slice(this, start, end) +// Raise an unexpected token error. - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return utf16leSlice(this, start, end) +pp.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token"); +}; - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = (encoding + '').toLowerCase() - loweredCase = true - } - } +function DestructuringErrors() { + this.shorthandAssign = + this.trailingComma = + this.parenthesizedAssign = + this.parenthesizedBind = + this.doubleProto = + -1; } -// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect -// Buffer instances. -Buffer.prototype._isBuffer = true - -function swap (b, n, m) { - var i = b[n] - b[n] = b[m] - b[m] = i -} +pp.checkPatternErrors = function(refDestructuringErrors, isAssign) { + if (!refDestructuringErrors) { return } + if (refDestructuringErrors.trailingComma > -1) + { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } + var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; + if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); } +}; -Buffer.prototype.swap16 = function swap16 () { - var len = this.length - if (len % 2 !== 0) { - throw new RangeError('Buffer size must be a multiple of 16-bits') - } - for (var i = 0; i < len; i += 2) { - swap(this, i, i + 1) - } - return this -} +pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + if (!refDestructuringErrors) { return false } + var shorthandAssign = refDestructuringErrors.shorthandAssign; + var doubleProto = refDestructuringErrors.doubleProto; + if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } + if (shorthandAssign >= 0) + { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } + if (doubleProto >= 0) + { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } +}; -Buffer.prototype.swap32 = function swap32 () { - var len = this.length - if (len % 4 !== 0) { - throw new RangeError('Buffer size must be a multiple of 32-bits') - } - for (var i = 0; i < len; i += 4) { - swap(this, i, i + 3) - swap(this, i + 1, i + 2) - } - return this -} +pp.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } + if (this.awaitPos) + { this.raise(this.awaitPos, "Await expression cannot be a default value"); } +}; -Buffer.prototype.swap64 = function swap64 () { - var len = this.length - if (len % 8 !== 0) { - throw new RangeError('Buffer size must be a multiple of 64-bits') - } - for (var i = 0; i < len; i += 8) { - swap(this, i, i + 7) - swap(this, i + 1, i + 6) - swap(this, i + 2, i + 5) - swap(this, i + 3, i + 4) - } - return this -} +pp.isSimpleAssignTarget = function(expr) { + if (expr.type === "ParenthesizedExpression") + { return this.isSimpleAssignTarget(expr.expression) } + return expr.type === "Identifier" || expr.type === "MemberExpression" +}; -Buffer.prototype.toString = function toString () { - var length = this.length | 0 - if (length === 0) return '' - if (arguments.length === 0) return utf8Slice(this, 0, length) - return slowToString.apply(this, arguments) -} +var pp$1 = Parser.prototype; -Buffer.prototype.equals = function equals (b) { - if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') - if (this === b) return true - return Buffer.compare(this, b) === 0 -} +// ### Statement parsing -Buffer.prototype.inspect = function inspect () { - var str = '' - var max = exports.INSPECT_MAX_BYTES - if (this.length > 0) { - str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') - if (this.length > max) str += ' ... ' - } - return '' -} +// Parse a program. Initializes the parser, reads any number of +// statements, and wraps them in a Program node. Optionally takes a +// `program` argument. If present, the statements will be appended +// to its body instead of creating a new node. -Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { - if (!Buffer.isBuffer(target)) { - throw new TypeError('Argument must be a Buffer') - } +pp$1.parseTopLevel = function(node) { + var this$1 = this; - if (start === undefined) { - start = 0 - } - if (end === undefined) { - end = target ? target.length : 0 - } - if (thisStart === undefined) { - thisStart = 0 + var exports = {}; + if (!node.body) { node.body = []; } + while (this.type !== types.eof) { + var stmt = this$1.parseStatement(true, true, exports); + node.body.push(stmt); } - if (thisEnd === undefined) { - thisEnd = this.length + this.adaptDirectivePrologue(node.body); + this.next(); + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType; } + return this.finishNode(node, "Program") +}; - if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { - throw new RangeError('out of range index') - } +var loopLabel = {kind: "loop"}; +var switchLabel = {kind: "switch"}; - if (thisStart >= thisEnd && start >= end) { - return 0 - } - if (thisStart >= thisEnd) { - return -1 - } - if (start >= end) { - return 1 +pp$1.isLet = function() { + if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + if (nextCh === 91 || nextCh === 123) { return true } // '{' and '[' + if (isIdentifierStart(nextCh, true)) { + var pos = next + 1; + while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; } + var ident = this.input.slice(next, pos); + if (!keywordRelationalOperator.test(ident)) { return true } } + return false +}; - start >>>= 0 - end >>>= 0 - thisStart >>>= 0 - thisEnd >>>= 0 - - if (this === target) return 0 - - var x = thisEnd - thisStart - var y = end - start - var len = Math.min(x, y) +// check 'async [no LineTerminator here] function' +// - 'async /*foo*/ function' is OK. +// - 'async /*\n*/ function' is invalid. +pp$1.isAsyncFunction = function() { + if (this.options.ecmaVersion < 8 || !this.isContextual("async")) + { return false } - var thisCopy = this.slice(thisStart, thisEnd) - var targetCopy = target.slice(start, end) + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length; + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) +}; - for (var i = 0; i < len; ++i) { - if (thisCopy[i] !== targetCopy[i]) { - x = thisCopy[i] - y = targetCopy[i] - break - } +// Parse a single statement. +// +// If expecting a statement and finding a slash operator, parse a +// regular expression literal. This is to handle cases like +// `if (foo) /blah/.exec(foo)`, where looking at the previous token +// does not help. + +pp$1.parseStatement = function(declaration, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind; + + if (this.isLet()) { + starttype = types._var; + kind = "let"; } - if (x < y) return -1 - if (y < x) return 1 - return 0 -} + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. -// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, -// OR the last index of `val` in `buffer` at offset <= `byteOffset`. -// -// Arguments: -// - buffer - a Buffer to search -// - val - a string, Buffer, or number -// - byteOffset - an index into `buffer`; will be clamped to an int32 -// - encoding - an optional encoding, relevant is val is a string -// - dir - true for indexOf, false for lastIndexOf -function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { - // Empty buffer means no match - if (buffer.length === 0) return -1 + switch (starttype) { + case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case types._debugger: return this.parseDebuggerStatement(node) + case types._do: return this.parseDoStatement(node) + case types._for: return this.parseForStatement(node) + case types._function: + if (!declaration && this.options.ecmaVersion >= 6) { this.unexpected(); } + return this.parseFunctionStatement(node, false) + case types._class: + if (!declaration) { this.unexpected(); } + return this.parseClass(node, true) + case types._if: return this.parseIfStatement(node) + case types._return: return this.parseReturnStatement(node) + case types._switch: return this.parseSwitchStatement(node) + case types._throw: return this.parseThrowStatement(node) + case types._try: return this.parseTryStatement(node) + case types._const: case types._var: + kind = kind || this.value; + if (!declaration && kind !== "var") { this.unexpected(); } + return this.parseVarStatement(node, kind) + case types._while: return this.parseWhileStatement(node) + case types._with: return this.parseWithStatement(node) + case types.braceL: return this.parseBlock() + case types.semi: return this.parseEmptyStatement(node) + case types._export: + case types._import: + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } + if (!this.inModule) + { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } + } + return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports) - // Normalize byteOffset - if (typeof byteOffset === 'string') { - encoding = byteOffset - byteOffset = 0 - } else if (byteOffset > 0x7fffffff) { - byteOffset = 0x7fffffff - } else if (byteOffset < -0x80000000) { - byteOffset = -0x80000000 - } - byteOffset = +byteOffset // Coerce to Number. - if (isNaN(byteOffset)) { - // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer - byteOffset = dir ? 0 : (buffer.length - 1) - } + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction()) { + if (!declaration) { this.unexpected(); } + this.next(); + return this.parseFunctionStatement(node, true) + } - // Normalize byteOffset: negative offsets start from the end of the buffer - if (byteOffset < 0) byteOffset = buffer.length + byteOffset - if (byteOffset >= buffer.length) { - if (dir) return -1 - else byteOffset = buffer.length - 1 - } else if (byteOffset < 0) { - if (dir) byteOffset = 0 - else return -1 + var maybeName = this.value, expr = this.parseExpression(); + if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) + { return this.parseLabeledStatement(node, maybeName, expr) } + else { return this.parseExpressionStatement(node, expr) } } +}; - // Normalize val - if (typeof val === 'string') { - val = Buffer.from(val, encoding) +pp$1.parseBreakContinueStatement = function(node, keyword) { + var this$1 = this; + + var isBreak = keyword === "break"; + this.next(); + if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; } + else if (this.type !== types.name) { this.unexpected(); } + else { + node.label = this.parseIdent(); + this.semicolon(); } - // Finally, search either indexOf (if dir is true) or lastIndexOf - if (Buffer.isBuffer(val)) { - // Special case: looking for empty string/buffer always fails - if (val.length === 0) { - return -1 - } - return arrayIndexOf(buffer, val, byteOffset, encoding, dir) - } else if (typeof val === 'number') { - val = val & 0xFF // Search for a byte value [0-255] - if (Buffer.TYPED_ARRAY_SUPPORT && - typeof Uint8Array.prototype.indexOf === 'function') { - if (dir) { - return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) - } else { - return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) - } + // Verify that there is an actual destination to break or + // continue to. + var i = 0; + for (; i < this.labels.length; ++i) { + var lab = this$1.labels[i]; + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } + if (node.label && isBreak) { break } } - return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) } + if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") +}; - throw new TypeError('val must be string, number or Buffer') -} +pp$1.parseDebuggerStatement = function(node) { + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement") +}; -function arrayIndexOf (arr, val, byteOffset, encoding, dir) { - var indexSize = 1 - var arrLength = arr.length - var valLength = val.length +pp$1.parseDoStatement = function(node) { + this.next(); + this.labels.push(loopLabel); + node.body = this.parseStatement(false); + this.labels.pop(); + this.expect(types._while); + node.test = this.parseParenExpression(); + if (this.options.ecmaVersion >= 6) + { this.eat(types.semi); } + else + { this.semicolon(); } + return this.finishNode(node, "DoWhileStatement") +}; - if (encoding !== undefined) { - encoding = String(encoding).toLowerCase() - if (encoding === 'ucs2' || encoding === 'ucs-2' || - encoding === 'utf16le' || encoding === 'utf-16le') { - if (arr.length < 2 || val.length < 2) { - return -1 +// Disambiguating between a `for` and a `for`/`in` or `for`/`of` +// loop is non-trivial. Basically, we have to parse the init `var` +// statement or expression, disallowing the `in` operator (see +// the second parameter to `parseExpression`), and then check +// whether the next token is `in` or `of`. When there is no init +// part (semicolon immediately after the opening parenthesis), it +// is a regular `for` loop. + +pp$1.parseForStatement = function(node) { + this.next(); + var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1; + this.labels.push(loopLabel); + this.enterLexicalScope(); + this.expect(types.parenL); + if (this.type === types.semi) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, null) + } + var isLet = this.isLet(); + if (this.type === types._var || this.type === types._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value; + this.next(); + this.parseVar(init$1, true, kind); + this.finishNode(init$1, "VariableDeclaration"); + if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 && + !(kind !== "var" && init$1.declarations[0].init)) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } } - indexSize = 2 - arrLength /= 2 - valLength /= 2 - byteOffset /= 2 + return this.parseForIn(node, init$1) } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init$1) } - - function read (buf, i) { - if (indexSize === 1) { - return buf[i] - } else { - return buf.readUInt16BE(i * indexSize) + var refDestructuringErrors = new DestructuringErrors; + var init = this.parseExpression(true, refDestructuringErrors); + if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } } + this.toAssignable(init, false, refDestructuringErrors); + this.checkLVal(init); + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true); } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) +}; - var i - if (dir) { - var foundIndex = -1 - for (i = byteOffset; i < arrLength; i++) { - if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { - if (foundIndex === -1) foundIndex = i - if (i - foundIndex + 1 === valLength) return foundIndex * indexSize - } else { - if (foundIndex !== -1) i -= i - foundIndex - foundIndex = -1 - } - } - } else { - if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength - for (i = byteOffset; i >= 0; i--) { - var found = true - for (var j = 0; j < valLength; j++) { - if (read(arr, i + j) !== read(val, j)) { - found = false - break - } - } - if (found) return i - } - } - - return -1 -} +pp$1.parseFunctionStatement = function(node, isAsync) { + this.next(); + return this.parseFunction(node, true, false, isAsync) +}; -Buffer.prototype.includes = function includes (val, byteOffset, encoding) { - return this.indexOf(val, byteOffset, encoding) !== -1 -} +pp$1.parseIfStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement(!this.strict && this.type === types._function); + node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type === types._function) : null; + return this.finishNode(node, "IfStatement") +}; -Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, true) -} +pp$1.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + { this.raise(this.start, "'return' outside of function"); } + this.next(); -Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, false) -} + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. -function hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining - } - } + if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; } + else { node.argument = this.parseExpression(); this.semicolon(); } + return this.finishNode(node, "ReturnStatement") +}; - // must be an even number of digits - var strLen = string.length - if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') +pp$1.parseSwitchStatement = function(node) { + var this$1 = this; - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; ++i) { - var parsed = parseInt(string.substr(i * 2, 2), 16) - if (isNaN(parsed)) return i - buf[offset + i] = parsed - } - return i -} + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.expect(types.braceL); + this.labels.push(switchLabel); + this.enterLexicalScope(); -function utf8Write (buf, string, offset, length) { - return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) -} + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. -function asciiWrite (buf, string, offset, length) { - return blitBuffer(asciiToBytes(string), buf, offset, length) -} + var cur; + for (var sawDefault = false; this.type !== types.braceR;) { + if (this$1.type === types._case || this$1.type === types._default) { + var isCase = this$1.type === types._case; + if (cur) { this$1.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this$1.startNode()); + cur.consequent = []; + this$1.next(); + if (isCase) { + cur.test = this$1.parseExpression(); + } else { + if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses"); } + sawDefault = true; + cur.test = null; + } + this$1.expect(types.colon); + } else { + if (!cur) { this$1.unexpected(); } + cur.consequent.push(this$1.parseStatement(true)); + } + } + this.exitLexicalScope(); + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.next(); // Closing brace + this.labels.pop(); + return this.finishNode(node, "SwitchStatement") +}; -function latin1Write (buf, string, offset, length) { - return asciiWrite(buf, string, offset, length) -} +pp$1.parseThrowStatement = function(node) { + this.next(); + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + { this.raise(this.lastTokEnd, "Illegal newline after throw"); } + node.argument = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ThrowStatement") +}; -function base64Write (buf, string, offset, length) { - return blitBuffer(base64ToBytes(string), buf, offset, length) -} +// Reused empty array added for node fields that are always empty. -function ucs2Write (buf, string, offset, length) { - return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) -} +var empty = []; -Buffer.prototype.write = function write (string, offset, length, encoding) { - // Buffer#write(string) - if (offset === undefined) { - encoding = 'utf8' - length = this.length - offset = 0 - // Buffer#write(string, encoding) - } else if (length === undefined && typeof offset === 'string') { - encoding = offset - length = this.length - offset = 0 - // Buffer#write(string, offset[, length][, encoding]) - } else if (isFinite(offset)) { - offset = offset | 0 - if (isFinite(length)) { - length = length | 0 - if (encoding === undefined) encoding = 'utf8' +pp$1.parseTryStatement = function(node) { + this.next(); + node.block = this.parseBlock(); + node.handler = null; + if (this.type === types._catch) { + var clause = this.startNode(); + this.next(); + if (this.eat(types.parenL)) { + clause.param = this.parseBindingAtom(); + this.enterLexicalScope(); + this.checkLVal(clause.param, "let"); + this.expect(types.parenR); } else { - encoding = length - length = undefined + if (this.options.ecmaVersion < 10) { this.unexpected(); } + clause.param = null; + this.enterLexicalScope(); } - // legacy write(string, encoding, offset, length) - remove in v0.13 - } else { - throw new Error( - 'Buffer.write(string, encoding, offset[, length]) is no longer supported' - ) + clause.body = this.parseBlock(false); + this.exitLexicalScope(); + node.handler = this.finishNode(clause, "CatchClause"); } + node.finalizer = this.eat(types._finally) ? this.parseBlock() : null; + if (!node.handler && !node.finalizer) + { this.raise(node.start, "Missing catch or finally clause"); } + return this.finishNode(node, "TryStatement") +}; - var remaining = this.length - offset - if (length === undefined || length > remaining) length = remaining +pp$1.parseVarStatement = function(node, kind) { + this.next(); + this.parseVar(node, false, kind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") +}; - if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { - throw new RangeError('Attempt to write outside buffer bounds') - } +pp$1.parseWhileStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + this.labels.push(loopLabel); + node.body = this.parseStatement(false); + this.labels.pop(); + return this.finishNode(node, "WhileStatement") +}; - if (!encoding) encoding = 'utf8' +pp$1.parseWithStatement = function(node) { + if (this.strict) { this.raise(this.start, "'with' in strict mode"); } + this.next(); + node.object = this.parseParenExpression(); + node.body = this.parseStatement(false); + return this.finishNode(node, "WithStatement") +}; - var loweredCase = false - for (;;) { - switch (encoding) { - case 'hex': - return hexWrite(this, string, offset, length) +pp$1.parseEmptyStatement = function(node) { + this.next(); + return this.finishNode(node, "EmptyStatement") +}; - case 'utf8': - case 'utf-8': - return utf8Write(this, string, offset, length) +pp$1.parseLabeledStatement = function(node, maybeName, expr) { + var this$1 = this; - case 'ascii': - return asciiWrite(this, string, offset, length) + for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1) + { + var label = list[i$1]; - case 'latin1': - case 'binary': - return latin1Write(this, string, offset, length) + if (label.name === maybeName) + { this$1.raise(expr.start, "Label '" + maybeName + "' is already declared"); + } } + var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null; + for (var i = this.labels.length - 1; i >= 0; i--) { + var label$1 = this$1.labels[i]; + if (label$1.statementStart === node.start) { + // Update information about previous labels on this node + label$1.statementStart = this$1.start; + label$1.kind = kind; + } else { break } + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); + node.body = this.parseStatement(true); + if (node.body.type === "ClassDeclaration" || + node.body.type === "VariableDeclaration" && node.body.kind !== "var" || + node.body.type === "FunctionDeclaration" && (this.strict || node.body.generator || node.body.async)) + { this.raiseRecoverable(node.body.start, "Invalid labeled declaration"); } + this.labels.pop(); + node.label = expr; + return this.finishNode(node, "LabeledStatement") +}; - case 'base64': - // Warning: maxLength not taken into account in base64Write - return base64Write(this, string, offset, length) +pp$1.parseExpressionStatement = function(node, expr) { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") +}; - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return ucs2Write(this, string, offset, length) +// Parse a semicolon-enclosed block of statements, handling `"use +// strict"` declarations when `allowStrict` is true (used for +// function bodies). - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} +pp$1.parseBlock = function(createNewLexicalScope) { + var this$1 = this; + if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; -Buffer.prototype.toJSON = function toJSON () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) + var node = this.startNode(); + node.body = []; + this.expect(types.braceL); + if (createNewLexicalScope) { + this.enterLexicalScope(); } -} - -function base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return base64.fromByteArray(buf) - } else { - return base64.fromByteArray(buf.slice(start, end)) + while (!this.eat(types.braceR)) { + var stmt = this$1.parseStatement(true); + node.body.push(stmt); } -} - -function utf8Slice (buf, start, end) { - end = Math.min(buf.length, end) - var res = [] - - var i = start - while (i < end) { - var firstByte = buf[i] - var codePoint = null - var bytesPerSequence = (firstByte > 0xEF) ? 4 - : (firstByte > 0xDF) ? 3 - : (firstByte > 0xBF) ? 2 - : 1 + if (createNewLexicalScope) { + this.exitLexicalScope(); + } + return this.finishNode(node, "BlockStatement") +}; - if (i + bytesPerSequence <= end) { - var secondByte, thirdByte, fourthByte, tempCodePoint +// Parse a regular `for` loop. The disambiguation code in +// `parseStatement` will already have parsed the init statement or +// expression. - switch (bytesPerSequence) { - case 1: - if (firstByte < 0x80) { - codePoint = firstByte - } - break - case 2: - secondByte = buf[i + 1] - if ((secondByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) - if (tempCodePoint > 0x7F) { - codePoint = tempCodePoint - } - } - break - case 3: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) - if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { - codePoint = tempCodePoint - } - } - break - case 4: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - fourthByte = buf[i + 3] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) - if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { - codePoint = tempCodePoint - } - } - } - } +pp$1.parseFor = function(node, init) { + node.init = init; + this.expect(types.semi); + node.test = this.type === types.semi ? null : this.parseExpression(); + this.expect(types.semi); + node.update = this.type === types.parenR ? null : this.parseExpression(); + this.expect(types.parenR); + this.exitLexicalScope(); + node.body = this.parseStatement(false); + this.labels.pop(); + return this.finishNode(node, "ForStatement") +}; - if (codePoint === null) { - // we did not generate a valid codePoint so insert a - // replacement char (U+FFFD) and advance only 1 byte - codePoint = 0xFFFD - bytesPerSequence = 1 - } else if (codePoint > 0xFFFF) { - // encode to utf16 (surrogate pair dance) - codePoint -= 0x10000 - res.push(codePoint >>> 10 & 0x3FF | 0xD800) - codePoint = 0xDC00 | codePoint & 0x3FF - } +// Parse a `for`/`in` and `for`/`of` loop, which are almost +// same from parser's perspective. - res.push(codePoint) - i += bytesPerSequence +pp$1.parseForIn = function(node, init) { + var type = this.type === types._in ? "ForInStatement" : "ForOfStatement"; + this.next(); + if (type === "ForInStatement") { + if (init.type === "AssignmentPattern" || + (init.type === "VariableDeclaration" && init.declarations[0].init != null && + (this.strict || init.declarations[0].id.type !== "Identifier"))) + { this.raise(init.start, "Invalid assignment in for-in loop head"); } } + node.left = init; + node.right = type === "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign(); + this.expect(types.parenR); + this.exitLexicalScope(); + node.body = this.parseStatement(false); + this.labels.pop(); + return this.finishNode(node, type) +}; - return decodeCodePointsArray(res) -} +// Parse a list of variable declarations. -// Based on http://stackoverflow.com/a/22747272/680742, the browser with -// the lowest limit is Chrome, with 0x10000 args. -// We go 1 magnitude less, for safety -var MAX_ARGUMENTS_LENGTH = 0x1000 +pp$1.parseVar = function(node, isFor, kind) { + var this$1 = this; -function decodeCodePointsArray (codePoints) { - var len = codePoints.length - if (len <= MAX_ARGUMENTS_LENGTH) { - return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + node.declarations = []; + node.kind = kind; + for (;;) { + var decl = this$1.startNode(); + this$1.parseVarId(decl, kind); + if (this$1.eat(types.eq)) { + decl.init = this$1.parseMaybeAssign(isFor); + } else if (kind === "const" && !(this$1.type === types._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) { + this$1.unexpected(); + } else if (decl.id.type !== "Identifier" && !(isFor && (this$1.type === types._in || this$1.isContextual("of")))) { + this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value"); + } else { + decl.init = null; + } + node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")); + if (!this$1.eat(types.comma)) { break } } + return node +}; - // Decode in chunks to avoid "call stack size exceeded". - var res = '' - var i = 0 - while (i < len) { - res += String.fromCharCode.apply( - String, - codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) - ) - } - return res -} +pp$1.parseVarId = function(decl, kind) { + decl.id = this.parseBindingAtom(kind); + this.checkLVal(decl.id, kind, false); +}; -function asciiSlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) +// Parse a function declaration or literal (depending on the +// `isStatement` parameter). - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i] & 0x7F) +pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) { + this.initFunction(node); + if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) + { node.generator = this.eat(types.star); } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + if (isStatement) { + node.id = isStatement === "nullableID" && this.type !== types.name ? null : this.parseIdent(); + if (node.id) { + this.checkLVal(node.id, this.inModule && !this.inFunction ? "let" : "var"); + } } - return ret -} -function latin1Slice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; + this.inGenerator = node.generator; + this.inAsync = node.async; + this.yieldPos = 0; + this.awaitPos = 0; + this.inFunction = true; + this.enterFunctionScope(); - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i]) - } - return ret -} + if (!isStatement) + { node.id = this.type === types.name ? this.parseIdent() : null; } -function hexSlice (buf, start, end) { - var len = buf.length + this.parseFunctionParams(node); + this.parseFunctionBody(node, allowExpressionBody); - if (!start || start < 0) start = 0 - if (!end || end < 0 || end > len) end = len + this.inGenerator = oldInGen; + this.inAsync = oldInAsync; + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.inFunction = oldInFunc; + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +}; - var out = '' - for (var i = start; i < end; ++i) { - out += toHex(buf[i]) - } - return out -} +pp$1.parseFunctionParams = function(node) { + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); +}; -function utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) - } - return res -} +// Parse a class declaration or literal (depending on the +// `isStatement` parameter). -Buffer.prototype.slice = function slice (start, end) { - var len = this.length - start = ~~start - end = end === undefined ? len : ~~end +pp$1.parseClass = function(node, isStatement) { + var this$1 = this; - if (start < 0) { - start += len - if (start < 0) start = 0 - } else if (start > len) { - start = len - } + this.next(); - if (end < 0) { - end += len - if (end < 0) end = 0 - } else if (end > len) { - end = len + this.parseClassId(node, isStatement); + this.parseClassSuper(node); + var classBody = this.startNode(); + var hadConstructor = false; + classBody.body = []; + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + var member = this$1.parseClassMember(classBody); + if (member && member.type === "MethodDefinition" && member.kind === "constructor") { + if (hadConstructor) { this$1.raise(member.start, "Duplicate constructor in the same class"); } + hadConstructor = true; + } } + node.body = this.finishNode(classBody, "ClassBody"); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +}; - if (end < start) end = start +pp$1.parseClassMember = function(classBody) { + var this$1 = this; - var newBuf - if (Buffer.TYPED_ARRAY_SUPPORT) { - newBuf = this.subarray(start, end) - newBuf.__proto__ = Buffer.prototype - } else { - var sliceLen = end - start - newBuf = new Buffer(sliceLen, undefined) - for (var i = 0; i < sliceLen; ++i) { - newBuf[i] = this[i + start] + if (this.eat(types.semi)) { return null } + + var method = this.startNode(); + var tryContextual = function (k, noLineBreak) { + if ( noLineBreak === void 0 ) noLineBreak = false; + + var start = this$1.start, startLoc = this$1.startLoc; + if (!this$1.eatContextual(k)) { return false } + if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true } + if (method.key) { this$1.unexpected(); } + method.computed = false; + method.key = this$1.startNodeAt(start, startLoc); + method.key.name = k; + this$1.finishNode(method.key, "Identifier"); + return false + }; + + method.kind = "method"; + method.static = tryContextual("static"); + var isGenerator = this.eat(types.star); + var isAsync = false; + if (!isGenerator) { + if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); + } else if (tryContextual("get")) { + method.kind = "get"; + } else if (tryContextual("set")) { + method.kind = "set"; } } + if (!method.key) { this.parsePropertyName(method); } + var key = method.key; + if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" || + key.type === "Literal" && key.value === "constructor")) { + if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); } + if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } + if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } + method.kind = "constructor"; + } else if (method.static && key.type === "Identifier" && key.name === "prototype") { + this.raise(key.start, "Classes may not have a static property named prototype"); + } + this.parseClassMethod(classBody, method, isGenerator, isAsync); + if (method.kind === "get" && method.value.params.length !== 0) + { this.raiseRecoverable(method.value.start, "getter should have no params"); } + if (method.kind === "set" && method.value.params.length !== 1) + { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); } + if (method.kind === "set" && method.value.params[0].type === "RestElement") + { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); } + return method +}; - return newBuf -} +pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) { + method.value = this.parseMethod(isGenerator, isAsync); + classBody.body.push(this.finishNode(method, "MethodDefinition")); +}; -/* - * Need to make sure that buffer isn't trying to write out of bounds. - */ -function checkOffset (offset, ext, length) { - if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') - if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') -} +pp$1.parseClassId = function(node, isStatement) { + node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null; +}; -Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) +pp$1.parseClassSuper = function(node) { + node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; +}; - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } +// Parses module export declaration. - return val -} +pp$1.parseExport = function(node, exports) { + var this$1 = this; -Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - checkOffset(offset, byteLength, this.length) + this.next(); + // export * from '...' + if (this.eat(types.star)) { + this.expectContextual("from"); + if (this.type !== types.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") } - - var val = this[offset + --byteLength] - var mul = 1 - while (byteLength > 0 && (mul *= 0x100)) { - val += this[offset + --byteLength] * mul + if (this.eat(types._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart); + var isAsync; + if (this.type === types._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + node.declaration = this.parseFunction(fNode, "nullableID", false, isAsync); + } else if (this.type === types._class) { + var cNode = this.startNode(); + node.declaration = this.parseClass(cNode, "nullableID"); + } else { + node.declaration = this.parseMaybeAssign(); + this.semicolon(); + } + return this.finishNode(node, "ExportDefaultDeclaration") } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(true); + if (node.declaration.type === "VariableDeclaration") + { this.checkVariableExport(exports, node.declaration.declarations); } + else + { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); } + node.specifiers = []; + node.source = null; + } else { // export { x, y as z } [from '...'] + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(exports); + if (this.eatContextual("from")) { + if (this.type !== types.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + } else { + // check for keywords used as local names + for (var i = 0, list = node.specifiers; i < list.length; i += 1) { + var spec = list[i]; - return val -} + this$1.checkUnreserved(spec.local); + } -Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - return this[offset] -} + node.source = null; + } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") +}; -Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return this[offset] | (this[offset + 1] << 8) -} +pp$1.checkExport = function(exports, name, pos) { + if (!exports) { return } + if (has(exports, name)) + { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } + exports[name] = true; +}; -Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return (this[offset] << 8) | this[offset + 1] -} +pp$1.checkPatternExport = function(exports, pat) { + var this$1 = this; -Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) + var type = pat.type; + if (type === "Identifier") + { this.checkExport(exports, pat.name, pat.start); } + else if (type === "ObjectPattern") + { for (var i = 0, list = pat.properties; i < list.length; i += 1) + { + var prop = list[i]; - return ((this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + - (this[offset + 3] * 0x1000000) -} + this$1.checkPatternExport(exports, prop); + } } + else if (type === "ArrayPattern") + { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { + var elt = list$1[i$1]; -Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) + if (elt) { this$1.checkPatternExport(exports, elt); } + } } + else if (type === "Property") + { this.checkPatternExport(exports, pat.value); } + else if (type === "AssignmentPattern") + { this.checkPatternExport(exports, pat.left); } + else if (type === "RestElement") + { this.checkPatternExport(exports, pat.argument); } + else if (type === "ParenthesizedExpression") + { this.checkPatternExport(exports, pat.expression); } +}; - return (this[offset] * 0x1000000) + - ((this[offset + 1] << 16) | - (this[offset + 2] << 8) | - this[offset + 3]) -} +pp$1.checkVariableExport = function(exports, decls) { + var this$1 = this; -Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) + if (!exports) { return } + for (var i = 0, list = decls; i < list.length; i += 1) + { + var decl = list[i]; - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul + this$1.checkPatternExport(exports, decl.id); } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) +}; - return val -} +pp$1.shouldParseExportStatement = function() { + return this.type.keyword === "var" || + this.type.keyword === "const" || + this.type.keyword === "class" || + this.type.keyword === "function" || + this.isLet() || + this.isAsyncFunction() +}; -Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) +// Parses a comma-separated list of module exports. - var i = byteLength - var mul = 1 - var val = this[offset + --i] - while (i > 0 && (mul *= 0x100)) { - val += this[offset + --i] * mul +pp$1.parseExportSpecifiers = function(exports) { + var this$1 = this; + + var nodes = [], first = true; + // export { x, y as z } [from '...'] + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this$1.expect(types.comma); + if (this$1.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var node = this$1.startNode(); + node.local = this$1.parseIdent(true); + node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local; + this$1.checkExport(exports, node.exported.name, node.exported.start); + nodes.push(this$1.finishNode(node, "ExportSpecifier")); } - mul *= 0x80 + return nodes +}; - if (val >= mul) val -= Math.pow(2, 8 * byteLength) +// Parses import declaration. - return val -} +pp$1.parseImport = function(node) { + this.next(); + // import '...' + if (this.type === types.string) { + node.specifiers = empty; + node.source = this.parseExprAtom(); + } else { + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected(); + } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration") +}; -Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - if (!(this[offset] & 0x80)) return (this[offset]) - return ((0xff - this[offset] + 1) * -1) -} +// Parses a comma-separated list of module imports. -Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset] | (this[offset + 1] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} +pp$1.parseImportSpecifiers = function() { + var this$1 = this; -Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset + 1] | (this[offset] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} + var nodes = [], first = true; + if (this.type === types.name) { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode(); + node.local = this.parseIdent(); + this.checkLVal(node.local, "let"); + nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); + if (!this.eat(types.comma)) { return nodes } + } + if (this.type === types.star) { + var node$1 = this.startNode(); + this.next(); + this.expectContextual("as"); + node$1.local = this.parseIdent(); + this.checkLVal(node$1.local, "let"); + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); + return nodes + } + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this$1.expect(types.comma); + if (this$1.afterTrailingComma(types.braceR)) { break } + } else { first = false; } -Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) + var node$2 = this$1.startNode(); + node$2.imported = this$1.parseIdent(true); + if (this$1.eatContextual("as")) { + node$2.local = this$1.parseIdent(); + } else { + this$1.checkUnreserved(node$2.imported); + node$2.local = node$2.imported; + } + this$1.checkLVal(node$2.local, "let"); + nodes.push(this$1.finishNode(node$2, "ImportSpecifier")); + } + return nodes +}; - return (this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16) | - (this[offset + 3] << 24) -} +// Set `ExpressionStatement#directive` property for directive prologues. +pp$1.adaptDirectivePrologue = function(statements) { + for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { + statements[i].directive = statements[i].expression.raw.slice(1, -1); + } +}; +pp$1.isDirectiveCandidate = function(statement) { + return ( + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" && + typeof statement.expression.value === "string" && + // Reject parenthesized strings. + (this.input[statement.start] === "\"" || this.input[statement.start] === "'") + ) +}; -Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) +var pp$2 = Parser.prototype; - return (this[offset] << 24) | - (this[offset + 1] << 16) | - (this[offset + 2] << 8) | - (this[offset + 3]) -} +// Convert existing expression atom to assignable pattern +// if possible. -Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, true, 23, 4) -} +pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) { + var this$1 = this; -Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, false, 23, 4) -} + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + { this.raise(node.start, "Can not use 'await' as identifier inside an async function"); } + break -Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, true, 52, 8) -} + case "ObjectPattern": + case "ArrayPattern": + case "RestElement": + break -Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, false, 52, 8) -} + case "ObjectExpression": + node.type = "ObjectPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; -function checkInt (buf, value, offset, ext, max, min) { - if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') - if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') - if (offset + ext > buf.length) throw new RangeError('Index out of range') -} + this$1.toAssignable(prop, isBinding); + // Early error: + // AssignmentRestProperty[Yield, Await] : + // `...` DestructuringAssignmentTarget[Yield, Await] + // + // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. + if ( + prop.type === "RestElement" && + (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + ) { + this$1.raise(prop.argument.start, "Unexpected token"); + } + } + break -Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } + case "Property": + // AssignmentProperty has type === "Property" + if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } + this.toAssignable(node.value, isBinding); + break - var mul = 1 - var i = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } + case "ArrayExpression": + node.type = "ArrayPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + this.toAssignableList(node.elements, isBinding); + break - return offset + byteLength -} + case "SpreadElement": + node.type = "RestElement"; + this.toAssignable(node.argument, isBinding); + if (node.argument.type === "AssignmentPattern") + { this.raise(node.argument.start, "Rest elements cannot have a default value"); } + break -Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } + case "AssignmentExpression": + if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } + node.type = "AssignmentPattern"; + delete node.operator; + this.toAssignable(node.left, isBinding); + // falls through to AssignmentPattern - var i = byteLength - 1 - var mul = 1 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } + case "AssignmentPattern": + break - return offset + byteLength -} + case "ParenthesizedExpression": + this.toAssignable(node.expression, isBinding); + break -Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - this[offset] = (value & 0xff) - return offset + 1 -} + case "MemberExpression": + if (!isBinding) { break } -function objectWriteUInt16 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { - buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> - (littleEndian ? i : 1 - i) * 8 - } -} + default: + this.raise(node.start, "Assigning to rvalue"); + } + } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + return node +}; -Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} +// Convert list of expression atoms to binding list. -Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} +pp$2.toAssignableList = function(exprList, isBinding) { + var this$1 = this; -function objectWriteUInt32 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffffffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { - buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + var end = exprList.length; + for (var i = 0; i < end; i++) { + var elt = exprList[i]; + if (elt) { this$1.toAssignable(elt, isBinding); } } -} - -Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset + 3] = (value >>> 24) - this[offset + 2] = (value >>> 16) - this[offset + 1] = (value >>> 8) - this[offset] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, true) + if (end) { + var last = exprList[end - 1]; + if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + { this.unexpected(last.argument.start); } } - return offset + 4 -} + return exprList +}; -Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} +// Parses spread element. -Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) +pp$2.parseSpread = function(refDestructuringErrors) { + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeAssign(false, refDestructuringErrors); + return this.finishNode(node, "SpreadElement") +}; - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } +pp$2.parseRestBinding = function() { + var node = this.startNode(); + this.next(); - var i = 0 - var mul = 1 - var sub = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } + // RestElement inside of a function parameter must be an identifier + if (this.options.ecmaVersion === 6 && this.type !== types.name) + { this.unexpected(); } - return offset + byteLength -} + node.argument = this.parseBindingAtom(); -Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) + return this.finishNode(node, "RestElement") +}; - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } +// Parses lvalue (assignable) atom. - var i = byteLength - 1 - var mul = 1 - var sub = 0 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { - sub = 1 +pp$2.parseBindingAtom = function() { + if (this.options.ecmaVersion >= 6) { + switch (this.type) { + case types.bracketL: + var node = this.startNode(); + this.next(); + node.elements = this.parseBindingList(types.bracketR, true, true); + return this.finishNode(node, "ArrayPattern") + + case types.braceL: + return this.parseObj(true) } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } + return this.parseIdent() +}; - return offset + byteLength -} - -Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - if (value < 0) value = 0xff + value + 1 - this[offset] = (value & 0xff) - return offset + 1 -} +pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) { + var this$1 = this; -Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) + var elts = [], first = true; + while (!this.eat(close)) { + if (first) { first = false; } + else { this$1.expect(types.comma); } + if (allowEmpty && this$1.type === types.comma) { + elts.push(null); + } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { + break + } else if (this$1.type === types.ellipsis) { + var rest = this$1.parseRestBinding(); + this$1.parseBindingListItem(rest); + elts.push(rest); + if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } + this$1.expect(close); + break + } else { + var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc); + this$1.parseBindingListItem(elem); + elts.push(elem); + } } - return offset + 2 -} + return elts +}; -Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} +pp$2.parseBindingListItem = function(param) { + return param +}; -Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - this[offset + 2] = (value >>> 16) - this[offset + 3] = (value >>> 24) - } else { - objectWriteUInt32(this, value, offset, true) - } - return offset + 4 -} +// Parses assignment pattern around given atom if possible. -Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (value < 0) value = 0xffffffff + value + 1 - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} +pp$2.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom(); + if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.right = this.parseMaybeAssign(); + return this.finishNode(node, "AssignmentPattern") +}; -function checkIEEE754 (buf, value, offset, ext, max, min) { - if (offset + ext > buf.length) throw new RangeError('Index out of range') - if (offset < 0) throw new RangeError('Index out of range') -} +// Verify that a node is an lval — something that can be assigned +// to. +// bindingType can be either: +// 'var' indicating that the lval creates a 'var' binding +// 'let' indicating that the lval creates a lexical ('let' or 'const') binding +// 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references -function writeFloat (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) - } - ieee754.write(buf, value, offset, littleEndian, 23, 4) - return offset + 4 -} +pp$2.checkLVal = function(expr, bindingType, checkClashes) { + var this$1 = this; -Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) -} + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } + if (checkClashes) { + if (has(checkClashes, expr.name)) + { this.raiseRecoverable(expr.start, "Argument name clash"); } + checkClashes[expr.name] = true; + } + if (bindingType && bindingType !== "none") { + if ( + bindingType === "var" && !this.canDeclareVarName(expr.name) || + bindingType !== "var" && !this.canDeclareLexicalName(expr.name) + ) { + this.raiseRecoverable(expr.start, ("Identifier '" + (expr.name) + "' has already been declared")); + } + if (bindingType === "var") { + this.declareVarName(expr.name); + } else { + this.declareLexicalName(expr.name); + } + } + break -Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { - return writeFloat(this, value, offset, false, noAssert) -} + case "MemberExpression": + if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); } + break -function writeDouble (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + case "ObjectPattern": + for (var i = 0, list = expr.properties; i < list.length; i += 1) + { + var prop = list[i]; + + this$1.checkLVal(prop, bindingType, checkClashes); } - ieee754.write(buf, value, offset, littleEndian, 52, 8) - return offset + 8 -} + break -Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) -} + case "Property": + // AssignmentProperty has type === "Property" + this.checkLVal(expr.value, bindingType, checkClashes); + break -Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) -} + case "ArrayPattern": + for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { + var elem = list$1[i$1]; -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function copy (target, targetStart, start, end) { - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (targetStart >= target.length) targetStart = target.length - if (!targetStart) targetStart = 0 - if (end > 0 && end < start) end = start + if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); } + } + break - // Copy 0 bytes; we're done - if (end === start) return 0 - if (target.length === 0 || this.length === 0) return 0 + case "AssignmentPattern": + this.checkLVal(expr.left, bindingType, checkClashes); + break - // Fatal error conditions - if (targetStart < 0) { - throw new RangeError('targetStart out of bounds') - } - if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') - if (end < 0) throw new RangeError('sourceEnd out of bounds') + case "RestElement": + this.checkLVal(expr.argument, bindingType, checkClashes); + break - // Are we oob? - if (end > this.length) end = this.length - if (target.length - targetStart < end - start) { - end = target.length - targetStart + start + case "ParenthesizedExpression": + this.checkLVal(expr.expression, bindingType, checkClashes); + break + + default: + this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue"); } +}; - var len = end - start - var i +// A recursive descent parser operates by defining functions for all +// syntactic elements, and recursively calling those, each function +// advancing the input stream and returning an AST node. Precedence +// of constructs (for example, the fact that `!x[1]` means `!(x[1])` +// instead of `(!x)[1]` is handled by the fact that the parser +// function that parses unary prefix operators is called first, and +// in turn calls the function that parses `[]` subscripts — that +// way, it'll receive the node for `x[1]` already parsed, and wraps +// *that* in the unary operator node. +// +// Acorn uses an [operator precedence parser][opp] to handle binary +// operator precedence, because it is much more compact than using +// the technique outlined above, which uses different, nesting +// functions to specify precedence, for all of the ten binary +// precedence levels that JavaScript defines. +// +// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser - if (this === target && start < targetStart && targetStart < end) { - // descending copy from end - for (i = len - 1; i >= 0; --i) { - target[i + targetStart] = this[i + start] - } - } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { - // ascending copy from start - for (i = 0; i < len; ++i) { - target[i + targetStart] = this[i + start] - } - } else { - Uint8Array.prototype.set.call( - target, - this.subarray(start, start + len), - targetStart - ) - } +var pp$3 = Parser.prototype; - return len -} +// Check if property name clashes with already added. +// Object/class getters and setters are not allowed to clash — +// either with each other or with an init property — and in +// strict mode, init properties are also not allowed to be repeated. -// Usage: -// buffer.fill(number[, offset[, end]]) -// buffer.fill(buffer[, offset[, end]]) -// buffer.fill(string[, offset[, end]][, encoding]) -Buffer.prototype.fill = function fill (val, start, end, encoding) { - // Handle string cases: - if (typeof val === 'string') { - if (typeof start === 'string') { - encoding = start - start = 0 - end = this.length - } else if (typeof end === 'string') { - encoding = end - end = this.length - } - if (val.length === 1) { - var code = val.charCodeAt(0) - if (code < 256) { - val = code +pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) { + if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") + { return } + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + { return } + var key = prop.key; + var name; + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) { + if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; } + // Backwards-compat kludge. Can be removed in version 6.0 + else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } } + propHash.proto = true; } - if (encoding !== undefined && typeof encoding !== 'string') { - throw new TypeError('encoding must be a string') - } - if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { - throw new TypeError('Unknown encoding: ' + encoding) - } - } else if (typeof val === 'number') { - val = val & 255 - } - - // Invalid ranges are not set to a default, so can range check early. - if (start < 0 || this.length < start || this.length < end) { - throw new RangeError('Out of range index') - } - - if (end <= start) { - return this + return } - - start = start >>> 0 - end = end === undefined ? this.length : end >>> 0 - - if (!val) val = 0 - - var i - if (typeof val === 'number') { - for (i = start; i < end; ++i) { - this[i] = val + name = "$" + name; + var other = propHash[name]; + if (other) { + var redefinition; + if (kind === "init") { + redefinition = this.strict && other.init || other.get || other.set; + } else { + redefinition = other.init || other[kind]; } + if (redefinition) + { this.raiseRecoverable(key.start, "Redefinition of property"); } } else { - var bytes = Buffer.isBuffer(val) - ? val - : utf8ToBytes(new Buffer(val, encoding).toString()) - var len = bytes.length - for (i = 0; i < end - start; ++i) { - this[i + start] = bytes[i % len] - } + other = propHash[name] = { + init: false, + get: false, + set: false + }; } + other[kind] = true; +}; - return this -} +// ### Expression parsing -// HELPER FUNCTIONS -// ================ +// These nest, from the most general expression type at the top to +// 'atomic', nondivisible expression types at the bottom. Most of +// the functions will simply let the function(s) below them parse, +// and, *if* the syntactic construct they handle is present, wrap +// the AST node that the inner parser gave them in another node. -var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g +// Parse a full expression. The optional arguments are used to +// forbid the `in` operator (in for loops initalization expressions) +// and provide reference for storing '=' operator inside shorthand +// property assignment in contexts where both object expression +// and object pattern might appear (so it's possible to raise +// delayed syntax error at correct position). -function base64clean (str) { - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = stringtrim(str).replace(INVALID_BASE64_RE, '') - // Node converts strings with length < 2 to '' - if (str.length < 2) return '' - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + '=' - } - return str -} +pp$3.parseExpression = function(noIn, refDestructuringErrors) { + var this$1 = this; -function stringtrim (str) { - if (str.trim) return str.trim() - return str.replace(/^\s+|\s+$/g, '') -} + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeAssign(noIn, refDestructuringErrors); + if (this.type === types.comma) { + var node = this.startNodeAt(startPos, startLoc); + node.expressions = [expr]; + while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); } + return this.finishNode(node, "SequenceExpression") + } + return expr +}; -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) -} +// Parse an assignment expression. This includes applications of +// operators like `+=`. -function utf8ToBytes (string, units) { - units = units || Infinity - var codePoint - var length = string.length - var leadSurrogate = null - var bytes = [] +pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + if (this.inGenerator && this.isContextual("yield")) { return this.parseYield() } - for (var i = 0; i < length; ++i) { - codePoint = string.charCodeAt(i) + var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1; + if (refDestructuringErrors) { + oldParenAssign = refDestructuringErrors.parenthesizedAssign; + oldTrailingComma = refDestructuringErrors.trailingComma; + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; + } else { + refDestructuringErrors = new DestructuringErrors; + ownDestructuringErrors = true; + } - // is surrogate component - if (codePoint > 0xD7FF && codePoint < 0xE000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xDBFF) { - // unexpected trail - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } + var startPos = this.start, startLoc = this.startLoc; + if (this.type === types.parenL || this.type === types.name) + { this.potentialArrowAt = this.start; } + var left = this.parseMaybeConditional(noIn, refDestructuringErrors); + if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } + if (this.type.isAssign) { + var node = this.startNodeAt(startPos, startLoc); + node.operator = this.value; + node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left; + if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); } + refDestructuringErrors.shorthandAssign = -1; // reset because shorthand default was used correctly + this.checkLVal(left); + this.next(); + node.right = this.parseMaybeAssign(noIn); + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } + } + if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } + if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } + return left +}; - // valid lead - leadSurrogate = codePoint +// Parse a ternary conditional (`?:`) operator. - continue - } +pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprOps(noIn, refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + if (this.eat(types.question)) { + var node = this.startNodeAt(startPos, startLoc); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + this.expect(types.colon); + node.alternate = this.parseMaybeAssign(noIn); + return this.finishNode(node, "ConditionalExpression") + } + return expr +}; - // 2 leads in a row - if (codePoint < 0xDC00) { - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - leadSurrogate = codePoint - continue - } +// Start the precedence parser. - // valid surrogate pair - codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - } +pp$3.parseExprOps = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeUnary(refDestructuringErrors, false); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn) +}; - leadSurrogate = null +// Parse binary operators with the operator precedence parsing +// algorithm. `left` is the left-hand side of the operator. +// `minPrec` provides context that allows the function to stop and +// defer further parser to one of its callers when it encounters an +// operator that has a lower precedence than the set it is parsing. - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) break - bytes.push(codePoint) - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) break - bytes.push( - codePoint >> 0x6 | 0xC0, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) break - bytes.push( - codePoint >> 0xC | 0xE0, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) break - bytes.push( - codePoint >> 0x12 | 0xF0, - codePoint >> 0xC & 0x3F | 0x80, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else { - throw new Error('Invalid code point') +pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { + var prec = this.type.binop; + if (prec != null && (!noIn || this.type !== types._in)) { + if (prec > minPrec) { + var logical = this.type === types.logicalOR || this.type === types.logicalAND; + var op = this.value; + this.next(); + var startPos = this.start, startLoc = this.startLoc; + var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn); + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical); + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) } } + return left +}; - return bytes -} +pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.operator = op; + node.right = right; + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") +}; -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} +// Parse unary operators, both prefix and postfix. -function utf16leToBytes (str, units) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - if ((units -= 2) < 0) break +pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + var this$1 = this; - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) + var startPos = this.start, startLoc = this.startLoc, expr; + if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) { + expr = this.parseAwait(); + sawUnary = true; + } else if (this.type.prefix) { + var node = this.startNode(), update = this.type === types.incDec; + node.operator = this.value; + node.prefix = true; + this.next(); + node.argument = this.parseMaybeUnary(null, true); + this.checkExpressionErrors(refDestructuringErrors, true); + if (update) { this.checkLVal(node.argument); } + else if (this.strict && node.operator === "delete" && + node.argument.type === "Identifier") + { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } + else { sawUnary = true; } + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); + } else { + expr = this.parseExprSubscripts(refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this$1.startNodeAt(startPos, startLoc); + node$1.operator = this$1.value; + node$1.prefix = false; + node$1.argument = expr; + this$1.checkLVal(expr); + this$1.next(); + expr = this$1.finishNode(node$1, "UpdateExpression"); + } } - return byteArray -} - -function base64ToBytes (str) { - return base64.toByteArray(base64clean(str)) -} + if (!sawUnary && this.eat(types.starstar)) + { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) } + else + { return expr } +}; -function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; ++i) { - if ((i + offset >= dst.length) || (i >= src.length)) break - dst[i + offset] = src[i] - } - return i -} +// Parse call, dot, and `[]`-subscript expressions. -function isnan (val) { - return val !== val // eslint-disable-line no-self-compare -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"base64-js":48,"ieee754":87,"isarray":90}],51:[function(require,module,exports){ -(function (Buffer){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +pp$3.parseExprSubscripts = function(refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprAtom(refDestructuringErrors); + var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")"; + if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr } + var result = this.parseSubscripts(expr, startPos, startLoc); + if (refDestructuringErrors && result.type === "MemberExpression") { + if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } + if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } + } + return result +}; -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. +pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { + var this$1 = this; -function isArray(arg) { - if (Array.isArray) { - return Array.isArray(arg); + var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async"; + for (var computed = (void 0);;) { + if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) { + var node = this$1.startNodeAt(startPos, startLoc); + node.object = base; + node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true); + node.computed = !!computed; + if (computed) { this$1.expect(types.bracketR); } + base = this$1.finishNode(node, "MemberExpression"); + } else if (!noCalls && this$1.eat(types.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos; + this$1.yieldPos = 0; + this$1.awaitPos = 0; + var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors); + if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) { + this$1.checkPatternErrors(refDestructuringErrors, false); + this$1.checkYieldAwaitInDefaultParams(); + this$1.yieldPos = oldYieldPos; + this$1.awaitPos = oldAwaitPos; + return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true) + } + this$1.checkExpressionErrors(refDestructuringErrors, true); + this$1.yieldPos = oldYieldPos || this$1.yieldPos; + this$1.awaitPos = oldAwaitPos || this$1.awaitPos; + var node$1 = this$1.startNodeAt(startPos, startLoc); + node$1.callee = base; + node$1.arguments = exprList; + base = this$1.finishNode(node$1, "CallExpression"); + } else if (this$1.type === types.backQuote) { + var node$2 = this$1.startNodeAt(startPos, startLoc); + node$2.tag = base; + node$2.quasi = this$1.parseTemplate({isTagged: true}); + base = this$1.finishNode(node$2, "TaggedTemplateExpression"); + } else { + return base + } } - return objectToString(arg) === '[object Array]'; -} -exports.isArray = isArray; +}; -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; +// Parse an atomic expression — either a single token that is an +// expression, an expression started by a keyword like `function` or +// `new`, or an expression wrapped in punctuation like `()`, `[]`, +// or `{}`. -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; +pp$3.parseExprAtom = function(refDestructuringErrors) { + var node, canBeArrow = this.potentialArrowAt === this.start; + switch (this.type) { + case types._super: + if (!this.inFunction) + { this.raise(this.start, "'super' outside of function or class"); } + node = this.startNode(); + this.next(); + // The `super` keyword can appear at below: + // SuperProperty: + // super [ Expression ] + // super . IdentifierName + // SuperCall: + // super Arguments + if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL) + { this.unexpected(); } + return this.finishNode(node, "Super") -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; + case types._this: + node = this.startNode(); + this.next(); + return this.finishNode(node, "ThisExpression") -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; + case types.name: + var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; + var id = this.parseIdent(this.type !== types.name); + if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function)) + { return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) } + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(types.arrow)) + { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) } + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) { + id = this.parseIdent(); + if (this.canInsertSemicolon() || !this.eat(types.arrow)) + { this.unexpected(); } + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) + } + } + return id -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; + case types.regexp: + var value = this.value; + node = this.parseLiteral(value.value); + node.regex = {pattern: value.pattern, flags: value.flags}; + return node -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; + case types.num: case types.string: + return this.parseLiteral(this.value) -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; + case types._null: case types._true: case types._false: + node = this.startNode(); + node.value = this.type === types._null ? null : this.type === types._true; + node.raw = this.type.keyword; + this.next(); + return this.finishNode(node, "Literal") -function isRegExp(re) { - return objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; + case types.parenL: + var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow); + if (refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) + { refDestructuringErrors.parenthesizedAssign = start; } + if (refDestructuringErrors.parenthesizedBind < 0) + { refDestructuringErrors.parenthesizedBind = start; } + } + return expr -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; + case types.bracketL: + node = this.startNode(); + this.next(); + node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors); + return this.finishNode(node, "ArrayExpression") -function isDate(d) { - return objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; + case types.braceL: + return this.parseObj(false, refDestructuringErrors) -function isError(e) { - return (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; + case types._function: + node = this.startNode(); + this.next(); + return this.parseFunction(node, false) -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; + case types._class: + return this.parseClass(this.startNode(), false) -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; + case types._new: + return this.parseNew() -exports.isBuffer = Buffer.isBuffer; + case types.backQuote: + return this.parseTemplate() -function objectToString(o) { - return Object.prototype.toString.call(o); -} + default: + this.unexpected(); + } +}; -}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) -},{"../../is-buffer/index.js":89}],52:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +pp$3.parseLiteral = function(value) { + var node = this.startNode(); + node.value = value; + node.raw = this.input.slice(this.start, this.end); + this.next(); + return this.finishNode(node, "Literal") +}; -function EventEmitter() { - this._events = this._events || {}; - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; +pp$3.parseParenExpression = function() { + this.expect(types.parenL); + var val = this.parseExpression(); + this.expect(types.parenR); + return val }; -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; +pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { + var this$1 = this; - if (!this._events) - this._events = {}; + var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; + if (this.options.ecmaVersion >= 6) { + this.next(); - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event + var innerStartPos = this.start, innerStartLoc = this.startLoc; + var exprList = [], first = true, lastIsComma = false; + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; + this.yieldPos = 0; + this.awaitPos = 0; + while (this.type !== types.parenR) { + first ? first = false : this$1.expect(types.comma); + if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) { + lastIsComma = true; + break + } else if (this$1.type === types.ellipsis) { + spreadStart = this$1.start; + exprList.push(this$1.parseParenItem(this$1.parseRestBinding())); + if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } + break } else { - // At least give some kind of context to the user - var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); - err.context = er; - throw err; + exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)); } } - } + var innerEndPos = this.start, innerEndLoc = this.startLoc; + this.expect(types.parenR); - handler = this._events[type]; + if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + return this.parseParenArrowList(startPos, startLoc, exprList) + } - if (isUndefined(handler)) - return false; + if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } + if (spreadStart) { this.unexpected(spreadStart); } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - args = Array.prototype.slice.call(arguments, 1); - handler.apply(this, args); + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc); + val.expressions = exprList; + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); + } else { + val = exprList[0]; } - } else if (isObject(handler)) { - args = Array.prototype.slice.call(arguments, 1); - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); + } else { + val = this.parseParenExpression(); } - return true; + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc); + par.expression = val; + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val + } }; -EventEmitter.prototype.addListener = function(type, listener) { - var m; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events) - this._events = {}; +pp$3.parseParenItem = function(item) { + return item +}; - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); +pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) +}; - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; +// New's precedence is slightly tricky. It must allow its argument to +// be a `[]` or dot subscript expression, but not a call — at least, +// not without wrapping it in parentheses. Thus, it uses the noCalls +// argument to parseSubscripts to prevent it from consuming the +// argument list. - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; - } +var empty$1 = []; - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } - } +pp$3.parseNew = function() { + var node = this.startNode(); + var meta = this.parseIdent(true); + if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) { + node.meta = meta; + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + if (node.property.name !== "target" || containsEsc) + { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); } + if (!this.inFunction) + { this.raiseRecoverable(node.start, "new.target can only be used in functions"); } + return this.finishNode(node, "MetaProperty") } - - return this; + var startPos = this.start, startLoc = this.startLoc; + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); + if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); } + else { node.arguments = empty$1; } + return this.finishNode(node, "NewExpression") }; -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - var fired = false; +// Parse template expression. - function g() { - this.removeListener(type, g); +pp$3.parseTemplateElement = function(ref) { + var isTagged = ref.isTagged; - if (!fired) { - fired = true; - listener.apply(this, arguments); + var elem = this.startNode(); + if (this.type === types.invalidTemplate) { + if (!isTagged) { + this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); } + elem.value = { + raw: this.value, + cooked: null + }; + } else { + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), + cooked: this.value + }; } + this.next(); + elem.tail = this.type === types.backQuote; + return this.finishNode(elem, "TemplateElement") +}; - g.listener = listener; - this.on(type, g); +pp$3.parseTemplate = function(ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; - return this; + var node = this.startNode(); + this.next(); + node.expressions = []; + var curElt = this.parseTemplateElement({isTagged: isTagged}); + node.quasis = [curElt]; + while (!curElt.tail) { + this$1.expect(types.dollarBraceL); + node.expressions.push(this$1.parseExpression()); + this$1.expect(types.braceR); + node.quasis.push(curElt = this$1.parseTemplateElement({isTagged: isTagged})); + } + this.next(); + return this.finishNode(node, "TemplateLiteral") }; -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); +pp$3.isAsyncProp = function(prop) { + return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && + (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) && + !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +}; - if (!this._events || !this._events[type]) - return this; +// Parse an object literal or binding pattern. - list = this._events[type]; - length = list.length; - position = -1; - - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); - - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; - } - } - - if (position < 0) - return this; +pp$3.parseObj = function(isPattern, refDestructuringErrors) { + var this$1 = this; - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); - } + var node = this.startNode(), first = true, propHash = {}; + node.properties = []; + this.next(); + while (!this.eat(types.braceR)) { + if (!first) { + this$1.expect(types.comma); + if (this$1.afterTrailingComma(types.braceR)) { break } + } else { first = false; } - if (this._events.removeListener) - this.emit('removeListener', type, listener); + var prop = this$1.parseProperty(isPattern, refDestructuringErrors); + if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); } + node.properties.push(prop); } - - return this; + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") }; -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; - - if (!this._events) - return this; - - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; +pp$3.parseProperty = function(isPattern, refDestructuringErrors) { + var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; + if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) { + if (isPattern) { + prop.argument = this.parseIdent(false); + if (this.type === types.comma) { + this.raise(this.start, "Comma is not permitted after the rest element"); + } + return this.finishNode(prop, "RestElement") + } + // To disallow parenthesized identifier via `this.toAssignable()`. + if (this.type === types.parenL && refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0) { + refDestructuringErrors.parenthesizedAssign = this.start; + } + if (refDestructuringErrors.parenthesizedBind < 0) { + refDestructuringErrors.parenthesizedBind = this.start; + } + } + // Parse argument. + prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); + // To disallow trailing comma via `this.toAssignable()`. + if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { + refDestructuringErrors.trailingComma = this.start; + } + // Finish + return this.finishNode(prop, "SpreadElement") } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); + if (this.options.ecmaVersion >= 6) { + prop.method = false; + prop.shorthand = false; + if (isPattern || refDestructuringErrors) { + startPos = this.start; + startLoc = this.startLoc; } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; + if (!isPattern) + { isGenerator = this.eat(types.star); } } - - listeners = this._events[type]; - - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); + var containsEsc = this.containsEsc; + this.parsePropertyName(prop); + if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); + this.parsePropertyName(prop, refDestructuringErrors); + } else { + isAsync = false; } - delete this._events[type]; - - return this; + this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); + return this.finishNode(prop, "Property") }; -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; +pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { + if ((isGenerator || isAsync) && this.type === types.colon) + { this.unexpected(); } -EventEmitter.prototype.listenerCount = function(type) { - if (this._events) { - var evlistener = this._events[type]; + if (this.eat(types.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); + prop.kind = "init"; + } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) { + if (isPattern) { this.unexpected(); } + prop.kind = "init"; + prop.method = true; + prop.value = this.parseMethod(isGenerator, isAsync); + } else if (!isPattern && !containsEsc && + this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type !== types.comma && this.type !== types.braceR)) { + if (isGenerator || isAsync) { this.unexpected(); } + prop.kind = prop.key.name; + this.parsePropertyName(prop); + prop.value = this.parseMethod(false); + var paramCount = prop.kind === "get" ? 0 : 1; + if (prop.value.params.length !== paramCount) { + var start = prop.value.start; + if (prop.kind === "get") + { this.raiseRecoverable(start, "getter should have no params"); } + else + { this.raiseRecoverable(start, "setter should have exactly one param"); } + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } + } + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + this.checkUnreserved(prop.key); + prop.kind = "init"; + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); + } else if (this.type === types.eq && refDestructuringErrors) { + if (refDestructuringErrors.shorthandAssign < 0) + { refDestructuringErrors.shorthandAssign = this.start; } + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); + } else { + prop.value = prop.key; + } + prop.shorthand = true; + } else { this.unexpected(); } +}; - if (isFunction(evlistener)) - return 1; - else if (evlistener) - return evlistener.length; +pp$3.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(types.bracketL)) { + prop.computed = true; + prop.key = this.parseMaybeAssign(); + this.expect(types.bracketR); + return prop.key + } else { + prop.computed = false; + } } - return 0; + return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true) }; -EventEmitter.listenerCount = function(emitter, type) { - return emitter.listenerCount(type); +// Initialize empty function node. + +pp$3.initFunction = function(node) { + node.id = null; + if (this.options.ecmaVersion >= 6) { + node.generator = false; + node.expression = false; + } + if (this.options.ecmaVersion >= 8) + { node.async = false; } }; -function isFunction(arg) { - return typeof arg === 'function'; -} +// Parse object or class method. -function isNumber(arg) { - return typeof arg === 'number'; -} +pp$3.parseMethod = function(isGenerator, isAsync) { + var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } -function isUndefined(arg) { - return arg === void 0; -} + this.inGenerator = node.generator; + this.inAsync = node.async; + this.yieldPos = 0; + this.awaitPos = 0; + this.inFunction = true; + this.enterFunctionScope(); -},{}],53:[function(require,module,exports){ -'use strict'; + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + this.parseFunctionBody(node, false); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + this.inGenerator = oldInGen; + this.inAsync = oldInAsync; + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.inFunction = oldInFunc; + return this.finishNode(node, "FunctionExpression") +}; -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +// Parse arrow function expression with given parameters. -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +pp$3.parseArrowExpression = function(node, params, isAsync) { + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; -var FunctionBuilderBase = require('../function-builder-base'); -var CPUFunctionNode = require('./function-node'); + this.enterFunctionScope(); + this.initFunction(node); + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } -/** - * @class CPUFunctionBuilder - * - * @extends FunctionBuilderBase - * - * @desc Builds functions to execute on CPU from JavaScript function Strings - * - */ -module.exports = function (_FunctionBuilderBase) { - _inherits(CPUFunctionBuilder, _FunctionBuilderBase); + this.inGenerator = false; + this.inAsync = node.async; + this.yieldPos = 0; + this.awaitPos = 0; + this.inFunction = true; - function CPUFunctionBuilder() { - _classCallCheck(this, CPUFunctionBuilder); + node.params = this.toAssignableList(params, true); + this.parseFunctionBody(node, true); - var _this = _possibleConstructorReturn(this, (CPUFunctionBuilder.__proto__ || Object.getPrototypeOf(CPUFunctionBuilder)).call(this)); + this.inGenerator = oldInGen; + this.inAsync = oldInAsync; + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.inFunction = oldInFunc; + return this.finishNode(node, "ArrowFunctionExpression") +}; - _this.Node = CPUFunctionNode; - return _this; - } +// Parse function body and check parameters. - return CPUFunctionBuilder; -}(FunctionBuilderBase); -},{"../function-builder-base":58,"./function-node":54}],54:[function(require,module,exports){ -'use strict'; +pp$3.parseFunctionBody = function(node, isArrowFunction) { + var isExpression = isArrowFunction && this.type !== types.braceL; + var oldStrict = this.strict, useStrict = false; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + if (isExpression) { + node.body = this.parseMaybeAssign(); + node.expression = true; + this.checkParams(node, false); + } else { + var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); + if (!oldStrict || nonSimple) { + useStrict = this.strictDirective(this.end); + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldLabels = this.labels; + this.labels = []; + if (useStrict) { this.strict = true; } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + // Add the params to varDeclaredNames to ensure that an error is thrown + // if a let/const declaration in the function clashes with one of the params. + this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params)); + node.body = this.parseBlock(false); + node.expression = false; + this.adaptDirectivePrologue(node.body.body); + this.labels = oldLabels; + } + this.exitFunctionScope(); -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + if (this.strict && node.id) { + // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' + this.checkLVal(node.id, "none"); + } + this.strict = oldStrict; +}; -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +pp$3.isSimpleParamList = function(params) { + for (var i = 0, list = params; i < list.length; i += 1) + { + var param = list[i]; -var BaseFunctionNode = require('../function-node-base'); -var utils = require('../../core/utils'); + if (param.type !== "Identifier") { return false + } } + return true +}; -/** - * @class CPUFunctionNode - * - * @extends BaseFunctionNode# - * - * @desc [INTERNAL] Represents a single function, inside JS - * - *

This handles all the raw state, converted state, etc. Of a single function.

- * - * @prop functionName - {String} Name of the function - * @prop jsFunction - {Function} The JS Function the node represents - * @prop jsFunctionString - {String} jsFunction.toString() - * @prop paramNames - {String[]} Parameter names of the function - * @prop paramTypes - {String[]} Shader land parameters type assumption - * @prop isRootKernel - {Boolean} Special indicator, for kernel function - * @prop webglFunctionString - {String} webgl converted function string - * @prop openglFunctionString - {String} opengl converted function string - * @prop calledFunctions - {String[]} List of all the functions called - * @prop initVariables - {String[]} List of variables initialized in the function - * @prop readVariables - {String[]} List of variables read operations occur - * @prop writeVariables - {String[]} List of variables write operations occur - * - */ -module.exports = function (_BaseFunctionNode) { - _inherits(CPUFunctionNode, _BaseFunctionNode); +// Checks function params for various disallowed patterns such as using "eval" +// or "arguments" and duplicate parameters. - function CPUFunctionNode(functionName, jsFunction, options) { - _classCallCheck(this, CPUFunctionNode); +pp$3.checkParams = function(node, allowDuplicates) { + var this$1 = this; - var _this = _possibleConstructorReturn(this, (CPUFunctionNode.__proto__ || Object.getPrototypeOf(CPUFunctionNode)).call(this, functionName, jsFunction, options)); + var nameHash = {}; + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; - _this.paramSizes = options ? options.paramSizes : []; - _this.memberStates = []; - return _this; - } + this$1.checkLVal(param, "var", allowDuplicates ? null : nameHash); + } +}; - _createClass(CPUFunctionNode, [{ - key: 'pushMemberState', - value: function pushMemberState(name) { - this.memberStates.push(name); - } - }, { - key: 'popMemberState', - value: function popMemberState(name) { - if (this.memberState === name) { - this.memberStates.pop(); - } else { - throw new Error('Cannot popMemberState ' + name + ' when in ' + this.memberState); - } - } - }, { - key: 'generate', - value: function generate() { - if (this.debug) { - console.log(this); - } - this.functionStringArray = this.astGeneric(this.getJsAST(), []); - this.functionString = this.functionStringArray.join('').trim(); - return this.functionString; - } +// Parses a comma-separated list of expressions, and returns them as +// an array. `close` is the token type that ends the list, and +// `allowEmpty` can be turned on to allow subsequent commas with +// nothing in between them to be parsed as `null` (which is needed +// for array literals). - /** - * @memberOf CPUFunctionNode# - * @function - * @name getFunctionPrototypeString - * - * @desc Returns the converted JS function - * - * @returns {String} function string, result is cached under this.getFunctionPrototypeString - * - */ +pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var this$1 = this; - }, { - key: 'getFunctionPrototypeString', - value: function getFunctionPrototypeString() { - if (this.webGlFunctionPrototypeString) { - return this.webGlFunctionPrototypeString; - } - return this.webGlFunctionPrototypeString = this.generate(); - } + var elts = [], first = true; + while (!this.eat(close)) { + if (!first) { + this$1.expect(types.comma); + if (allowTrailingComma && this$1.afterTrailingComma(close)) { break } + } else { first = false; } - /** - * @memberOf CPUFunctionNode# - * @function - * @name astFunctionDeclaration - * - * @desc Parses the abstract syntax tree for to its *named function declaration* - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ + var elt = (void 0); + if (allowEmpty && this$1.type === types.comma) + { elt = null; } + else if (this$1.type === types.ellipsis) { + elt = this$1.parseSpread(refDestructuringErrors); + if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0) + { refDestructuringErrors.trailingComma = this$1.start; } + } else { + elt = this$1.parseMaybeAssign(false, refDestructuringErrors); + } + elts.push(elt); + } + return elts +}; - }, { - key: 'astFunctionDeclaration', - value: function astFunctionDeclaration(ast, retArr) { - if (this.addFunction) { - this.addFunction(null, utils.getAstString(this.jsFunctionString, ast)); - } - return retArr; - } +pp$3.checkUnreserved = function(ref) { + var start = ref.start; + var end = ref.end; + var name = ref.name; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astFunctionPrototype - * - * @desc Parses the abstract syntax tree for to its *named function prototype* - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ + if (this.inGenerator && name === "yield") + { this.raiseRecoverable(start, "Can not use 'yield' as identifier inside a generator"); } + if (this.inAsync && name === "await") + { this.raiseRecoverable(start, "Can not use 'await' as identifier inside an async function"); } + if (this.isKeyword(name)) + { this.raise(start, ("Unexpected keyword '" + name + "'")); } + if (this.options.ecmaVersion < 6 && + this.input.slice(start, end).indexOf("\\") !== -1) { return } + var re = this.strict ? this.reservedWordsStrict : this.reservedWords; + if (re.test(name)) { + if (!this.inAsync && name === "await") + { this.raiseRecoverable(start, "Can not use keyword 'await' outside an async function"); } + this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); + } +}; - }, { - key: 'astFunctionPrototype', - value: function astFunctionPrototype(ast, retArr) { - // Setup function return type and name - if (this.isRootKernel || this.isSubKernel) { - return retArr; - } +// Parse the next token as an identifier. If `liberal` is true (used +// when parsing properties), it will also convert keywords into +// identifiers. - retArr.push(this.returnType); - retArr.push(' '); - retArr.push(this.functionName); - retArr.push('('); +pp$3.parseIdent = function(liberal, isBinding) { + var node = this.startNode(); + if (liberal && this.options.allowReserved === "never") { liberal = false; } + if (this.type === types.name) { + node.name = this.value; + } else if (this.type.keyword) { + node.name = this.type.keyword; - // Arguments handling - for (var i = 0; i < this.paramNames.length; ++i) { - if (i > 0) { - retArr.push(', '); - } - retArr.push(this.paramTypes[i]); - retArr.push(' '); - retArr.push('user_'); - retArr.push(this.paramNames[i]); - } + // To fix https://github.com/acornjs/acorn/issues/575 + // `class` and `function` keywords push new context into this.context. + // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. + // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword + if ((node.name === "class" || node.name === "function") && + (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { + this.context.pop(); + } + } else { + this.unexpected(); + } + this.next(); + this.finishNode(node, "Identifier"); + if (!liberal) { this.checkUnreserved(node); } + return node +}; - retArr.push(');\n'); +// Parses yield expression inside generator. - return retArr; - } +pp$3.parseYield = function() { + if (!this.yieldPos) { this.yieldPos = this.start; } - /** - * @memberOf CPUFunctionNode# - * @function - * @name astFunctionExpression - * - * @desc Parses the abstract syntax tree for to its *named function* - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ + var node = this.startNode(); + this.next(); + if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(types.star); + node.argument = this.parseMaybeAssign(); + } + return this.finishNode(node, "YieldExpression") +}; - }, { - key: 'astFunctionExpression', - value: function astFunctionExpression(ast, retArr) { +pp$3.parseAwait = function() { + if (!this.awaitPos) { this.awaitPos = this.start; } - // Setup function return type and name - if (!this.isRootKernel) { - retArr.push('function'); - this.kernalAst = ast; - retArr.push(' '); - retArr.push(this.functionName); - retArr.push('('); + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeUnary(null, true); + return this.finishNode(node, "AwaitExpression") +}; - // Arguments handling - for (var i = 0; i < this.paramNames.length; ++i) { - var paramName = this.paramNames[i]; +var pp$4 = Parser.prototype; - if (i > 0) { - retArr.push(', '); - } +// This function is used to raise exceptions on parse errors. It +// takes an offset integer (into the current `input`) to indicate +// the location of the error, attaches the position to the end +// of the error message, and then raises a `SyntaxError` with that +// message. - retArr.push(' '); - retArr.push('user_'); - retArr.push(paramName); - } +pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos); + message += " (" + loc.line + ":" + loc.column + ")"; + var err = new SyntaxError(message); + err.pos = pos; err.loc = loc; err.raisedAt = this.pos; + throw err +}; - // Function opening - retArr.push(') {\n'); - } +pp$4.raiseRecoverable = pp$4.raise; - // Body statement iteration - for (var _i = 0; _i < ast.body.body.length; ++_i) { - this.astGeneric(ast.body.body[_i], retArr); - retArr.push('\n'); - } +pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } +}; - if (!this.isRootKernel) { - // Function closing - retArr.push('}\n'); - } - return retArr; - } +var pp$5 = Parser.prototype; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astReturnStatement - * - * @desc Parses the abstract syntax tree for to *return* statement - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ +// Object.assign polyfill +var assign = Object.assign || function(target) { + var sources = [], len = arguments.length - 1; + while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ]; - }, { - key: 'astReturnStatement', - value: function astReturnStatement(ast, retArr) { - if (this.isRootKernel) { - retArr.push('kernelResult = '); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - } else if (this.isSubKernel) { - retArr.push(this.functionName + 'Result = '); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - retArr.push('return ' + this.functionName + 'Result;'); - } else { - retArr.push('return '); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - } + for (var i = 0, list = sources; i < list.length; i += 1) { + var source = list[i]; - //throw this.astErrorOutput( - // 'Non main function return, is not supported : '+this.currentFunctionNamespace, - // ast - //); + for (var key in source) { + if (has(source, key)) { + target[key] = source[key]; + } + } + } + return target +}; - return retArr; - } +// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. - /** - * @memberOf CPUFunctionNode# - * @function - * @name astLiteral - * - * @desc Parses the abstract syntax tree for *literal value* - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ +pp$5.enterFunctionScope = function() { + // var: a hash of var-declared names in the current lexical scope + // lexical: a hash of lexically-declared names in the current lexical scope + // childVar: a hash of var-declared names in all child lexical scopes of the current lexical scope (within the current function scope) + // parentLexical: a hash of lexically-declared names in all parent lexical scopes of the current lexical scope (within the current function scope) + this.scopeStack.push({var: {}, lexical: {}, childVar: {}, parentLexical: {}}); +}; - }, { - key: 'astLiteral', - value: function astLiteral(ast, retArr) { +pp$5.exitFunctionScope = function() { + this.scopeStack.pop(); +}; - // Reject non numeric literals - if (isNaN(ast.value)) { - throw this.astErrorOutput('Non-numeric literal not supported : ' + ast.value, ast); - } +pp$5.enterLexicalScope = function() { + var parentScope = this.scopeStack[this.scopeStack.length - 1]; + var childScope = {var: {}, lexical: {}, childVar: {}, parentLexical: {}}; - retArr.push(ast.value); + this.scopeStack.push(childScope); + assign(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical); +}; - return retArr; - } +pp$5.exitLexicalScope = function() { + var childScope = this.scopeStack.pop(); + var parentScope = this.scopeStack[this.scopeStack.length - 1]; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astBinaryExpression - * - * @desc Parses the abstract syntax tree for *binary* expression - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ + assign(parentScope.childVar, childScope.var, childScope.childVar); +}; - }, { - key: 'astBinaryExpression', - value: function astBinaryExpression(ast, retArr) { - retArr.push('('); - this.astGeneric(ast.left, retArr); - retArr.push(ast.operator); - this.astGeneric(ast.right, retArr); - retArr.push(')'); - return retArr; - } +/** + * A name can be declared with `var` if there are no variables with the same name declared with `let`/`const` + * in the current lexical scope or any of the parent lexical scopes in this function. + */ +pp$5.canDeclareVarName = function(name) { + var currentScope = this.scopeStack[this.scopeStack.length - 1]; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astIdentifierExpression - * - * @desc Parses the abstract syntax tree for *identifier* expression - * - * @param {Object} idtNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ + return !has(currentScope.lexical, name) && !has(currentScope.parentLexical, name) +}; - }, { - key: 'astIdentifierExpression', - value: function astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode); - } +/** + * A name can be declared with `let`/`const` if there are no variables with the same name declared with `let`/`const` + * in the current scope, and there are no variables with the same name declared with `var` in the current scope or in + * any child lexical scopes in this function. + */ +pp$5.canDeclareLexicalName = function(name) { + var currentScope = this.scopeStack[this.scopeStack.length - 1]; - switch (this.state) { - case 'input-index-y': - case 'input-index-z': - retArr.push('('); - } + return !has(currentScope.lexical, name) && !has(currentScope.var, name) && !has(currentScope.childVar, name) +}; - switch (idtNode.name) { - case 'gpu_threadX': - retArr.push('threadId.x'); - break; - case 'gpu_threadY': - retArr.push('threadId.y'); - break; - case 'gpu_threadZ': - retArr.push('threadId.z'); - break; - case 'gpu_outputX': - retArr.push('uOutputDim.x'); - break; - case 'gpu_outputY': - retArr.push('uOutputDim.y'); - break; - case 'gpu_outputZ': - retArr.push('uOutputDim.z'); - break; - case 'Infinity': - retArr.push('Infinity'); - break; - default: - if (this.constants && this.constants.hasOwnProperty(idtNode.name)) { - retArr.push('constants_' + idtNode.name); - } else { - var userParamName = this.getUserParamName(idtNode.name); - if (userParamName !== null) { - retArr.push('user_' + userParamName); - } else { - retArr.push('user_' + idtNode.name); - } - } - } +pp$5.declareVarName = function(name) { + this.scopeStack[this.scopeStack.length - 1].var[name] = true; +}; - switch (this.state) { - case 'input-index-y': - { - var size = this.paramSizes[this.paramNames.indexOf(this.memberState)]; - retArr.push(' * ' + size[0] + ')'); - break; - } - case 'input-index-z': - { - var _size = this.paramSizes[this.paramNames.indexOf(this.memberState)]; - retArr.push(' * ' + _size[0] * _size[1] + ')'); - break; - } - } +pp$5.declareLexicalName = function(name) { + this.scopeStack[this.scopeStack.length - 1].lexical[name] = true; +}; - return retArr; - } +var Node = function Node(parser, pos, loc) { + this.type = ""; + this.start = pos; + this.end = 0; + if (parser.options.locations) + { this.loc = new SourceLocation(parser, loc); } + if (parser.options.directSourceFile) + { this.sourceFile = parser.options.directSourceFile; } + if (parser.options.ranges) + { this.range = [pos, 0]; } +}; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astForStatement - * - * @desc Parses the abstract syntax tree forfor *for-loop* expression - * - * @param {Object} forNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the parsed cpu string - */ +// Start an AST node, attaching a start offset. - }, { - key: 'astForStatement', - value: function astForStatement(forNode, retArr) { - if (forNode.type !== 'ForStatement') { - throw this.astErrorOutput('Invalid for statement', forNode); - } +var pp$6 = Parser.prototype; - if (forNode.test && forNode.test.type === 'BinaryExpression') { - if ((forNode.test.right.type === 'Identifier' || forNode.test.right.type === 'Literal') && forNode.test.operator === '<' && this.isIdentifierConstant(forNode.test.right.name) === false) { +pp$6.startNode = function() { + return new Node(this, this.start, this.startLoc) +}; - if (!this.loopMaxIterations) { - console.warn('Warning: loopMaxIterations is not set! Using default of 1000 which may result in unintended behavior.'); - console.warn('Set loopMaxIterations or use a for loop of fixed length to silence this message.'); - } +pp$6.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) +}; - retArr.push('for ('); - this.astGeneric(forNode.init, retArr); - if (retArr[retArr.length - 1] !== ';') { - retArr.push(';'); - } - this.astGeneric(forNode.test.left, retArr); - retArr.push(forNode.test.operator); - retArr.push('LOOP_MAX'); - retArr.push(';'); - this.astGeneric(forNode.update, retArr); - retArr.push(')'); +// Finish an AST node, adding `type` and `end` properties. - retArr.push('{\n'); - retArr.push('if ('); - this.astGeneric(forNode.test.left, retArr); - retArr.push(forNode.test.operator); - this.astGeneric(forNode.test.right, retArr); - retArr.push(') {\n'); - if (forNode.body.type === 'BlockStatement') { - for (var i = 0; i < forNode.body.body.length; i++) { - this.astGeneric(forNode.body.body[i], retArr); - } - } else { - this.astGeneric(forNode.body, retArr); - } - retArr.push('} else {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); +function finishNodeAt(node, type, pos, loc) { + node.type = type; + node.end = pos; + if (this.options.locations) + { node.loc.end = loc; } + if (this.options.ranges) + { node.range[1] = pos; } + return node +} - return retArr; - } else if (forNode.init.declarations) { - var declarations = JSON.parse(JSON.stringify(forNode.init.declarations)); - var updateArgument = forNode.update.argument; - if (!Array.isArray(declarations) || declarations.length < 1) { - console.log(this.jsFunctionString); - throw new Error('Error: Incompatible for loop declaration'); - } +pp$6.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) +}; - if (declarations.length > 1) { - var initArgument = null; - for (var _i2 = 0; _i2 < declarations.length; _i2++) { - var declaration = declarations[_i2]; - if (declaration.id.name === updateArgument.name) { - initArgument = declaration; - declarations.splice(_i2, 1); - } else { - retArr.push('var '); - this.astGeneric(declaration, retArr); - retArr.push(';'); - } - } +// Finish node at given position - retArr.push('for (let '); - this.astGeneric(initArgument, retArr); - retArr.push(';'); - } else { - retArr.push('for ('); - this.astGeneric(forNode.init, retArr); - } +pp$6.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) +}; - this.astGeneric(forNode.test, retArr); - retArr.push(';'); - this.astGeneric(forNode.update, retArr); - retArr.push(')'); - this.astGeneric(forNode.body, retArr); - return retArr; - } - } +// The algorithm used to determine whether a regexp can appear at a +// given point in the program is loosely based on sweet.js' approach. +// See https://github.com/mozilla/sweet.js/wiki/design - throw this.astErrorOutput('Invalid for statement', forNode); - } +var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { + this.token = token; + this.isExpr = !!isExpr; + this.preserveSpace = !!preserveSpace; + this.override = override; + this.generator = !!generator; +}; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astWhileStatement - * - * @desc Parses the abstract syntax tree for *while* loop - * - * - * @param {Object} whileNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the parsed openclgl string - */ +var types$1 = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", false), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), + f_stat: new TokContext("function", false), + f_expr: new TokContext("function", true), + f_expr_gen: new TokContext("function", true, false, null, true), + f_gen: new TokContext("function", false, false, null, true) +}; - }, { - key: 'astWhileStatement', - value: function astWhileStatement(whileNode, retArr) { - if (whileNode.type !== 'WhileStatement') { - throw this.astErrorOutput('Invalid while statement', whileNode); - } +var pp$7 = Parser.prototype; - retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); - retArr.push('if ('); - this.astGeneric(whileNode.test, retArr); - retArr.push(') {\n'); - this.astGeneric(whileNode.body, retArr); - retArr.push('} else {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); - - return retArr; - } +pp$7.initialContext = function() { + return [types$1.b_stat] +}; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astWhileStatement - * - * @desc Parses the abstract syntax tree for *do while* loop - * - * - * @param {Object} doWhileNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the parsed webgl string - */ +pp$7.braceIsBlock = function(prevType) { + var parent = this.curContext(); + if (parent === types$1.f_expr || parent === types$1.f_stat) + { return true } + if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr)) + { return !parent.isExpr } - }, { - key: 'astDoWhileStatement', - value: function astDoWhileStatement(doWhileNode, retArr) { - if (doWhileNode.type !== 'DoWhileStatement') { - throw this.astErrorOutput('Invalid while statement', doWhileNode); - } + // The check for `tt.name && exprAllowed` detects whether we are + // after a `yield` or `of` construct. See the `updateContext` for + // `tt.name`. + if (prevType === types._return || prevType === types.name && this.exprAllowed) + { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } + if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow) + { return true } + if (prevType === types.braceL) + { return parent === types$1.b_stat } + if (prevType === types._var || prevType === types.name) + { return false } + return !this.exprAllowed +}; - retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); - this.astGeneric(doWhileNode.body, retArr); - retArr.push('if (!'); - this.astGeneric(doWhileNode.test, retArr); - retArr.push(') {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); +pp$7.inGeneratorContext = function() { + var this$1 = this; - return retArr; - } + for (var i = this.context.length - 1; i >= 1; i--) { + var context = this$1.context[i]; + if (context.token === "function") + { return context.generator } + } + return false +}; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astAssignmentExpression - * - * @desc Parses the abstract syntax tree for *Assignment* Expression - * - * @param {Object} assNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ +pp$7.updateContext = function(prevType) { + var update, type = this.type; + if (type.keyword && prevType === types.dot) + { this.exprAllowed = false; } + else if (update = type.updateContext) + { update.call(this, prevType); } + else + { this.exprAllowed = type.beforeExpr; } +}; - }, { - key: 'astAssignmentExpression', - value: function astAssignmentExpression(assNode, retArr) { - this.astGeneric(assNode.left, retArr); - retArr.push(assNode.operator); - this.astGeneric(assNode.right, retArr); - return retArr; - } +// Token-specific context update code - /** - * @memberOf CPUFunctionNode# - * @function - * @name astEmptyStatement - * - * @desc Parses the abstract syntax tree for an *Empty* Statement - * - * @param {Object} eNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ +types.parenR.updateContext = types.braceR.updateContext = function() { + if (this.context.length === 1) { + this.exprAllowed = true; + return + } + var out = this.context.pop(); + if (out === types$1.b_stat && this.curContext().token === "function") { + out = this.context.pop(); + } + this.exprAllowed = !out.isExpr; +}; - }, { - key: 'astEmptyStatement', - value: function astEmptyStatement(eNode, retArr) { - //retArr.push(';\n'); - return retArr; - } +types.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr); + this.exprAllowed = true; +}; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astBlockStatement - * - * @desc Parses the abstract syntax tree for *Block* statement - * - * @param {Object} bNode - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ +types.dollarBraceL.updateContext = function() { + this.context.push(types$1.b_tmpl); + this.exprAllowed = true; +}; - }, { - key: 'astBlockStatement', - value: function astBlockStatement(bNode, retArr) { - retArr.push('{\n'); - for (var i = 0; i < bNode.body.length; i++) { - this.astGeneric(bNode.body[i], retArr); - } - retArr.push('}\n'); - return retArr; - } +types.parenL.updateContext = function(prevType) { + var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while; + this.context.push(statementParens ? types$1.p_stat : types$1.p_expr); + this.exprAllowed = true; +}; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astExpressionStatement - * - * @desc Parses the abstract syntax tree for *generic expression* statement - * - * @param {Object} esNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ +types.incDec.updateContext = function() { + // tokExprAllowed stays unchanged +}; - }, { - key: 'astExpressionStatement', - value: function astExpressionStatement(esNode, retArr) { - this.astGeneric(esNode.expression, retArr); - retArr.push(';\n'); - return retArr; - } +types._function.updateContext = types._class.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && + !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat)) + { this.context.push(types$1.f_expr); } + else + { this.context.push(types$1.f_stat); } + this.exprAllowed = false; +}; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astVariableDeclaration - * - * @desc Parses the abstract syntax tree for *Variable Declaration* - * - * @param {Object} vardecNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ +types.backQuote.updateContext = function() { + if (this.curContext() === types$1.q_tmpl) + { this.context.pop(); } + else + { this.context.push(types$1.q_tmpl); } + this.exprAllowed = false; +}; - }, { - key: 'astVariableDeclaration', - value: function astVariableDeclaration(vardecNode, retArr) { - retArr.push('var '); - for (var i = 0; i < vardecNode.declarations.length; i++) { - if (i > 0) { - retArr.push(','); - } - this.astGeneric(vardecNode.declarations[i], retArr); - } - retArr.push(';'); - return retArr; - } +types.star.updateContext = function(prevType) { + if (prevType === types._function) { + var index = this.context.length - 1; + if (this.context[index] === types$1.f_expr) + { this.context[index] = types$1.f_expr_gen; } + else + { this.context[index] = types$1.f_gen; } + } + this.exprAllowed = true; +}; - /** - * @memberOf CPUFunctionNode# - * @function - * @name astVariableDeclarator - * - * @desc Parses the abstract syntax tree for *Variable Declarator* - * - * @param {Object} ivardecNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astVariableDeclarator', - value: function astVariableDeclarator(ivardecNode, retArr) { - this.astGeneric(ivardecNode.id, retArr); - if (ivardecNode.init !== null) { - retArr.push('='); - this.astGeneric(ivardecNode.init, retArr); - } - return retArr; - } - - /** - * @memberOf CPUFunctionNode# - * @function - * @name astIfStatement - * - * @desc Parses the abstract syntax tree for *If* Statement - * - * @param {Object} ifNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astIfStatement', - value: function astIfStatement(ifNode, retArr) { - retArr.push('if ('); - this.astGeneric(ifNode.test, retArr); - retArr.push(')'); - if (ifNode.consequent.type === 'BlockStatement') { - this.astGeneric(ifNode.consequent, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.consequent, retArr); - retArr.push('\n}\n'); - } - - if (ifNode.alternate) { - retArr.push('else '); - if (ifNode.alternate.type === 'BlockStatement') { - this.astGeneric(ifNode.alternate, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.alternate, retArr); - retArr.push('\n}\n'); - } - } - return retArr; - } - - /** - * @memberOf CPUFunctionNode# - * @function - * @name astBreakStatement - * - * @desc Parses the abstract syntax tree for *Break* Statement - * - * @param {Object} brNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astBreakStatement', - value: function astBreakStatement(brNode, retArr) { - retArr.push('break;\n'); - return retArr; - } - - /** - * @memberOf CPUFunctionNode# - * @function - * @name astContinueStatement - * - * @desc Parses the abstract syntax tree for *Continue* Statement - * - * @param {Object} crNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astContinueStatement', - value: function astContinueStatement(crNode, retArr) { - retArr.push('continue;\n'); - return retArr; - } - - /** - * @memberOf CPUFunctionNode# - * @function - * @name astLogicalExpression - * - * @desc Parses the abstract syntax tree for *Logical* Expression - * - * @param {Object} logNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astLogicalExpression', - value: function astLogicalExpression(logNode, retArr) { - retArr.push('('); - this.astGeneric(logNode.left, retArr); - retArr.push(logNode.operator); - this.astGeneric(logNode.right, retArr); - retArr.push(')'); - return retArr; - } - - /** - * @memberOf CPUFunctionNode# - * @function - * @name astUpdateExpression - * - * @desc Parses the abstract syntax tree for *Update* Expression - * - * @param {Object} uNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astUpdateExpression', - value: function astUpdateExpression(uNode, retArr) { - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); - } - - return retArr; - } - - /** - * @memberOf CPUFunctionNode# - * @function - * @name astUnaryExpression - * - * @desc Parses the abstract syntax tree for *Unary* Expression - * - * @param {Object} uNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astUnaryExpression', - value: function astUnaryExpression(uNode, retArr) { - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); - } - - return retArr; - } - - /** - * @memberOf CPUFunctionNode# - * @function - * @name astThisExpression - * - * @desc Parses the abstract syntax tree for *This* expression - * - * @param {Object} tNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astThisExpression', - value: function astThisExpression(tNode, retArr) { - retArr.push('_this'); - return retArr; - } - - /** - * @memberOf CPUFunctionNode# - * @function - * @name astMemberExpression - * - * @desc Parses the abstract syntax tree for *Member* Expression - * - * @param {Object} mNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astMemberExpression', - value: function astMemberExpression(mNode, retArr) { - if (mNode.computed) { - if (mNode.object.type === 'Identifier') { - this.pushState('identifier'); - this.astGeneric(mNode.object, retArr); - this.popState('identifier'); - retArr.push('['); - if (this.isInput(mNode.object.name)) { - this.astGeneric(mNode.property, retArr); - } else { - this.astGeneric(mNode.property, retArr); - } - retArr.push(']'); - } else { - if (mNode.object.object) { - if (mNode.object.object.object && this.isInput(mNode.object.object.object.name)) { - this.pushMemberState(mNode.object.object.object.name); - this.pushState('input-index-z'); - this.astGeneric(mNode.object, retArr); - var last = retArr.pop(); - retArr.push(' + '); - this.popState('input-index-z'); - this.pushState('input-index'); - this.astGeneric(mNode.property, retArr); - this.popState('input-index'); - retArr.push(last); - this.popMemberState(mNode.object.object.object.name); - } else if (this.isInput(mNode.object.object.name)) { - this.pushMemberState(mNode.object.object.name); - if (!this.isState('input-index-z')) { - this.pushState('input-index-y'); - } - this.astGeneric(mNode.object, retArr); - var _last = retArr.pop(); - retArr.push(' + '); - if (!this.isState('input-index-z')) { - this.popState('input-index-y'); - } - - var isInputIndexZ = this.isState('input-index-z'); - if (isInputIndexZ) { - this.pushState('input-index-y'); - } else { - this.pushState('input-index'); - } - this.astGeneric(mNode.property, retArr); - if (isInputIndexZ) { - this.popState('input-index-y'); - } else { - this.popState('input-index'); - } - retArr.push(_last); - this.popMemberState(mNode.object.object.name); - } else { - this.astGeneric(mNode.object, retArr); - var _last2 = retArr.pop(); - retArr.push(']['); - this.astGeneric(mNode.property, retArr); - retArr.push(_last2); - } - } else { - this.astGeneric(mNode.object, retArr); - var _last3 = retArr.pop(); - retArr.push(']['); - this.astGeneric(mNode.property, retArr); - retArr.push(_last3); - } - } - } else { - var unrolled = this.astMemberExpressionUnroll(mNode); - if (mNode.property.type === 'Identifier' && mNode.computed) { - unrolled = 'user_' + unrolled; - } - - // Its a reference to `this`, add '_' before - if (unrolled.indexOf('this') === 0) { - unrolled = '_' + unrolled; - } - - switch (this.state) { - case 'input-index-y': - case 'input-index-z': - retArr.push('('); - } - - switch (unrolled) { - case '_this.output.x': - retArr.push(this.output[0]); - break; - case '_this.output.y': - retArr.push(this.output[1]); - break; - case '_this.output.z': - retArr.push(this.output[2]); - break; - default: - retArr.push(unrolled); - } - - switch (this.state) { - case 'input-index-y': - { - var size = this.paramSizes[this.paramNames.indexOf(this.memberState)]; - retArr.push(' * ' + size[0] + ')'); - break; - } - case 'input-index-z': - { - var _size2 = this.paramSizes[this.paramNames.indexOf(this.memberState)]; - retArr.push(' * ' + _size2[0] * _size2[1] + ')'); - break; - } - } - } - return retArr; - } - }, { - key: 'astSequenceExpression', - value: function astSequenceExpression(sNode, retArr) { - for (var i = 0; i < sNode.expressions.length; i++) { - if (i > 0) { - retArr.push(','); - } - this.astGeneric(sNode.expressions, retArr); - } - return retArr; - } - - /** - * @memberOf CPUFunctionNode# - * @function - * @name astCallExpression - * - * @desc Parses the abstract syntax tree for *call* expression - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astCallExpression', - value: function astCallExpression(ast, retArr) { - if (ast.callee) { - // Get the full function call, unrolled - var funcName = this.astMemberExpressionUnroll(ast.callee); - - // Register the function into the called registry - if (this.calledFunctions.indexOf(funcName) < 0) { - this.calledFunctions.push(funcName); - } - if (!this.hasOwnProperty('funcName')) { - this.calledFunctionsArguments[funcName] = []; - } - - var functionArguments = []; - this.calledFunctionsArguments[funcName].push(functionArguments); - - // Call the function - retArr.push(funcName); - - // Open arguments space - retArr.push('('); - - // Add the vars - for (var i = 0; i < ast.arguments.length; ++i) { - var argument = ast.arguments[i]; - if (i > 0) { - retArr.push(', '); - } - this.astGeneric(argument, retArr); - if (argument.type === 'Identifier') { - var paramIndex = this.paramNames.indexOf(argument.name); - if (paramIndex === -1) { - functionArguments.push(null); - } else { - functionArguments.push({ - name: argument.name, - type: this.paramTypes[paramIndex] - }); - } - } else { - functionArguments.push(null); - } - } - - // Close arguments space - retArr.push(')'); - - return retArr; - } - - // Failure, unknown expression - throw this.astErrorOutput('Unknown CallExpression', ast); - - return retArr; - } - - /** - * @memberOf CPUFunctionNode# - * @function - * @name astArrayExpression - * - * @desc Parses the abstract syntax tree for *Array* Expression - * - * @param {Object} arrNode - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astArrayExpression', - value: function astArrayExpression(arrNode, retArr) { - var arrLen = arrNode.elements.length; - - retArr.push('new Float32Array('); - for (var i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); - } - var subNode = arrNode.elements[i]; - this.astGeneric(subNode, retArr); - } - retArr.push(')'); - - return retArr; - - // // Failure, unknown expression - // throw this.astErrorOutput( - // 'Unknown ArrayExpression', - // arrNode - //); - } - }, { - key: 'astDebuggerStatement', - value: function astDebuggerStatement(arrNode, retArr) { - retArr.push('debugger;'); - return retArr; - } - }, { - key: 'memberState', - get: function get() { - return this.memberStates[this.memberStates.length - 1]; - } - }]); - - return CPUFunctionNode; -}(BaseFunctionNode); -},{"../../core/utils":84,"../function-node-base":59}],55:[function(require,module,exports){ -'use strict'; - -var utils = require('../../core/utils'); -var kernelRunShortcut = require('../kernel-run-shortcut'); - -function removeFnNoise(fn) { - if (/^function /.test(fn)) { - fn = fn.substring(9); - } - return fn.replace(/[_]typeof/g, 'typeof'); -} - -function removeNoise(str) { - return str.replace(/[_]typeof/g, 'typeof'); -} - -module.exports = function (cpuKernel, name) { - return '() => {\n ' + kernelRunShortcut.toString() + ';\n const utils = {\n allPropertiesOf: ' + removeNoise(utils.allPropertiesOf.toString()) + ',\n clone: ' + removeNoise(utils.clone.toString()) + ',\n checkOutput: ' + removeNoise(utils.checkOutput.toString()) + '\n };\n const Utils = utils;\n class ' + (name || 'Kernel') + ' {\n constructor() { \n this.argumentsLength = 0;\n this._canvas = null;\n this._webGl = null;\n this.built = false;\n this.program = null;\n this.paramNames = ' + JSON.stringify(cpuKernel.paramNames) + ';\n this.paramTypes = ' + JSON.stringify(cpuKernel.paramTypes) + ';\n this.texSize = ' + JSON.stringify(cpuKernel.texSize) + ';\n this.output = ' + JSON.stringify(cpuKernel.output) + ';\n this._kernelString = `' + cpuKernel._kernelString + '`;\n this.output = ' + JSON.stringify(cpuKernel.output) + ';\n\t\t this.run = function() {\n this.run = null;\n this.build();\n return this.run.apply(this, arguments);\n }.bind(this);\n this.thread = {\n x: 0,\n y: 0,\n z: 0\n };\n }\n setCanvas(canvas) { this._canvas = canvas; return this; }\n setWebGl(webGl) { this._webGl = webGl; return this; }\n ' + removeFnNoise(cpuKernel.build.toString()) + '\n ' + removeFnNoise(cpuKernel.setupParams.toString()) + '\n run () { ' + cpuKernel.kernelString + ' }\n getKernelString() { return this._kernelString; }\n ' + removeFnNoise(cpuKernel.validateOptions.toString()) + '\n };\n return kernelRunShortcut(new Kernel());\n };'; -}; -},{"../../core/utils":84,"../kernel-run-shortcut":61}],56:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var KernelBase = require('../kernel-base'); -var utils = require('../../core/utils'); -var kernelString = require('./kernel-string'); - -module.exports = function (_KernelBase) { - _inherits(CPUKernel, _KernelBase); - - /** - * @constructor CPUKernel - * - * @desc Kernel Implementation for CPU. - * - *

Instantiates properties to the CPU Kernel.

- * - * @extends KernelBase - * - * @prop {Object} thread - The thread dimensions, x, y and z - * @prop {Object} output - The canvas dimensions - * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel - * @prop {Function} run - Method to run the kernel - * - */ - function CPUKernel(fnString, settings) { - _classCallCheck(this, CPUKernel); - - var _this = _possibleConstructorReturn(this, (CPUKernel.__proto__ || Object.getPrototypeOf(CPUKernel)).call(this, fnString, settings)); - - _this._fn = null; - _this.run = null; - _this._canvasCtx = null; - _this._imageData = null; - _this._colorData = null; - _this._kernelString = null; - _this.thread = { - x: 0, - y: 0, - z: 0 - }; - - _this.run = function () { - this.run = null; - this.build.apply(this, arguments); - return this.run.apply(this, arguments); - }.bind(_this); - return _this; - } - - /** - * @memberOf CPUKernel# - * @function - * @name validateOptions - * - * @desc Validate options related to CPU Kernel, such as - * dimensions size, and auto dimension support. - * - */ - - - _createClass(CPUKernel, [{ - key: 'validateOptions', - value: function validateOptions() { - if (!this.output || this.output.length === 0) { - if (arguments.length !== 1) { - throw 'Auto dimensions only supported for kernels with only one input'; - } - - var argType = utils.getArgumentType(arguments[0]); - if (argType === 'Array') { - this.output = utils.getDimensions(argType); - } else if (argType === 'Texture') { - this.output = arguments[0].output; - } else { - throw 'Auto dimensions not supported for input type: ' + argType; - } - } - - utils.checkOutput(this.output); - } - - /** - * @memberOf CPUKernel# - * @function - * @name build - * - * @desc Builds the Kernel, by generating the kernel - * string using thread dimensions, and arguments - * supplied to the kernel. - * - *

If the graphical flag is enabled, canvas is used.

- * - */ - - }, { - key: 'build', - value: function build() { - this.setupParams(arguments); - this.validateOptions(); - var threadDim = this.threadDim = utils.clone(this.output); - - while (threadDim.length < 3) { - threadDim.push(1); - } - - if (this.graphical) { - var canvas = this.getCanvas(); - canvas.width = threadDim[0]; - canvas.height = threadDim[1]; - this._canvasCtx = canvas.getContext('2d'); - this._imageData = this._canvasCtx.createImageData(threadDim[0], threadDim[1]); - this._colorData = new Uint8ClampedArray(threadDim[0] * threadDim[1] * 4); - } - - var kernelString = this.getKernelString(); - - if (this.debug) { - console.log('Options:'); - console.dir(this); - console.log('Function output:'); - console.log(kernelString); - } - - this.kernelString = kernelString; - this.run = new Function([], kernelString).bind(this)(); - } - }, { - key: 'color', - value: function color(r, g, b, a) { - if (typeof a === 'undefined') { - a = 1; - } - - r = Math.floor(r * 255); - g = Math.floor(g * 255); - b = Math.floor(b * 255); - a = Math.floor(a * 255); - - var width = this.output[0]; - var height = this.output[1]; - - var x = this.thread.x; - var y = height - this.thread.y - 1; - - var index = x + y * width; - - this._colorData[index * 4 + 0] = r; - this._colorData[index * 4 + 1] = g; - this._colorData[index * 4 + 2] = b; - this._colorData[index * 4 + 3] = a; - } - - /** - * @memberOf CPUKernel# - * @function - * @name getKernelString - * - * @desc Generates kernel string for this kernel program. - * - *

If sub-kernels are supplied, they are also factored in. - * This string can be saved by calling the `toString` method - * and then can be reused later.

- * - * @returns {String} result - * - */ - - }, { - key: 'getKernelString', - value: function getKernelString() { - var _this2 = this; - - if (this._kernelString !== null) return this._kernelString; - - var builder = this.functionBuilder; - - // Thread dim fix (to make compilable) - var threadDim = this.threadDim || (this.threadDim = utils.clone(this.output)); - while (threadDim.length < 3) { - threadDim.push(1); - } - - builder.addKernel(this.fnString, { - prototypeOnly: false, - constants: this.constants, - output: threadDim, - debug: this.debug, - loopMaxIterations: this.loopMaxIterations, - paramNames: this.paramNames, - paramTypes: this.paramTypes, - paramSizes: this.paramSizes - }); - - builder.addFunctions(this.functions, { - constants: this.constants, - output: threadDim - }); - - builder.addNativeFunctions(this.nativeFunctions); - - if (this.subKernels !== null) { - this.subKernelOutputTextures = []; - this.subKernelOutputVariableNames = []; - for (var i = 0; i < this.subKernels.length; i++) { - var subKernel = this.subKernels[i]; - builder.addSubKernel(subKernel, { - prototypeOnly: false, - constants: this.constants, - output: this.output, - debug: this.debug, - loopMaxIterations: this.loopMaxIterations - }); - this.subKernelOutputVariableNames.push(subKernel.name + 'Result'); - } - } else if (this.subKernelProperties !== null) { - this.subKernelOutputVariableNames = []; - var _i = 0; - for (var p in this.subKernelProperties) { - if (!this.subKernelProperties.hasOwnProperty(p)) continue; - var _subKernel = this.subKernelProperties[p]; - builder.addSubKernel(_subKernel); - this.subKernelOutputVariableNames.push(_subKernel.name + 'Result'); - _i++; - } - } - - var prototypes = builder.getPrototypes('kernel'); - var kernel = null; - if (prototypes.length > 1) { - prototypes = prototypes.filter(function (fn) { - if (/^function/.test(fn)) return fn; - kernel = fn; - return false; - }); - } else { - kernel = prototypes.shift(); - } - var kernelString = this._kernelString = '\n\t\tvar LOOP_MAX = ' + this._getLoopMaxString() + ';\n\t\tvar _this = this;\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) { - return ' var ' + name + ' = null;\n'; - }).join('')) + '\n return function (' + this.paramNames.map(function (paramName) { - return 'user_' + paramName; - }).join(', ') + ') {\n ' + this._processInputs() + '\n var ret = new Array(' + threadDim[2] + ');\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) { - return ' ' + name + 'Z = new Array(' + threadDim[2] + ');\n'; - }).join('')) + '\n for (this.thread.z = 0; this.thread.z < ' + threadDim[2] + '; this.thread.z++) {\n ret[this.thread.z] = new Array(' + threadDim[1] + ');\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) { - return ' ' + name + 'Z[this.thread.z] = new Array(' + threadDim[1] + ');\n'; - }).join('')) + '\n for (this.thread.y = 0; this.thread.y < ' + threadDim[1] + '; this.thread.y++) {\n ret[this.thread.z][this.thread.y] = ' + (this.floatOutput ? 'new Float32Array(' + threadDim[0] + ')' : 'new Array(' + threadDim[0] + ')') + ';\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) { - return ' ' + name + 'Z[this.thread.z][this.thread.y] = ' + (_this2.floatOutput ? 'new Float32Array(' + threadDim[0] + ')' : 'new Array(' + threadDim[0] + ')') + ';\n'; - }).join('')) + '\n for (this.thread.x = 0; this.thread.x < ' + threadDim[0] + '; this.thread.x++) {\n var kernelResult;\n ' + kernel + '\n ret[this.thread.z][this.thread.y][this.thread.x] = kernelResult;\n' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) { - return ' ' + name + 'Z[this.thread.z][this.thread.y][this.thread.x] = ' + name + ';\n'; - }).join('')) + '\n }\n }\n }\n \n if (this.graphical) {\n this._imageData.data.set(this._colorData);\n this._canvasCtx.putImageData(this._imageData, 0, 0);\n return;\n }\n \n if (this.output.length === 1) {\n ret = ret[0][0];\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) { - return ' ' + name + ' = ' + name + 'Z[0][0];\n'; - }).join('')) + '\n \n } else if (this.output.length === 2) {\n ret = ret[0];\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) { - return ' ' + name + ' = ' + name + 'Z[0];\n'; - }).join('')) + '\n } else {\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) { - return ' ' + name + ' = ' + name + 'Z;\n'; - }).join('')) + '\n }\n \n ' + (this.subKernelOutputVariableNames === null ? 'return ret;\n' : this.subKernels !== null ? 'var result = [\n ' + this.subKernelOutputVariableNames.map(function (name) { - return '' + name; - }).join(',\n') + '\n ];\n result.result = ret;\n return result;\n' : 'return {\n result: ret,\n ' + Object.keys(this.subKernelProperties).map(function (name, i) { - return name + ': ' + _this2.subKernelOutputVariableNames[i]; - }).join(',\n') + '\n };') + '\n ' + (prototypes.length > 0 ? prototypes.join('\n') : '') + '\n }.bind(this);'; - return kernelString; - } - - /** - * @memberOf CPUKernel# - * @function - * @name toString - * - * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused. - * - */ - - }, { - key: 'toString', - value: function toString() { - return kernelString(this); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getLoopMaxString - * - * @desc Get the maximum loop size String. - * - * @returns {String} result - * - */ - - }, { - key: '_getLoopMaxString', - value: function _getLoopMaxString() { - return this.loopMaxIterations ? ' ' + parseInt(this.loopMaxIterations) + ';\n' : ' 1000;\n'; - } - }, { - key: '_processInputs', - value: function _processInputs() { - var result = []; - for (var i = 0; i < this.paramTypes.length; i++) { - switch (this.paramTypes[i]) { - case 'HTMLImage': - result.push(' user_' + this.paramNames[i] + ' = this._imageTo2DArray(user_' + this.paramNames[i] + ')'); - break; - case 'HTMLImageArray': - result.push(' user_' + this.paramNames[i] + ' = this._imageTo3DArray(user_' + this.paramNames[i] + ')'); - break; - case 'Input': - result.push(' user_' + this.paramNames[i] + ' = user_' + this.paramNames[i] + '.value'); - break; - } - } - return result.join(';\n'); - } - }, { - key: '_imageTo2DArray', - value: function _imageTo2DArray(image) { - this._canvasCtx.drawImage(image, 0, 0, image.width, image.height); - var pixelsData = this._canvasCtx.getImageData(0, 0, image.width, image.height).data; - var imageArray = new Array(image.height); - var index = 0; - for (var y = image.height - 1; y >= 0; y--) { - imageArray[y] = new Array(image.width); - for (var x = 0; x < image.width; x++) { - imageArray[y][x] = [pixelsData[index++] / 255, pixelsData[index++] / 255, pixelsData[index++] / 255, pixelsData[index++] / 255]; - } - } - return imageArray; - } - }, { - key: '_imageTo3DArray', - value: function _imageTo3DArray(images) { - var imagesArray = new Array(images.length); - for (var i = 0; i < images.length; i++) { - imagesArray[i] = this._imageTo2DArray(images[i]); - } - return imagesArray; - } - }]); - - return CPUKernel; -}(KernelBase); -},{"../../core/utils":84,"../kernel-base":60,"./kernel-string":55}],57:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var utils = require('../../core/utils'); -var RunnerBase = require('../runner-base'); -var CPUKernel = require('./kernel'); -var CPUFunctionBuilder = require('./function-builder'); - -module.exports = function (_RunnerBase) { - _inherits(CPURunner, _RunnerBase); - - /** - * @constructor CPURunner - * - * @desc Instantiates a Runner instance for the kernel. - * - * @extends RunnerBase - * - * @param {Object} settings - Settings to instantiate properties in RunnerBase, with given values - * - */ - - function CPURunner(settings) { - _classCallCheck(this, CPURunner); - - var _this = _possibleConstructorReturn(this, (CPURunner.__proto__ || Object.getPrototypeOf(CPURunner)).call(this, new CPUFunctionBuilder(), settings)); - - _this.Kernel = CPUKernel; - _this.kernel = null; - return _this; - } - - /** - * @memberOf CPURunner# - * @function - * @name getMode() - * - * Return the current mode in which gpu.js is executing. - * - * @returns {String} The current mode; "cpu". - * - */ - - - _createClass(CPURunner, [{ - key: 'getMode', - value: function getMode() { - return 'cpu'; - } - }]); - - return CPURunner; -}(RunnerBase); -},{"../../core/utils":84,"../runner-base":62,"./function-builder":53,"./kernel":56}],58:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -module.exports = function () { - - /** - * @constructor FunctionBuilderBase - * - * @desc This handles all the raw state, converted state, etc. of a single function. - * [INTERNAL] A collection of functionNodes. - * - * @prop {Object} nodeMap - Object map, where nodeMap[function] = new FunctionNode; - * @prop {Object} gpu - The current gpu instance bound to this builder - * @prop {Object} rootKernel - The root kernel object, contains the paramNames, dimensions etc. - * - */ - function FunctionBuilderBase(gpu) { - _classCallCheck(this, FunctionBuilderBase); - - this.nodeMap = {}; - this.nativeFunctions = {}; - this.gpu = gpu; - this.rootKernel = null; - this.Node = null; - } - - _createClass(FunctionBuilderBase, [{ - key: 'addNativeFunction', - value: function addNativeFunction(functionName, glslFunctionString) { - this.nativeFunctions[functionName] = glslFunctionString; - } - - /** - * @memberOf FunctionBuilderBase# - * @function - * @name addFunction - * - * @desc Instantiates a FunctionNode, and add it to the nodeMap - * - * @param {String} functionName - Function name to assume, if its null, it attempts to extract from the function - * @param {Function} jsFunction - JS Function to do conversion - * @param {Object} [options] - * - */ - - }, { - key: 'addFunction', - value: function addFunction(functionName, jsFunction, options) { - this.addFunctionNode(new this.Node(functionName, jsFunction, options).setAddFunction(this.addFunction.bind(this))); - } - }, { - key: 'addFunctions', - value: function addFunctions(functions, options) { - if (functions) { - if (Array.isArray(functions)) { - for (var i = 0; i < functions.length; i++) { - this.addFunction(null, functions[i], options); - } - } else { - for (var p in functions) { - this.addFunction(p, functions[p], options); - } - } - } - } - }, { - key: 'addNativeFunctions', - value: function addNativeFunctions(nativeFunctions) { - for (var functionName in nativeFunctions) { - if (!nativeFunctions.hasOwnProperty(functionName)) continue; - this.addNativeFunction(functionName, nativeFunctions[functionName]); - } - } - - /** - * @memberOf FunctionBuilderBase# - * @function - * @name addFunctionNode - * - * @desc Add the function node directly - * - * @param {functionNode} inNode - functionNode to add - * - */ - - }, { - key: 'addFunctionNode', - value: function addFunctionNode(inNode) { - this.nodeMap[inNode.functionName] = inNode; - if (inNode.isRootKernel) { - this.rootKernel = inNode; - } - } - - /** - * @memberOf FunctionBuilderBase# - * @function - * @name traceFunctionCalls - * - * @desc Trace all the depending functions being called, from a single function - * - * This allow for 'unneeded' functions to be automatically optimized out. - * Note that the 0-index, is the starting function trace. - * - * @param {String} functionName - Function name to trace from, default to 'kernel' - * @param {String[]} retList - Returning list of function names that is traced. Including itself. - * @param {Object} [parent] - Parent node - * - * @returns {String[]} Returning list of function names that is traced. Including itself. - */ - - }, { - key: 'traceFunctionCalls', - value: function traceFunctionCalls(functionName, retList, parent) { - functionName = functionName || 'kernel'; - retList = retList || []; - - var fNode = this.nodeMap[functionName]; - if (fNode) { - // Check if function already exists - var functionIndex = retList.indexOf(functionName); - if (functionIndex === -1) { - retList.push(functionName); - if (parent) { - fNode.parent = parent; - } - fNode.getFunctionString(); //ensure JS trace is done - for (var i = 0; i < fNode.calledFunctions.length; ++i) { - this.traceFunctionCalls(fNode.calledFunctions[i], retList, fNode); - } - } else { - /** - * https://github.com/gpujs/gpu.js/issues/207 - * if dependent function is already in the list, because a function depends on it, and because it has - * already been traced, we know that we must move the dependent function to the end of the the retList. - * */ - var dependantFunctionName = retList.splice(functionIndex, 1)[0]; - retList.push(dependantFunctionName); - } - } - - if (this.nativeFunctions[functionName]) { - if (retList.indexOf(functionName) >= 0) { - // Does nothing if already traced - } else { - retList.push(functionName); - } - } - - return retList; - } - - /** - * @memberOf FunctionBuilderBase# - * @function - * @name addKernel - * - * @desc Add a new kernel to this instance - * - * @param {String} fnString - Kernel function as a String - * @param {Object} options - Settings object to set constants, debug mode, etc. - * - * - * @returns {Object} The inserted kernel as a Kernel Node - * - */ - - }, { - key: 'addKernel', - value: function addKernel(fnString, options) { - var kernelNode = new this.Node('kernel', fnString, options); - kernelNode.setAddFunction(this.addFunction.bind(this)); - kernelNode.isRootKernel = true; - this.addFunctionNode(kernelNode); - return kernelNode; - } - - /** - * @memberOf FunctionBuilderBase# - * @function - * @name addSubKernel - * - * @desc Add a new sub-kernel to the current kernel instance - * - * @param {Function} jsFunction - Sub-kernel function (JavaScript) - * @param {Object} options - Settings object to set constants, debug mode, etc. - * - * @returns {Object} The inserted sub-kernel as a Kernel Node - * - */ - - }, { - key: 'addSubKernel', - value: function addSubKernel(jsFunction, options) { - var kernelNode = new this.Node(null, jsFunction, options); - kernelNode.setAddFunction(this.addFunction.bind(this)); - kernelNode.isSubKernel = true; - this.addFunctionNode(kernelNode); - return kernelNode; - } - - /** - * @memberOf CPUFunctionBuilder# - * @name getPrototypeString - * @function - * - * @desc Return the string for a function - * - * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack - * - * @returns {String} The full string, of all the various functions. Trace optimized if functionName given - * - */ - - }, { - key: 'getPrototypeString', - value: function getPrototypeString(functionName) { - return this.getPrototypes(functionName).join('\n'); - } - - /** - * @memberOf CPUFunctionBuilder# - * @name getPrototypeString - * @function - * - * @desc Return the string for a function - * - * @param {String} [functionName] - Function name to trace from. If null, it returns the WHOLE builder stack - * - * @returns {Array} The full string, of all the various functions. Trace optimized if functionName given - * - */ - - }, { - key: 'getPrototypes', - value: function getPrototypes(functionName) { - this.rootKernel.generate(); - if (functionName) { - return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); - } - return this.getPrototypesFromFunctionNames(Object.keys(this.nodeMap)); - } - - /** - * @memberOf FunctionBuilderBase# - * @function - * @name getStringFromFunctionNames - * - * @desc Get string from function names - * - * @param {String[]} functionList - List of function to build string - * - * @returns {String} The string, of all the various functions. Trace optimized if functionName given - * - */ - - }, { - key: 'getStringFromFunctionNames', - value: function getStringFromFunctionNames(functionList) { - var ret = []; - for (var i = 0; i < functionList.length; ++i) { - var node = this.nodeMap[functionList[i]]; - if (node) { - ret.push(this.nodeMap[functionList[i]].getFunctionString()); - } - } - return ret.join('\n'); - } - - /** - * @memberOf FunctionBuilderBase# - * @function - * @name getPrototypeStringFromFunctionNames - * - * @desc Return string of all functions converted - * - * @param {String[]} functionList - List of function names to build the string. - * @param {Object} [opt - Settings object passed to functionNode. See functionNode for more details. - * - * @returns {Array} Prototypes of all functions converted - * - */ - - }, { - key: 'getPrototypesFromFunctionNames', - value: function getPrototypesFromFunctionNames(functionList, opt) { - var ret = []; - for (var i = 0; i < functionList.length; ++i) { - var functionName = functionList[i]; - var node = this.nodeMap[functionName]; - if (node) { - ret.push(node.getFunctionPrototypeString(opt)); - } else if (this.nativeFunctions[functionName]) { - ret.push(this.nativeFunctions[functionName]); - } - } - return ret; - } - - /** - * @memberOf FunctionBuilderBase# - * @function - * @name getPrototypeStringFromFunctionNames - * - * @desc Return string of all functions converted - * - * @param {String[]} functionList - List of function names to build the string. - * @param {Object} opt - Settings object passed to functionNode. See functionNode for more details. - * - * @returns {String} Prototype string of all functions converted - * - */ - - }, { - key: 'getPrototypeStringFromFunctionNames', - value: function getPrototypeStringFromFunctionNames(functionList, opt) { - return this.getPrototypesFromFunctionNames(functionList, opt).toString(); - } - - /** - * @memberOf FunctionBuilderBase# - * @function - * @name getString - * - * Get string for a particular function name - * - * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack - * - * @returns {String} The string, of all the various functions. Trace optimized if functionName given - * - */ - - }, { - key: 'getString', - value: function getString(functionName, opt) { - if (opt === undefined) { - opt = {}; - } - - if (functionName) { - return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName, [], opt).reverse(), opt); - } - return this.getStringFromFunctionNames(Object.keys(this.nodeMap), opt); - } - }]); - - return FunctionBuilderBase; -}(); -},{}],59:[function(require,module,exports){ -'use strict'; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var utils = require('../core/utils'); -var acorn = require('acorn'); - -module.exports = function () { - - /** - * @constructor FunctionNodeBase - * - * @desc Represents a single function, inside JS, webGL, or openGL. - * - *

This handles all the raw state, converted state, etc. Of a single function.

- * - * @prop {String} functionName - Name of the function - * @prop {Function} jsFunction - The JS Function the node represents - * @prop {String} jsFunctionString - jsFunction.toString() - * @prop {String[]} paramNames - Parameter names of the function - * @prop {String[]} paramTypes - Shader land parameters type assumption - * @prop {Boolean} isRootKernel - Special indicator, for kernel function - * @prop {String} webglFunctionString - webgl converted function string - * @prop {String} openglFunctionString - opengl converted function string - * @prop {String[]} calledFunctions - List of all the functions called - * @param {String} functionName - Function name to assume, if its null, it attempts to extract from the function - * @param {Function|String} jsFunction - JS Function to do conversion - * @param {Object} options - * - */ - function BaseFunctionNode(functionName, jsFunction, options) { - _classCallCheck(this, BaseFunctionNode); - - this.calledFunctions = []; - this.calledFunctionsArguments = {}; - this.addFunction = null; - this.isRootKernel = false; - this.isSubKernel = false; - this.parent = null; - this.debug = null; - this.prototypeOnly = null; - this.constants = null; - this.output = null; - this.declarations = {}; - this.states = []; - this.fixIntegerDivisionAccuracy = null; - - var paramTypes = void 0; - var returnType = void 0; - if (options) { - if (options.hasOwnProperty('debug')) { - this.debug = options.debug; - } - if (options.hasOwnProperty('prototypeOnly')) { - this.prototypeOnly = options.prototypeOnly; - } - if (options.hasOwnProperty('constants')) { - this.constants = options.constants; - } - if (options.hasOwnProperty('output')) { - this.output = options.output; - } - if (options.hasOwnProperty('loopMaxIterations')) { - this.loopMaxIterations = options.loopMaxIterations; - } - if (options.hasOwnProperty('paramTypes')) { - this.paramTypes = paramTypes = options.paramTypes; - } - if (options.hasOwnProperty('returnType')) { - returnType = options.returnType; - } - if (options.hasOwnProperty('fixIntegerDivisionAccuracy')) { - this.fixIntegerDivisionAccuracy = options.fixIntegerDivisionAccuracy; - } - } - - // - // Missing jsFunction object exception - // - if (!jsFunction) { - throw 'jsFunction, parameter is missing'; - } - - // - // Setup jsFunction and its string property + validate them - // - this.jsFunctionString = jsFunction.toString(); - if (!utils.isFunctionString(this.jsFunctionString)) { - console.error('jsFunction, to string conversion check failed: not a function?', this.jsFunctionString); - throw 'jsFunction, to string conversion check failed: not a function?'; - } - - if (!utils.isFunction(jsFunction)) { - //throw 'jsFunction, is not a valid JS Function'; - this.jsFunction = null; - } else { - this.jsFunction = jsFunction; - } - - // - // Setup the function name property - // - this.functionName = functionName || jsFunction && jsFunction.name || utils.getFunctionNameFromString(this.jsFunctionString); - - if (!this.functionName) { - throw 'jsFunction, missing name argument or value'; - } - - // - // Extract parameter name, and its argument types - // - this.paramNames = utils.getParamNamesFromString(this.jsFunctionString); - if (paramTypes) { - if (Array.isArray(paramTypes)) { - if (paramTypes.length !== this.paramNames.length) { - throw 'Invalid argument type array length, against function length -> (' + paramTypes.length + ',' + this.paramNames.length + ')'; - } - this.paramTypes = paramTypes; - } else if ((typeof paramTypes === 'undefined' ? 'undefined' : _typeof(paramTypes)) === 'object') { - var paramVariableNames = Object.keys(paramTypes); - if (paramTypes.hasOwnProperty('returns')) { - this.returnType = paramTypes.returns; - paramVariableNames.splice(paramVariableNames.indexOf('returns'), 1); - } - if (paramVariableNames.length > 0 && paramVariableNames.length !== this.paramNames.length) { - throw 'Invalid argument type array length, against function length -> (' + paramVariableNames.length + ',' + this.paramNames.length + ')'; - } else { - this.paramTypes = this.paramNames.map(function (key) { - if (paramTypes.hasOwnProperty(key)) { - return paramTypes[key]; - } else { - return 'float'; - } - }); - } - } - } else { - this.paramTypes = []; - } - - // - // Return type handling - // - if (!this.returnType) { - this.returnType = returnType || 'float'; - } - } - - _createClass(BaseFunctionNode, [{ - key: 'isIdentifierConstant', - value: function isIdentifierConstant(paramName) { - if (!this.constants) return false; - return this.constants.hasOwnProperty(paramName); - } - }, { - key: 'isInput', - value: function isInput(paramName) { - return this.paramTypes[this.paramNames.indexOf(paramName)] === 'Input'; - } - }, { - key: 'setAddFunction', - value: function setAddFunction(fn) { - this.addFunction = fn; - return this; - } - }, { - key: 'pushState', - value: function pushState(state) { - this.states.push(state); - } - }, { - key: 'popState', - value: function popState(state) { - if (this.state !== state) { - throw new Error('Cannot popState ' + state + ' when in ' + this.state); - } - this.states.pop(); - } - }, { - key: 'isState', - value: function isState(state) { - return this.state === state; - } - }, { - key: 'getJsFunction', - - /** - * - * Core Functions - * - */ - - /** - * @memberOf FunctionNodeBase# - * @function - * @name getJSFunction - * - * @desc Gets and return the stored JS Function. - * Note: that this internally eval the function, if only the string was provided on construction - * - * @returns {Function} The function object - * - */ - value: function getJsFunction() { - if (this.jsFunction) { - return this.jsFunction; - } - - if (this.jsFunctionString) { - this.jsFunction = eval(this.jsFunctionString); - return this.jsFunction; - } - - throw 'Missing jsFunction, and jsFunctionString parameter'; - } - - /** - * @memberOf FunctionNodeBase# - * @function - * @name astMemberExpressionUnroll - * @desc Parses the abstract syntax tree for binary expression. - * - *

Utility function for astCallExpression.

- * - * @param {Object} ast - the AST object to parse - * - * @returns {String} the function namespace call, unrolled - */ - - }, { - key: 'astMemberExpressionUnroll', - value: function astMemberExpressionUnroll(ast) { - if (ast.type === 'Identifier') { - return ast.name; - } else if (ast.type === 'ThisExpression') { - return 'this'; - } - - if (ast.type === 'MemberExpression') { - if (ast.object && ast.property) { - //babel sniffing - if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') { - return this.astMemberExpressionUnroll(ast.property); - } - - return this.astMemberExpressionUnroll(ast.object) + '.' + this.astMemberExpressionUnroll(ast.property); - } - } - - //babel sniffing - if (ast.hasOwnProperty('expressions')) { - var firstExpression = ast.expressions[0]; - if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) { - return this.astMemberExpressionUnroll(ast.expressions[1]); - } - } - - // Failure, unknown expression - throw this.astErrorOutput('Unknown CallExpression_unroll', ast); - } - - /** - * @memberOf FunctionNodeBase# - * @function - * @name getJsAST - * - * @desc Parses the class function JS, and returns its Abstract Syntax Tree object. - * - * This is used internally to convert to shader code - * - * @param {Object} [inParser] - Parser to use, assumes in scope 'parser' if null or undefined - * - * @returns {Object} The function AST Object, note that result is cached under this.jsFunctionAST; - * - */ - - }, { - key: 'getJsAST', - value: function getJsAST(inParser) { - if (this.jsFunctionAST) { - return this.jsFunctionAST; - } - - inParser = inParser || acorn; - if (inParser === null) { - throw 'Missing JS to AST parser'; - } - - var ast = inParser.parse('var ' + this.functionName + ' = ' + this.jsFunctionString + ';', { - locations: true - }); - if (ast === null) { - throw 'Failed to parse JS code'; - } - - // take out the function object, outside the var declarations - var funcAST = ast.body[0].declarations[0].init; - this.jsFunctionAST = funcAST; - - return funcAST; - } - - /** - * @memberOf FunctionNodeBase# - * @function - * @name getFunctionString - * - * @desc Returns the converted webgl shader function equivalent of the JS function - * - * @returns {String} webgl function string, result is cached under this.webGlFunctionString - * - */ - - }, { - key: 'getFunctionString', - value: function getFunctionString() { - this.generate(); - return this.functionString; - } - - /** - * @memberOf FunctionNodeBase# - * @function - * @name setFunctionString - * - * @desc Set the functionString value, overwriting it - * - * @param {String} functionString - Shader code string, representing the function - * - */ - - }, { - key: 'setFunctionString', - value: function setFunctionString(functionString) { - this.functionString = functionString; - } - - /** - * @memberOf FunctionNodeBase# - * @function - * @name getParamType - * - * @desc Return the type of parameter sent to subKernel/Kernel. - * - * @param {String} paramName - Name of the parameter - * - * @returns {String} Type of the parameter - * - */ - - }, { - key: 'getParamType', - value: function getParamType(paramName) { - var paramIndex = this.paramNames.indexOf(paramName); - if (paramIndex === -1) { - if (this.declarations.hasOwnProperty(paramName)) { - return this.declarations[paramName]; - } else { - return null; - } - } else { - if (!this.parent) { - if (this.paramTypes[paramIndex]) return this.paramTypes[paramIndex]; - } else { - if (this.paramTypes[paramIndex]) return this.paramTypes[paramIndex]; - var calledFunctionArguments = this.parent.calledFunctionsArguments[this.functionName]; - for (var i = 0; i < calledFunctionArguments.length; i++) { - var calledFunctionArgument = calledFunctionArguments[i]; - if (calledFunctionArgument[paramIndex] !== null) { - return this.paramTypes[paramIndex] = calledFunctionArgument[paramIndex].type; - } - } - } - } - return null; - } - - /** - * @memberOf FunctionNodeBase# - * @function - * @name getUserParamName - * - * @desc Return the name of the *user parameter*(subKernel parameter) corresponding - * to the parameter supplied to the kernel - * - * @param {String} paramName - Name of the parameter - * - * @returns {String} Name of the parameter - * - */ - - }, { - key: 'getUserParamName', - value: function getUserParamName(paramName) { - var paramIndex = this.paramNames.indexOf(paramName); - if (paramIndex === -1) return null; - if (!this.parent) return null; - var calledFunctionArguments = this.parent.calledFunctionsArguments[this.functionName]; - for (var i = 0; i < calledFunctionArguments.length; i++) { - var calledFunctionArgument = calledFunctionArguments[i]; - var param = calledFunctionArgument[paramIndex]; - if (param !== null && param.type !== 'Integer') { - return param.name; - } - } - return null; - } - }, { - key: 'generate', - value: function generate(options) { - throw new Error('generate not defined on BaseFunctionNode'); - } - - /** - * @memberOf FunctionNodeBase# - * @function - * @name astGeneric - * - * @desc Parses the abstract syntax tree for generically to its respective function - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the parsed string array - */ - - }, { - key: 'astGeneric', - value: function astGeneric(ast, retArr) { - if (ast === null) { - throw this.astErrorOutput('NULL ast', ast); - } else { - if (Array.isArray(ast)) { - for (var i = 0; i < ast.length; i++) { - this.astGeneric(ast[i], retArr); - } - return retArr; - } - - switch (ast.type) { - case 'FunctionDeclaration': - return this.astFunctionDeclaration(ast, retArr); - case 'FunctionExpression': - return this.astFunctionExpression(ast, retArr); - case 'ReturnStatement': - return this.astReturnStatement(ast, retArr); - case 'Literal': - return this.astLiteral(ast, retArr); - case 'BinaryExpression': - return this.astBinaryExpression(ast, retArr); - case 'Identifier': - return this.astIdentifierExpression(ast, retArr); - case 'AssignmentExpression': - return this.astAssignmentExpression(ast, retArr); - case 'ExpressionStatement': - return this.astExpressionStatement(ast, retArr); - case 'EmptyStatement': - return this.astEmptyStatement(ast, retArr); - case 'BlockStatement': - return this.astBlockStatement(ast, retArr); - case 'IfStatement': - return this.astIfStatement(ast, retArr); - case 'BreakStatement': - return this.astBreakStatement(ast, retArr); - case 'ContinueStatement': - return this.astContinueStatement(ast, retArr); - case 'ForStatement': - return this.astForStatement(ast, retArr); - case 'WhileStatement': - return this.astWhileStatement(ast, retArr); - case 'DoWhileStatement': - return this.astDoWhileStatement(ast, retArr); - case 'VariableDeclaration': - return this.astVariableDeclaration(ast, retArr); - case 'VariableDeclarator': - return this.astVariableDeclarator(ast, retArr); - case 'ThisExpression': - return this.astThisExpression(ast, retArr); - case 'SequenceExpression': - return this.astSequenceExpression(ast, retArr); - case 'UnaryExpression': - return this.astUnaryExpression(ast, retArr); - case 'UpdateExpression': - return this.astUpdateExpression(ast, retArr); - case 'LogicalExpression': - return this.astLogicalExpression(ast, retArr); - case 'MemberExpression': - return this.astMemberExpression(ast, retArr); - case 'CallExpression': - return this.astCallExpression(ast, retArr); - case 'ArrayExpression': - return this.astArrayExpression(ast, retArr); - case 'DebuggerStatement': - return this.astDebuggerStatement(ast, retArr); - } - - throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast); - } - } - /** - * @function - * @name astErrorOutput - * @ignore - * @desc To throw the AST error, with its location. - * - * @todo add location support fpr the AST error - * - * @param {Object} error - the error message output - * @param {Object} ast - the AST object where the error is - */ - - }, { - key: 'astErrorOutput', - value: function astErrorOutput(error, ast) { - console.error(utils.getAstString(this.jsFunctionString, ast)); - console.error(error, ast, this); - return error; - } - }, { - key: 'astDebuggerStatement', - value: function astDebuggerStatement(arrNode, retArr) { - return retArr; - } - }, { - key: 'astFunctionDeclaration', - value: function astFunctionDeclaration(ast, retArr) { - return retArr; - } - }, { - key: 'astFunctionExpression', - value: function astFunctionExpression(ast, retArr) { - return retArr; - } - }, { - key: 'astReturnStatement', - value: function astReturnStatement(ast, retArr) { - return retArr; - } - }, { - key: 'astLiteral', - value: function astLiteral(ast, retArr) { - return retArr; - } - }, { - key: 'astBinaryExpression', - value: function astBinaryExpression(ast, retArr) { - return retArr; - } - }, { - key: 'astIdentifierExpression', - value: function astIdentifierExpression(ast, retArr) { - return retArr; - } - }, { - key: 'astAssignmentExpression', - value: function astAssignmentExpression(ast, retArr) { - return retArr; - } - }, { - key: 'astExpressionStatement', - value: function astExpressionStatement(ast, retArr) { - return retArr; - } - }, { - key: 'astEmptyStatement', - value: function astEmptyStatement(ast, retArr) { - return retArr; - } - }, { - key: 'astBlockStatement', - value: function astBlockStatement(ast, retArr) { - return retArr; - } - }, { - key: 'astIfStatement', - value: function astIfStatement(ast, retArr) { - return retArr; - } - }, { - key: 'astBreakStatement', - value: function astBreakStatement(ast, retArr) { - return retArr; - } - }, { - key: 'astContinueStatement', - value: function astContinueStatement(ast, retArr) { - return retArr; - } - }, { - key: 'astForStatement', - value: function astForStatement(ast, retArr) { - return retArr; - } - }, { - key: 'astWhileStatement', - value: function astWhileStatement(ast, retArr) { - return retArr; - } - }, { - key: 'astDoWhileStatement', - value: function astDoWhileStatement(ast, retArr) { - return retArr; - } - }, { - key: 'astVariableDeclaration', - value: function astVariableDeclaration(ast, retArr) { - return retArr; - } - }, { - key: 'astVariableDeclarator', - value: function astVariableDeclarator(ast, retArr) { - return retArr; - } - }, { - key: 'astThisExpression', - value: function astThisExpression(ast, retArr) { - return retArr; - } - }, { - key: 'astSequenceExpression', - value: function astSequenceExpression(ast, retArr) { - return retArr; - } - }, { - key: 'astUnaryExpression', - value: function astUnaryExpression(ast, retArr) { - return retArr; - } - }, { - key: 'astUpdateExpression', - value: function astUpdateExpression(ast, retArr) { - return retArr; - } - }, { - key: 'astLogicalExpression', - value: function astLogicalExpression(ast, retArr) { - return retArr; - } - }, { - key: 'astMemberExpression', - value: function astMemberExpression(ast, retArr) { - return retArr; - } - }, { - key: 'astCallExpression', - value: function astCallExpression(ast, retArr) { - return retArr; - } - }, { - key: 'astArrayExpression', - value: function astArrayExpression(ast, retArr) { - return retArr; - } - - /** - * @ignore - * @function - * @name pushParameter - * - * @desc [INTERNAL] pushes a fn parameter onto retArr and 'casts' to int if necessary - * i.e. deal with force-int-parameter state - * - * @param {Array} retArr - return array string - * @param {String} parameter - the parameter name - * - */ - - }, { - key: 'pushParameter', - value: function pushParameter(retArr, parameter) { - if (this.isState('in-get-call-parameters')) { - retArr.push('int(' + parameter + ')'); - } else { - retArr.push(parameter); - } - } - }, { - key: 'state', - get: function get() { - return this.states[this.states.length - 1]; - } - }]); - - return BaseFunctionNode; -}(); -},{"../core/utils":84,"acorn":86}],60:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var utils = require('../core/utils'); -var Input = require('../core/input'); - -module.exports = function () { - - /** - * @constructor KernelBase - * - * @desc Implements the base class for Kernels, and is used as a - * parent class for all Kernel implementations. - * - * This contains the basic methods needed by all Kernel implementations, - * like setDimensions, addSubKernel, etc. - * - * @prop {Array} paramNames - Name of the parameters of the kernel function - * @prop {String} fnString - Kernel function as a String - * @prop {Array} dimensions - Dimensions of the kernel function, this.thread.x, etc. - * @prop {Boolean} debug - Toggle debug mode - * @prop {String} graphical - Toggle graphical mode - * @prop {number} loopMaxIterations - Maximum number of loop iterations - * @prop {Object} constants - Global constants - * @prop {Array} subKernels - Sub kernels bound to this kernel instance - * @prop {Object} subKernelProperties - Sub kernels bound to this kernel instance as key/value pairs - * @prop {Array} subKernelOutputVariableNames - Names of the variables outputted by the subkerls - * @prop {Boolean} fixIntegerDivisionAccuracy - fix issues with some graphics cards not returning whole numbers when dividing by factors of 3 - * - */ - function KernelBase(fnString, settings) { - _classCallCheck(this, KernelBase); - - this.paramNames = utils.getParamNamesFromString(fnString); - this.fnString = fnString; - this.output = null; - this.debug = false; - this.graphical = false; - this.loopMaxIterations = 0; - this.constants = null; - this.wraparound = null; - this.hardcodeConstants = null; - this.outputToTexture = null; - this.outputImmutable = null; - this.texSize = null; - this._canvas = null; - this._webGl = null; - this.threadDim = null; - this.floatTextures = null; - this.floatOutput = null; - this.floatOutputForce = null; - this.addFunction = null; - this.functions = null; - this.nativeFunctions = null; - this.subKernels = null; - this.subKernelProperties = null; - this.subKernelNames = null; - this.subKernelOutputVariableNames = null; - this.functionBuilder = null; - this.paramTypes = null; - this.paramSizes = null; - this.fixIntegerDivisionAccuracy = null; - - for (var p in settings) { - if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue; - this[p] = settings[p]; - } - if (settings.hasOwnProperty('canvas')) { - this._canvas = settings.canvas; - } - if (settings.hasOwnProperty('output')) { - this.setOutput(settings.output); // Flatten output object - } - - if (!this._canvas) this._canvas = utils.initCanvas(); - } - - _createClass(KernelBase, [{ - key: 'build', - value: function build() { - throw new Error('"build" not defined on Base'); - } - - /** - * @memberOf KernelBase# - * @function - * @name setupParams - * - * @desc Setup the parameter types for the parameters - * supplied to the Kernel function - * - * @param {IArguments} args - The actual parameters sent to the Kernel - * - */ - - }, { - key: 'setupParams', - value: function setupParams(args) { - this.paramTypes = []; - this.paramSizes = []; - for (var i = 0; i < args.length; i++) { - var arg = args[i]; - this.paramTypes.push(utils.getArgumentType(arg)); - this.paramSizes.push(arg.constructor === Input ? arg.size : null); - } - } - }, { - key: 'setAddFunction', - value: function setAddFunction(cb) { - this.addFunction = cb; - return this; - } - }, { - key: 'setFunctions', - value: function setFunctions(functions) { - this.functions = functions; - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name setOutput - * - * @desc Set dimensions of the kernel function - * - * @param {Array|Object} output - The output array to set the kernel output size to - * - */ - - }, { - key: 'setOutput', - value: function setOutput(output) { - if (output.hasOwnProperty('x')) { - if (output.hasOwnProperty('y')) { - if (output.hasOwnProperty('z')) { - this.output = [output.x, output.y, output.z]; - } else { - this.output = [output.x, output.y]; - } - } else { - this.output = [output.x]; - } - } else { - this.output = output; - } - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name setDebug - * - * @desc Toggle debug mode - * - * @param {Boolean} flag - true to enable debug - * - */ - - }, { - key: 'setDebug', - value: function setDebug(flag) { - this.debug = flag; - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name setGraphical - * - * @desc Toggle graphical output mode - * - * @param {Boolean} flag - true to enable graphical output - * - */ - - }, { - key: 'setGraphical', - value: function setGraphical(flag) { - this.graphical = flag; - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name setLoopMaxIterations - * - * @desc Set the maximum number of loop iterations - * - * @param {number} max - iterations count - * - */ - - }, { - key: 'setLoopMaxIterations', - value: function setLoopMaxIterations(max) { - this.loopMaxIterations = max; - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name setFixIntegerDivisionAccuracy - * - * @desc Fix division by factor of 3 FP accuracy bug - * - * @param {Boolean} fix - should fix - * - */ - - }, { - key: 'setFixIntegerDivisionAccuracy', - value: function setFixIntegerDivisionAccuracy(fix) { - this.fixIntegerDivisionAccuracy = fix; - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name setConstants - * @desc Set Constants - */ - - }, { - key: 'setConstants', - value: function setConstants(constants) { - this.constants = constants; - return this; - } - }, { - key: 'setWraparound', - value: function setWraparound(flag) { - console.warn('Wraparound mode is not supported and undocumented.'); - this.wraparound = flag; - return this; - } - }, { - key: 'setHardcodeConstants', - value: function setHardcodeConstants(flag) { - this.hardcodeConstants = flag; - return this; - } - }, { - key: 'setOutputToTexture', - value: function setOutputToTexture(flag) { - this.outputToTexture = flag; - return this; - } - }, { - key: 'setOutputImmutable', - value: function setOutputImmutable(flag) { - this.outputImmutable = flag; - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name setFloatTextures - * - * @desc Toggle texture output mode - * - * @param {Boolean} flag - true to enable floatTextures - * - */ - - }, { - key: 'setFloatTextures', - value: function setFloatTextures(flag) { - this.floatTextures = flag; - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name setFloatOutput - * - * @desc Toggle output mode - * - * @param {Boolean} flag - true to enable float - * - */ - - }, { - key: 'setFloatOutput', - value: function setFloatOutput(flag) { - this.floatOutput = flag; - return this; - } - }, { - key: 'setFloatOutputForce', - value: function setFloatOutputForce(flag) { - this.floatOutputForce = flag; - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name setCanvas - * - * @desc Bind the canvas to kernel - * - * @param {Canvas} canvas - Canvas to bind - * - */ - - }, { - key: 'setCanvas', - value: function setCanvas(canvas) { - this._canvas = canvas; - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name setCanvas - * - * @desc Bind the webGL instance to kernel - * - * @param {Canvas} webGL - webGL instance to bind - * - */ - - }, { - key: 'setWebGl', - value: function setWebGl(webGl) { - this._webGl = webGl; - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name getCanvas() - * - * @desc Returns the current canvas instance bound to the kernel - * - */ - - }, { - key: 'getCanvas', - value: function getCanvas() { - return this._canvas; - } - - /** - * @memberOf KernelBase# - * @function - * @name getWebGl() - * - * @desc Returns the current webGl instance bound to the kernel - * - */ - - }, { - key: 'getWebGl', - value: function getWebGl() { - return this._webGl; - } - }, { - key: 'validateOptions', - value: function validateOptions() { - throw new Error('validateOptions not defined'); - } - }, { - key: 'exec', - value: function exec() { - return this.execute.apply(this, arguments); - } - }, { - key: 'execute', - value: function execute() { - var _this = this; - - // - // Prepare the required objects - // - var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments); - - // - // Setup and return the promise, and execute the function, in synchronous mode - // - return utils.newPromise(function (accept, reject) { - try { - accept(_this.run.apply(_this, args)); - } catch (e) { - // - // Error : throw rejection - // - reject(e); - } - }); - } - - /** - * @memberOf KernelBase# - * @function - * @name addSubKernel - * - * @desc Add a sub kernel to the root kernel instance. - * This is what `createKernelMap` uses. - * - * @param {String} fnString - function (as a String) of the subKernel to add - * - */ - - }, { - key: 'addSubKernel', - value: function addSubKernel(fnString) { - if (this.subKernels === null) { - this.subKernels = []; - this.subKernelNames = []; - } - this.subKernels.push(fnString); - this.subKernelNames.push(utils.getFunctionNameFromString(fnString)); - return this; - } - - /** - * @memberOf KernelBase# - * @function - * @name addSubKernelProperty - * - * @desc Add a sub kernel to the root kernel instance, indexed by a property name - * This is what `createKernelMap` uses. - * - * @param {String} property - property key for the subKernel - * @param {String} fnString - function (as a String) of the subKernel to add - * - */ - - }, { - key: 'addSubKernelProperty', - value: function addSubKernelProperty(property, fnString) { - if (this.subKernelProperties === null) { - this.subKernelProperties = {}; - this.subKernelNames = []; - } - if (this.subKernelProperties.hasOwnProperty(property)) { - throw new Error('cannot add sub kernel ' + property + ', already defined'); - } - this.subKernelProperties[property] = fnString; - this.subKernelNames.push(utils.getFunctionNameFromString(fnString)); - return this; - } - }, { - key: 'addNativeFunction', - value: function addNativeFunction(name, source) { - this.functionBuilder.addNativeFunction(name, source); - } - - /** - * - * Destroys all memory associated with this kernel - * - * @name destroy - * @function - * @memberOf KernelBase# - * - * * @param {Boolean} removeCanvasReferences remve any associated canvas references? - * - */ - - }, { - key: 'destroy', - value: function destroy() {} - }]); - - return KernelBase; -}(); -},{"../core/input":81,"../core/utils":84}],61:[function(require,module,exports){ -'use strict'; - -var utils = require('../core/utils'); - -module.exports = function kernelRunShortcut(kernel) { - var shortcut = function shortcut() { - return kernel.run.apply(kernel, arguments); - }; - - utils.allPropertiesOf(kernel).forEach(function (key) { - if (key[0] === '_' && key[1] === '_') return; - if (typeof kernel[key] === 'function') { - if (key.substring(0, 3) === 'add' || key.substring(0, 3) === 'set') { - shortcut[key] = function () { - kernel[key].apply(kernel, arguments); - return shortcut; - }; - } else { - shortcut[key] = kernel[key].bind(kernel); - } - } else { - shortcut.__defineGetter__(key, function () { - return kernel[key]; - }); - shortcut.__defineSetter__(key, function (value) { - kernel[key] = value; - }); - } - }); - - shortcut.kernel = kernel; - - return shortcut; -}; -},{"../core/utils":84}],62:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var utils = require('../core/utils'); -var kernelRunShortcut = require('./kernel-run-shortcut'); - -module.exports = function () { - - /** - * @constructor BaseRunner - * - * @desc Represents the 'private/protected' namespace of the GPU class - * - *

I know @private makes more sense, but since the documentation engine state is undetirmined. - * (See https://github.com/gpujs/gpu.js/issues/19 regarding documentation engine issue) - * File isolation is currently the best way to go.

- * - * *base.js* internal functions namespace
- * *gpu.js* PUBLIC function namespace
- * - * @prop {Object} settings - Settings object used to set Dimensions, etc. - * @prop {String} kernel - Current kernel instance - * @prop {Object} canvas - Canvas instance attached to the kernel - * @prop {Object} webGl - WebGl instance attached to the kernel - * @prop {Function} fn - Kernel function to run - * @prop {Object} functionBuilder - FunctionBuilder instance - * @prop {String} fnString - Kernel function (as a String) - * @prop {String} endianness - endian information like Little-endian, Big-endian. - * - */ - - function BaseRunner(functionBuilder, settings) { - _classCallCheck(this, BaseRunner); - - settings = settings || {}; - this.kernel = settings.kernel; - this.canvas = settings.canvas; - this.webGl = settings.webGl; - this.fn = null; - this.functionBuilder = functionBuilder; - this.fnString = null; - this.endianness = utils.systemEndianness(); - } - - /** - * @memberOf BaseRunner# - * @function - * @name textureToArray - * - * @desc Converts the provided Texture instance to a JavaScript Array - * - * @param {Object} texture - Texture Object - * - */ - - - _createClass(BaseRunner, [{ - key: 'textureToArray', - value: function textureToArray(texture) { - var copy = this.createKernel(function (x) { - return x[this.thread.z][this.thread.y][this.thread.x]; - }); - - return copy(texture); - } - - /** - * @memberOf BaseRunner# - * @function - * - * @name deleteTexture - * - * @desc Deletes the provided Texture instance - * - * @param {Object} texture - Texture Object - */ - - }, { - key: 'deleteTexture', - value: function deleteTexture(texture) { - this.webGl.deleteTexture(texture.texture); - } - - /** - * @memberOf BaseRunner# - * @function - * @name buildPromiseKernel - * - * @desc Get and returns the ASYNCHRONOUS executor, of a class and kernel - * This returns a Promise object from an argument set. - * - * Note that there is no current implementation. - * - */ - - }, { - key: 'buildPromiseKernel', - value: function buildPromiseKernel() { - throw new Error('not yet implemented'); - } - }, { - key: 'getMode', - value: function getMode() { - throw new Error('"mode" not implemented on BaseRunner'); - } - - /** - * @memberOf BaseRunner# - * @function - * - * @name buildKernel - * - * @desc Get and returns the Synchronous executor, of a class and kernel - * Which returns the result directly after passing the arguments. - * - */ - - }, { - key: 'buildKernel', - value: function buildKernel(fn, settings) { - settings = Object.assign({}, settings || {}); - var fnString = fn.toString(); - if (!settings.functionBuilder) { - settings.functionBuilder = this.functionBuilder; - } - - if (!settings.canvas) { - settings.canvas = this.canvas; - } - - if (!settings.webGl) { - settings.webGl = this.webgl; - } - - return kernelRunShortcut(new this.Kernel(fnString, settings)); - } - }]); - - return BaseRunner; -}(); -},{"../core/utils":84,"./kernel-run-shortcut":61}],63:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var FunctionBuilderBase = require('../function-builder-base'); -var WebGLFunctionNode = require('./function-node'); - -/** - * @class WebGLFunctionBuilder - * - * @extends FunctionBuilderBase - * - * @desc Builds webGl functions (shaders) from JavaScript function Strings - * - */ -module.exports = function (_FunctionBuilderBase) { - _inherits(WebGLFunctionBuilder, _FunctionBuilderBase); - - function WebGLFunctionBuilder() { - _classCallCheck(this, WebGLFunctionBuilder); - - var _this = _possibleConstructorReturn(this, (WebGLFunctionBuilder.__proto__ || Object.getPrototypeOf(WebGLFunctionBuilder)).call(this)); - - _this.Node = WebGLFunctionNode; - return _this; - } - - //--------------------------------------------------------- - // - // Polyfill stuff - // - //--------------------------------------------------------- - - // Round function used in polyfill - - - _createClass(WebGLFunctionBuilder, [{ - key: 'polyfillStandardFunctions', - - - /** - * @memberOf FunctionBuilderBase# - * @function - * @name polyfillStandardFunctions - * - * @desc Polyfill in the missing Math functions (round) - * - */ - value: function polyfillStandardFunctions() { - this.addFunction('round', _round); - } - }], [{ - key: 'round', - value: function round(a) { - return _round(a); - } - }]); - - return WebGLFunctionBuilder; -}(FunctionBuilderBase); - -function _round(a) { - return Math.floor(a + 0.5); -} -},{"../function-builder-base":58,"./function-node":64}],64:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var FunctionNodeBase = require('../function-node-base'); -var utils = require('../../core/utils'); -// Closure capture for the ast function, prevent collision with existing AST functions -// The prefixes to use -var jsMathPrefix = 'Math.'; -var localPrefix = 'this.'; -var constantsPrefix = 'this.constants.'; - -var DECODE32_ENCODE32 = /decode32\(\s+encode32\(/g; -var ENCODE32_DECODE32 = /encode32\(\s+decode32\(/g; - -// these debugs were hugely usefull... -// TODO: optimise out - webpack/babel options? maybe some generic logging support in core/utils? -// const debugLog = console.log -var debugLog = function debugLog() {}; -/** - * @class WebGLFunctionNode - * - * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to generate its respective webGL code. - * - * @extends FunctionNodeBase - * - * @param {functionNode} inNode - The function node object - * - * @returns the converted webGL function string - * - */ -module.exports = function (_FunctionNodeBase) { - _inherits(WebGLFunctionNode, _FunctionNodeBase); - - function WebGLFunctionNode() { - _classCallCheck(this, WebGLFunctionNode); - - return _possibleConstructorReturn(this, (WebGLFunctionNode.__proto__ || Object.getPrototypeOf(WebGLFunctionNode)).apply(this, arguments)); - } - - _createClass(WebGLFunctionNode, [{ - key: 'generate', - value: function generate() { - if (this.debug) { - debugLog(this); - } - if (this.prototypeOnly) { - return WebGLFunctionNode.astFunctionPrototype(this.getJsAST(), [], this).join('').trim(); - } else { - this.functionStringArray = this.astGeneric(this.getJsAST(), [], this); - } - this.functionString = webGlRegexOptimize(this.functionStringArray.join('').trim()); - return this.functionString; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astFunctionDeclaration - * - * @desc Parses the abstract syntax tree for to its *named function declaration* - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astFunctionDeclaration', - value: function astFunctionDeclaration(ast, retArr) { - if (this.addFunction) { - this.addFunction(null, utils.getAstString(this.jsFunctionString, ast)); - } - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astFunctionPrototype - * @static - * - * @desc Parses the abstract syntax tree for to its *named function prototype* - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astFunctionExpression', - - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astFunctionExpression - * - * @desc Parses the abstract syntax tree for to its *named function* - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - value: function astFunctionExpression(ast, retArr) { - - // Setup function return type and name - if (this.isRootKernel) { - retArr.push('void'); - this.kernalAst = ast; - } else { - retArr.push(this.returnType); - } - retArr.push(' '); - retArr.push(this.functionName); - retArr.push('('); - - if (!this.isRootKernel) { - // Arguments handling - for (var i = 0; i < this.paramNames.length; ++i) { - var paramName = this.paramNames[i]; - - if (i > 0) { - retArr.push(', '); - } - var type = this.getParamType(paramName); - switch (type) { - case 'Texture': - case 'Input': - case 'Array': - retArr.push('sampler2D'); - break; - default: - retArr.push('float'); - } - - retArr.push(' '); - retArr.push('user_'); - retArr.push(paramName); - } - } - - // Function opening - retArr.push(') {\n'); - - // Body statement iteration - for (var _i = 0; _i < ast.body.body.length; ++_i) { - this.astGeneric(ast.body.body[_i], retArr); - retArr.push('\n'); - } - - // Function closing - retArr.push('}\n'); - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astReturnStatement - * - * @desc Parses the abstract syntax tree for to *return* statement - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astReturnStatement', - value: function astReturnStatement(ast, retArr) { - if (this.isRootKernel) { - retArr.push('kernelResult = '); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - retArr.push('return;'); - } else if (this.isSubKernel) { - retArr.push(this.functionName + 'Result = '); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - retArr.push('return ' + this.functionName + 'Result;'); - } else { - retArr.push('return '); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - } - - //throw this.astErrorOutput( - // 'Non main function return, is not supported : '+this.currentFunctionNamespace, - // ast - //); - - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astLiteral - * - * @desc Parses the abstract syntax tree for *literal value* - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astLiteral', - value: function astLiteral(ast, retArr) { - - // Reject non numeric literals - if (isNaN(ast.value)) { - throw this.astErrorOutput('Non-numeric literal not supported : ' + ast.value, ast); - } - - // Push the literal value as a float/int - retArr.push(ast.value); - - var inGetParams = this.isState('in-get-call-parameters'); - // If it was an int, node made a float if necessary - if (Number.isInteger(ast.value)) { - if (!inGetParams) { - retArr.push('.0'); - } - } else if (this.isState('in-get-call-parameters')) { - // or cast to an int as we are addressing an input array - retArr.pop(); - retArr.push('int('); - retArr.push(ast.value); - retArr.push(')'); - } - - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astBinaryExpression - * - * @desc Parses the abstract syntax tree for *binary* expression - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astBinaryExpression', - value: function astBinaryExpression(ast, retArr) { - retArr.push('('); - - if (ast.operator === '%') { - retArr.push('mod('); - this.astGeneric(ast.left, retArr); - retArr.push(','); - this.astGeneric(ast.right, retArr); - retArr.push(')'); - } else if (ast.operator === '===') { - this.astGeneric(ast.left, retArr); - retArr.push('=='); - this.astGeneric(ast.right, retArr); - } else if (ast.operator === '!==') { - this.astGeneric(ast.left, retArr); - retArr.push('!='); - this.astGeneric(ast.right, retArr); - } else if (this.fixIntegerDivisionAccuracy && ast.operator === '/') { - retArr.push('div_with_int_check('); - this.astGeneric(ast.left, retArr); - retArr.push(', '); - this.astGeneric(ast.right, retArr); - retArr.push(')'); - } else { - this.astGeneric(ast.left, retArr); - retArr.push(ast.operator); - this.astGeneric(ast.right, retArr); - } - - retArr.push(')'); - - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astIdentifierExpression - * - * @desc Parses the abstract syntax tree for *identifier* expression - * - * @param {Object} idtNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astIdentifierExpression', - value: function astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode); - } - // do we need to cast addressing vales to float? - var castFloat = !this.isState('in-get-call-parameters'); - - switch (idtNode.name) { - case 'gpu_threadX': - castFloat && retArr.push('float('); - retArr.push('threadId.x'); - castFloat && retArr.push(')'); - break; - case 'gpu_threadY': - castFloat && retArr.push('float('); - retArr.push('threadId.y'); - castFloat && retArr.push(')'); - break; - case 'gpu_threadZ': - castFloat && retArr.push('float('); - retArr.push('threadId.z'); - castFloat && retArr.push(')'); - break; - case 'gpu_outputX': - retArr.push('uOutputDim.x'); - break; - case 'gpu_outputY': - retArr.push('uOutputDim.y'); - break; - case 'gpu_outputZ': - retArr.push('uOutputDim.z'); - break; - case 'Infinity': - // https://stackoverflow.com/a/47543127/1324039 - retArr.push('3.402823466e+38'); - break; - default: - if (this.constants && this.constants.hasOwnProperty(idtNode.name)) { - this.pushParameter(retArr, 'constants_' + idtNode.name); - } else { - var userParamName = this.getUserParamName(idtNode.name); - if (userParamName !== null) { - this.pushParameter(retArr, 'user_' + userParamName); - } else { - this.pushParameter(retArr, 'user_' + idtNode.name); - } - } - } - - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astForStatement - * - * @desc Parses the abstract syntax tree forfor *for-loop* expression - * - * @param {Object} forNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the parsed webgl string - */ - - }, { - key: 'astForStatement', - value: function astForStatement(forNode, retArr) { - if (forNode.type !== 'ForStatement') { - throw this.astErrorOutput('Invalid for statment', forNode); - } - - if (forNode.test && forNode.test.type === 'BinaryExpression') { - if (forNode.test.right.type === 'Identifier' && forNode.test.operator === '<' && this.isIdentifierConstant(forNode.test.right.name) === false) { - - if (!this.loopMaxIterations) { - console.warn('Warning: loopMaxIterations is not set! Using default of 1000 which may result in unintended behavior.'); - console.warn('Set loopMaxIterations or use a for loop of fixed length to silence this message.'); - } - - retArr.push('for ('); - this.astGeneric(forNode.init, retArr); - this.astGeneric(forNode.test.left, retArr); - retArr.push(forNode.test.operator); - retArr.push('LOOP_MAX'); - retArr.push(';'); - this.astGeneric(forNode.update, retArr); - retArr.push(')'); - - retArr.push('{\n'); - retArr.push('if ('); - this.astGeneric(forNode.test.left, retArr); - retArr.push(forNode.test.operator); - this.astGeneric(forNode.test.right, retArr); - retArr.push(') {\n'); - if (forNode.body.type === 'BlockStatement') { - for (var i = 0; i < forNode.body.body.length; i++) { - this.astGeneric(forNode.body.body[i], retArr); - } - } else { - this.astGeneric(forNode.body, retArr); - } - retArr.push('} else {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); - - return retArr; - } else { - var declarations = JSON.parse(JSON.stringify(forNode.init.declarations)); - var updateArgument = forNode.update.argument; - if (!Array.isArray(declarations) || declarations.length < 1) { - debugLog(this.jsFunctionString); - throw new Error('Error: Incompatible for loop declaration'); - } - - if (declarations.length > 1) { - var initArgument = null; - for (var _i2 = 0; _i2 < declarations.length; _i2++) { - var declaration = declarations[_i2]; - if (declaration.id.name === updateArgument.name) { - initArgument = declaration; - declarations.splice(_i2, 1); - } else { - retArr.push('float '); - this.astGeneric(declaration, retArr); - retArr.push(';'); - } - } - - retArr.push('for (float '); - this.astGeneric(initArgument, retArr); - retArr.push(';'); - } else { - retArr.push('for ('); - this.astGeneric(forNode.init, retArr); - } - - this.astGeneric(forNode.test, retArr); - retArr.push(';'); - this.astGeneric(forNode.update, retArr); - retArr.push(')'); - this.astGeneric(forNode.body, retArr); - return retArr; - } - } - - throw this.astErrorOutput('Invalid for statement', forNode); - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astWhileStatement - * - * @desc Parses the abstract syntax tree for *while* loop - * - * - * @param {Object} whileNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the parsed webgl string - */ - - }, { - key: 'astWhileStatement', - value: function astWhileStatement(whileNode, retArr) { - if (whileNode.type !== 'WhileStatement') { - throw this.astErrorOutput('Invalid while statment', whileNode); - } - - retArr.push('for (float i = 0.0; i < LOOP_MAX; i++) {'); - retArr.push('if ('); - this.astGeneric(whileNode.test, retArr); - retArr.push(') {\n'); - this.astGeneric(whileNode.body, retArr); - retArr.push('} else {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); - - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astWhileStatement - * - * @desc Parses the abstract syntax tree for *do while* loop - * - * - * @param {Object} doWhileNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the parsed webgl string - */ - - }, { - key: 'astDoWhileStatement', - value: function astDoWhileStatement(doWhileNode, retArr) { - if (doWhileNode.type !== 'DoWhileStatement') { - throw this.astErrorOutput('Invalid while statment', doWhileNode); - } - - retArr.push('for (float i = 0.0; i < LOOP_MAX; i++) {'); - this.astGeneric(doWhileNode.body, retArr); - retArr.push('if (!'); - this.astGeneric(doWhileNode.test, retArr); - retArr.push(') {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); - - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astAssignmentExpression - * - * @desc Parses the abstract syntax tree for *Assignment* Expression - * - * @param {Object} assNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astAssignmentExpression', - value: function astAssignmentExpression(assNode, retArr) { - if (assNode.operator === '%=') { - this.astGeneric(assNode.left, retArr); - retArr.push('='); - retArr.push('mod('); - this.astGeneric(assNode.left, retArr); - retArr.push(','); - this.astGeneric(assNode.right, retArr); - retArr.push(')'); - } else { - this.astGeneric(assNode.left, retArr); - retArr.push(assNode.operator); - this.astGeneric(assNode.right, retArr); - return retArr; - } - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astEmptyStatement - * - * @desc Parses the abstract syntax tree for an *Empty* Statement - * - * @param {Object} eNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astEmptyStatement', - value: function astEmptyStatement(eNode, retArr) { - //retArr.push(';\n'); - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astBlockStatement - * - * @desc Parses the abstract syntax tree for *Block* statement - * - * @param {Object} bNode - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astBlockStatement', - value: function astBlockStatement(bNode, retArr) { - retArr.push('{\n'); - for (var i = 0; i < bNode.body.length; i++) { - this.astGeneric(bNode.body[i], retArr); - } - retArr.push('}\n'); - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astExpressionStatement - * - * @desc Parses the abstract syntax tree for *generic expression* statement - * - * @param {Object} esNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astExpressionStatement', - value: function astExpressionStatement(esNode, retArr) { - this.astGeneric(esNode.expression, retArr); - retArr.push(';\n'); - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astVariableDeclaration - * - * @desc Parses the abstract syntax tree for *Variable Declaration* - * - * @param {Object} vardecNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astVariableDeclaration', - value: function astVariableDeclaration(vardecNode, retArr) { - for (var i = 0; i < vardecNode.declarations.length; i++) { - var declaration = vardecNode.declarations[i]; - if (i > 0) { - retArr.push(','); - } - var retDeclaration = []; - this.astGeneric(declaration, retDeclaration); - if (retDeclaration[2] === 'getImage2D(' || retDeclaration[2] === 'getImage3D(') { - if (i === 0) { - retArr.push('vec4 '); - } - this.declarations[declaration.id.name] = 'vec4'; - } else { - if (i === 0) { - retArr.push('float '); - } - this.declarations[declaration.id.name] = 'float'; - } - retArr.push.apply(retArr, retDeclaration); - } - retArr.push(';'); - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astVariableDeclarator - * - * @desc Parses the abstract syntax tree for *Variable Declarator* - * - * @param {Object} ivardecNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astVariableDeclarator', - value: function astVariableDeclarator(ivardecNode, retArr) { - this.astGeneric(ivardecNode.id, retArr); - if (ivardecNode.init !== null) { - retArr.push('='); - this.astGeneric(ivardecNode.init, retArr); - } - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astIfStatement - * - * @desc Parses the abstract syntax tree for *If* Statement - * - * @param {Object} ifNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astIfStatement', - value: function astIfStatement(ifNode, retArr) { - retArr.push('if ('); - this.astGeneric(ifNode.test, retArr); - retArr.push(')'); - if (ifNode.consequent.type === 'BlockStatement') { - this.astGeneric(ifNode.consequent, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.consequent, retArr); - retArr.push('\n}\n'); - } - - if (ifNode.alternate) { - retArr.push('else '); - if (ifNode.alternate.type === 'BlockStatement') { - this.astGeneric(ifNode.alternate, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.alternate, retArr); - retArr.push('\n}\n'); - } - } - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astBreakStatement - * - * @desc Parses the abstract syntax tree for *Break* Statement - * - * @param {Object} brNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astBreakStatement', - value: function astBreakStatement(brNode, retArr) { - retArr.push('break;\n'); - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astContinueStatement - * - * @desc Parses the abstract syntax tree for *Continue* Statement - * - * @param {Object} crNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astContinueStatement', - value: function astContinueStatement(crNode, retArr) { - retArr.push('continue;\n'); - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astLogicalExpression - * - * @desc Parses the abstract syntax tree for *Logical* Expression - * - * @param {Object} logNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astLogicalExpression', - value: function astLogicalExpression(logNode, retArr) { - retArr.push('('); - this.astGeneric(logNode.left, retArr); - retArr.push(logNode.operator); - this.astGeneric(logNode.right, retArr); - retArr.push(')'); - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astUpdateExpression - * - * @desc Parses the abstract syntax tree for *Update* Expression - * - * @param {Object} uNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astUpdateExpression', - value: function astUpdateExpression(uNode, retArr) { - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); - } - - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astUnaryExpression - * - * @desc Parses the abstract syntax tree for *Unary* Expression - * - * @param {Object} uNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astUnaryExpression', - value: function astUnaryExpression(uNode, retArr) { - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); - } - - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astThisExpression - * - * @desc Parses the abstract syntax tree for *This* expression - * - * @param {Object} tNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astThisExpression', - value: function astThisExpression(tNode, retArr) { - retArr.push('this'); - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astMemberExpression - * - * @desc Parses the abstract syntax tree for *Member* Expression - * - * @param {Object} mNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astMemberExpression', - value: function astMemberExpression(mNode, retArr) { - debugLog("[in] astMemberExpression " + mNode.object.type); - if (mNode.computed) { - if (mNode.object.type === 'Identifier') { - // Working logger - var reqName = mNode.object.name; - var funcName = this.functionName || 'kernel'; - var assumeNotTexture = false; - - // Possibly an array request - handle it as such - if (this.paramNames) { - var idx = this.paramNames.indexOf(reqName); - if (idx >= 0 && this.paramTypes[idx] === 'float') { - assumeNotTexture = true; - } - } - debugLog("- astMemberExpression " + reqName + " " + funcName); - if (assumeNotTexture) { - // Get from array - this.astGeneric(mNode.object, retArr); - retArr.push('[int('); - this.astGeneric(mNode.property, retArr); - retArr.push(')]'); - } else { - var isInGetParams = this.isState('in-get-call-parameters'); - var multiMemberExpression = this.isState('multi-member-expression'); - if (multiMemberExpression) { - this.popState('multi-member-expression'); - } - this.pushState('not-in-get-call-parameters'); - - // This normally refers to the global read only input vars - switch (this.getParamType(mNode.object.name)) { - case 'vec4': - // Get from local vec4 - this.astGeneric(mNode.object, retArr); - retArr.push('['); - retArr.push(mNode.property.raw); - retArr.push(']'); - if (multiMemberExpression) { - this.popState('not-in-get-call-parameters'); - } - break; - case 'HTMLImageArray': - // Get from image - retArr.push('getImage3D('); - this.astGeneric(mNode.object, retArr); - retArr.push(', ivec2('); - this.astGeneric(mNode.object, retArr); - retArr.push('Size[0],'); - this.astGeneric(mNode.object, retArr); - retArr.push('Size[1]), ivec3('); - this.astGeneric(mNode.object, retArr); - retArr.push('Dim[0],'); - this.astGeneric(mNode.object, retArr); - retArr.push('Dim[1],'); - this.astGeneric(mNode.object, retArr); - retArr.push('Dim[2]'); - retArr.push('), '); - this.popState('not-in-get-call-parameters'); - this.pushState('in-get-call-parameters'); - this.astGeneric(mNode.property, retArr); - if (!multiMemberExpression) { - this.popState('in-get-call-parameters'); - } - retArr.push(')'); - break; - case 'HTMLImage': - // Get from image - retArr.push('getImage2D('); - this.astGeneric(mNode.object, retArr); - retArr.push(', ivec2('); - this.astGeneric(mNode.object, retArr); - retArr.push('Size[0],'); - this.astGeneric(mNode.object, retArr); - retArr.push('Size[1]), ivec3('); - this.astGeneric(mNode.object, retArr); - retArr.push('Dim[0],'); - this.astGeneric(mNode.object, retArr); - retArr.push('Dim[1],'); - this.astGeneric(mNode.object, retArr); - retArr.push('Dim[2]'); - retArr.push('), '); - this.popState('not-in-get-call-parameters'); - this.pushState('in-get-call-parameters'); - this.astGeneric(mNode.property, retArr); - if (!multiMemberExpression) { - this.popState('in-get-call-parameters'); - } - retArr.push(')'); - break; - default: - // Get from texture - if (isInGetParams) { - retArr.push('int('); - } - retArr.push('get('); - this.astGeneric(mNode.object, retArr); - retArr.push(', ivec2('); - this.astGeneric(mNode.object, retArr); - retArr.push('Size[0],'); - this.astGeneric(mNode.object, retArr); - retArr.push('Size[1]), ivec3('); - this.astGeneric(mNode.object, retArr); - retArr.push('Dim[0],'); - this.astGeneric(mNode.object, retArr); - retArr.push('Dim[1],'); - this.astGeneric(mNode.object, retArr); - retArr.push('Dim[2]'); - retArr.push('), '); - this.astGeneric(mNode.object, retArr); - retArr.push('BitRatio'); - retArr.push(', '); - this.popState('not-in-get-call-parameters'); - this.pushState('in-get-call-parameters'); - this.astGeneric(mNode.property, retArr); - if (!multiMemberExpression) { - this.popState('in-get-call-parameters'); - } - retArr.push(')'); - if (isInGetParams) { - retArr.push(')'); - } - break; - } - } - } else { - - debugLog("- astMemberExpression obj:", mNode.object); - var stateStackDepth = this.states.length; - var startedInGetParamsState = this.isState('in-get-call-parameters'); - if (!startedInGetParamsState) { - this.pushState('multi-member-expression'); - } - this.astGeneric(mNode.object, retArr); - if (this.isState('multi-member-expression')) { - this.popState('multi-member-expression'); - } - var changedGetParamsState = !startedInGetParamsState && this.isState('in-get-call-parameters'); - var last = retArr.pop(); - retArr.push(','); - debugLog("- astMemberExpression prop:", mNode.property); - var shouldPopParamState = this.isState('should-pop-in-get-call-parameters'); - if (shouldPopParamState) { - // go back to in-get-call-parameters state - this.popState('should-pop-in-get-call-parameters'); - } - this.astGeneric(mNode.property, retArr); - retArr.push(last); - - if (changedGetParamsState) { - // calling memberExpression should pop... - this.pushState('should-pop-in-get-call-parameters'); - } else if (shouldPopParamState) { - // do the popping! - this.popState('in-get-call-parameters'); - } - } - } else { - - // Unroll the member expression - var unrolled = this.astMemberExpressionUnroll(mNode); - var unrolled_lc = unrolled.toLowerCase(); - debugLog("- astMemberExpression unrolled:", unrolled); - // Its a constant, remove this.constants. - if (unrolled.indexOf(constantsPrefix) === 0) { - unrolled = 'constants_' + unrolled.slice(constantsPrefix.length); - } - - // do we need to cast addressing vales to float? - var castFloat = !this.isState('in-get-call-parameters'); - - switch (unrolled_lc) { - case 'this.thread.x': - castFloat && retArr.push('float('); - retArr.push('threadId.x'); - castFloat && retArr.push(')'); - break; - case 'this.thread.y': - castFloat && retArr.push('float('); - retArr.push('threadId.y'); - castFloat && retArr.push(')'); - break; - case 'this.thread.z': - castFloat && retArr.push('float('); - retArr.push('threadId.z'); - castFloat && retArr.push(')'); - break; - case 'this.output.x': - retArr.push(this.output[0] + '.0'); - break; - case 'this.output.y': - retArr.push(this.output[1] + '.0'); - break; - case 'this.output.z': - retArr.push(this.output[2] + '.0'); - break; - default: - retArr.push(unrolled); - } - } - debugLog("[out] astMemberExpression " + mNode.object.type); - return retArr; - } - }, { - key: 'astSequenceExpression', - value: function astSequenceExpression(sNode, retArr) { - for (var i = 0; i < sNode.expressions.length; i++) { - if (i > 0) { - retArr.push(','); - } - this.astGeneric(sNode.expressions, retArr); - } - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astCallExpression - * - * @desc Parses the abstract syntax tree for *call* expression - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astCallExpression', - value: function astCallExpression(ast, retArr) { - if (ast.callee) { - // Get the full function call, unrolled - var funcName = this.astMemberExpressionUnroll(ast.callee); - - // Its a math operator, remove the prefix - if (funcName.indexOf(jsMathPrefix) === 0) { - funcName = funcName.slice(jsMathPrefix.length); - } - - // Its a local function, remove this - if (funcName.indexOf(localPrefix) === 0) { - funcName = funcName.slice(localPrefix.length); - } - - // if this if grows to more than one, lets use a switch - if (funcName === 'atan2') { - funcName = 'atan'; - } - - // Register the function into the called registry - if (this.calledFunctions.indexOf(funcName) < 0) { - this.calledFunctions.push(funcName); - } - if (!this.hasOwnProperty('funcName')) { - this.calledFunctionsArguments[funcName] = []; - } - - var functionArguments = []; - this.calledFunctionsArguments[funcName].push(functionArguments); - - // Call the function - retArr.push(funcName); - - // Open arguments space - retArr.push('('); - - // Add the vars - for (var i = 0; i < ast.arguments.length; ++i) { - var argument = ast.arguments[i]; - if (i > 0) { - retArr.push(', '); - } - this.astGeneric(argument, retArr); - if (argument.type === 'Identifier') { - var paramIndex = this.paramNames.indexOf(argument.name); - if (paramIndex === -1) { - functionArguments.push(null); - } else { - functionArguments.push({ - name: argument.name, - type: this.paramTypes[paramIndex] - }); - } - } else { - functionArguments.push(null); - } - } - - // Close arguments space - retArr.push(')'); - - return retArr; - } - - // Failure, unknown expression - throw this.astErrorOutput('Unknown CallExpression', ast); - - return retArr; - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name astArrayExpression - * - * @desc Parses the abstract syntax tree for *Array* Expression - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astArrayExpression', - value: function astArrayExpression(arrNode, retArr) { - var arrLen = arrNode.elements.length; - - retArr.push('float[' + arrLen + ']('); - for (var i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); - } - var subNode = arrNode.elements[i]; - this.astGeneric(subNode, retArr); - } - retArr.push(')'); - - return retArr; - - // // Failure, unknown expression - // throw this.astErrorOutput( - // 'Unknown ArrayExpression', - // arrNode - //); - } - - /** - * @memberOf WebGLFunctionNode# - * @function - * @name getFunctionPrototypeString - * - * @desc Returns the converted webgl shader function equivalent of the JS function - * - * @returns {String} webgl function string, result is cached under this.getFunctionPrototypeString - * - */ - - }, { - key: 'getFunctionPrototypeString', - value: function getFunctionPrototypeString() { - if (this.webGlFunctionPrototypeString) { - return this.webGlFunctionPrototypeString; - } - return this.webGlFunctionPrototypeString = this.generate(); - } - }, { - key: 'build', - value: function build() { - return this.getFunctionPrototypeString().length > 0; - } - }], [{ - key: 'astFunctionPrototype', - value: function astFunctionPrototype(ast, retArr) { - // Setup function return type and name - if (this.isRootKernel || this.isSubKernel) { - return retArr; - } - - retArr.push(this.returnType); - retArr.push(' '); - retArr.push(this.functionName); - retArr.push('('); - - // Arguments handling - for (var i = 0; i < this.paramNames.length; ++i) { - if (i > 0) { - retArr.push(', '); - } - - retArr.push(this.paramTypes[i]); - retArr.push(' '); - retArr.push('user_'); - retArr.push(this.paramNames[i]); - } - - retArr.push(');\n'); - - return retArr; - } - }]); - - return WebGLFunctionNode; -}(FunctionNodeBase); - -function isIdentifierKernelParam(paramName, ast, funcParam) { - return funcParam.paramNames.indexOf(paramName) !== -1; -} - -function ensureIndentifierType(paramName, expectedType, ast, funcParam) { - var start = ast.loc.start; - - if (!isIdentifierKernelParam(paramName) && expectedType !== 'float') { - throw new Error('Error unexpected identifier ' + paramName + ' on line ' + start.line); - } else { - var actualType = funcParam.paramTypes[funcParam.paramNames.indexOf(paramName)]; - if (actualType !== expectedType) { - throw new Error('Error unexpected identifier ' + paramName + ' on line ' + start.line); - } - } -} - -/** - * @ignore - * @function - * @name webgl_regex_optimize - * - * @desc [INTERNAL] Takes the near final webgl function string, and do regex search and replacments. - * For voodoo optimize out the following: - * - * - decode32(encode32(
- * - encode32(decode32(
- * - * @param {String} inStr - The webGl function String - * - */ -function webGlRegexOptimize(inStr) { - return inStr.replace(DECODE32_ENCODE32, '((').replace(ENCODE32_DECODE32, '(('); -} -},{"../../core/utils":84,"../function-node-base":59}],65:[function(require,module,exports){ -'use strict'; - -var utils = require('../../core/utils'); -var kernelRunShortcut = require('../kernel-run-shortcut'); - -function removeFnNoise(fn) { - if (/^function /.test(fn)) { - fn = fn.substring(9); - } - return fn.replace(/[_]typeof/g, 'typeof'); -} - -function removeNoise(str) { - return str.replace(/[_]typeof/g, 'typeof'); -} - -module.exports = function (gpuKernel, name) { - return '() => {\n ' + kernelRunShortcut.toString() + ';\n const utils = {\n allPropertiesOf: ' + removeNoise(utils.allPropertiesOf.toString()) + ',\n clone: ' + removeNoise(utils.clone.toString()) + ',\n splitArray: ' + removeNoise(utils.splitArray.toString()) + ',\n getArgumentType: ' + removeNoise(utils.getArgumentType.toString()) + ',\n getDimensions: ' + removeNoise(utils.getDimensions.toString()) + ',\n dimToTexSize: ' + removeNoise(utils.dimToTexSize.toString()) + ',\n flattenTo: ' + removeNoise(utils.flattenTo.toString()) + ',\n flatten2dArrayTo: ' + removeNoise(utils.flatten2dArrayTo.toString()) + ',\n flatten3dArrayTo: ' + removeNoise(utils.flatten3dArrayTo.toString()) + ',\n systemEndianness: \'' + removeNoise(utils.systemEndianness()) + '\',\n initWebGl: ' + removeNoise(utils.initWebGl.toString()) + ',\n isArray: ' + removeNoise(utils.isArray.toString()) + ',\n checkOutput: ' + removeNoise(utils.checkOutput.toString()) + '\n };\n const Utils = utils;\n const canvases = [];\n const maxTexSizes = {};\n class ' + (name || 'Kernel') + ' {\n constructor() {\n this.maxTexSize = null;\n this.argumentsLength = 0;\n this._canvas = null;\n this._webGl = null;\n this.built = false;\n this.program = null;\n this.paramNames = ' + JSON.stringify(gpuKernel.paramNames) + ';\n this.paramTypes = ' + JSON.stringify(gpuKernel.paramTypes) + ';\n this.texSize = ' + JSON.stringify(gpuKernel.texSize) + ';\n this.output = ' + JSON.stringify(gpuKernel.output) + ';\n this.compiledFragShaderString = `' + gpuKernel.compiledFragShaderString + '`;\n\t\t this.compiledVertShaderString = `' + gpuKernel.compiledVertShaderString + '`;\n\t\t this.programUniformLocationCache = {};\n\t\t this.textureCache = {};\n\t\t this.subKernelOutputTextures = null;\n\t\t this.subKernelOutputVariableNames = null;\n\t\t this.uniform1fCache = {};\n\t\t this.uniform1iCache = {};\n\t\t this.uniform2fCache = {};\n\t\t this.uniform2fvCache = {};\n\t\t this.uniform2ivCache = {};\n\t\t this.uniform3fvCache = {};\n\t\t this.uniform3ivCache = {};\n }\n ' + removeFnNoise(gpuKernel._getFragShaderString.toString()) + '\n ' + removeFnNoise(gpuKernel._getVertShaderString.toString()) + '\n validateOptions() {}\n setupParams() {}\n setCanvas(canvas) { this._canvas = canvas; return this; }\n setWebGl(webGl) { this._webGl = webGl; return this; }\n ' + removeFnNoise(gpuKernel.getUniformLocation.toString()) + '\n ' + removeFnNoise(gpuKernel.setupParams.toString()) + '\n ' + removeFnNoise(gpuKernel.build.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.run.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel._addArgument.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.getArgumentTexture.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.getTextureCache.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.getOutputTexture.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.renderOutput.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.updateMaxTexSize.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel._setupOutputTexture.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.detachTextureCache.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.setUniform1f.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.setUniform1i.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.setUniform2f.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.setUniform2fv.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.setUniform2iv.toString()) + '\n\t\t ' + removeFnNoise(gpuKernel.setUniform3fv.toString()) + ' \n\t\t ' + removeFnNoise(gpuKernel.setUniform3iv.toString()) + ' \n };\n return kernelRunShortcut(new Kernel());\n };'; -}; -},{"../../core/utils":84,"../kernel-run-shortcut":61}],66:[function(require,module,exports){ -'use strict'; - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var KernelBase = require('../kernel-base'); -var utils = require('../../core/utils'); -var Texture = require('../../core/texture'); -var fragShaderString = require('./shader-frag'); -var vertShaderString = require('./shader-vert'); -var kernelString = require('./kernel-string'); -var canvases = []; -var maxTexSizes = {}; - -module.exports = function (_KernelBase) { - _inherits(WebGLKernel, _KernelBase); - - _createClass(WebGLKernel, null, [{ - key: 'fragShaderString', - get: function get() { - return fragShaderString; - } - }, { - key: 'vertShaderString', - get: function get() { - return vertShaderString; - } - /** - * @constructor WebGLKernel - * - * @desc Kernel Implementation for WebGL. - *

This builds the shaders and runs them on the GPU, - * the outputs the result back as float(enabled by default) and Texture.

- * - * @extends KernelBase - * - * @prop {Object} textureCache - webGl Texture cache - * @prop {Object} threadDim - The thread dimensions, x, y and z - * @prop {Object} programUniformLocationCache - Location of program variables in memory - * @prop {Object} framebuffer - Webgl frameBuffer - * @prop {Object} buffer - WebGL buffer - * @prop {Object} program - The webGl Program - * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel - * @prop {Boolean} outputToTexture - Set output type to Texture, instead of float - * @prop {String} endianness - Endian information like Little-endian, Big-endian. - * @prop {Array} paramTypes - Types of parameters sent to the Kernel - * @prop {number} argumentsLength - Number of parameters sent to the Kernel - * @prop {String} compiledFragShaderString - Compiled fragment shader string - * @prop {String} compiledVertShaderString - Compiled Vertical shader string - */ - - }]); - - function WebGLKernel(fnString, settings) { - _classCallCheck(this, WebGLKernel); - - var _this = _possibleConstructorReturn(this, (WebGLKernel.__proto__ || Object.getPrototypeOf(WebGLKernel)).call(this, fnString, settings)); - - _this.textureCache = {}; - _this.threadDim = {}; - _this.programUniformLocationCache = {}; - _this.framebuffer = null; - - _this.buffer = null; - _this.program = null; - _this.outputToTexture = settings.outputToTexture; - _this.endianness = utils.systemEndianness(); - _this.subKernelOutputTextures = null; - _this.subKernelOutputVariableNames = null; - _this.argumentsLength = 0; - _this.compiledFragShaderString = null; - _this.compiledVertShaderString = null; - _this.fragShader = null; - _this.vertShader = null; - _this.drawBuffersMap = null; - _this.outputTexture = null; - _this.maxTexSize = null; - _this.uniform1fCache = {}; - _this.uniform1iCache = {}; - _this.uniform2fCache = {}; - _this.uniform2fvCache = {}; - _this.uniform2ivCache = {}; - _this.uniform3fvCache = {}; - _this.uniform3ivCache = {}; - if (!_this._webGl) _this._webGl = _this.initWebGl(); - return _this; - } - - _createClass(WebGLKernel, [{ - key: 'initWebGl', - value: function initWebGl() { - return utils.initWebGl(this.getCanvas()); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name validateOptions - * - * @desc Validate options related to Kernel, such as - * floatOutputs and Textures, texSize, output, - * graphical output. - * - */ - - }, { - key: 'validateOptions', - value: function validateOptions() { - var isFloatReadPixel = utils.isFloatReadPixelsSupported(); - if (this.floatTextures === true && !utils.OES_texture_float) { - throw new Error('Float textures are not supported on this browser'); - } else if (this.floatOutput === true && this.floatOutputForce !== true && !isFloatReadPixel) { - throw new Error('Float texture outputs are not supported on this browser'); - } else if (this.floatTextures === undefined && utils.OES_texture_float) { - this.floatTextures = true; - this.floatOutput = isFloatReadPixel; - } - - var hasIntegerDivisionBug = utils.hasIntegerDivisionAccuracyBug(); - if (this.fixIntegerDivisionAccuracy == null) { - this.fixIntegerDivisionAccuracy = hasIntegerDivisionBug; - } else if (this.fixIntegerDivisionAccuracy && !hasIntegerDivisionBug) { - this.fixIntegerDivisionAccuracy = false; - } - - utils.checkOutput(this.output); - - if (!this.output || this.output.length === 0) { - if (arguments.length !== 1) { - throw new Error('Auto output only supported for kernels with only one input'); - } - - var argType = utils.getArgumentType(arguments[0]); - if (argType === 'Array') { - this.output = utils.getDimensions(argType); - } else if (argType === 'Texture') { - this.output = arguments[0].output; - } else { - throw new Error('Auto output not supported for input type: ' + argType); - } - } - - this.texSize = utils.dimToTexSize({ - floatTextures: this.floatTextures, - floatOutput: this.floatOutput - }, this.output, true); - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); - } - - if (this.floatOutput) { - this.floatOutput = false; - console.warn('Cannot use graphical mode and float output at the same time'); - } - - this.texSize = utils.clone(this.output); - } else if (this.floatOutput === undefined && utils.OES_texture_float) { - this.floatOutput = true; - } - } - }, { - key: 'updateMaxTexSize', - value: function updateMaxTexSize() { - var texSize = this.texSize; - var canvas = this._canvas; - if (this.maxTexSize === null) { - var canvasIndex = canvases.indexOf(canvas); - if (canvasIndex === -1) { - canvasIndex = canvases.length; - canvases.push(canvas); - maxTexSizes[canvasIndex] = [texSize[0], texSize[1]]; - } - this.maxTexSize = maxTexSizes[canvasIndex]; - } - if (this.maxTexSize[0] < texSize[0]) { - this.maxTexSize[0] = texSize[0]; - } - if (this.maxTexSize[1] < texSize[1]) { - this.maxTexSize[1] = texSize[1]; - } - } - - /** - * @memberOf WebGLKernel# - * @function - * @name build - * - * @desc Builds the Kernel, by compiling Fragment and Vertical Shaders, - * and instantiates the program. - * - */ - - }, { - key: 'build', - value: function build() { - this.validateOptions(); - this.setupParams(arguments); - this.updateMaxTexSize(); - var texSize = this.texSize; - var gl = this._webGl; - var canvas = this._canvas; - gl.enable(gl.SCISSOR_TEST); - gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - canvas.width = this.maxTexSize[0]; - canvas.height = this.maxTexSize[1]; - var threadDim = this.threadDim = utils.clone(this.output); - while (threadDim.length < 3) { - threadDim.push(1); - } - - if (this.functionBuilder) this._addKernels(); - - var compiledVertShaderString = this._getVertShaderString(arguments); - var vertShader = gl.createShader(gl.VERTEX_SHADER); - gl.shaderSource(vertShader, compiledVertShaderString); - gl.compileShader(vertShader); - if (this.vertShader) {} - this.vertShader = vertShader; - - var compiledFragShaderString = this._getFragShaderString(arguments); - var fragShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragShader, compiledFragShaderString); - gl.compileShader(fragShader); - this.fragShader = fragShader; - - if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) { - console.log(compiledVertShaderString); - console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(vertShader)); - throw new Error('Error compiling vertex shader'); - } - if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) { - console.log(compiledFragShaderString); - console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(fragShader)); - throw new Error('Error compiling fragment shader'); - } - - if (this.debug) { - console.log('Options:'); - console.dir(this); - console.log('GLSL Shader Output:'); - console.log(compiledFragShaderString); - } - - var program = this.program = gl.createProgram(); - gl.attachShader(program, vertShader); - gl.attachShader(program, fragShader); - gl.linkProgram(program); - this.framebuffer = gl.createFramebuffer(); - this.framebuffer.width = texSize[0]; - this.framebuffer.height = texSize[1]; - - var vertices = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]); - var texCoords = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]); - - var texCoordOffset = vertices.byteLength; - - var buffer = this.buffer; - if (!buffer) { - buffer = this.buffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW); - } else { - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - } - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices); - gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords); - - var aPosLoc = gl.getAttribLocation(this.program, 'aPos'); - gl.enableVertexAttribArray(aPosLoc); - gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, gl.FALSE, 0, 0); - var aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord'); - gl.enableVertexAttribArray(aTexCoordLoc); - gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, gl.FALSE, 0, texCoordOffset); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - - if (!this.outputImmutable) { - this._setupOutputTexture(); - if (this.subKernelOutputVariableNames !== null && this.subKernelOutputVariableNames.length > 0) { - this._setupSubOutputTextures(this.subKernelOutputVariableNames.length); - } - } - } - - /** - * @memberOf WebGLKernel# - * @function - * @name run - * - * @desc Run the kernel program, and send the output to renderOutput - * - *

This method calls a helper method *renderOutput* to return the result.

- * - * @returns {Object|Undefined} Result The final output of the program, as float, and as Textures for reuse. - * - * - */ - - }, { - key: 'run', - value: function run() { - if (this.program === null) { - this.build.apply(this, arguments); - } - var paramNames = this.paramNames; - var paramTypes = this.paramTypes; - var texSize = this.texSize; - var gl = this._webGl; - - gl.useProgram(this.program); - gl.scissor(0, 0, texSize[0], texSize[1]); - - if (!this.hardcodeConstants) { - this.setUniform3iv('uOutputDim', this.threadDim); - this.setUniform2iv('uTexSize', texSize); - } - - this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); - - this.argumentsLength = 0; - for (var texIndex = 0; texIndex < paramNames.length; texIndex++) { - this._addArgument(arguments[texIndex], paramTypes[texIndex], paramNames[texIndex]); - } - - if (this.graphical) { - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return; - } - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (this.outputImmutable) { - this._setupOutputTexture(); - } - var outputTexture = this.outputTexture; - - if (this.subKernelOutputVariableNames !== null) { - if (this.outputImmutable) { - this.subKernelOutputTextures = []; - this._setupSubOutputTextures(this.subKernelOutputVariableNames.length); - } - this.drawBuffers.drawBuffersWEBGL(this.drawBuffersMap); - } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - - if (this.subKernelOutputTextures !== null) { - if (this.subKernels !== null) { - var output = []; - output.result = this.renderOutput(outputTexture); - for (var i = 0; i < this.subKernels.length; i++) { - output.push(new Texture(this.subKernelOutputTextures[i], texSize, this.threadDim, this.output, this._webGl)); - } - return output; - } else if (this.subKernelProperties !== null) { - var _output = { - result: this.renderOutput(outputTexture) - }; - var _i = 0; - for (var p in this.subKernelProperties) { - if (!this.subKernelProperties.hasOwnProperty(p)) continue; - _output[p] = new Texture(this.subKernelOutputTextures[_i], texSize, this.threadDim, this.output, this._webGl); - _i++; - } - return _output; - } - } - - return this.renderOutput(outputTexture); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name renderOutput - * - * - * @desc Helper function to return webGl function's output. - * Since the program runs on GPU, we need to get the - * output of the program back to CPU and then return them. - * - * *Note*: This should not be called directly. - * - * @param {Object} outputTexture - Output Texture returned by webGl program - * - * @returns {Object|Array} result - * - * - */ - - }, { - key: 'renderOutput', - value: function renderOutput(outputTexture) { - var texSize = this.texSize; - var gl = this._webGl; - var threadDim = this.threadDim; - var output = this.output; - if (this.outputToTexture) { - return new Texture(outputTexture, texSize, this.threadDim, output, this._webGl); - } else { - var result = void 0; - if (this.floatOutput) { - result = new Float32Array(texSize[0] * texSize[1] * 4); - gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.FLOAT, result); - } else { - var bytes = new Uint8Array(texSize[0] * texSize[1] * 4); - gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, bytes); - result = new Float32Array(bytes.buffer); - } - - result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]); - - if (output.length === 1) { - return result; - } else if (output.length === 2) { - return utils.splitArray(result, output[0]); - } else if (output.length === 3) { - var cube = utils.splitArray(result, output[0] * output[1]); - return cube.map(function (x) { - return utils.splitArray(x, output[0]); - }); - } - } - } - - /** - * @memberOf WebGLKernel# - * @function - * @name getOutputTexture - * - * @desc This return defined outputTexture, which is setup in .build(), or if immutable, is defined in .run() - * - * @returns {Object} Output Texture Cache - * - */ - - }, { - key: 'getOutputTexture', - value: function getOutputTexture() { - return this.outputTexture; - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _setupOutputTexture - * @private - * - * @desc Setup and replace output texture - */ - - }, { - key: '_setupOutputTexture', - value: function _setupOutputTexture() { - var gl = this._webGl; - var texSize = this.texSize; - var texture = this.outputTexture = this._webGl.createTexture(); - gl.activeTexture(gl.TEXTURE0 + this.paramNames.length); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.floatOutput) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); - } - - /** - * @memberOf WebGLKernel# - * @param length - * @private - * - * @desc Setup and replace sub-output textures - */ - - }, { - key: '_setupSubOutputTextures', - value: function _setupSubOutputTextures(length) { - var gl = this._webGl; - var texSize = this.texSize; - var drawBuffersMap = this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - var textures = this.subKernelOutputTextures = []; - for (var i = 0; i < length; i++) { - var texture = this._webGl.createTexture(); - textures.push(texture); - drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); - gl.activeTexture(gl.TEXTURE0 + this.paramNames.length + i); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.floatOutput) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); - } - } - - /** - * @memberOf WebGLKernel# - * @function - * @name getArgumentTexture - * - * @desc This uses *getTextureCache** to get the Texture Cache of the argument supplied - * - * @param {String} name - Name of the argument - * - * Texture cache for the supplied argument - * - */ - - }, { - key: 'getArgumentTexture', - value: function getArgumentTexture(name) { - return this.getTextureCache('ARGUMENT_' + name); - } - - /** - * @memberOf WebGLKernel# - * @name getTextureCache - * @function - * - * @desc Returns the Texture Cache of the supplied parameter (can be kernel, sub-kernel or argument) - * - * @param {String} name - Name of the subkernel, argument, or kernel. - * - * @returns {Object} Texture cache - * - */ - - }, { - key: 'getTextureCache', - value: function getTextureCache(name) { - if (this.textureCache.hasOwnProperty(name)) { - return this.textureCache[name]; - } - return this.textureCache[name] = this._webGl.createTexture(); - } - - /** - * @memberOf WebGLKernel# - * @name detachTextureCache - * @function - * @desc removes a texture from the kernel's cache - * @param {String} name - Name of texture - */ - - }, { - key: 'detachTextureCache', - value: function detachTextureCache(name) { - delete this.textureCache[name]; - } - }, { - key: 'setUniform1f', - value: function setUniform1f(name, value) { - if (this.uniform1fCache.hasOwnProperty(name)) { - var cache = this.uniform1fCache[name]; - if (value === cache) { - return; - } - } - this.uniform1fCache[name] = value; - var loc = this.getUniformLocation(name); - this._webGl.uniform1f(loc, value); - } - }, { - key: 'setUniform1i', - value: function setUniform1i(name, value) { - if (this.uniform1iCache.hasOwnProperty(name)) { - var cache = this.uniform1iCache[name]; - if (value === cache) { - return; - } - } - this.uniform1iCache[name] = value; - var loc = this.getUniformLocation(name); - this._webGl.uniform1i(loc, value); - } - }, { - key: 'setUniform2f', - value: function setUniform2f(name, value1, value2) { - if (this.uniform2fCache.hasOwnProperty(name)) { - var cache = this.uniform2fCache[name]; - if (value1 === cache[0] && value2 === cache[1]) { - return; - } - } - this.uniform2fCache[name] = [value1, value2]; - var loc = this.getUniformLocation(name); - this._webGl.uniform2f(loc, value1, value2); - } - }, { - key: 'setUniform2fv', - value: function setUniform2fv(name, value) { - if (this.uniform2fvCache.hasOwnProperty(name)) { - var cache = this.uniform2fvCache[name]; - if (value[0] === cache[0] && value[1] === cache[1]) { - return; - } - } - this.uniform2fvCache[name] = value; - var loc = this.getUniformLocation(name); - this._webGl.uniform2fv(loc, value); - } - }, { - key: 'setUniform2iv', - value: function setUniform2iv(name, value) { - if (this.uniform2ivCache.hasOwnProperty(name)) { - var cache = this.uniform2ivCache[name]; - if (value[0] === cache[0] && value[1] === cache[1]) { - return; - } - } - this.uniform2ivCache[name] = value; - var loc = this.getUniformLocation(name); - this._webGl.uniform2iv(loc, value); - } - }, { - key: 'setUniform3fv', - value: function setUniform3fv(name, value) { - if (this.uniform3fvCache.hasOwnProperty(name)) { - var cache = this.uniform3fvCache[name]; - if (value[0] === cache[0] && value[1] === cache[1] && value[2] === cache[2]) { - return; - } - } - this.uniform3fvCache[name] = value; - var loc = this.getUniformLocation(name); - this._webGl.uniform3fv(loc, value); - } - }, { - key: 'setUniform3iv', - value: function setUniform3iv(name, value) { - if (this.uniform3ivCache.hasOwnProperty(name)) { - var cache = this.uniform3ivCache[name]; - if (value[0] === cache[0] && value[1] === cache[1] && value[2] === cache[2]) { - return; - } - } - this.uniform3ivCache[name] = value; - var loc = this.getUniformLocation(name); - this._webGl.uniform3iv(loc, value); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name getUniformLocation - * - * @desc Return WebGlUniformLocation for various variables - * related to webGl program, such as user-defiend variables, - * as well as, dimension sizes, etc. - * - */ - - }, { - key: 'getUniformLocation', - value: function getUniformLocation(name) { - if (this.programUniformLocationCache.hasOwnProperty(name)) { - return this.programUniformLocationCache[name]; - } - return this.programUniformLocationCache[name] = this._webGl.getUniformLocation(this.program, name); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getFragShaderArtifactMap - * - * @desc Generate Shader artifacts for the kernel program. - * The final object contains HEADER, KERNEL, MAIN_RESULT, and others. - * - * @param {Array} args - The actual parameters sent to the Kernel - * - * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.) - * - */ - - }, { - key: '_getFragShaderArtifactMap', - value: function _getFragShaderArtifactMap(args) { - return { - HEADER: this._getHeaderString(), - LOOP_MAX: this._getLoopMaxString(), - CONSTANTS: this._getConstantsString(), - DECODE32_ENDIANNESS: this._getDecode32EndiannessString(), - ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(), - DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(), - GET_WRAPAROUND: this._getGetWraparoundString(), - GET_TEXTURE_CHANNEL: this._getGetTextureChannelString(), - GET_TEXTURE_INDEX: this._getGetTextureIndexString(), - GET_RESULT: this._getGetResultString(), - MAIN_PARAMS: this._getMainParamsString(args), - MAIN_CONSTANTS: this._getMainConstantsString(), - KERNEL: this._getKernelString(), - MAIN_RESULT: this._getMainResultString() - }; - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _addArgument - * - * @desc Adds kernel parameters to the Argument Texture, - * binding it to the webGl instance, etc. - * - * @param {Array|Texture|Number} value - The actual argument supplied to the kernel - * @param {String} type - Type of the argument - * @param {String} name - Name of the argument - * - */ - - }, { - key: '_addArgument', - value: function _addArgument(value, type, name) { - var gl = this._webGl; - var argumentTexture = this.getArgumentTexture(name); - if (value instanceof Texture) { - type = 'Texture'; - } - switch (type) { - case 'Array': - { - var dim = utils.getDimensions(value, true); - var size = utils.dimToTexSize({ - floatTextures: this.floatTextures, - floatOutput: this.floatOutput - }, dim); - gl.activeTexture(gl.TEXTURE0 + this.argumentsLength); - gl.bindTexture(gl.TEXTURE_2D, argumentTexture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - - var length = size[0] * size[1]; - - var _formatArrayTransfer2 = this._formatArrayTransfer(value, length), - valuesFlat = _formatArrayTransfer2.valuesFlat, - bitRatio = _formatArrayTransfer2.bitRatio; - - var buffer = void 0; - if (this.floatTextures) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1], 0, gl.RGBA, gl.FLOAT, valuesFlat); - } else { - buffer = new Uint8Array(valuesFlat.buffer); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0] / bitRatio, size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, buffer); - } - - if (!this.hardcodeConstants) { - this.setUniform3iv('user_' + name + 'Dim', dim); - this.setUniform2iv('user_' + name + 'Size', size); - } - this.setUniform1i('user_' + name + 'BitRatio', bitRatio); - this.setUniform1i('user_' + name, this.argumentsLength); - break; - } - case 'Integer': - case 'Float': - { - this.setUniform1f('user_' + name, value); - break; - } - case 'Input': - { - var input = value; - var _dim = input.size; - var _size = utils.dimToTexSize({ - floatTextures: this.floatTextures, - floatOutput: this.floatOutput - }, _dim); - gl.activeTexture(gl.TEXTURE0 + this.argumentsLength); - gl.bindTexture(gl.TEXTURE_2D, argumentTexture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - - var _length = _size[0] * _size[1]; - - var _formatArrayTransfer3 = this._formatArrayTransfer(value.value, _length), - _valuesFlat = _formatArrayTransfer3.valuesFlat, - _bitRatio = _formatArrayTransfer3.bitRatio; - - if (this.floatTextures) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, _size[0], _size[1], 0, gl.RGBA, gl.FLOAT, inputArray); - } else { - var _buffer = new Uint8Array(_valuesFlat.buffer); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, _size[0] / _bitRatio, _size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, _buffer); - } - - if (!this.hardcodeConstants) { - this.setUniform3iv('user_' + name + 'Dim', _dim); - this.setUniform2iv('user_' + name + 'Size', _size); - } - this.setUniform1i('user_' + name + 'BitRatio', _bitRatio); - this.setUniform1i('user_' + name, this.argumentsLength); - break; - } - case 'HTMLImage': - { - var inputImage = value; - var _dim2 = [inputImage.width, inputImage.height, 1]; - var _size2 = [inputImage.width, inputImage.height]; - - gl.activeTexture(gl.TEXTURE0 + this.argumentsLength); - gl.bindTexture(gl.TEXTURE_2D, argumentTexture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); - // Upload the image into the texture. - var mipLevel = 0; // the largest mip - var internalFormat = gl.RGBA; // format we want in the texture - var srcFormat = gl.RGBA; // format of data we are supplying - var srcType = gl.UNSIGNED_BYTE; // type of data we are supplying - gl.texImage2D(gl.TEXTURE_2D, mipLevel, internalFormat, srcFormat, srcType, inputImage); - this.setUniform3iv('user_' + name + 'Dim', _dim2); - this.setUniform2iv('user_' + name + 'Size', _size2); - this.setUniform1i('user_' + name, this.argumentsLength); - break; - } - case 'Texture': - { - var inputTexture = value; - var _dim3 = inputTexture.dimensions; - var _size3 = inputTexture.size; - - gl.activeTexture(gl.TEXTURE0 + this.argumentsLength); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - this.setUniform3iv('user_' + name + 'Dim', _dim3); - this.setUniform2iv('user_' + name + 'Size', _size3); - this.setUniform1i('user_' + name + 'BitRatio', 1); // aways float32 - this.setUniform1i('user_' + name, this.argumentsLength); - break; - } - default: - throw new Error('Input type not supported (WebGL): ' + value); - } - this.argumentsLength++; - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _formatArrayTransfer - * - * @desc Adds kernel parameters to the Argument Texture, - * binding it to the webGl instance, etc. - * - * @param {Array} value - The actual argument supplied to the kernel - * @param {String} length - the expected total length of the output array - * - * @returns {Object} bitRatio - bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4 - * valuesFlat - flattened array to transfer - */ - - }, { - key: '_formatArrayTransfer', - value: function _formatArrayTransfer(value, length) { - var bitRatio = 1; // bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4 - var valuesFlat = value; - if (utils.isArray(value[0]) || this.floatTextures) { - // not already flat - valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - } else { - - switch (value.constructor) { - case Uint8Array: - case Int8Array: - bitRatio = 4; - break; - case Uint16Array: - case Int16Array: - bitRatio = 2; - case Float32Array: - case Int32Array: - break; - - default: - valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - } - } - return { - bitRatio: bitRatio, - valuesFlat: valuesFlat - }; - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getHeaderString - * - * @desc Get the header string for the program. - * This returns an empty string if no sub-kernels are defined. - * - * @returns {String} result - * - */ - - }, { - key: '_getHeaderString', - value: function _getHeaderString() { - return this.subKernels !== null || this.subKernelProperties !== null ? - //webgl2 '#version 300 es\n' : - '#extension GL_EXT_draw_buffers : require\n' : ''; - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getLoopMaxString - * - * @desc Get the maximum loop size String. - * - * @returns {String} result - * - */ - - }, { - key: '_getLoopMaxString', - value: function _getLoopMaxString() { - return this.loopMaxIterations ? ' ' + parseInt(this.loopMaxIterations) + '.0;\n' : ' 1000.0;\n'; - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getConstantsString - * - * @desc Generate transpiled glsl Strings for constant parameters sent to a kernel - * - * They can be defined by *hardcodeConstants* - * - * @returns {String} result - * - */ - - }, { - key: '_getConstantsString', - value: function _getConstantsString() { - var result = []; - var threadDim = this.threadDim; - var texSize = this.texSize; - if (this.hardcodeConstants) { - result.push('ivec3 uOutputDim = ivec3(' + threadDim[0] + ',' + threadDim[1] + ', ' + threadDim[2] + ')', 'ivec2 uTexSize = ivec2(' + texSize[0] + ', ' + texSize[1] + ')'); - } else { - result.push('uniform ivec3 uOutputDim', 'uniform ivec2 uTexSize'); - } - - return this._linesToString(result); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getTextureCoordinate - * - * @desc Get texture coordinate string for the program - * - * @returns {String} result - * - */ - - }, { - key: '_getTextureCoordinate', - value: function _getTextureCoordinate() { - var names = this.subKernelOutputVariableNames; - if (names === null || names.length < 1) { - return 'varying vec2 vTexCoord;\n'; - } else { - return 'out vec2 vTexCoord;\n'; - } - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getDecode32EndiannessString - * - * @desc Get Decode32 endianness string for little-endian and big-endian - * - * @returns {String} result - * - */ - - }, { - key: '_getDecode32EndiannessString', - value: function _getDecode32EndiannessString() { - return this.endianness === 'LE' ? '' : ' rgba.rgba = rgba.abgr;\n'; - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getEncode32EndiannessString - * - * @desc Get Encode32 endianness string for little-endian and big-endian - * - * @returns {String} result - * - */ - - }, { - key: '_getEncode32EndiannessString', - value: function _getEncode32EndiannessString() { - return this.endianness === 'LE' ? '' : ' rgba.rgba = rgba.abgr;\n'; - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getDivideWithIntegerCheckString - * - * @desc if fixIntegerDivisionAccuracy provide method to replace / - * - * @returns {String} result - * - */ - - }, { - key: '_getDivideWithIntegerCheckString', - value: function _getDivideWithIntegerCheckString() { - return this.fixIntegerDivisionAccuracy ? '\n\t\t\t float div_with_int_check(float x, float y) {\n\t\t\t if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {\n\t\t\t return float(int(x)/int(y));\n\t\t\t }\n\t\t\t return x / y;\n\t\t\t}\n\t\t\t' : ''; - } - - /** - * @function - * @memberOf WebGLKernel# - * @name _getGetWraparoundString - * - * @returns {String} wraparound string - */ - - }, { - key: '_getGetWraparoundString', - value: function _getGetWraparoundString() { - return this.wraparound ? ' xyz = mod(xyz, texDim);\n' : ''; - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getGetTextureChannelString - * - */ - - }, { - key: '_getGetTextureChannelString', - value: function _getGetTextureChannelString() { - if (!this.floatTextures) return ''; - - return this._linesToString([' int channel = integerMod(index, 4)', ' index = index / 4']); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getGetTextureIndexString - * - * @desc Get generic texture index string, if floatTextures flag is true. - * - * @example - * ' index = float(int(index)/4);\n' - * - */ - - }, { - key: '_getGetTextureIndexString', - value: function _getGetTextureIndexString() { - return this.floatTextures ? ' index = index / 4;\n' : ''; - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getGetResultString - * - */ - - }, { - key: '_getGetResultString', - value: function _getGetResultString() { - if (!this.floatTextures) { - return ' return decode(texel, x, bitRatio);'; - } - return this._linesToString([' if (channel == 0) return texel.r', ' if (channel == 1) return texel.g', ' if (channel == 2) return texel.b', ' if (channel == 3) return texel.a']); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getMainParamsString - * - * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel - * - * @param {Array} args - The actual parameters sent to the Kernel - * - * @returns {String} result - * - */ - - }, { - key: '_getMainParamsString', - value: function _getMainParamsString(args) { - var result = []; - var paramTypes = this.paramTypes; - var paramNames = this.paramNames; - for (var i = 0; i < paramNames.length; i++) { - var param = args[i]; - var paramName = paramNames[i]; - var paramType = paramTypes[i]; - if (this.hardcodeConstants) { - if (paramType === 'Array' || paramType === 'Texture') { - var paramDim = utils.getDimensions(param, true); - var paramSize = utils.dimToTexSize({ - floatTextures: this.floatTextures, - floatOutput: this.floatOutput - }, paramDim); - - result.push('uniform sampler2D user_' + paramName, 'ivec2 user_' + paramName + 'Size = vec2(' + paramSize[0] + ', ' + paramSize[1] + ')', 'ivec3 user_' + paramName + 'Dim = vec3(' + paramDim[0] + ', ' + paramDim[1] + ', ' + paramDim[2] + ')', 'uniform int user_' + paramName + 'BitRatio'); - } else if (paramType === 'Integer') { - result.push('float user_' + paramName + ' = ' + param + '.0'); - } else if (paramType === 'Float') { - result.push('float user_' + paramName + ' = ' + param); - } - } else { - if (paramType === 'Array' || paramType === 'Texture' || paramType === 'Input' || paramType === 'HTMLImage') { - result.push('uniform sampler2D user_' + paramName, 'uniform ivec2 user_' + paramName + 'Size', 'uniform ivec3 user_' + paramName + 'Dim'); - if (paramType !== 'HTMLImage') { - result.push('uniform int user_' + paramName + 'BitRatio'); - } - } else if (paramType === 'Integer' || paramType === 'Float') { - result.push('uniform float user_' + paramName); - } else { - throw new Error('Param type ' + paramType + ' not supported in WebGL, only WebGL2'); - } - } - } - return this._linesToString(result); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getMainConstantsString - * - */ - - }, { - key: '_getMainConstantsString', - value: function _getMainConstantsString() { - var result = []; - if (this.constants) { - for (var name in this.constants) { - if (!this.constants.hasOwnProperty(name)) continue; - var value = this.constants[name]; - var type = utils.getArgumentType(value); - switch (type) { - case 'Integer': - result.push('const float constants_' + name + ' = ' + parseInt(value) + '.0'); - break; - case 'Float': - result.push('const float constants_' + name + ' = ' + parseFloat(value)); - break; - default: - throw new Error('Unsupported constant ' + name + ' type ' + type); - } - } - } - return this._linesToString(result); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getKernelString - * - * @desc Get Kernel program string (in *glsl*) for a kernel. - * - * @returns {String} result - * - */ - - }, { - key: '_getKernelString', - value: function _getKernelString() { - var result = []; - var names = this.subKernelOutputVariableNames; - if (names !== null) { - result.push('float kernelResult = 0.0'); - for (var i = 0; i < names.length; i++) { - result.push('float ' + names[i] + ' = 0.0'); - } - } else { - result.push('float kernelResult = 0.0'); - } - - return this._linesToString(result) + this.functionBuilder.getPrototypeString('kernel'); - } - - /** - * - * @memberOf WebGLKernel# - * @function - * @name _getMainResultString - * - * @desc Get main result string with checks for floatOutput, graphical, subKernelsOutputs, etc. - * - * @returns {String} result - * - */ - - }, { - key: '_getMainResultString', - value: function _getMainResultString() { - var names = this.subKernelOutputVariableNames; - var result = []; - - if (this.floatOutput) { - result.push(' index *= 4'); - } - - if (this.graphical) { - result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor = actualColor'); - } else if (this.floatOutput) { - var channels = ['r', 'g', 'b', 'a']; - - for (var i = 0; i < channels.length; ++i) { - result.push(' threadId = indexTo3D(index, uOutputDim)'); - result.push(' kernel()'); - - if (names) { - result.push(' gl_FragData[0].' + channels[i] + ' = kernelResult'); - - for (var j = 0; j < names.length; ++j) { - result.push(' gl_FragData[' + (j + 1) + '].' + channels[i] + ' = ' + names[j]); - } - } else { - result.push(' gl_FragColor.' + channels[i] + ' = kernelResult'); - } - - if (i < channels.length - 1) { - result.push(' index += 1'); - } - } - } else if (names !== null) { - result.push(' threadId = indexTo3D(index, uOutputDim)'); - result.push(' kernel()'); - result.push(' gl_FragData[0] = encode32(kernelResult)'); - for (var _i2 = 0; _i2 < names.length; _i2++) { - result.push(' gl_FragData[' + (_i2 + 1) + '] = encode32(' + names[_i2] + ')'); - } - } else { - result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor = encode32(kernelResult)'); - } - - return this._linesToString(result); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _linesToString - * - * @param {Array} lines - An Array of strings - * - * @returns {String} Single combined String, seperated by *\n* - * - */ - - }, { - key: '_linesToString', - value: function _linesToString(lines) { - if (lines.length > 0) { - return lines.join(';\n') + ';\n'; - } else { - return '\n'; - } - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _replaceArtifacts - * - * @param {String} src - Shader string - * @param {Array} map - Variables/Constants associated with shader - * - */ - - }, { - key: '_replaceArtifacts', - value: function _replaceArtifacts(src, map) { - return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z])*)__;\n/g, function (match, artifact) { - if (map.hasOwnProperty(artifact)) { - return map[artifact]; - } - throw 'unhandled artifact ' + artifact; - }); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _addKernels - * - * @desc Adds all the sub-kernels supplied with this Kernel instance. - * - */ - - }, { - key: '_addKernels', - value: function _addKernels() { - var _this2 = this; - - var builder = this.functionBuilder; - var gl = this._webGl; - - builder.addFunctions(this.functions, { - constants: this.constants, - output: this.output - }); - builder.addNativeFunctions(this.nativeFunctions); - - builder.addKernel(this.fnString, { - prototypeOnly: false, - constants: this.constants, - output: this.output, - debug: this.debug, - loopMaxIterations: this.loopMaxIterations, - paramNames: this.paramNames, - paramTypes: this.paramTypes, - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - - if (this.subKernels !== null) { - var drawBuffers = this.drawBuffers = gl.getExtension('WEBGL_draw_buffers'); - if (!drawBuffers) throw new Error('could not instantiate draw buffers extension'); - this.subKernelOutputVariableNames = []; - this.subKernels.forEach(function (subKernel) { - return _this2._addSubKernel(subKernel); - }); - } else if (this.subKernelProperties !== null) { - var _drawBuffers = this.drawBuffers = gl.getExtension('WEBGL_draw_buffers'); - if (!_drawBuffers) throw new Error('could not instantiate draw buffers extension'); - this.subKernelOutputVariableNames = []; - Object.keys(this.subKernelProperties).forEach(function (property) { - return _this2._addSubKernel(_this2.subKernelProperties[property]); - }); - } - } - }, { - key: '_addSubKernel', - value: function _addSubKernel(subKernel) { - this.functionBuilder.addSubKernel(subKernel, { - prototypeOnly: false, - constants: this.constants, - output: this.output, - debug: this.debug, - loopMaxIterations: this.loopMaxIterations, - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - this.subKernelOutputVariableNames.push(subKernel.name + 'Result'); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getFragShaderString - * - * @desc Get the fragment shader String. - * If the String hasn't been compiled yet, - * then this method compiles it as well - * - * @param {Array} args - The actual parameters sent to the Kernel - * - * @returns {string} Fragment Shader string - * - */ - - }, { - key: '_getFragShaderString', - value: function _getFragShaderString(args) { - if (this.compiledFragShaderString !== null) { - return this.compiledFragShaderString; - } - return this.compiledFragShaderString = this._replaceArtifacts(this.constructor.fragShaderString, this._getFragShaderArtifactMap(args)); - } - - /** - * @memberOf WebGLKernel# - * @function - * @name _getVertShaderString - * - * @desc Get the vertical shader String - * - * @param {Array} args - The actual parameters sent to the Kernel - * - * @returns {string} Vertical Shader string - * - */ - - }, { - key: '_getVertShaderString', - value: function _getVertShaderString(args) { - if (this.compiledVertShaderString !== null) { - return this.compiledVertShaderString; - } - return this.compiledVertShaderString = this.constructor.vertShaderString; - } - - /** - * @memberOf WebGLKernel# - * @function - * @name toString - * - * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused. - * - */ - - }, { - key: 'toString', - value: function toString() { - return kernelString(this); - } - }, { - key: 'addFunction', - value: function addFunction(fn) { - this.functionBuilder.addFunction(null, fn); - } - }, { - key: 'destroy', - value: function destroy(removeCanvasReferences) { - _get(WebGLKernel.prototype.__proto__ || Object.getPrototypeOf(WebGLKernel.prototype), 'destroy', this).call(this); - if (this.outputTexture) { - this._webGl.deleteTexture(this.outputTexture); - } - if (this.buffer) { - this._webGl.deleteBuffer(this.buffer); - } - if (this.framebuffer) { - this._webGl.deleteFramebuffer(this.framebuffer); - } - - if (this.vertShader) { - this._webGl.deleteShader(this.vertShader); - } - - if (this.fragShader) { - this._webGl.deleteShader(this.fragShader); - } - - if (this.program) { - this._webGl.deleteProgram(this.program); - } - - var keys = Object.keys(this.textureCache); - - for (var i = 0; i < keys.length; i++) { - var name = keys[i]; - this._webGl.deleteTexture(this.textureCache[name]); - } - - if (this.subKernelOutputTextures) { - for (var _i3 = 0; _i3 < this.subKernelOutputTextures.length; _i3++) { - this._webGl.deleteTexture(this.subKernelOutputTextures[_i3]); - } - } - if (removeCanvasReferences) { - var idx = canvases.indexOf(this._canvas); - if (idx >= 0) { - canvases[idx] = null; - maxTexSizes[idx] = null; - } - } - delete this._webGl; - } - }]); - - return WebGLKernel; -}(KernelBase); -},{"../../core/texture":82,"../../core/utils":84,"../kernel-base":60,"./kernel-string":65,"./shader-frag":68,"./shader-vert":69}],67:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var RunnerBase = require('../runner-base'); -var WebGLKernel = require('./kernel'); -var WebGLFunctionBuilder = require('./function-builder'); - -module.exports = function (_RunnerBase) { - _inherits(WebGLRunner, _RunnerBase); - - /** - * @constructor WebGLRunner - * - * @extends RunnerBase - * @desc Instantiates a Runner instance for the kernel. - * - * @param {Object} settings - Settings to instantiate properties in RunnerBase, with given values - * - */ - function WebGLRunner(settings) { - _classCallCheck(this, WebGLRunner); - - var _this = _possibleConstructorReturn(this, (WebGLRunner.__proto__ || Object.getPrototypeOf(WebGLRunner)).call(this, new WebGLFunctionBuilder(), settings)); - - _this.Kernel = WebGLKernel; - _this.kernel = null; - return _this; - } - - /** - * @memberOf WebGLRunner# - * @function - * @name getMode - * - * @desc Return the current mode in which gpu.js is executing. - * - * @returns {String} The current mode; "cpu". - * - */ - - - _createClass(WebGLRunner, [{ - key: 'getMode', - value: function getMode() { - return 'gpu'; - } - }]); - - return WebGLRunner; -}(RunnerBase); -},{"../runner-base":62,"./function-builder":63,"./kernel":66}],68:[function(require,module,exports){ -"use strict"; - -module.exports = "__HEADER__;\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nconst float LOOP_MAX = __LOOP_MAX__;\n\n__CONSTANTS__;\n\nvarying vec2 vTexCoord;\n\nvec4 round(vec4 x) {\n return floor(x + 0.5);\n}\n\nfloat round(float x) {\n return floor(x + 0.5);\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x / y));\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 rgba) {\n __DECODE32_ENDIANNESS__;\n rgba *= 255.0;\n vec2 gte128;\n gte128.x = rgba.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = rgba.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * rgba.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n rgba.b = rgba.b - 128.0 * gte128.x;\n res = dot(rgba, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nvec4 encode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 rgba = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n rgba.rg = integerMod(rgba.rg, 256.0);\n rgba.b = integerMod(rgba.b, 128.0);\n rgba.a = exponent*0.5 + 63.5;\n rgba.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n rgba = floor(rgba);\n rgba *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return rgba;\n}\n// Dragons end here\n\nfloat decode(vec4 rgba, int x, int bitRatio) {\n if (bitRatio == 1) {\n return decode32(rgba);\n }\n __DECODE32_ENDIANNESS__;\n int channel = integerMod(x, bitRatio);\n if (bitRatio == 4) {\n if (channel == 0) return rgba.r * 255.0;\n if (channel == 1) return rgba.g * 255.0;\n if (channel == 2) return rgba.b * 255.0;\n if (channel == 3) return rgba.a * 255.0;\n }\n else {\n if (channel == 0) return rgba.r * 255.0 + rgba.g * 65280.0;\n if (channel == 1) return rgba.b * 255.0 + rgba.a * 65280.0;\n }\n}\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, int z, int y, int x) {\n ivec3 xyz = ivec3(x, y, z);\n __GET_WRAPAROUND__;\n int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);\n __GET_TEXTURE_CHANNEL__;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n __GET_TEXTURE_INDEX__;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n __GET_RESULT__;\n \n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n ivec3 xyz = ivec3(x, y, z);\n __GET_WRAPAROUND__;\n int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);\n __GET_TEXTURE_CHANNEL__;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n __GET_TEXTURE_INDEX__;\n return texture2D(tex, st / vec2(texSize));\n}\n\nfloat get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, int y, int x) {\n return get(tex, texSize, texDim, bitRatio, int(0), y, x);\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int y, int x) {\n return getImage2D(tex, texSize, texDim, int(0), y, x);\n}\n\nfloat get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, int x) {\n return get(tex, texSize, texDim, bitRatio, int(0), int(0), x);\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int x) {\n return getImage2D(tex, texSize, texDim, int(0), int(0), x);\n}\n\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nvoid color(sampler2D image) {\n actualColor = texture2D(image, vTexCoord);\n}\n\n__MAIN_PARAMS__;\n__MAIN_CONSTANTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}"; -},{}],69:[function(require,module,exports){ -"use strict"; - -module.exports = "precision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nattribute vec2 aPos;\nattribute vec2 aTexCoord;\n\nvarying vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"; -},{}],70:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var WebGLKernel = require('./kernel'); -var utils = require('../../core/utils'); - -/** - * @class WebGLValidatorKernel - * - * @desc Helper class for WebGLKernel to validate texture size and dimensions. - * - */ -module.exports = function (_WebGLKernel) { - _inherits(WebGLValidatorKernel, _WebGLKernel); - - function WebGLValidatorKernel() { - _classCallCheck(this, WebGLValidatorKernel); - - return _possibleConstructorReturn(this, (WebGLValidatorKernel.__proto__ || Object.getPrototypeOf(WebGLValidatorKernel)).apply(this, arguments)); - } - - _createClass(WebGLValidatorKernel, [{ - key: 'validateOptions', - - - /** - * @memberOf WebGLValidatorKernel# - * @function - * @name validateOptions - * - */ - value: function validateOptions() { - this.texSize = utils.dimToTexSize({ - floatTextures: this.floatTextures, - floatOutput: this.floatOutput - }, this.output, true); - } - }]); - - return WebGLValidatorKernel; -}(WebGLKernel); -},{"../../core/utils":84,"./kernel":66}],71:[function(require,module,exports){ -'use strict'; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var FunctionBuilderBase = require('../function-builder-base'); -var WebGL2FunctionNode = require('./function-node'); - -/** - * @class WebGLFunctionBuilder - * - * @extends FunctionBuilderBase - * - * @desc Builds webGl functions (shaders) from JavaScript function Strings - * - */ -module.exports = function (_FunctionBuilderBase) { - _inherits(WebGL2FunctionBuilder, _FunctionBuilderBase); - - function WebGL2FunctionBuilder() { - _classCallCheck(this, WebGL2FunctionBuilder); - - var _this = _possibleConstructorReturn(this, (WebGL2FunctionBuilder.__proto__ || Object.getPrototypeOf(WebGL2FunctionBuilder)).call(this)); - - _this.Node = WebGL2FunctionNode; - return _this; - } - - return WebGL2FunctionBuilder; -}(FunctionBuilderBase); -},{"../function-builder-base":58,"./function-node":72}],72:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var WebGLFunctionNode = require('../web-gl/function-node'); - -// Closure capture for the ast function, prevent collision with existing AST functions -// The prefixes to use -var constantsPrefix = 'this.constants.'; - -var DECODE32_ENCODE32 = /decode32\(\s+encode32\(/g; -var ENCODE32_DECODE32 = /encode32\(\s+decode32\(/g; - -/** - * @class WebGL2FunctionNode - * - * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to generate its respective webGL code. - * - * @extends WebGLFunctionNode - * - * @returns the converted webGL function string - * - */ -module.exports = function (_WebGLFunctionNode) { - _inherits(WebGL2FunctionNode, _WebGLFunctionNode); - - function WebGL2FunctionNode() { - _classCallCheck(this, WebGL2FunctionNode); - - return _possibleConstructorReturn(this, (WebGL2FunctionNode.__proto__ || Object.getPrototypeOf(WebGL2FunctionNode)).apply(this, arguments)); - } - - _createClass(WebGL2FunctionNode, [{ - key: 'generate', - value: function generate() { - if (this.debug) { - console.log(this); - } - if (this.prototypeOnly) { - return WebGL2FunctionNode.astFunctionPrototype(this.getJsAST(), [], this).join('').trim(); - } else { - this.functionStringArray = this.astGeneric(this.getJsAST(), [], this); - } - this.functionString = webGlRegexOptimize(this.functionStringArray.join('').trim()); - return this.functionString; - } - - /** - * @memberOf WebGL2FunctionNode# - * @function - * @name astFunctionExpression - * - * @desc Parses the abstract syntax tree for to its *named function* - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astFunctionExpression', - value: function astFunctionExpression(ast, retArr) { - - // Setup function return type and name - if (this.isRootKernel) { - retArr.push('void'); - this.kernalAst = ast; - } else { - retArr.push(this.returnType); - } - retArr.push(' '); - retArr.push(this.functionName); - retArr.push('('); - - if (!this.isRootKernel) { - // Arguments handling - for (var i = 0; i < this.paramNames.length; ++i) { - var paramName = this.paramNames[i]; - - if (i > 0) { - retArr.push(', '); - } - var type = this.getParamType(paramName); - switch (type) { - case 'Texture': - case 'Input': - case 'Array': - case 'HTMLImage': - retArr.push('sampler2D'); - break; - default: - retArr.push('float'); - } - - retArr.push(' '); - retArr.push('user_'); - retArr.push(paramName); - } - } - - // Function opening - retArr.push(') {\n'); - - // Body statement iteration - for (var _i = 0; _i < ast.body.body.length; ++_i) { - this.astGeneric(ast.body.body[_i], retArr); - retArr.push('\n'); - } - - // Function closing - retArr.push('}\n'); - return retArr; - } - - /** - * @memberOf WebGL2FunctionNode# - * @function - * @name astIdentifierExpression - * - * @desc Parses the abstract syntax tree for *identifier* expression - * - * @param {Object} idtNode - An ast Node - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - - }, { - key: 'astIdentifierExpression', - value: function astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode); - } - - // do we need to cast addressing vales to float? - var castFloat = !this.isState('in-get-call-parameters'); - - switch (idtNode.name) { - case 'gpu_threadX': - castFloat && retArr.push('float('); - retArr.push('threadId.x'); - castFloat && retArr.push(')'); - break; - case 'gpu_threadY': - castFloat && retArr.push('float('); - retArr.push('threadId.y'); - castFloat && retArr.push(')'); - break; - case 'gpu_threadZ': - castFloat && retArr.push('float('); - retArr.push('threadId.z'); - castFloat && retArr.push(')'); - break; - case 'gpu_outputX': - retArr.push('uOutputDim.x'); - break; - case 'gpu_outputY': - retArr.push('uOutputDim.y'); - break; - case 'gpu_outputZ': - retArr.push('uOutputDim.z'); - break; - case 'Infinity': - retArr.push('intBitsToFloat(2139095039)'); - break; - default: - if (this.constants && this.constants.hasOwnProperty(idtNode.name)) { - this.pushParameter(retArr, 'constants_' + idtNode.name); - } else { - var userParamName = this.getUserParamName(idtNode.name); - if (userParamName !== null) { - this.pushParameter(retArr, 'user_' + userParamName); - } else { - this.pushParameter(retArr, 'user_' + idtNode.name); - } - } - } - - return retArr; - } - }]); - - return WebGL2FunctionNode; -}(WebGLFunctionNode); - -/** - * @ignore - * @function - * @name webgl_regex_optimize - * - * @desc [INTERNAL] Takes the near final webgl function string, and do regex search and replacments. - * For voodoo optimize out the following: - * - * - decode32(encode32(
- * - encode32(decode32(
- * - * @param {String} inStr - The webGl function String - * - */ -function webGlRegexOptimize(inStr) { - return inStr.replace(DECODE32_ENCODE32, '((').replace(ENCODE32_DECODE32, '(('); -} -},{"../web-gl/function-node":64}],73:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var WebGLKernel = require('../web-gl/kernel'); -var utils = require('../../core/utils'); -var Texture = require('../../core/texture'); -var fragShaderString = require('./shader-frag'); -var vertShaderString = require('./shader-vert'); - -module.exports = function (_WebGLKernel) { - _inherits(WebGL2Kernel, _WebGLKernel); - - function WebGL2Kernel() { - _classCallCheck(this, WebGL2Kernel); - - return _possibleConstructorReturn(this, (WebGL2Kernel.__proto__ || Object.getPrototypeOf(WebGL2Kernel)).apply(this, arguments)); - } - - _createClass(WebGL2Kernel, [{ - key: 'initWebGl', - value: function initWebGl() { - return utils.initWebGl2(this.getCanvas()); - } - /** - * @memberOf WebGL2Kernel# - * @function - * @name validateOptions - * - * @desc Validate options related to Kernel, such as - * floatOutputs and Textures, texSize, output, - * graphical output. - * - */ - - }, { - key: 'validateOptions', - value: function validateOptions() { - var isFloatReadPixel = utils.isFloatReadPixelsSupportedWebGL2(); - if (this.floatOutput === true && this.floatOutputForce !== true && !isFloatReadPixel) { - throw new Error('Float texture outputs are not supported on this browser'); - } else if (this.floatTextures === undefined) { - this.floatTextures = true; - this.floatOutput = isFloatReadPixel; - } - - var hasIntegerDivisionBug = utils.hasIntegerDivisionAccuracyBug(); - if (this.fixIntegerDivisionAccuracy == null) { - this.fixIntegerDivisionAccuracy = hasIntegerDivisionBug; - } else if (this.fixIntegerDivisionAccuracy && !hasIntegerDivisionBug) { - this.fixIntegerDivisionAccuracy = false; - } - - utils.checkOutput(this.output); - - if (!this.output || this.output.length === 0) { - if (arguments.length !== 1) { - throw new Error('Auto output only supported for kernels with only one input'); - } - - var argType = utils.getArgumentType(arguments[0]); - if (argType === 'Array') { - this.output = utils.getDimensions(argType); - } else if (argType === 'Texture') { - this.output = arguments[0].output; - } else { - throw new Error('Auto output not supported for input type: ' + argType); - } - } - - this.texSize = utils.dimToTexSize({ - floatTextures: this.floatTextures, - floatOutput: this.floatOutput - }, this.output, true); - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); - } - - if (this.floatOutput) { - this.floatOutput = false; - console.warn('Cannot use graphical mode and float output at the same time'); - } - - this.texSize = utils.clone(this.output); - } else if (this.floatOutput === undefined) { - this.floatOutput = true; - } - - if (this.floatOutput || this.floatOutputForce) { - this._webGl.getExtension('EXT_color_buffer_float'); - } - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name run - * - * @desc Run the kernel program, and send the output to renderOutput - * - *

This method calls a helper method *renderOutput* to return the result.

- * - * @returns {Object|Undefined} Result The final output of the program, as float, and as Textures for reuse. - * - * - */ - - }, { - key: 'run', - value: function run() { - if (this.program === null) { - this.build.apply(this, arguments); - } - var paramNames = this.paramNames; - var paramTypes = this.paramTypes; - var texSize = this.texSize; - var gl = this._webGl; - - gl.useProgram(this.program); - gl.scissor(0, 0, texSize[0], texSize[1]); - - if (!this.hardcodeConstants) { - this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); - this.setUniform2iv('uTexSize', texSize); - } - - this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); - - this.argumentsLength = 0; - for (var texIndex = 0; texIndex < paramNames.length; texIndex++) { - this._addArgument(arguments[texIndex], paramTypes[texIndex], paramNames[texIndex]); - } - - if (this.graphical) { - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return; - } - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (this.outputImmutable) { - this._setupOutputTexture(); - } - var outputTexture = this.outputTexture; - - if (this.subKernelOutputVariableNames !== null) { - if (this.outputImmutable) { - this.subKernelOutputTextures = []; - this._setupSubOutputTextures(this.subKernelOutputVariableNames.length); - } - gl.drawBuffers(this.drawBuffersMap); - } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - - if (this.subKernelOutputTextures !== null) { - if (this.subKernels !== null) { - var output = []; - output.result = this.renderOutput(outputTexture); - for (var i = 0; i < this.subKernels.length; i++) { - output.push(new Texture(this.subKernelOutputTextures[i], texSize, this.threadDim, this.output, this._webGl)); - } - return output; - } else if (this.subKernelProperties !== null) { - var _output = { - result: this.renderOutput(outputTexture) - }; - var _i = 0; - for (var p in this.subKernelProperties) { - if (!this.subKernelProperties.hasOwnProperty(p)) continue; - _output[p] = new Texture(this.subKernelOutputTextures[_i], texSize, this.threadDim, this.output, this._webGl); - _i++; - } - return _output; - } - } - - return this.renderOutput(outputTexture); - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name getOutputTexture - * - * @desc This return defined outputTexture, which is setup in .build(), or if immutable, is defined in .run() - * - * @returns {Object} Output Texture Cache - * - */ - - }, { - key: 'getOutputTexture', - value: function getOutputTexture() { - return this.outputTexture; - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name _setupOutputTexture - * @private - * - * @desc Setup and replace output texture - */ - - }, { - key: '_setupOutputTexture', - value: function _setupOutputTexture() { - var gl = this._webGl; - var texSize = this.texSize; - var texture = this.outputTexture = this._webGl.createTexture(); - gl.activeTexture(gl.TEXTURE0 + this.paramNames.length); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.floatOutput) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); - } - - /** - * @memberOf WebGL2Kernel# - * @param length - * @private - * - * @desc Setup and replace sub-output textures - */ - - }, { - key: '_setupSubOutputTextures', - value: function _setupSubOutputTextures(length) { - var gl = this._webGl; - var texSize = this.texSize; - var drawBuffersMap = this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - var textures = this.subKernelOutputTextures = []; - for (var i = 0; i < length; i++) { - var texture = this._webGl.createTexture(); - textures.push(texture); - drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); - gl.activeTexture(gl.TEXTURE0 + this.paramNames.length + i); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.floatOutput) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); - } - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name _addArgument - * - * @desc Adds kernel parameters to the Argument Texture, - * binding it to the webGl instance, etc. - * - * @param {Array|Texture|Number} value - The actual argument supplied to the kernel - * @param {String} type - Type of the argument - * @param {String} name - Name of the argument - * - */ - - }, { - key: '_addArgument', - value: function _addArgument(value, type, name) { - var gl = this._webGl; - var argumentTexture = this.getArgumentTexture(name); - if (value instanceof Texture) { - type = 'Texture'; - } - switch (type) { - case 'Array': - { - var dim = utils.getDimensions(value, true); - var size = utils.dimToTexSize({ - floatTextures: this.floatTextures, - floatOutput: this.floatOutput - }, dim); - gl.activeTexture(gl.TEXTURE0 + this.argumentsLength); - gl.bindTexture(gl.TEXTURE_2D, argumentTexture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - - var length = size[0] * size[1]; - - var _formatArrayTransfer = this._formatArrayTransfer(value, length), - valuesFlat = _formatArrayTransfer.valuesFlat, - bitRatio = _formatArrayTransfer.bitRatio; - - var buffer = void 0; - if (this.floatTextures) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, size[0], size[1], 0, gl.RGBA, gl.FLOAT, valuesFlat); - } else { - buffer = new Uint8Array(valuesFlat.buffer); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0] / bitRatio, size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, buffer); - } - - if (!this.hardcodeConstants) { - this.setUniform3iv('user_' + name + 'Dim', dim); - this.setUniform2iv('user_' + name + 'Size', size); - } - this.setUniform1i('user_' + name + 'BitRatio', bitRatio); - this.setUniform1i('user_' + name, this.argumentsLength); - break; - } - case 'Integer': - case 'Float': - { - this.setUniform1f('user_' + name, value); - break; - } - case 'Input': - { - var input = value; - var _dim = input.size; - var _size = utils.dimToTexSize({ - floatTextures: this.floatTextures, - floatOutput: this.floatOutput - }, _dim); - gl.activeTexture(gl.TEXTURE0 + this.argumentsLength); - gl.bindTexture(gl.TEXTURE_2D, argumentTexture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - - var _length = _size[0] * _size[1]; - - var _formatArrayTransfer2 = this._formatArrayTransfer(value.value, _length), - _valuesFlat = _formatArrayTransfer2.valuesFlat, - _bitRatio = _formatArrayTransfer2.bitRatio; - - if (this.floatTextures) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, _size[0], _size[1], 0, gl.RGBA, gl.FLOAT, inputArray); - } else { - var _buffer = new Uint8Array(_valuesFlat.buffer); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, _size[0] / _bitRatio, _size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, _buffer); - } - - if (!this.hardcodeConstants) { - this.setUniform3iv('user_' + name + 'Dim', _dim); - this.setUniform2iv('user_' + name + 'Size', _size); - } - this.setUniform1i('user_' + name + 'BitRatio', _bitRatio); - this.setUniform1i('user_' + name, this.argumentsLength); - break; - } - case 'HTMLImage': - { - var inputImage = value; - var _dim2 = [inputImage.width, inputImage.height, 1]; - var _size2 = [inputImage.width, inputImage.height]; - - gl.activeTexture(gl.TEXTURE0 + this.argumentsLength); - gl.bindTexture(gl.TEXTURE_2D, argumentTexture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); - // Upload the image into the texture. - var mipLevel = 0; // the largest mip - var internalFormat = gl.RGBA; // format we want in the texture - var srcFormat = gl.RGBA; // format of data we are supplying - var srcType = gl.UNSIGNED_BYTE; // type of data we are supplying - gl.texImage2D(gl.TEXTURE_2D, mipLevel, internalFormat, srcFormat, srcType, inputImage); - this.setUniform3iv('user_' + name + 'Dim', _dim2); - this.setUniform2iv('user_' + name + 'Size', _size2); - this.setUniform1i('user_' + name, this.argumentsLength); - break; - } - case 'HTMLImageArray': - { - var inputImages = value; - var _dim3 = [inputImages[0].width, inputImages[0].height, inputImages.length]; - var _size3 = [inputImages[0].width, inputImages[0].height]; - - gl.activeTexture(gl.TEXTURE0 + this.argumentsLength); - gl.bindTexture(gl.TEXTURE_2D_ARRAY, argumentTexture); - gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); - // Upload the images into the texture. - var _mipLevel = 0; // the largest mip - var _internalFormat = gl.RGBA; // format we want in the texture - var width = inputImages[0].width; - var height = inputImages[0].height; - var textureDepth = inputImages.length; - var border = 0; - var _srcFormat = gl.RGBA; // format of data we are supplying - var _srcType = gl.UNSIGNED_BYTE; // type of data we are supplying - gl.texImage3D(gl.TEXTURE_2D_ARRAY, _mipLevel, _internalFormat, width, height, textureDepth, border, _srcFormat, _srcType, null); - for (var i = 0; i < inputImages.length; i++) { - var xOffset = 0; - var yOffset = 0; - var imageDepth = 1; - gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, _mipLevel, xOffset, yOffset, i, inputImages[i].width, inputImages[i].height, imageDepth, _srcFormat, _srcType, inputImages[i]); - } - this.setUniform3iv('user_' + name + 'Dim', _dim3); - this.setUniform2iv('user_' + name + 'Size', _size3); - this.setUniform1i('user_' + name, this.argumentsLength); - break; - } - case 'Texture': - { - var inputTexture = value; - var _dim4 = inputTexture.dimensions; - var _size4 = inputTexture.size; - - gl.activeTexture(gl.TEXTURE0 + this.argumentsLength); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - this.setUniform3iv('user_' + name + 'Dim', _dim4); - this.setUniform2iv('user_' + name + 'Size', _size4); - this.setUniform1i('user_' + name + 'BitRatio', 1); // always float32 - this.setUniform1i('user_' + name, this.argumentsLength); - break; - } - default: - throw new Error('Input type not supported (WebGL): ' + value); - } - this.argumentsLength++; - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name _getGetResultString - * - */ - - }, { - key: '_getGetResultString', - value: function _getGetResultString() { - if (!this.floatTextures) { - return ' return decode(texel, x, bitRatio);'; - } - return ' return texel[channel];'; - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name _getHeaderString - * - * @desc Get the header string for the program. - * This returns an empty string if no sub-kernels are defined. - * - * @returns {String} result - * - */ - - }, { - key: '_getHeaderString', - value: function _getHeaderString() { - return ''; - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name _getTextureCoordinate - * - * @desc Get texture coordinate string for the program - * - * @returns {String} result - * - */ - - }, { - key: '_getTextureCoordinate', - value: function _getTextureCoordinate() { - var names = this.subKernelOutputVariableNames; - if (names === null || names.length < 1) { - return 'in highp vec2 vTexCoord;\n'; - } else { - return 'out highp vec2 vTexCoord;\n'; - } - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name _getMainParamsString - * - * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel - * - * @param {Array} args - The actual parameters sent to the Kernel - * - * @returns {String} result - * - */ - - }, { - key: '_getMainParamsString', - value: function _getMainParamsString(args) { - var result = []; - var paramTypes = this.paramTypes; - var paramNames = this.paramNames; - for (var i = 0; i < paramNames.length; i++) { - var param = args[i]; - var paramName = paramNames[i]; - var paramType = paramTypes[i]; - if (this.hardcodeConstants) { - if (paramType === 'Array' || paramType === 'Texture') { - var paramDim = utils.getDimensions(param, true); - var paramSize = utils.dimToTexSize({ - floatTextures: this.floatTextures, - floatOutput: this.floatOutput - }, paramDim); - - result.push('uniform highp sampler2D user_' + paramName, 'highp ivec2 user_' + paramName + 'Size = ivec2(' + paramSize[0] + ', ' + paramSize[1] + ')', 'highp ivec3 user_' + paramName + 'Dim = ivec3(' + paramDim[0] + ', ' + paramDim[1] + ', ' + paramDim[2] + ')', 'uniform highp int user_' + paramName + 'BitRatio'); - - if (paramType === 'Array') { - result.push('uniform highp int user_' + paramName + 'BitRatio'); - } - } else if (paramType === 'Integer') { - result.push('highp float user_' + paramName + ' = ' + param + '.0'); - } else if (paramType === 'Float') { - result.push('highp float user_' + paramName + ' = ' + param); - } - } else { - if (paramType === 'Array' || paramType === 'Texture' || paramType === 'Input' || paramType === 'HTMLImage') { - result.push('uniform highp sampler2D user_' + paramName, 'uniform highp ivec2 user_' + paramName + 'Size', 'uniform highp ivec3 user_' + paramName + 'Dim'); - if (paramType !== 'HTMLImage') { - result.push('uniform highp int user_' + paramName + 'BitRatio'); - } - } else if (paramType === 'HTMLImageArray') { - result.push('uniform highp sampler2DArray user_' + paramName, 'uniform highp ivec2 user_' + paramName + 'Size', 'uniform highp ivec3 user_' + paramName + 'Dim'); - } else if (paramType === 'Integer' || paramType === 'Float') { - result.push('uniform float user_' + paramName); - } - } - } - return this._linesToString(result); - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name _getKernelString - * - * @desc Get Kernel program string (in *glsl*) for a kernel. - * - * @returns {String} result - * - */ - - }, { - key: '_getKernelString', - value: function _getKernelString() { - var result = []; - var names = this.subKernelOutputVariableNames; - if (names !== null) { - result.push('float kernelResult = 0.0'); - result.push('layout(location = 0) out vec4 data0'); - for (var i = 0; i < names.length; i++) { - result.push('float ' + names[i] + ' = 0.0', 'layout(location = ' + (i + 1) + ') out vec4 data' + (i + 1)); - } - } else { - result.push('out vec4 data0'); - result.push('float kernelResult = 0.0'); - } - - return this._linesToString(result) + this.functionBuilder.getPrototypeString('kernel'); - } - - /** - * - * @memberOf WebGL2Kernel# - * @function - * @name _getMainResultString - * - * @desc Get main result string with checks for floatOutput, graphical, subKernelsOutputs, etc. - * - * @returns {String} result - * - */ - - }, { - key: '_getMainResultString', - value: function _getMainResultString() { - var names = this.subKernelOutputVariableNames; - var result = []; - - if (this.floatOutput) { - result.push(' index *= 4'); - } - - if (this.graphical) { - result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' data0 = actualColor'); - } else if (this.floatOutput) { - var channels = ['r', 'g', 'b', 'a']; - - for (var i = 0; i < channels.length; ++i) { - result.push(' threadId = indexTo3D(index, uOutputDim)'); - result.push(' kernel()'); - - if (names) { - result.push(' data0.' + channels[i] + ' = kernelResult'); - - for (var j = 0; j < names.length; ++j) { - result.push(' data' + (j + 1) + '.' + channels[i] + ' = ' + names[j]); - } - } else { - result.push(' data0.' + channels[i] + ' = kernelResult'); - } - - if (i < channels.length - 1) { - result.push(' index += 1'); - } - } - } else if (names !== null) { - result.push(' threadId = indexTo3D(index, uOutputDim)'); - result.push(' kernel()'); - result.push(' data0 = encode32(kernelResult)'); - for (var _i2 = 0; _i2 < names.length; _i2++) { - result.push(' data' + (_i2 + 1) + ' = encode32(' + names[_i2] + ')'); - } - } else { - result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' data0 = encode32(kernelResult)'); - } - - return this._linesToString(result); - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name _addKernels - * - * @desc Adds all the sub-kernels supplied with this Kernel instance. - * - */ - - }, { - key: '_addKernels', - value: function _addKernels() { - var _this2 = this; - - var builder = this.functionBuilder; - var gl = this._webGl; - - builder.addFunctions(this.functions, { - constants: this.constants, - output: this.output - }); - builder.addNativeFunctions(this.nativeFunctions); - - builder.addKernel(this.fnString, { - prototypeOnly: false, - constants: this.constants, - output: this.output, - debug: this.debug, - loopMaxIterations: this.loopMaxIterations, - paramNames: this.paramNames, - paramTypes: this.paramTypes, - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - - if (this.subKernels !== null) { - this.subKernelOutputTextures = []; - this.subKernelOutputVariableNames = []; - this.subKernels.forEach(function (subKernel) { - return _this2._addSubKernel(subKernel); - }); - } else if (this.subKernelProperties !== null) { - this.subKernelOutputTextures = []; - this.subKernelOutputVariableNames = []; - Object.keys(this.subKernelProperties).forEach(function (property) { - return _this2._addSubKernel(_this2.subKernelProperties[property]); - }); - } - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name _getFragShaderString - * - * @desc Get the fragment shader String. - * If the String hasn't been compiled yet, - * then this method compiles it as well - * - * @param {Array} args - The actual parameters sent to the Kernel - * - * @returns {string} Fragment Shader string - * - */ - - }, { - key: '_getFragShaderString', - value: function _getFragShaderString(args) { - if (this.compiledFragShaderString !== null) { - return this.compiledFragShaderString; - } - return this.compiledFragShaderString = this._replaceArtifacts(this.constructor.fragShaderString, this._getFragShaderArtifactMap(args)); - } - - /** - * @memberOf WebGL2Kernel# - * @function - * @name _getVertShaderString - * - * @desc Get the vertical shader String - * - * @param {Array} args - The actual parameters sent to the Kernel - * - * @returns {string} Vertical Shader string - * - */ - - }, { - key: '_getVertShaderString', - value: function _getVertShaderString(args) { - if (this.compiledVertShaderString !== null) { - return this.compiledVertShaderString; - } - return this.compiledVertShaderString = this.constructor.vertShaderString; - } - }], [{ - key: 'fragShaderString', - get: function get() { - return fragShaderString; - } - }, { - key: 'vertShaderString', - get: function get() { - return vertShaderString; - } - }]); - - return WebGL2Kernel; -}(WebGLKernel); -},{"../../core/texture":82,"../../core/utils":84,"../web-gl/kernel":66,"./shader-frag":75,"./shader-vert":76}],74:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var RunnerBase = require('../runner-base'); -var WebGL2FunctionBuilder = require('./function-builder'); -var WebGL2Kernel = require('./kernel'); - -module.exports = function (_RunnerBase) { - _inherits(WebGL2Runner, _RunnerBase); - - /** - * @constructor WebGL2Runner - * - * @extends RunnerBase - * @desc Instantiates a Runner instance for the kernel. - * - * @param {Object} settings - Settings to instantiate properties in RunnerBase, with given values - * - */ - function WebGL2Runner(settings) { - _classCallCheck(this, WebGL2Runner); - - var _this = _possibleConstructorReturn(this, (WebGL2Runner.__proto__ || Object.getPrototypeOf(WebGL2Runner)).call(this, new WebGL2FunctionBuilder(), settings)); - - _this.Kernel = WebGL2Kernel; - _this.kernel = null; - return _this; - } - - /** - * @memberOf WebGL2Runner# - * @function - * @name getMode - * - * @desc Return the current mode in which gpu.js is executing. - * - * @returns {String} The current mode; "gpu". - * - */ - - - _createClass(WebGL2Runner, [{ - key: 'getMode', - value: function getMode() { - return 'gpu'; - } - }]); - - return WebGL2Runner; -}(RunnerBase); -},{"../runner-base":62,"./function-builder":71,"./kernel":73}],75:[function(require,module,exports){ -"use strict"; - -module.exports = "#version 300 es\n__HEADER__;\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nconst float LOOP_MAX = __LOOP_MAX__;\n\n__CONSTANTS__;\n\nin vec2 vTexCoord;\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x/y));\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 rgba) {\n __DECODE32_ENDIANNESS__;\n rgba *= 255.0;\n vec2 gte128;\n gte128.x = rgba.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = rgba.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * rgba.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n rgba.b = rgba.b - 128.0 * gte128.x;\n res = dot(rgba, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nvec4 encode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 rgba = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n rgba.rg = integerMod(rgba.rg, 256.0);\n rgba.b = integerMod(rgba.b, 128.0);\n rgba.a = exponent*0.5 + 63.5;\n rgba.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n rgba = floor(rgba);\n rgba *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return rgba;\n}\n// Dragons end here\n\nfloat decode(vec4 rgba, int x, int bitRatio) {\n if (bitRatio == 1) {\n return decode32(rgba);\n }\n __DECODE32_ENDIANNESS__;\n int channel = integerMod(x, bitRatio);\n if (bitRatio == 4) {\n return rgba[channel] * 255.0;\n }\n else {\n return rgba[channel*2] * 255.0 + rgba[channel*2 + 1] * 65280.0;\n }\n}\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, int z, int y, int x) {\n ivec3 xyz = ivec3(x, y, z);\n __GET_WRAPAROUND__;\n int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);\n __GET_TEXTURE_CHANNEL__;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n __GET_TEXTURE_INDEX__;\n vec4 texel = texture(tex, st / vec2(texSize));\n __GET_RESULT__;\n \n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n ivec3 xyz = ivec3(x, y, z);\n __GET_WRAPAROUND__;\n int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);\n __GET_TEXTURE_CHANNEL__;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n __GET_TEXTURE_INDEX__;\n return texture(tex, st / vec2(texSize));\n}\n\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n ivec3 xyz = ivec3(x, y, z);\n __GET_WRAPAROUND__;\n int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);\n __GET_TEXTURE_CHANNEL__;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n __GET_TEXTURE_INDEX__;\n return texture(tex, vec3(st / vec2(texSize), z));\n}\n\nfloat get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, int y, int x) {\n return get(tex, texSize, texDim, bitRatio, 0, y, x);\n}\n\nfloat get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, int x) {\n return get(tex, texSize, texDim, bitRatio, 0, 0, x);\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int y, int x) {\n return getImage2D(tex, texSize, texDim, 0, y, x);\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int x) {\n return getImage2D(tex, texSize, texDim, 0, 0, x);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\n__MAIN_PARAMS__;\n__MAIN_CONSTANTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}"; -},{}],76:[function(require,module,exports){ -"use strict"; - -module.exports = "#version 300 es\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nin vec2 aPos;\nin vec2 aTexCoord;\n\nout vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"; -},{}],77:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var WebGLKernel = require('./kernel'); -var utils = require('../../core/utils'); - -/** - * @class WebGLValidatorKernel - * - * @desc Helper class for WebGLKernel to validate texture size and dimensions. - * - */ -module.exports = function (_WebGLKernel) { - _inherits(WebGL2ValidatorKernel, _WebGLKernel); - - function WebGL2ValidatorKernel() { - _classCallCheck(this, WebGL2ValidatorKernel); - - return _possibleConstructorReturn(this, (WebGL2ValidatorKernel.__proto__ || Object.getPrototypeOf(WebGL2ValidatorKernel)).apply(this, arguments)); - } - - _createClass(WebGL2ValidatorKernel, [{ - key: 'validateOptions', - - - /** - * @memberOf WebGLValidatorKernel# - * @function - * @name validateOptions - * - */ - value: function validateOptions() { - this._webGl.getExtension('EXT_color_buffer_float'); - this.texSize = utils.dimToTexSize({ - floatTextures: this.floatTextures, - floatOutput: this.floatOutput - }, this.output, true); - } - }]); - - return WebGL2ValidatorKernel; -}(WebGLKernel); -},{"../../core/utils":84,"./kernel":73}],78:[function(require,module,exports){ -'use strict'; - -var utils = require('./utils'); -module.exports = function alias(name, fn) { - var fnString = fn.toString(); - return new Function('return function ' + name + ' (' + utils.getParamNamesFromString(fnString).join(', ') + ') {' + utils.getFunctionBodyFromString(fnString) + '}')(); -}; -},{"./utils":84}],79:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var UtilsCore = require("./utils-core"); - -/** - * This is a minimalistic version of GPU.js used - * to run precompiled GPU.JS code. - * - * This intentionally excludes the JS AST compiller : which is 400kb alone/ - * - * @class GPUCore - */ -module.exports = function () { - function GPUCore() { - _classCallCheck(this, GPUCore); - } - - _createClass(GPUCore, null, [{ - key: "validateKernelObj", - - - /** - * @name validateKernelObj - * @function - * @static - * @memberOf GPUCore - * - * @description Validates the KernelObj to comply with the defined format - * Note that this does only a limited sanity check, and does not - * guarantee a full working validation. - * - * For the kernel object format see : - * - * @param {Object|String} kernelObj - KernelObj used to validate - * - * @returns {Object} The validated kernel object, converted from JSON if needed - * - */ - value: function validateKernelObj(kernelObj) { - - // NULL validation - if (kernelObj === null) { - throw "KernelObj being validated is NULL"; - } - - // String JSON conversion - if (typeof kernelObj === "string") { - try { - kernelObj = JSON.parse(kernelObj); - } catch (e) { - console.error(e); - throw "Failed to convert KernelObj from JSON string"; - } - - // NULL validation - if (kernelObj === null) { - throw "Invalid (NULL) KernelObj JSON string representation"; - } - } - - // Check for kernel obj flag - if (kernelObj.isKernelObj !== true) { - throw "Failed missing isKernelObj flag check"; - } - - // Return the validated kernelObj - return kernelObj; - } - - /** - * @name loadKernelObj - * @function - * @static - * @memberOf GPUCore - * - * @description Loads the precompiled kernel object. For GPUCore this is the ONLY way to create the kernel. - * To generate the kernelObj use - * - * Note that this function calls internally, and throws an exception if it fails. - * - * @see GPUCore.validateKernelObj - * @see Kernel.exportKernelObj - * - * @param {Object} kernelObj - The precompiled kernel object - * @param {Object} inOpt - [Optional] the option overrides to use - * - * @returns {Function} The kernel function - * - */ - - }, { - key: "loadKernelObj", - value: function loadKernelObj(kernelObj, inOpt) { - - // Validates the kernelObj, throws an exception if it fails - kernelObj = validateKernelObj(kernelObj); - } - }]); - - return GPUCore; -}(); -},{"./utils-core":83}],80:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var utils = require('./utils'); -var WebGLRunner = require('../backend/web-gl/runner'); -var WebGL2Runner = require('../backend/web-gl2/runner'); -var CPURunner = require('../backend/cpu/runner'); -var WebGLValidatorKernel = require('../backend/web-gl/validator-kernel'); -var WebGL2ValidatorKernel = require('../backend/web-gl2/validator-kernel'); -var GPUCore = require("./gpu-core"); - -/** - * Initialises the GPU.js library class which manages the webGlContext for the created functions. - * @class - * @extends GPUCore - */ - -var GPU = function (_GPUCore) { - _inherits(GPU, _GPUCore); - - /** - * Creates an instance of GPU. - * @param {any} settings - Settings to set mode, andother properties. See #GPUCore - * @memberOf GPU# - */ - function GPU(settings) { - _classCallCheck(this, GPU); - - var _this = _possibleConstructorReturn(this, (GPU.__proto__ || Object.getPrototypeOf(GPU)).call(this, settings)); - - settings = settings || {}; - _this._canvas = settings.canvas || null; - _this._webGl = settings.webGl || null; - var mode = settings.mode; - var detectedMode = void 0; - if (!utils.isWebGlSupported()) { - if (mode && mode !== 'cpu') { - throw new Error('A requested mode of "' + mode + '" and is not supported'); - } else { - console.warn('Warning: gpu not supported, falling back to cpu support'); - detectedMode = 'cpu'; - } - } else { - detectedMode = mode || 'gpu'; - } - _this.kernels = []; - - var runnerSettings = { - canvas: _this._canvas, - webGl: _this._webGl - }; - - switch (detectedMode) { - // public options - case 'cpu': - _this._runner = new CPURunner(runnerSettings); - break; - case 'gpu': - var Runner = _this.getGPURunner(); - _this._runner = new Runner(runnerSettings); - break; - - // private explicit options for testing - case 'webgl2': - _this._runner = new WebGL2Runner(runnerSettings); - break; - case 'webgl': - _this._runner = new WebGLRunner(runnerSettings); - break; - - // private explicit options for internal - case 'webgl2-validator': - _this._runner = new WebGL2Runner(runnerSettings); - _this._runner.Kernel = WebGL2ValidatorKernel; - break; - case 'webgl-validator': - _this._runner = new WebGLRunner(runnerSettings); - _this._runner.Kernel = WebGLValidatorKernel; - break; - default: - throw new Error('"' + mode + '" mode is not defined'); - } - return _this; - } - /** - * - * This creates a callable function object to call the kernel function with the argument parameter set - * - * @name createKernel - * @function - * @memberOf GPU## - * - * @param {Function} fn - The calling to perform the conversion - * @param {Object} [settings] - The parameter configuration object - * @property {String} settings.dimensions - Thread dimension array (Defaults to [1024]) - * @property {String} settings.mode - CPU / GPU configuration mode (Defaults to null) - * - * The following modes are supported - * *'falsey'* : Attempts to build GPU mode, else fallbacks - * *'gpu'* : Attempts to build GPU mode, else fallbacks - * *'cpu'* : Forces JS fallback mode only - * - * - * @returns {Function} callable function to run - * - */ - - - _createClass(GPU, [{ - key: 'createKernel', - value: function createKernel(fn, settings) { - // - // basic parameters safety checks - // - if (typeof fn === 'undefined') { - throw 'Missing fn parameter'; - } - if (!utils.isFunction(fn) && typeof fn !== 'string') { - throw 'fn parameter not a function'; - } - - var kernel = this._runner.buildKernel(fn, settings || {}); - - //if canvas didn't come from this, propagate from kernel - if (!this._canvas) { - this._canvas = kernel.getCanvas(); - } - if (!this._runner.canvas) { - this._runner.canvas = kernel.getCanvas(); - } - - this.kernels.push(kernel); - - return kernel; - } - - /** - * - * Create a super kernel which executes sub kernels - * and saves their output to be used with the next sub kernel. - * This can be useful if we want to save the output on one kernel, - * and then use it as an input to another kernel. *Machine Learning* - * - * @name createKernelMap - * @function - * @memberOf GPU# - * - * @param {Object|Array} subKernels - Sub kernels for this kernel - * @param {Function} rootKernel - Root kernel - * - * @returns {Function} callable kernel function - * - * @example - * const megaKernel = gpu.createKernelMap({ - * addResult: function add(a, b) { - * return a[this.thread.x] + b[this.thread.x]; - * }, - * multiplyResult: function multiply(a, b) { - * return a[this.thread.x] * b[this.thread.x]; - * }, - * }, function(a, b, c) { - * return multiply(add(a, b), c); - * }); - * - * megaKernel(a, b, c); - * - * Note: You can also define subKernels as an array of functions. - * > [add, multiply] - * - */ - - }, { - key: 'createKernelMap', - value: function createKernelMap() { - var fn = void 0; - var settings = void 0; - if (typeof arguments[arguments.length - 2] === 'function') { - fn = arguments[arguments.length - 2]; - settings = arguments[arguments.length - 1]; - } else { - fn = arguments[arguments.length - 1]; - } - - if (!utils.isWebGlDrawBuffersSupported()) { - this._runner = new CPURunner(settings); - } - - var kernel = this.createKernel(fn, settings); - if (Array.isArray(arguments[0])) { - var functions = arguments[0]; - for (var i = 0; i < functions.length; i++) { - kernel.addSubKernel(functions[i]); - } - } else { - var _functions = arguments[0]; - for (var p in _functions) { - if (!_functions.hasOwnProperty(p)) continue; - kernel.addSubKernelProperty(p, _functions[p]); - } - } - - return kernel; - } - - /** - * - * Combine different kernels into one super Kernel, - * useful to perform multiple operations inside one - * kernel without the penalty of data transfer between - * cpu and gpu. - * - * The number of kernel functions sent to this method can be variable. - * You can send in one, two, etc. - * - * @name combineKernels - * @function - * @memberOf GPU# - * - * @param {Function} subKernels - Kernel function(s) to combine. - * @param {Function} rootKernel - Root kernel to combine kernels into - * - * @example - * combineKernels(add, multiply, function(a,b,c){ - * return add(multiply(a,b), c) - * }) - * - * @returns {Function} Callable kernel function - * - */ - - }, { - key: 'combineKernels', - value: function combineKernels() { - var lastKernel = arguments[arguments.length - 2]; - var combinedKernel = arguments[arguments.length - 1]; - if (this.getMode() === 'cpu') return combinedKernel; - - var canvas = arguments[0].getCanvas(); - var webGl = arguments[0].getWebGl(); - - for (var i = 0; i < arguments.length - 1; i++) { - arguments[i].setCanvas(canvas).setWebGl(webGl).setOutputToTexture(true); - } - - return function () { - combinedKernel.apply(null, arguments); - var texSize = lastKernel.texSize; - var gl = lastKernel.getWebGl(); - var threadDim = lastKernel.threadDim; - var result = void 0; - if (lastKernel.floatOutput) { - result = new Float32Array(texSize[0] * texSize[1] * 4); - gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.FLOAT, result); - } else { - var bytes = new Uint8Array(texSize[0] * texSize[1] * 4); - gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, bytes); - result = new Float32Array(bytes.buffer); - } - - result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]); - - if (lastKernel.output.length === 1) { - return result; - } else if (lastKernel.output.length === 2) { - return utils.splitArray(result, lastKernel.output[0]); - } else if (lastKernel.output.length === 3) { - var cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]); - return cube.map(function (x) { - return utils.splitArray(x, lastKernel.output[0]); - }); - } - }; - } - }, { - key: 'getGPURunner', - value: function getGPURunner() { - if (typeof WebGL2RenderingContext !== 'undefined') return WebGL2Runner; - if (typeof WebGLRenderingContext !== 'undefined') return WebGLRunner; - } - - /** - * - * Adds additional functions, that the kernel may call. - * - * @name addFunction - * @function - * @memberOf GPU# - * - * @param {Function|String} fn - JS Function to do conversion - * @param {String[]|Object} paramTypes - Parameter type array, assumes all parameters are 'float' if null - * @param {String} returnType - The return type, assumes 'float' if null - * - * @returns {GPU} returns itself - * - */ - - }, { - key: 'addFunction', - value: function addFunction(fn, paramTypes, returnType) { - this._runner.functionBuilder.addFunction(null, fn, paramTypes, returnType); - return this; - } - - /** - * - * Adds additional native functions, that the kernel may call. - * - * @name addNativeFunction - * @function - * @memberOf GPU# - * - * @param {String} name - native function name, used for reverse lookup - * @param {String} nativeFunction - the native function implementation, as it would be defined in it's entirety - * - * @returns {GPU} returns itself - * - */ - - }, { - key: 'addNativeFunction', - value: function addNativeFunction(name, nativeFunction) { - this._runner.functionBuilder.addNativeFunction(name, nativeFunction); - return this; - } - - /** - * - * Return the current mode in which gpu.js is executing. - * @name getMode - * @function - * @memberOf GPU# - * - * @returns {String} The current mode, "cpu", "webgl", etc. - * - */ - - }, { - key: 'getMode', - value: function getMode() { - return this._runner.getMode(); - } - - /** - * - * Return TRUE, if browser supports WebGl AND Canvas - * - * @name get isWebGlSupported - * @function - * @memberOf GPU# - * - * Note: This function can also be called directly `GPU.isWebGlSupported()` - * - * @returns {Boolean} TRUE if browser supports webGl - * - */ - - }, { - key: 'isWebGlSupported', - value: function isWebGlSupported() { - return utils.isWebGlSupported(); - } - - /** - * - * Return TRUE, if system has integer division accuracy issue - * - * @name get hasIntegerDivisionAccuracyBug - * @function - * @memberOf GPU# - * - * Note: This function can also be called directly `GPU.hasIntegerDivisionAccuracyBug()` - * - * @returns {Boolean} TRUE if system has integer division accuracy issue - * - * - */ - - }, { - key: 'hasIntegerDivisionAccuracyBug', - value: function hasIntegerDivisionAccuracyBug() { - return utils.hasIntegerDivisionAccuracyBug(); - } - - /** - * - * Return the canvas object bound to this gpu instance. - * - * @name getCanvas - * @function - * @memberOf GPU# - * - * @returns {Object} Canvas object if present - * - */ - - }, { - key: 'getCanvas', - value: function getCanvas() { - return this._canvas; - } - - /** - * - * Return the webGl object bound to this gpu instance. - * - * @name getWebGl - * @function - * @memberOf GPU# - * - * @returns {Object} WebGl object if present - * - */ - - }, { - key: 'getWebGl', - value: function getWebGl() { - return this._webGl; - } - - /** - * - * Destroys all memory associated with gpu.js & the webGl if we created it - * - * @name destroy - * @function - * @memberOf GPU# - * - * - */ - - }, { - key: 'destroy', - value: function destroy() { - var _this2 = this; - - // perform on next runloop - for some reason we dont get lose context events - // if webGl is created and destroyed in the same run loop. - setTimeout(function () { - var kernels = _this2.kernels; - - var destroyWebGl = !_this2._webGl && kernels.length && kernels[0]._webGl; - for (var i = 0; i < _this2.kernels.length; i++) { - _this2.kernels[i].destroy(true); // remove canvas if exists - } - - if (destroyWebGl) { - destroyWebGl.OES_texture_float = null; - destroyWebGl.OES_texture_float_linear = null; - destroyWebGl.OES_element_index_uint = null; - var loseContextExt = destroyWebGl.getExtension('WEBGL_lose_context'); - if (loseContextExt) { - loseContextExt.loseContext(); - } - } - }, 0); - } - }]); - - return GPU; -}(GPUCore); - -; - -// This ensure static methods are "inherited" -// See: https://stackoverflow.com/questions/5441508/how-to-inherit-static-methods-from-base-class-in-javascript -Object.assign(GPU, GPUCore); - -module.exports = GPU; -},{"../backend/cpu/runner":57,"../backend/web-gl/runner":67,"../backend/web-gl/validator-kernel":70,"../backend/web-gl2/runner":74,"../backend/web-gl2/validator-kernel":77,"./gpu-core":79,"./utils":84}],81:[function(require,module,exports){ -"use strict"; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -module.exports = function Input(value, size) { - _classCallCheck(this, Input); - - this.value = value; - if (Array.isArray(size)) { - this.size = []; - for (var i = 0; i < size.length; i++) { - this.size[i] = size[i]; - } - while (this.size.length < 3) { - this.size.push(1); - } - } else { - if (size.z) { - this.size = [size.x, size.y, size.z]; - } else if (size.y) { - this.size = [size.x, size.y, 1]; - } else { - this.size = [size.x, 1, 1]; - } - } -}; -},{}],82:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -module.exports = function () { - - /** - * @desc WebGl Texture implementation in JS - * @constructor Texture - * @param {Object} texture - * @param {Array} size - * @param dimensions - * @param {Array} output - * @param {Object} webGl - */ - function Texture(texture, size, dimensions, output, webGl) { - _classCallCheck(this, Texture); - - this.texture = texture; - this.size = size; - this.dimensions = dimensions; - this.output = output; - this.webGl = webGl; - this.kernel = null; - } - - /** - * @name toArray - * @function - * @memberOf Texture# - * - * @desc Converts the Texture into a JavaScript Array. - * - * @param {Object} The `gpu` Object - * - */ - - - _createClass(Texture, [{ - key: 'toArray', - value: function toArray(gpu) { - if (!gpu) throw new Error('You need to pass the GPU object for toArray to work.'); - if (this.kernel) return this.kernel(this); - - this.kernel = gpu.createKernel(function (x) { - return x[this.thread.z][this.thread.y][this.thread.x]; - }).setOutput(this.output); - - return this.kernel(this); - } - - /** - * @name delete - * @desc Deletes the Texture. - * @function - * @memberOf Texture# - * - * - */ - - }, { - key: 'delete', - value: function _delete() { - return this.webGl.deleteTexture(this.texture); - } - }]); - - return Texture; -}(); -},{}],83:[function(require,module,exports){ -'use strict'; - -/** - * - * @desc Reduced subset of Utils, used exclusively in gpu-core.js - * Various utility functions / snippets of code that GPU.JS uses internally.\ - * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere) - * - * Note that all methods in this class is 'static' by nature `UtilsCore.functionName()` - * - * @class UtilsCore - * - */ - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var UtilsCore = function () { - function UtilsCore() { - _classCallCheck(this, UtilsCore); - } - - _createClass(UtilsCore, null, [{ - key: 'isCanvas', - - - /** - * @typedef {Object} webGlContext - */ - - /** - * @typedef {Object} CanvasDOMObject - */ - - //----------------------------------------------------------------------------- - // - // Canvas validation and support - // - //----------------------------------------------------------------------------- - - /** - * @name isCanvas - * @static - * @function - * @memberOf UtilsCore - * - * - * @desc Return TRUE, on a valid DOM canvas object - * - * Note: This does just a VERY simply sanity check. And may give false positives. - * - * @param {CanvasDOMObject} canvasObj - Object to validate - * - * @returns {Boolean} TRUE if the object is a DOM canvas - * - */ - value: function isCanvas(canvasObj) { - return canvasObj !== null && canvasObj.nodeName && canvasObj.getContext && canvasObj.nodeName.toUpperCase() === 'CANVAS'; - } - - /** - * @name isCanvasSupported - * @function - * @static - * @memberOf UtilsCore - * - * @desc Return TRUE, if browser supports canvas - * - * @returns {Boolean} TRUE if browser supports canvas - * - */ - - }, { - key: 'isCanvasSupported', - value: function isCanvasSupported() { - return _isCanvasSupported; - } - - /** - * @name initCanvas - * @function - * @static - * @memberOf UtilsCore - * - * @desc Initiate and returns a canvas, for usage in init_webgl. - * Returns only if canvas is supported by browser. - * - * @returns {CanvasDOMObject} CanvasDOMObject if supported by browser, else null - * - */ - - }, { - key: 'initCanvas', - value: function initCanvas() { - // Fail fast if browser previously detected no support - if (!_isCanvasSupported) { - return null; - } - - // Create a new canvas DOM - var canvas = document.createElement('canvas'); - - // Default width and height, to fix webgl issue in safari - canvas.width = 2; - canvas.height = 2; - - // Returns the canvas - return canvas; - } - - //----------------------------------------------------------------------------- - // - // Webgl validation and support - // - //----------------------------------------------------------------------------- - - - /** - * - * @name isWebGl - * @function - * @static - * @memberOf UtilsCore - * - * @desc Return TRUE, on a valid webGlContext object - * - * Note: This does just a VERY simply sanity check. And may give false positives. - * - * @param {webGlContext} webGlObj - Object to validate - * - * @returns {Boolean} TRUE if the object is a webGlContext object - * - */ - - }, { - key: 'isWebGl', - value: function isWebGl(webGlObj) { - return webGlObj && typeof webGlObj.getExtension === 'function'; - } - - /** - * @name isWebGlSupported - * @function - * @static - * @memberOf UtilsCore - * - * @desc Return TRUE, if browser supports webgl - * - * @returns {Boolean} TRUE if browser supports webgl - * - */ - - }, { - key: 'isWebGlSupported', - value: function isWebGlSupported() { - return _isWebGlSupported; - } - }, { - key: 'isWebGlDrawBuffersSupported', - value: function isWebGlDrawBuffersSupported() { - return _isWebGlDrawBuffersSupported; - } - - // Default webgl options to use - - }, { - key: 'initWebGlDefaultOptions', - value: function initWebGlDefaultOptions() { - return { - alpha: false, - depth: false, - antialias: false - }; - } - - /** - * @name initWebGl - * @function - * @static - * @memberOf UtilsCore - * - * @desc Initiate and returns a webGl, from a canvas object - * Returns only if webGl is supported by browser. - * - * @param {CanvasDOMObject} canvasObj - Object to validate - * - * @returns {CanvasDOMObject} CanvasDOMObject if supported by browser, else null - * - */ - - }, { - key: 'initWebGl', - value: function initWebGl(canvasObj) { - - // First time setup, does the browser support check memorizer - if (typeof _isCanvasSupported !== 'undefined' || canvasObj === null) { - if (!_isCanvasSupported) { - return null; - } - } - - // Fail fast for invalid canvas object - if (!UtilsCore.isCanvas(canvasObj)) { - throw new Error('Invalid canvas object - ' + canvasObj); - } - - // Create a new canvas DOM - var webGl = canvasObj.getContext('experimental-webgl', UtilsCore.initWebGlDefaultOptions()) || canvasObj.getContext('webgl', UtilsCore.initWebGlDefaultOptions()); - - if (webGl) { - // Get the extension that is needed - webGl.OES_texture_float = webGl.getExtension('OES_texture_float'); - webGl.OES_texture_float_linear = webGl.getExtension('OES_texture_float_linear'); - webGl.OES_element_index_uint = webGl.getExtension('OES_element_index_uint'); - } - - // Returns the canvas - return webGl; - } - - /** - * @name initWebGl2 - * @function - * @static - * @memberOf UtilsCore - * - * @desc Initiate and returns a webGl, from a canvas object - * Returns only if webGl is supported by browser. - * - * @param {CanvasDOMObject} canvasObj - Object to validate - * - * @returns {CanvasDOMObject} CanvasDOMObject if supported by browser, else null - * - */ - - }, { - key: 'initWebGl2', - value: function initWebGl2(canvasObj) { - - // First time setup, does the browser support check memorizer - if (typeof _isCanvasSupported !== 'undefined' || canvasObj === null) { - if (!_isCanvasSupported) { - return null; - } - } - - // Fail fast for invalid canvas object - if (!UtilsCore.isCanvas(canvasObj)) { - throw new Error('Invalid canvas object - ' + canvasObj); - } - - // Create a new canvas DOM - return canvasObj.getContext('webgl2', UtilsCore.initWebGlDefaultOptions()); - } - - /** - * @function - * @static - * @memberOf UtilsCore - * @param {number[]} output - * @throws if not correctly defined - */ - - }, { - key: 'checkOutput', - value: function checkOutput(output) { - for (var i = 0; i < output.length; i++) { - if (isNaN(output[i]) || output[i] < 1) { - throw new Error('kernel.output[' + i + '] incorrectly defined as `' + output[i] + '`, needs to be numeric, and greater than 0'); - } - } - } - }]); - - return UtilsCore; -}(); - -//----------------------------------------------------------------------------- -// -// Canvas & Webgl validation and support constants -// -//----------------------------------------------------------------------------- - -var _isCanvasSupported = typeof document !== 'undefined' ? UtilsCore.isCanvas(document.createElement('canvas')) : false; -var _testingWebGl = UtilsCore.initWebGl(UtilsCore.initCanvas()); -var _isWebGlSupported = UtilsCore.isWebGl(_testingWebGl); -var _isWebGlDrawBuffersSupported = _isWebGlSupported && Boolean(_testingWebGl.getExtension('WEBGL_draw_buffers')); - -if (_isWebGlSupported) { - UtilsCore.OES_texture_float = _testingWebGl.OES_texture_float; - UtilsCore.OES_texture_float_linear = _testingWebGl.OES_texture_float_linear; - UtilsCore.OES_element_index_uint = _testingWebGl.OES_element_index_uint; -} else { - UtilsCore.OES_texture_float = false; - UtilsCore.OES_texture_float_linear = false; - UtilsCore.OES_element_index_uint = false; -} - -module.exports = UtilsCore; -},{}],84:[function(require,module,exports){ -'use strict'; - -/** - * - * @classdesc Various utility functions / snippets of code that GPU.JS uses internally.\ - * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere) - * - * Note that all methods in this class are *static* by nature `Utils.functionName()` - * - * @class Utils - * @extends UtilsCore - * - */ - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var UtilsCore = require("./utils-core"); -var Input = require('./input'); -var Texture = require('./texture'); -// FUNCTION_NAME regex -var FUNCTION_NAME = /function ([^(]*)/; - -// STRIP COMMENTS regex -var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; - -// ARGUMENT NAMES regex -var ARGUMENT_NAMES = /([^\s,]+)/g; - -var _systemEndianness = function () { - var b = new ArrayBuffer(4); - var a = new Uint32Array(b); - var c = new Uint8Array(b); - a[0] = 0xdeadbeef; - if (c[0] === 0xef) return 'LE'; - if (c[0] === 0xde) return 'BE'; - throw new Error('unknown endianness'); -}(); - -var _isFloatReadPixelsSupported = null; -var _isFloatReadPixelsSupportedWebGL2 = null; - -var _isMixedIdentifiersSupported = function () { - try { - new Function('let i = 1; const j = 1;')(); - return true; - } catch (e) { - return false; - } -}(); - -var _hasIntegerDivisionAccuracyBug = null; - -/** - * @class - * @extends UtilsCore - */ - -var Utils = function (_UtilsCore) { - _inherits(Utils, _UtilsCore); - - function Utils() { - _classCallCheck(this, Utils); - - return _possibleConstructorReturn(this, (Utils.__proto__ || Object.getPrototypeOf(Utils)).apply(this, arguments)); - } - - _createClass(Utils, null, [{ - key: 'systemEndianness', - - - //----------------------------------------------------------------------------- - // - // System values support (currently only endianness) - // - //----------------------------------------------------------------------------- - - /** - * @memberOf Utils - * @name systemEndianness - * @function - * @static - * - * Gets the system endianness, and cache it - * - * @returns {String} 'LE' or 'BE' depending on system architecture - * - * Credit: https://gist.github.com/TooTallNate/4750953 - */ - value: function systemEndianness() { - return _systemEndianness; - } - - //----------------------------------------------------------------------------- - // - // Function and function string validations - // - //----------------------------------------------------------------------------- - - /** - * @memberOf Utils - * @name isFunction - * @function - * @static - * - * Return TRUE, on a JS function - * - * @param {Function} funcObj - Object to validate if its a function - * - * @returns {Boolean} TRUE if the object is a JS function - * - */ - - }, { - key: 'isFunction', - value: function isFunction(funcObj) { - return typeof funcObj === 'function'; - } - - /** - * @memberOf Utils - * @name isFunctionString - * @function - * @static - * - * Return TRUE, on a valid JS function string - * - * Note: This does just a VERY simply sanity check. And may give false positives. - * - * @param {String} funcStr - String of JS function to validate - * - * @returns {Boolean} TRUE if the string passes basic validation - * - */ - - }, { - key: 'isFunctionString', - value: function isFunctionString(funcStr) { - if (funcStr !== null) { - return funcStr.toString().slice(0, 'function'.length).toLowerCase() === 'function'; - } - return false; - } - - /** - * @memberOf Utils - * @name getFunctionName_fromString - * @function - * @static - * - * Return the function name from a JS function string - * - * @param {String} funcStr - String of JS function to validate - * - * @returns {String} Function name string (if found) - * - */ - - }, { - key: 'getFunctionNameFromString', - value: function getFunctionNameFromString(funcStr) { - return FUNCTION_NAME.exec(funcStr)[1]; - } - }, { - key: 'getFunctionBodyFromString', - value: function getFunctionBodyFromString(funcStr) { - return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}')); - } - - /** - * @memberOf Utils - * @name getParamNames_fromString - * @function - * @static - * - * Return list of parameter names extracted from the JS function string - * - * @param {String} funcStr - String of JS function to validate - * - * @returns {String[]} Array representing all the parameter names - * - */ - - }, { - key: 'getParamNamesFromString', - value: function getParamNamesFromString(func) { - var fnStr = func.toString().replace(STRIP_COMMENTS, ''); - var result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES); - if (result === null) result = []; - return result; - } - - //----------------------------------------------------------------------------- - // - // Object / function cloning and manipulation - // - //----------------------------------------------------------------------------- - - /** - * @memberOf Utils - * @name clone - * @function - * @static - * - * Returns a clone - * - * @param {Object} obj - Object to clone - * - * @returns {Object} Cloned object - * - */ - - }, { - key: 'clone', - value: function clone(obj) { - if (obj === null || (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj; - - var temp = obj.constructor(); // changed - - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - obj.isActiveClone = null; - temp[key] = Utils.clone(obj[key]); - delete obj.isActiveClone; - } - } - - return temp; - } - - /** - * @memberOf Utils - * @name newPromise - * @function - * @static - * - * Returns a `new Promise` object based on the underlying implmentation - * - * @param {Function} executor - Promise builder function - * - * @returns {Promise} Promise object - * - */ - - }, { - key: 'newPromise', - value: function newPromise(executor) { - var simple = Promise || small_promise; - if (simple === null) { - throw TypeError('Browser is missing Promise implementation. Consider adding small_promise.js polyfill'); - } - return new simple(executor); - } - - /** - * @memberOf Utils - * @name functionBinder - * @function - * @static - * - * Limited implementation of Function.bind, with fallback - * - * @param {Function} inFunc - to setup bind on - * @param {Object} thisObj - The this parameter to assume inside the binded function - * - * @returns {Function} The binded function - * - */ - - }, { - key: 'functionBinder', - value: function functionBinder(inFunc, thisObj) { - if (inFunc.bind) { - return inFunc.bind(thisObj); - } - - return function () { - var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments); - return inFunc.apply(thisObj, args); - }; - } - - /** - * @memberOf Utils - * @name isArray - * @function - * @static - * - * * Checks if is an array or Array-like object - * - * @param {Object} arg - The argument object to check if is array - * - * @returns {Boolean} true if is array or Array-like object - * - */ - - }, { - key: 'isArray', - value: function isArray(array) { - if (isNaN(array.length)) { - return false; - } - - return true; - } - - /** - * @memberOf Utils - * @name getArgumentType - * @function - * @static - * - * Evaluate the argument type, to apply respective logic for it - * - * @param {Object} arg - The argument object to evaluate type - * - * @returns {String} Argument type Array/Number/Float/Texture/Unknown - * - */ - - }, { - key: 'getArgumentType', - value: function getArgumentType(arg) { - if (Utils.isArray(arg)) { - if (arg[0].nodeName === 'IMG') { - return 'HTMLImageArray'; - } - return 'Array'; - } else if (typeof arg === 'number') { - if (Number.isInteger(arg)) { - return 'Integer'; - } - return 'Float'; - } else if (arg instanceof Texture) { - return 'Texture'; - } else if (arg instanceof Input) { - return 'Input'; - } else if (arg.nodeName === 'IMG') { - return 'HTMLImage'; - } else { - return 'Unknown'; - } - } - /** - * @typedef {Object} gpuJSObject - */ - - /** - * @memberOf Utils - * @name isFloatReadPixelsSupported - * @function - * @static - * - * Checks if the browser supports readPixels with float type - * - * @returns {Boolean} true if browser supports - * - */ - - }, { - key: 'isFloatReadPixelsSupported', - value: function isFloatReadPixelsSupported() { - if (_isFloatReadPixelsSupported !== null) { - return _isFloatReadPixelsSupported; - } - - var GPU = require('../index'); - var gpu = new GPU({ - mode: 'webgl-validator' - }); - var x = gpu.createKernel(function () { - return 1; - }, { - output: [2], - floatTextures: true, - floatOutput: true, - floatOutputForce: true - })(); - - _isFloatReadPixelsSupported = x[0] === 1; - gpu.destroy(); - return _isFloatReadPixelsSupported; - } - - /** - * @memberOf Utils - * @name isFloatReadPixelsSupportedWebGL2 - * @function - * @static - * - * Checks if the browser supports readPixels with float type - * - * @returns {Boolean} true if browser supports - * - */ - - }, { - key: 'isFloatReadPixelsSupportedWebGL2', - value: function isFloatReadPixelsSupportedWebGL2() { - if (_isFloatReadPixelsSupportedWebGL2 !== null) { - return _isFloatReadPixelsSupportedWebGL2; - } - - var GPU = require('../index'); - var gpu = new GPU({ - mode: 'webgl2-validator' - }); - var x = gpu.createKernel(function () { - return 1; - }, { - output: [2], - floatTextures: true, - floatOutput: true, - floatOutputForce: true - })(); - - _isFloatReadPixelsSupportedWebGL2 = x[0] === 1; - gpu.destroy(); - return _isFloatReadPixelsSupportedWebGL2; - } - - /** - * @memberOf Utils - * @name hasIntegerDivisionAccuracyBug - * @function - * @static - * - * Checks if the system has inaccuracies when dividing integers - * - * @returns {Boolean} true if bug is exhibited on this system - * - */ - - }, { - key: 'hasIntegerDivisionAccuracyBug', - value: function hasIntegerDivisionAccuracyBug() { - if (_hasIntegerDivisionAccuracyBug !== null) { - return _hasIntegerDivisionAccuracyBug; - } - - var GPU = require('../index'); - var gpu = new GPU({ - mode: 'webgl-validator' - }); - var x = gpu.createKernel(function (v1, v2) { - return v1[this.thread.x] / v2[this.thread.x]; - }, { - output: [1] - })([6, 6030401], [3, 3991]); - - // have we not got whole numbers for 6/3 or 6030401/3991 - // add more here if others see this problem - _hasIntegerDivisionAccuracyBug = x[0] !== 2 || x[1] !== 1511; - gpu.destroy(); - return _hasIntegerDivisionAccuracyBug; - } - }, { - key: 'isMixedIdentifiersSupported', - value: function isMixedIdentifiersSupported() { - return _isMixedIdentifiersSupported; - } - }, { - key: 'dimToTexSize', - value: function dimToTexSize(opt, dimensions, output) { - var numTexels = dimensions[0]; - var w = dimensions[0]; - var h = dimensions[1]; - for (var i = 1; i < dimensions.length; i++) { - numTexels *= dimensions[i]; - } - - if (opt.floatTextures && (!output || opt.floatOutput)) { - w = numTexels = Math.ceil(numTexels / 4); - } - // if given dimensions == a 2d image - if (h > 1 && w * h === numTexels) { - return [w, h]; - } - // find as close to square width, height sizes as possible - var sqrt = Math.sqrt(numTexels); - var high = Math.ceil(sqrt); - var low = Math.floor(sqrt); - while (high * low > numTexels) { - high--; - low = Math.ceil(numTexels / high); - } - w = low; - h = Math.ceil(numTexels / w); - return [w, h]; - } - - /** - * @memberOf Utils - * @name getDimensions - * @function - * @static - * - * Return the dimension of an array. - * - * @param {Array|String} x - The array - * @param {number} [pad] - To include padding in the dimension calculation [Optional] - * - * - * - */ - - }, { - key: 'getDimensions', - value: function getDimensions(x, pad) { - var ret = void 0; - if (Utils.isArray(x)) { - var dim = []; - var temp = x; - while (Utils.isArray(temp)) { - dim.push(temp.length); - temp = temp[0]; - } - ret = dim.reverse(); - } else if (x instanceof Texture) { - ret = x.output; - } else if (x instanceof Input) { - ret = x.size; - } else { - throw 'Unknown dimensions of ' + x; - } - - if (pad) { - ret = Utils.clone(ret); - while (ret.length < 3) { - ret.push(1); - } - } - // return ret; - return new Int32Array(ret); - } - - /** - * @memberOf Utils - * @name pad - * @function - * @static - * - * Pad an array AND its elements with leading and ending zeros - * - * @param {Array} arr - the array to pad zeros to - * @param {number} padding - amount of padding - * - * @returns {Array} Array with leading and ending zeros, and all the elements padded by zeros. - * - */ - - }, { - key: 'pad', - value: function pad(arr, padding) { - function zeros(n) { - return Array.apply(null, new Array(n)).map(Number.prototype.valueOf, 0); - } - - var len = arr.length + padding * 2; - - var ret = arr.map(function (x) { - return [].concat(zeros(padding), x, zeros(padding)); - }); - - for (var i = 0; i < padding; i++) { - ret = [].concat([zeros(len)], ret, [zeros(len)]); - } - - return ret; - } - - /** - * @memberOf Utils - * @name flatten2dArrayTo - * @function - * @static - * - * Puts a nested 2d array into a one-dimensional target array - * @param {Array|*} array - * @param {Float32Array|Float64Array} target - */ - - }, { - key: 'flatten2dArrayTo', - value: function flatten2dArrayTo(array, target) { - var offset = 0; - for (var y = 0; y < array.length; y++) { - target.set(array[y], offset); - offset += array[y].length; - } - } - - /** - * @memberOf Utils - * @name flatten3dArrayTo - * @function - * @static - * - * Puts a nested 3d array into a one-dimensional target array - * @param {Array|*} array - * @param {Float32Array|Float64Array} target - */ - - }, { - key: 'flatten3dArrayTo', - value: function flatten3dArrayTo(array, target) { - var offset = 0; - for (var z = 0; z < array.length; z++) { - for (var y = 0; y < array[z].length; y++) { - target.set(array[z][y], offset); - offset += array[z][y].length; - } - } - } - - /** - * @memberOf Utils - * @name flatten3dArrayTo - * @function - * @static - * - * Puts a nested 1d, 2d, or 3d array into a one-dimensional target array - * @param {Array|*} array - * @param {Float32Array|Float64Array} target - */ - - }, { - key: 'flattenTo', - value: function flattenTo(array, target) { - if (Utils.isArray(array[0])) { - if (Utils.isArray(array[0][0])) { - Utils.flatten3dArrayTo(array, target); - } else { - Utils.flatten2dArrayTo(array, target); - } - } else { - target.set(array); - } - } - - /** - * @memberOf Utils - * @name splitArray - * @function - * @static - * - * Splits an array into smaller arrays. - * Number of elements in one small chunk is given by `part` - * - * @param {Array} array - The array to split into chunks - * @param {Array} part - elements in one chunk - * - * @returns {Array} An array of smaller chunks - * - */ - - }, { - key: 'splitArray', - value: function splitArray(array, part) { - var result = []; - for (var i = 0; i < array.length; i += part) { - result.push(Array.prototype.slice.call(array, i, i + part)); - } - return result; - } - }, { - key: 'getAstString', - value: function getAstString(source, ast) { - var lines = Array.isArray(source) ? source : source.split(/\r?\n/g); - var start = ast.loc.start; - var end = ast.loc.end; - var result = []; - result.push(lines[start.line - 1].slice(start.column)); - for (var i = start.line; i < end.line - 1; i++) { - result.push(lines[i]); - } - result.push(lines[end.line - 1].slice(0, end.column)); - return result.join('\n'); - } - }, { - key: 'allPropertiesOf', - value: function allPropertiesOf(obj) { - var props = []; - - do { - props.push.apply(props, Object.getOwnPropertyNames(obj)); - } while (obj = Object.getPrototypeOf(obj)); - - return props; - } - }]); - - return Utils; -}(UtilsCore); - -// This ensure static methods are "inherited" -// See: https://stackoverflow.com/questions/5441508/how-to-inherit-static-methods-from-base-class-in-javascript - - -Object.assign(Utils, UtilsCore); - -module.exports = Utils; -},{"../index":85,"./input":81,"./texture":82,"./utils-core":83}],85:[function(require,module,exports){ -'use strict'; - -var GPU = require('./core/gpu'); -var alias = require('./core/alias'); -var utils = require('./core/utils'); -var Input = require('./core/input'); -var Texture = require('./core/texture'); - -var CPUFunctionBuilder = require('./backend/cpu/function-builder'); -var CPUFunctionNode = require('./backend/cpu/function-node'); -var CPUKernel = require('./backend/cpu/kernel'); -var CPURunner = require('./backend/cpu/runner'); - -var WebGLFunctionBuilder = require('./backend/web-gl/function-builder'); -var WebGLFunctionNode = require('./backend/web-gl/function-node'); -var WebGLKernel = require('./backend/web-gl/kernel'); -var WebGLRunner = require('./backend/web-gl/runner'); - -var WebGL2FunctionBuilder = require('./backend/web-gl2/function-builder'); -var WebGL2FunctionNode = require('./backend/web-gl2/function-node'); -var WebGL2Kernel = require('./backend/web-gl2/kernel'); -var WebGL2Runner = require('./backend/web-gl2/runner'); - -GPU.alias = alias; -GPU.utils = utils; -GPU.Texture = Texture; -GPU.Input = Input; -GPU.input = function (value, size) { - return new Input(value, size); -}; - -GPU.CPUFunctionBuilder = CPUFunctionBuilder; -GPU.CPUFunctionNode = CPUFunctionNode; -GPU.CPUKernel = CPUKernel; -GPU.CPURunner = CPURunner; - -GPU.WebGLFunctionBuilder = WebGLFunctionBuilder; -GPU.WebGLFunctionNode = WebGLFunctionNode; -GPU.WebGLKernel = WebGLKernel; -GPU.WebGLRunner = WebGLRunner; - -GPU.WebGL2FunctionBuilder = WebGL2FunctionBuilder; -GPU.WebGL2FunctionNode = WebGL2FunctionNode; -GPU.WebGL2Kernel = WebGL2Kernel; -GPU.WebGL2Runner = WebGL2Runner; - -if (typeof module !== 'undefined') { - module.exports = GPU; -} -if (typeof window !== 'undefined') { - window.GPU = GPU; -} -},{"./backend/cpu/function-builder":53,"./backend/cpu/function-node":54,"./backend/cpu/kernel":56,"./backend/cpu/runner":57,"./backend/web-gl/function-builder":63,"./backend/web-gl/function-node":64,"./backend/web-gl/kernel":66,"./backend/web-gl/runner":67,"./backend/web-gl2/function-builder":71,"./backend/web-gl2/function-node":72,"./backend/web-gl2/kernel":73,"./backend/web-gl2/runner":74,"./core/alias":78,"./core/gpu":80,"./core/input":81,"./core/texture":82,"./core/utils":84}],86:[function(require,module,exports){ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.acorn = {}))); -}(this, (function (exports) { 'use strict'; - -// Reserved word lists for various dialects of the language - -var reservedWords = { - 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", - 5: "class enum extends super const export import", - 6: "enum", - strict: "implements interface let package private protected public static yield", - strictBind: "eval arguments" -}; - -// And the keywords - -var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"; - -var keywords = { - 5: ecma5AndLessKeywords, - 6: ecma5AndLessKeywords + " const class extends export import super" -}; - -var keywordRelationalOperator = /^in(stanceof)?$/; - -// ## Character categories - -// Big ugly regular expressions that match characters in the -// whitespace, identifier, and identifier-start categories. These -// are only applied when a character is found to actually have a -// code point above 128. -// Generated by `bin/generate-identifier-regex.js`. - -var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312e\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fea\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; -var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; - -var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); -var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); - -nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; - -// These are a run-length and offset encoded representation of the -// >0xffff code points that are a valid part of identifiers. The -// offset starts at 0x10000, and each pair of numbers represents an -// offset to the next range, and then a size of the range. They were -// generated by bin/generate-identifier-regex.js - -// eslint-disable-next-line comma-spacing -var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,257,0,11,39,8,0,22,0,12,39,3,3,55,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,698,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,1,31,6124,20,754,9486,286,82,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,15,7472,3104,541]; - -// eslint-disable-next-line comma-spacing -var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,280,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,19719,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239]; - -// This has a complexity linear to the value of the code. The -// assumption is that looking up astral identifier characters is -// rare. -function isInAstralSet(code, set) { - var pos = 0x10000; - for (var i = 0; i < set.length; i += 2) { - pos += set[i]; - if (pos > code) { return false } - pos += set[i + 1]; - if (pos >= code) { return true } - } -} - -// Test whether a given character code starts an identifier. - -function isIdentifierStart(code, astral) { - if (code < 65) { return code === 36 } - if (code < 91) { return true } - if (code < 97) { return code === 95 } - if (code < 123) { return true } - if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) } - if (astral === false) { return false } - return isInAstralSet(code, astralIdentifierStartCodes) -} - -// Test whether a given character is part of an identifier. - -function isIdentifierChar(code, astral) { - if (code < 48) { return code === 36 } - if (code < 58) { return true } - if (code < 65) { return false } - if (code < 91) { return true } - if (code < 97) { return code === 95 } - if (code < 123) { return true } - if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) } - if (astral === false) { return false } - return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) -} - -// ## Token types - -// The assignment of fine-grained, information-carrying type objects -// allows the tokenizer to store the information it has about a -// token in a way that is very cheap for the parser to look up. - -// All token type variables start with an underscore, to make them -// easy to recognize. - -// The `beforeExpr` property is used to disambiguate between regular -// expressions and divisions. It is set on all token types that can -// be followed by an expression (thus, a slash after them would be a -// regular expression). -// -// The `startsExpr` property is used to check if the token ends a -// `yield` expression. It is set on all token types that either can -// directly start an expression (like a quotation mark) or can -// continue an expression (like the body of a string). -// -// `isLoop` marks a keyword as starting a loop, which is important -// to know when parsing a label, in order to allow or disallow -// continue jumps to that label. - -var TokenType = function TokenType(label, conf) { - if ( conf === void 0 ) conf = {}; - - this.label = label; - this.keyword = conf.keyword; - this.beforeExpr = !!conf.beforeExpr; - this.startsExpr = !!conf.startsExpr; - this.isLoop = !!conf.isLoop; - this.isAssign = !!conf.isAssign; - this.prefix = !!conf.prefix; - this.postfix = !!conf.postfix; - this.binop = conf.binop || null; - this.updateContext = null; -}; - -function binop(name, prec) { - return new TokenType(name, {beforeExpr: true, binop: prec}) -} -var beforeExpr = {beforeExpr: true}; -var startsExpr = {startsExpr: true}; - -// Map keyword names to token types. - -var keywords$1 = {}; - -// Succinct definitions of keyword token types -function kw(name, options) { - if ( options === void 0 ) options = {}; - - options.keyword = name; - return keywords$1[name] = new TokenType(name, options) -} - -var types = { - num: new TokenType("num", startsExpr), - regexp: new TokenType("regexp", startsExpr), - string: new TokenType("string", startsExpr), - name: new TokenType("name", startsExpr), - eof: new TokenType("eof"), - - // Punctuation token types. - bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), - bracketR: new TokenType("]"), - braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), - braceR: new TokenType("}"), - parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), - parenR: new TokenType(")"), - comma: new TokenType(",", beforeExpr), - semi: new TokenType(";", beforeExpr), - colon: new TokenType(":", beforeExpr), - dot: new TokenType("."), - question: new TokenType("?", beforeExpr), - arrow: new TokenType("=>", beforeExpr), - template: new TokenType("template"), - invalidTemplate: new TokenType("invalidTemplate"), - ellipsis: new TokenType("...", beforeExpr), - backQuote: new TokenType("`", startsExpr), - dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), - - // Operators. These carry several kinds of properties to help the - // parser use them properly (the presence of these properties is - // what categorizes them as operators). - // - // `binop`, when present, specifies that this operator is a binary - // operator, and will refer to its precedence. - // - // `prefix` and `postfix` mark the operator as a prefix or postfix - // unary operator. - // - // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as - // binary operators with a very low precedence, that should result - // in AssignmentExpression nodes. - - eq: new TokenType("=", {beforeExpr: true, isAssign: true}), - assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), - incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), - prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), - logicalOR: binop("||", 1), - logicalAND: binop("&&", 2), - bitwiseOR: binop("|", 3), - bitwiseXOR: binop("^", 4), - bitwiseAND: binop("&", 5), - equality: binop("==/!=/===/!==", 6), - relational: binop("/<=/>=", 7), - bitShift: binop("<>/>>>", 8), - plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), - modulo: binop("%", 10), - star: binop("*", 10), - slash: binop("/", 10), - starstar: new TokenType("**", {beforeExpr: true}), - - // Keyword token types. - _break: kw("break"), - _case: kw("case", beforeExpr), - _catch: kw("catch"), - _continue: kw("continue"), - _debugger: kw("debugger"), - _default: kw("default", beforeExpr), - _do: kw("do", {isLoop: true, beforeExpr: true}), - _else: kw("else", beforeExpr), - _finally: kw("finally"), - _for: kw("for", {isLoop: true}), - _function: kw("function", startsExpr), - _if: kw("if"), - _return: kw("return", beforeExpr), - _switch: kw("switch"), - _throw: kw("throw", beforeExpr), - _try: kw("try"), - _var: kw("var"), - _const: kw("const"), - _while: kw("while", {isLoop: true}), - _with: kw("with"), - _new: kw("new", {beforeExpr: true, startsExpr: true}), - _this: kw("this", startsExpr), - _super: kw("super", startsExpr), - _class: kw("class", startsExpr), - _extends: kw("extends", beforeExpr), - _export: kw("export"), - _import: kw("import"), - _null: kw("null", startsExpr), - _true: kw("true", startsExpr), - _false: kw("false", startsExpr), - _in: kw("in", {beforeExpr: true, binop: 7}), - _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), - _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), - _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), - _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) -}; - -// Matches a whole line break (where CRLF is considered a single -// line break). Used to count lines. - -var lineBreak = /\r\n?|\n|\u2028|\u2029/; -var lineBreakG = new RegExp(lineBreak.source, "g"); - -function isNewLine(code) { - return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 -} - -var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; - -var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; - -var ref = Object.prototype; -var hasOwnProperty = ref.hasOwnProperty; -var toString = ref.toString; - -// Checks if an object has a property. - -function has(obj, propName) { - return hasOwnProperty.call(obj, propName) -} - -var isArray = Array.isArray || (function (obj) { return ( - toString.call(obj) === "[object Array]" -); }); - -// These are used when `options.locations` is on, for the -// `startLoc` and `endLoc` properties. - -var Position = function Position(line, col) { - this.line = line; - this.column = col; -}; - -Position.prototype.offset = function offset (n) { - return new Position(this.line, this.column + n) -}; - -var SourceLocation = function SourceLocation(p, start, end) { - this.start = start; - this.end = end; - if (p.sourceFile !== null) { this.source = p.sourceFile; } -}; - -// The `getLineInfo` function is mostly useful when the -// `locations` option is off (for performance reasons) and you -// want to find the line/column position for a given character -// offset. `input` should be the code string that the offset refers -// into. - -function getLineInfo(input, offset) { - for (var line = 1, cur = 0;;) { - lineBreakG.lastIndex = cur; - var match = lineBreakG.exec(input); - if (match && match.index < offset) { - ++line; - cur = match.index + match[0].length; - } else { - return new Position(line, offset - cur) - } - } -} - -// A second optional argument can be given to further configure -// the parser process. These options are recognized: - -var defaultOptions = { - // `ecmaVersion` indicates the ECMAScript version to parse. Must - // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support - // for strict mode, the set of reserved words, and support for - // new syntax features. The default is 7. - ecmaVersion: 7, - // `sourceType` indicates the mode the code should be parsed in. - // Can be either `"script"` or `"module"`. This influences global - // strict mode and parsing of `import` and `export` declarations. - sourceType: "script", - // `onInsertedSemicolon` can be a callback that will be called - // when a semicolon is automatically inserted. It will be passed - // th position of the comma as an offset, and if `locations` is - // enabled, it is given the location as a `{line, column}` object - // as second argument. - onInsertedSemicolon: null, - // `onTrailingComma` is similar to `onInsertedSemicolon`, but for - // trailing commas. - onTrailingComma: null, - // By default, reserved words are only enforced if ecmaVersion >= 5. - // Set `allowReserved` to a boolean value to explicitly turn this on - // an off. When this option has the value "never", reserved words - // and keywords can also not be used as property names. - allowReserved: null, - // When enabled, a return at the top level is not considered an - // error. - allowReturnOutsideFunction: false, - // When enabled, import/export statements are not constrained to - // appearing at the top of the program. - allowImportExportEverywhere: false, - // When enabled, hashbang directive in the beginning of file - // is allowed and treated as a line comment. - allowHashBang: false, - // When `locations` is on, `loc` properties holding objects with - // `start` and `end` properties in `{line, column}` form (with - // line being 1-based and column 0-based) will be attached to the - // nodes. - locations: false, - // A function can be passed as `onToken` option, which will - // cause Acorn to call that function with object in the same - // format as tokens returned from `tokenizer().getToken()`. Note - // that you are not allowed to call the parser from the - // callback—that will corrupt its internal state. - onToken: null, - // A function can be passed as `onComment` option, which will - // cause Acorn to call that function with `(block, text, start, - // end)` parameters whenever a comment is skipped. `block` is a - // boolean indicating whether this is a block (`/* */`) comment, - // `text` is the content of the comment, and `start` and `end` are - // character offsets that denote the start and end of the comment. - // When the `locations` option is on, two more parameters are - // passed, the full `{line, column}` locations of the start and - // end of the comments. Note that you are not allowed to call the - // parser from the callback—that will corrupt its internal state. - onComment: null, - // Nodes have their start and end characters offsets recorded in - // `start` and `end` properties (directly on the node, rather than - // the `loc` object, which holds line/column data. To also add a - // [semi-standardized][range] `range` property holding a `[start, - // end]` array with the same numbers, set the `ranges` option to - // `true`. - // - // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 - ranges: false, - // It is possible to parse multiple files into a single AST by - // passing the tree produced by parsing the first file as - // `program` option in subsequent parses. This will add the - // toplevel forms of the parsed file to the `Program` (top) node - // of an existing parse tree. - program: null, - // When `locations` is on, you can pass this to record the source - // file in every node's `loc` object. - sourceFile: null, - // This value, if given, is stored in every node, whether - // `locations` is on or off. - directSourceFile: null, - // When enabled, parenthesized expressions are represented by - // (non-standard) ParenthesizedExpression nodes - preserveParens: false, - plugins: {} -}; - -// Interpret and default an options object - -function getOptions(opts) { - var options = {}; - - for (var opt in defaultOptions) - { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; } - - if (options.ecmaVersion >= 2015) - { options.ecmaVersion -= 2009; } - - if (options.allowReserved == null) - { options.allowReserved = options.ecmaVersion < 5; } - - if (isArray(options.onToken)) { - var tokens = options.onToken; - options.onToken = function (token) { return tokens.push(token); }; - } - if (isArray(options.onComment)) - { options.onComment = pushComment(options, options.onComment); } - - return options -} - -function pushComment(options, array) { - return function(block, text, start, end, startLoc, endLoc) { - var comment = { - type: block ? "Block" : "Line", - value: text, - start: start, - end: end - }; - if (options.locations) - { comment.loc = new SourceLocation(this, startLoc, endLoc); } - if (options.ranges) - { comment.range = [start, end]; } - array.push(comment); - } -} - -// Registered plugins -var plugins = {}; - -function keywordRegexp(words) { - return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$") -} - -var Parser = function Parser(options, input, startPos) { - this.options = options = getOptions(options); - this.sourceFile = options.sourceFile; - this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]); - var reserved = ""; - if (!options.allowReserved) { - for (var v = options.ecmaVersion;; v--) - { if (reserved = reservedWords[v]) { break } } - if (options.sourceType == "module") { reserved += " await"; } - } - this.reservedWords = keywordRegexp(reserved); - var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; - this.reservedWordsStrict = keywordRegexp(reservedStrict); - this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind); - this.input = String(input); - - // Used to signal to callers of `readWord1` whether the word - // contained any escape sequences. This is needed because words with - // escape sequences must not be interpreted as keywords. - this.containsEsc = false; - - // Load plugins - this.loadPlugins(options.plugins); - - // Set up token state - - // The current position of the tokenizer in the input. - if (startPos) { - this.pos = startPos; - this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; - this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; - } else { - this.pos = this.lineStart = 0; - this.curLine = 1; - } - - // Properties of the current token: - // Its type - this.type = types.eof; - // For tokens that include more information than their type, the value - this.value = null; - // Its start and end offset - this.start = this.end = this.pos; - // And, if locations are used, the {line, column} object - // corresponding to those offsets - this.startLoc = this.endLoc = this.curPosition(); - - // Position information for the previous token - this.lastTokEndLoc = this.lastTokStartLoc = null; - this.lastTokStart = this.lastTokEnd = this.pos; - - // The context stack is used to superficially track syntactic - // context to predict whether a regular expression is allowed in a - // given position. - this.context = this.initialContext(); - this.exprAllowed = true; - - // Figure out if it's a module code. - this.inModule = options.sourceType === "module"; - this.strict = this.inModule || this.strictDirective(this.pos); - - // Used to signify the start of a potential arrow function - this.potentialArrowAt = -1; - - // Flags to track whether we are in a function, a generator, an async function. - this.inFunction = this.inGenerator = this.inAsync = false; - // Positions to delayed-check that yield/await does not exist in default parameters. - this.yieldPos = this.awaitPos = 0; - // Labels in scope. - this.labels = []; - - // If enabled, skip leading hashbang line. - if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") - { this.skipLineComment(2); } - - // Scope tracking for duplicate variable names (see scope.js) - this.scopeStack = []; - this.enterFunctionScope(); - - // For RegExp validation - this.regexpState = null; -}; - -// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them -Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) }; -Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) }; - -Parser.prototype.extend = function extend (name, f) { - this[name] = f(this[name]); -}; - -Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { - var this$1 = this; - - for (var name in pluginConfigs) { - var plugin = plugins[name]; - if (!plugin) { throw new Error("Plugin '" + name + "' not found") } - plugin(this$1, pluginConfigs[name]); - } -}; - -Parser.prototype.parse = function parse () { - var node = this.options.program || this.startNode(); - this.nextToken(); - return this.parseTopLevel(node) -}; - -var pp = Parser.prototype; - -// ## Parser utilities - -var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/; -pp.strictDirective = function(start) { - var this$1 = this; - - for (;;) { - skipWhiteSpace.lastIndex = start; - start += skipWhiteSpace.exec(this$1.input)[0].length; - var match = literal.exec(this$1.input.slice(start)); - if (!match) { return false } - if ((match[1] || match[2]) == "use strict") { return true } - start += match[0].length; - } -}; - -// Predicate that tests whether the next token is of the given -// type, and if yes, consumes it as a side effect. - -pp.eat = function(type) { - if (this.type === type) { - this.next(); - return true - } else { - return false - } -}; - -// Tests whether parsed token is a contextual keyword. - -pp.isContextual = function(name) { - return this.type === types.name && this.value === name && !this.containsEsc -}; - -// Consumes contextual keyword if possible. - -pp.eatContextual = function(name) { - if (!this.isContextual(name)) { return false } - this.next(); - return true -}; - -// Asserts that following token is given contextual keyword. - -pp.expectContextual = function(name) { - if (!this.eatContextual(name)) { this.unexpected(); } -}; - -// Test whether a semicolon can be inserted at the current position. - -pp.canInsertSemicolon = function() { - return this.type === types.eof || - this.type === types.braceR || - lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) -}; - -pp.insertSemicolon = function() { - if (this.canInsertSemicolon()) { - if (this.options.onInsertedSemicolon) - { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } - return true - } -}; - -// Consume a semicolon, or, failing that, see if we are allowed to -// pretend that there is a semicolon at this position. - -pp.semicolon = function() { - if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); } -}; - -pp.afterTrailingComma = function(tokType, notNext) { - if (this.type == tokType) { - if (this.options.onTrailingComma) - { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } - if (!notNext) - { this.next(); } - return true - } -}; - -// Expect a token of a given type. If found, consume it, otherwise, -// raise an unexpected token error. - -pp.expect = function(type) { - this.eat(type) || this.unexpected(); -}; - -// Raise an unexpected token error. - -pp.unexpected = function(pos) { - this.raise(pos != null ? pos : this.start, "Unexpected token"); -}; - -function DestructuringErrors() { - this.shorthandAssign = - this.trailingComma = - this.parenthesizedAssign = - this.parenthesizedBind = - this.doubleProto = - -1; -} - -pp.checkPatternErrors = function(refDestructuringErrors, isAssign) { - if (!refDestructuringErrors) { return } - if (refDestructuringErrors.trailingComma > -1) - { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } - var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; - if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); } -}; - -pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { - if (!refDestructuringErrors) { return false } - var shorthandAssign = refDestructuringErrors.shorthandAssign; - var doubleProto = refDestructuringErrors.doubleProto; - if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } - if (shorthandAssign >= 0) - { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } - if (doubleProto >= 0) - { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } -}; - -pp.checkYieldAwaitInDefaultParams = function() { - if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) - { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } - if (this.awaitPos) - { this.raise(this.awaitPos, "Await expression cannot be a default value"); } -}; - -pp.isSimpleAssignTarget = function(expr) { - if (expr.type === "ParenthesizedExpression") - { return this.isSimpleAssignTarget(expr.expression) } - return expr.type === "Identifier" || expr.type === "MemberExpression" -}; - -var pp$1 = Parser.prototype; - -// ### Statement parsing - -// Parse a program. Initializes the parser, reads any number of -// statements, and wraps them in a Program node. Optionally takes a -// `program` argument. If present, the statements will be appended -// to its body instead of creating a new node. - -pp$1.parseTopLevel = function(node) { - var this$1 = this; - - var exports = {}; - if (!node.body) { node.body = []; } - while (this.type !== types.eof) { - var stmt = this$1.parseStatement(true, true, exports); - node.body.push(stmt); - } - this.adaptDirectivePrologue(node.body); - this.next(); - if (this.options.ecmaVersion >= 6) { - node.sourceType = this.options.sourceType; - } - return this.finishNode(node, "Program") -}; - -var loopLabel = {kind: "loop"}; -var switchLabel = {kind: "switch"}; - -pp$1.isLet = function() { - if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } - skipWhiteSpace.lastIndex = this.pos; - var skip = skipWhiteSpace.exec(this.input); - var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); - if (nextCh === 91 || nextCh == 123) { return true } // '{' and '[' - if (isIdentifierStart(nextCh, true)) { - var pos = next + 1; - while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; } - var ident = this.input.slice(next, pos); - if (!keywordRelationalOperator.test(ident)) { return true } - } - return false -}; - -// check 'async [no LineTerminator here] function' -// - 'async /*foo*/ function' is OK. -// - 'async /*\n*/ function' is invalid. -pp$1.isAsyncFunction = function() { - if (this.options.ecmaVersion < 8 || !this.isContextual("async")) - { return false } - - skipWhiteSpace.lastIndex = this.pos; - var skip = skipWhiteSpace.exec(this.input); - var next = this.pos + skip[0].length; - return !lineBreak.test(this.input.slice(this.pos, next)) && - this.input.slice(next, next + 8) === "function" && - (next + 8 == this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) -}; - -// Parse a single statement. -// -// If expecting a statement and finding a slash operator, parse a -// regular expression literal. This is to handle cases like -// `if (foo) /blah/.exec(foo)`, where looking at the previous token -// does not help. - -pp$1.parseStatement = function(declaration, topLevel, exports) { - var starttype = this.type, node = this.startNode(), kind; - - if (this.isLet()) { - starttype = types._var; - kind = "let"; - } - - // Most types of statements are recognized by the keyword they - // start with. Many are trivial to parse, some require a bit of - // complexity. - - switch (starttype) { - case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword) - case types._debugger: return this.parseDebuggerStatement(node) - case types._do: return this.parseDoStatement(node) - case types._for: return this.parseForStatement(node) - case types._function: - if (!declaration && this.options.ecmaVersion >= 6) { this.unexpected(); } - return this.parseFunctionStatement(node, false) - case types._class: - if (!declaration) { this.unexpected(); } - return this.parseClass(node, true) - case types._if: return this.parseIfStatement(node) - case types._return: return this.parseReturnStatement(node) - case types._switch: return this.parseSwitchStatement(node) - case types._throw: return this.parseThrowStatement(node) - case types._try: return this.parseTryStatement(node) - case types._const: case types._var: - kind = kind || this.value; - if (!declaration && kind != "var") { this.unexpected(); } - return this.parseVarStatement(node, kind) - case types._while: return this.parseWhileStatement(node) - case types._with: return this.parseWithStatement(node) - case types.braceL: return this.parseBlock() - case types.semi: return this.parseEmptyStatement(node) - case types._export: - case types._import: - if (!this.options.allowImportExportEverywhere) { - if (!topLevel) - { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } - if (!this.inModule) - { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } - } - return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports) - - // If the statement does not start with a statement keyword or a - // brace, it's an ExpressionStatement or LabeledStatement. We - // simply start parsing an expression, and afterwards, if the - // next token is a colon and the expression was a simple - // Identifier node, we switch to interpreting it as a label. - default: - if (this.isAsyncFunction()) { - if (!declaration) { this.unexpected(); } - this.next(); - return this.parseFunctionStatement(node, true) - } - - var maybeName = this.value, expr = this.parseExpression(); - if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) - { return this.parseLabeledStatement(node, maybeName, expr) } - else { return this.parseExpressionStatement(node, expr) } - } -}; - -pp$1.parseBreakContinueStatement = function(node, keyword) { - var this$1 = this; - - var isBreak = keyword == "break"; - this.next(); - if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; } - else if (this.type !== types.name) { this.unexpected(); } - else { - node.label = this.parseIdent(); - this.semicolon(); - } - - // Verify that there is an actual destination to break or - // continue to. - var i = 0; - for (; i < this.labels.length; ++i) { - var lab = this$1.labels[i]; - if (node.label == null || lab.name === node.label.name) { - if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } - if (node.label && isBreak) { break } - } - } - if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } - return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") -}; - -pp$1.parseDebuggerStatement = function(node) { - this.next(); - this.semicolon(); - return this.finishNode(node, "DebuggerStatement") -}; - -pp$1.parseDoStatement = function(node) { - this.next(); - this.labels.push(loopLabel); - node.body = this.parseStatement(false); - this.labels.pop(); - this.expect(types._while); - node.test = this.parseParenExpression(); - if (this.options.ecmaVersion >= 6) - { this.eat(types.semi); } - else - { this.semicolon(); } - return this.finishNode(node, "DoWhileStatement") -}; - -// Disambiguating between a `for` and a `for`/`in` or `for`/`of` -// loop is non-trivial. Basically, we have to parse the init `var` -// statement or expression, disallowing the `in` operator (see -// the second parameter to `parseExpression`), and then check -// whether the next token is `in` or `of`. When there is no init -// part (semicolon immediately after the opening parenthesis), it -// is a regular `for` loop. - -pp$1.parseForStatement = function(node) { - this.next(); - var awaitAt = (this.options.ecmaVersion >= 9 && this.inAsync && this.eatContextual("await")) ? this.lastTokStart : -1; - this.labels.push(loopLabel); - this.enterLexicalScope(); - this.expect(types.parenL); - if (this.type === types.semi) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, null) - } - var isLet = this.isLet(); - if (this.type === types._var || this.type === types._const || isLet) { - var init$1 = this.startNode(), kind = isLet ? "let" : this.value; - this.next(); - this.parseVar(init$1, true, kind); - this.finishNode(init$1, "VariableDeclaration"); - if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 && - !(kind !== "var" && init$1.declarations[0].init)) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } - } - return this.parseForIn(node, init$1) - } - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, init$1) - } - var refDestructuringErrors = new DestructuringErrors; - var init = this.parseExpression(true, refDestructuringErrors); - if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } - } - this.toAssignable(init, false, refDestructuringErrors); - this.checkLVal(init); - return this.parseForIn(node, init) - } else { - this.checkExpressionErrors(refDestructuringErrors, true); - } - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, init) -}; - -pp$1.parseFunctionStatement = function(node, isAsync) { - this.next(); - return this.parseFunction(node, true, false, isAsync) -}; - -pp$1.parseIfStatement = function(node) { - this.next(); - node.test = this.parseParenExpression(); - // allow function declarations in branches, but only in non-strict mode - node.consequent = this.parseStatement(!this.strict && this.type == types._function); - node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type == types._function) : null; - return this.finishNode(node, "IfStatement") -}; - -pp$1.parseReturnStatement = function(node) { - if (!this.inFunction && !this.options.allowReturnOutsideFunction) - { this.raise(this.start, "'return' outside of function"); } - this.next(); - - // In `return` (and `break`/`continue`), the keywords with - // optional arguments, we eagerly look for a semicolon or the - // possibility to insert one. - - if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; } - else { node.argument = this.parseExpression(); this.semicolon(); } - return this.finishNode(node, "ReturnStatement") -}; - -pp$1.parseSwitchStatement = function(node) { - var this$1 = this; - - this.next(); - node.discriminant = this.parseParenExpression(); - node.cases = []; - this.expect(types.braceL); - this.labels.push(switchLabel); - this.enterLexicalScope(); - - // Statements under must be grouped (by label) in SwitchCase - // nodes. `cur` is used to keep the node that we are currently - // adding statements to. - - var cur; - for (var sawDefault = false; this.type != types.braceR;) { - if (this$1.type === types._case || this$1.type === types._default) { - var isCase = this$1.type === types._case; - if (cur) { this$1.finishNode(cur, "SwitchCase"); } - node.cases.push(cur = this$1.startNode()); - cur.consequent = []; - this$1.next(); - if (isCase) { - cur.test = this$1.parseExpression(); - } else { - if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses"); } - sawDefault = true; - cur.test = null; - } - this$1.expect(types.colon); - } else { - if (!cur) { this$1.unexpected(); } - cur.consequent.push(this$1.parseStatement(true)); - } - } - this.exitLexicalScope(); - if (cur) { this.finishNode(cur, "SwitchCase"); } - this.next(); // Closing brace - this.labels.pop(); - return this.finishNode(node, "SwitchStatement") -}; - -pp$1.parseThrowStatement = function(node) { - this.next(); - if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) - { this.raise(this.lastTokEnd, "Illegal newline after throw"); } - node.argument = this.parseExpression(); - this.semicolon(); - return this.finishNode(node, "ThrowStatement") -}; - -// Reused empty array added for node fields that are always empty. - -var empty = []; - -pp$1.parseTryStatement = function(node) { - this.next(); - node.block = this.parseBlock(); - node.handler = null; - if (this.type === types._catch) { - var clause = this.startNode(); - this.next(); - this.expect(types.parenL); - clause.param = this.parseBindingAtom(); - this.enterLexicalScope(); - this.checkLVal(clause.param, "let"); - this.expect(types.parenR); - clause.body = this.parseBlock(false); - this.exitLexicalScope(); - node.handler = this.finishNode(clause, "CatchClause"); - } - node.finalizer = this.eat(types._finally) ? this.parseBlock() : null; - if (!node.handler && !node.finalizer) - { this.raise(node.start, "Missing catch or finally clause"); } - return this.finishNode(node, "TryStatement") -}; - -pp$1.parseVarStatement = function(node, kind) { - this.next(); - this.parseVar(node, false, kind); - this.semicolon(); - return this.finishNode(node, "VariableDeclaration") -}; - -pp$1.parseWhileStatement = function(node) { - this.next(); - node.test = this.parseParenExpression(); - this.labels.push(loopLabel); - node.body = this.parseStatement(false); - this.labels.pop(); - return this.finishNode(node, "WhileStatement") -}; - -pp$1.parseWithStatement = function(node) { - if (this.strict) { this.raise(this.start, "'with' in strict mode"); } - this.next(); - node.object = this.parseParenExpression(); - node.body = this.parseStatement(false); - return this.finishNode(node, "WithStatement") -}; - -pp$1.parseEmptyStatement = function(node) { - this.next(); - return this.finishNode(node, "EmptyStatement") -}; - -pp$1.parseLabeledStatement = function(node, maybeName, expr) { - var this$1 = this; - - for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1) - { - var label = list[i$1]; - - if (label.name === maybeName) - { this$1.raise(expr.start, "Label '" + maybeName + "' is already declared"); - } } - var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null; - for (var i = this.labels.length - 1; i >= 0; i--) { - var label$1 = this$1.labels[i]; - if (label$1.statementStart == node.start) { - // Update information about previous labels on this node - label$1.statementStart = this$1.start; - label$1.kind = kind; - } else { break } - } - this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); - node.body = this.parseStatement(true); - if (node.body.type == "ClassDeclaration" || - node.body.type == "VariableDeclaration" && node.body.kind != "var" || - node.body.type == "FunctionDeclaration" && (this.strict || node.body.generator)) - { this.raiseRecoverable(node.body.start, "Invalid labeled declaration"); } - this.labels.pop(); - node.label = expr; - return this.finishNode(node, "LabeledStatement") -}; - -pp$1.parseExpressionStatement = function(node, expr) { - node.expression = expr; - this.semicolon(); - return this.finishNode(node, "ExpressionStatement") -}; - -// Parse a semicolon-enclosed block of statements, handling `"use -// strict"` declarations when `allowStrict` is true (used for -// function bodies). - -pp$1.parseBlock = function(createNewLexicalScope) { - var this$1 = this; - if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; - - var node = this.startNode(); - node.body = []; - this.expect(types.braceL); - if (createNewLexicalScope) { - this.enterLexicalScope(); - } - while (!this.eat(types.braceR)) { - var stmt = this$1.parseStatement(true); - node.body.push(stmt); - } - if (createNewLexicalScope) { - this.exitLexicalScope(); - } - return this.finishNode(node, "BlockStatement") -}; - -// Parse a regular `for` loop. The disambiguation code in -// `parseStatement` will already have parsed the init statement or -// expression. - -pp$1.parseFor = function(node, init) { - node.init = init; - this.expect(types.semi); - node.test = this.type === types.semi ? null : this.parseExpression(); - this.expect(types.semi); - node.update = this.type === types.parenR ? null : this.parseExpression(); - this.expect(types.parenR); - this.exitLexicalScope(); - node.body = this.parseStatement(false); - this.labels.pop(); - return this.finishNode(node, "ForStatement") -}; - -// Parse a `for`/`in` and `for`/`of` loop, which are almost -// same from parser's perspective. - -pp$1.parseForIn = function(node, init) { - var type = this.type === types._in ? "ForInStatement" : "ForOfStatement"; - this.next(); - if (type == "ForInStatement") { - if (init.type === "AssignmentPattern" || - (init.type === "VariableDeclaration" && init.declarations[0].init != null && - (this.strict || init.declarations[0].id.type !== "Identifier"))) - { this.raise(init.start, "Invalid assignment in for-in loop head"); } - } - node.left = init; - node.right = type == "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign(); - this.expect(types.parenR); - this.exitLexicalScope(); - node.body = this.parseStatement(false); - this.labels.pop(); - return this.finishNode(node, type) -}; - -// Parse a list of variable declarations. - -pp$1.parseVar = function(node, isFor, kind) { - var this$1 = this; - - node.declarations = []; - node.kind = kind; - for (;;) { - var decl = this$1.startNode(); - this$1.parseVarId(decl, kind); - if (this$1.eat(types.eq)) { - decl.init = this$1.parseMaybeAssign(isFor); - } else if (kind === "const" && !(this$1.type === types._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) { - this$1.unexpected(); - } else if (decl.id.type != "Identifier" && !(isFor && (this$1.type === types._in || this$1.isContextual("of")))) { - this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value"); - } else { - decl.init = null; - } - node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")); - if (!this$1.eat(types.comma)) { break } - } - return node -}; - -pp$1.parseVarId = function(decl, kind) { - decl.id = this.parseBindingAtom(kind); - this.checkLVal(decl.id, kind, false); -}; - -// Parse a function declaration or literal (depending on the -// `isStatement` parameter). - -pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) { - this.initFunction(node); - if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) - { node.generator = this.eat(types.star); } - if (this.options.ecmaVersion >= 8) - { node.async = !!isAsync; } - - if (isStatement) { - node.id = isStatement === "nullableID" && this.type != types.name ? null : this.parseIdent(); - if (node.id) { - this.checkLVal(node.id, "var"); - } - } - - var oldInGen = this.inGenerator, oldInAsync = this.inAsync, - oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; - this.inGenerator = node.generator; - this.inAsync = node.async; - this.yieldPos = 0; - this.awaitPos = 0; - this.inFunction = true; - this.enterFunctionScope(); - - if (!isStatement) - { node.id = this.type == types.name ? this.parseIdent() : null; } - - this.parseFunctionParams(node); - this.parseFunctionBody(node, allowExpressionBody); - - this.inGenerator = oldInGen; - this.inAsync = oldInAsync; - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - this.inFunction = oldInFunc; - return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") -}; - -pp$1.parseFunctionParams = function(node) { - this.expect(types.parenL); - node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); - this.checkYieldAwaitInDefaultParams(); -}; - -// Parse a class declaration or literal (depending on the -// `isStatement` parameter). - -pp$1.parseClass = function(node, isStatement) { - var this$1 = this; - - this.next(); - - this.parseClassId(node, isStatement); - this.parseClassSuper(node); - var classBody = this.startNode(); - var hadConstructor = false; - classBody.body = []; - this.expect(types.braceL); - while (!this.eat(types.braceR)) { - var member = this$1.parseClassMember(classBody); - if (member && member.type === "MethodDefinition" && member.kind === "constructor") { - if (hadConstructor) { this$1.raise(member.start, "Duplicate constructor in the same class"); } - hadConstructor = true; - } - } - node.body = this.finishNode(classBody, "ClassBody"); - return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") -}; - -pp$1.parseClassMember = function(classBody) { - var this$1 = this; - - if (this.eat(types.semi)) { return null } - - var method = this.startNode(); - var tryContextual = function (k, noLineBreak) { - if ( noLineBreak === void 0 ) noLineBreak = false; - - var start = this$1.start, startLoc = this$1.startLoc; - if (!this$1.eatContextual(k)) { return false } - if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true } - if (method.key) { this$1.unexpected(); } - method.computed = false; - method.key = this$1.startNodeAt(start, startLoc); - method.key.name = k; - this$1.finishNode(method.key, "Identifier"); - return false - }; - - method.kind = "method"; - method.static = tryContextual("static"); - var isGenerator = this.eat(types.star); - var isAsync = false; - if (!isGenerator) { - if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { - isAsync = true; - isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); - } else if (tryContextual("get")) { - method.kind = "get"; - } else if (tryContextual("set")) { - method.kind = "set"; - } - } - if (!method.key) { this.parsePropertyName(method); } - var key = method.key; - if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" || - key.type === "Literal" && key.value === "constructor")) { - if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); } - if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } - if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } - method.kind = "constructor"; - } else if (method.static && key.type === "Identifier" && key.name === "prototype") { - this.raise(key.start, "Classes may not have a static property named prototype"); - } - this.parseClassMethod(classBody, method, isGenerator, isAsync); - if (method.kind === "get" && method.value.params.length !== 0) - { this.raiseRecoverable(method.value.start, "getter should have no params"); } - if (method.kind === "set" && method.value.params.length !== 1) - { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); } - if (method.kind === "set" && method.value.params[0].type === "RestElement") - { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); } - return method -}; - -pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) { - method.value = this.parseMethod(isGenerator, isAsync); - classBody.body.push(this.finishNode(method, "MethodDefinition")); -}; - -pp$1.parseClassId = function(node, isStatement) { - node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null; -}; - -pp$1.parseClassSuper = function(node) { - node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; -}; - -// Parses module export declaration. - -pp$1.parseExport = function(node, exports) { - var this$1 = this; - - this.next(); - // export * from '...' - if (this.eat(types.star)) { - this.expectContextual("from"); - if (this.type !== types.string) { this.unexpected(); } - node.source = this.parseExprAtom(); - this.semicolon(); - return this.finishNode(node, "ExportAllDeclaration") - } - if (this.eat(types._default)) { // export default ... - this.checkExport(exports, "default", this.lastTokStart); - var isAsync; - if (this.type === types._function || (isAsync = this.isAsyncFunction())) { - var fNode = this.startNode(); - this.next(); - if (isAsync) { this.next(); } - node.declaration = this.parseFunction(fNode, "nullableID", false, isAsync); - } else if (this.type === types._class) { - var cNode = this.startNode(); - node.declaration = this.parseClass(cNode, "nullableID"); - } else { - node.declaration = this.parseMaybeAssign(); - this.semicolon(); - } - return this.finishNode(node, "ExportDefaultDeclaration") - } - // export var|const|let|function|class ... - if (this.shouldParseExportStatement()) { - node.declaration = this.parseStatement(true); - if (node.declaration.type === "VariableDeclaration") - { this.checkVariableExport(exports, node.declaration.declarations); } - else - { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); } - node.specifiers = []; - node.source = null; - } else { // export { x, y as z } [from '...'] - node.declaration = null; - node.specifiers = this.parseExportSpecifiers(exports); - if (this.eatContextual("from")) { - if (this.type !== types.string) { this.unexpected(); } - node.source = this.parseExprAtom(); - } else { - // check for keywords used as local names - for (var i = 0, list = node.specifiers; i < list.length; i += 1) { - var spec = list[i]; - - this$1.checkUnreserved(spec.local); - } - - node.source = null; - } - this.semicolon(); - } - return this.finishNode(node, "ExportNamedDeclaration") -}; - -pp$1.checkExport = function(exports, name, pos) { - if (!exports) { return } - if (has(exports, name)) - { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } - exports[name] = true; -}; - -pp$1.checkPatternExport = function(exports, pat) { - var this$1 = this; - - var type = pat.type; - if (type == "Identifier") - { this.checkExport(exports, pat.name, pat.start); } - else if (type == "ObjectPattern") - { for (var i = 0, list = pat.properties; i < list.length; i += 1) - { - var prop = list[i]; - - this$1.checkPatternExport(exports, prop); - } } - else if (type == "ArrayPattern") - { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { - var elt = list$1[i$1]; - - if (elt) { this$1.checkPatternExport(exports, elt); } - } } - else if (type == "Property") - { this.checkPatternExport(exports, pat.value); } - else if (type == "AssignmentPattern") - { this.checkPatternExport(exports, pat.left); } - else if (type == "RestElement") - { this.checkPatternExport(exports, pat.argument); } - else if (type == "ParenthesizedExpression") - { this.checkPatternExport(exports, pat.expression); } -}; - -pp$1.checkVariableExport = function(exports, decls) { - var this$1 = this; - - if (!exports) { return } - for (var i = 0, list = decls; i < list.length; i += 1) - { - var decl = list[i]; - - this$1.checkPatternExport(exports, decl.id); - } -}; - -pp$1.shouldParseExportStatement = function() { - return this.type.keyword === "var" || - this.type.keyword === "const" || - this.type.keyword === "class" || - this.type.keyword === "function" || - this.isLet() || - this.isAsyncFunction() -}; - -// Parses a comma-separated list of module exports. - -pp$1.parseExportSpecifiers = function(exports) { - var this$1 = this; - - var nodes = [], first = true; - // export { x, y as z } [from '...'] - this.expect(types.braceL); - while (!this.eat(types.braceR)) { - if (!first) { - this$1.expect(types.comma); - if (this$1.afterTrailingComma(types.braceR)) { break } - } else { first = false; } - - var node = this$1.startNode(); - node.local = this$1.parseIdent(true); - node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local; - this$1.checkExport(exports, node.exported.name, node.exported.start); - nodes.push(this$1.finishNode(node, "ExportSpecifier")); - } - return nodes -}; - -// Parses import declaration. - -pp$1.parseImport = function(node) { - this.next(); - // import '...' - if (this.type === types.string) { - node.specifiers = empty; - node.source = this.parseExprAtom(); - } else { - node.specifiers = this.parseImportSpecifiers(); - this.expectContextual("from"); - node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected(); - } - this.semicolon(); - return this.finishNode(node, "ImportDeclaration") -}; - -// Parses a comma-separated list of module imports. - -pp$1.parseImportSpecifiers = function() { - var this$1 = this; - - var nodes = [], first = true; - if (this.type === types.name) { - // import defaultObj, { x, y as z } from '...' - var node = this.startNode(); - node.local = this.parseIdent(); - this.checkLVal(node.local, "let"); - nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); - if (!this.eat(types.comma)) { return nodes } - } - if (this.type === types.star) { - var node$1 = this.startNode(); - this.next(); - this.expectContextual("as"); - node$1.local = this.parseIdent(); - this.checkLVal(node$1.local, "let"); - nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); - return nodes - } - this.expect(types.braceL); - while (!this.eat(types.braceR)) { - if (!first) { - this$1.expect(types.comma); - if (this$1.afterTrailingComma(types.braceR)) { break } - } else { first = false; } - - var node$2 = this$1.startNode(); - node$2.imported = this$1.parseIdent(true); - if (this$1.eatContextual("as")) { - node$2.local = this$1.parseIdent(); - } else { - this$1.checkUnreserved(node$2.imported); - node$2.local = node$2.imported; - } - this$1.checkLVal(node$2.local, "let"); - nodes.push(this$1.finishNode(node$2, "ImportSpecifier")); - } - return nodes -}; - -// Set `ExpressionStatement#directive` property for directive prologues. -pp$1.adaptDirectivePrologue = function(statements) { - for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { - statements[i].directive = statements[i].expression.raw.slice(1, -1); - } -}; -pp$1.isDirectiveCandidate = function(statement) { - return ( - statement.type === "ExpressionStatement" && - statement.expression.type === "Literal" && - typeof statement.expression.value === "string" && - // Reject parenthesized strings. - (this.input[statement.start] === "\"" || this.input[statement.start] === "'") - ) -}; - -var pp$2 = Parser.prototype; - -// Convert existing expression atom to assignable pattern -// if possible. - -pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) { - var this$1 = this; - - if (this.options.ecmaVersion >= 6 && node) { - switch (node.type) { - case "Identifier": - if (this.inAsync && node.name === "await") - { this.raise(node.start, "Can not use 'await' as identifier inside an async function"); } - break - - case "ObjectPattern": - case "ArrayPattern": - case "RestElement": - break - - case "ObjectExpression": - node.type = "ObjectPattern"; - if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } - for (var i = 0, list = node.properties; i < list.length; i += 1) { - var prop = list[i]; - - this$1.toAssignable(prop, isBinding); - // Early error: - // AssignmentRestProperty[Yield, Await] : - // `...` DestructuringAssignmentTarget[Yield, Await] - // - // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. - if ( - prop.type === "RestElement" && - (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") - ) { - this$1.raise(prop.argument.start, "Unexpected token"); - } - } - break - - case "Property": - // AssignmentProperty has type == "Property" - if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } - this.toAssignable(node.value, isBinding); - break - - case "ArrayExpression": - node.type = "ArrayPattern"; - if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } - this.toAssignableList(node.elements, isBinding); - break - - case "SpreadElement": - node.type = "RestElement"; - this.toAssignable(node.argument, isBinding); - if (node.argument.type === "AssignmentPattern") - { this.raise(node.argument.start, "Rest elements cannot have a default value"); } - break - - case "AssignmentExpression": - if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } - node.type = "AssignmentPattern"; - delete node.operator; - this.toAssignable(node.left, isBinding); - // falls through to AssignmentPattern - - case "AssignmentPattern": - break - - case "ParenthesizedExpression": - this.toAssignable(node.expression, isBinding); - break - - case "MemberExpression": - if (!isBinding) { break } - - default: - this.raise(node.start, "Assigning to rvalue"); - } - } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } - return node -}; - -// Convert list of expression atoms to binding list. - -pp$2.toAssignableList = function(exprList, isBinding) { - var this$1 = this; - - var end = exprList.length; - for (var i = 0; i < end; i++) { - var elt = exprList[i]; - if (elt) { this$1.toAssignable(elt, isBinding); } - } - if (end) { - var last = exprList[end - 1]; - if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") - { this.unexpected(last.argument.start); } - } - return exprList -}; - -// Parses spread element. - -pp$2.parseSpread = function(refDestructuringErrors) { - var node = this.startNode(); - this.next(); - node.argument = this.parseMaybeAssign(false, refDestructuringErrors); - return this.finishNode(node, "SpreadElement") -}; - -pp$2.parseRestBinding = function() { - var node = this.startNode(); - this.next(); - - // RestElement inside of a function parameter must be an identifier - if (this.options.ecmaVersion === 6 && this.type !== types.name) - { this.unexpected(); } - - node.argument = this.parseBindingAtom(); - - return this.finishNode(node, "RestElement") -}; - -// Parses lvalue (assignable) atom. - -pp$2.parseBindingAtom = function() { - if (this.options.ecmaVersion >= 6) { - switch (this.type) { - case types.bracketL: - var node = this.startNode(); - this.next(); - node.elements = this.parseBindingList(types.bracketR, true, true); - return this.finishNode(node, "ArrayPattern") - - case types.braceL: - return this.parseObj(true) - } - } - return this.parseIdent() -}; - -pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) { - var this$1 = this; - - var elts = [], first = true; - while (!this.eat(close)) { - if (first) { first = false; } - else { this$1.expect(types.comma); } - if (allowEmpty && this$1.type === types.comma) { - elts.push(null); - } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { - break - } else if (this$1.type === types.ellipsis) { - var rest = this$1.parseRestBinding(); - this$1.parseBindingListItem(rest); - elts.push(rest); - if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } - this$1.expect(close); - break - } else { - var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc); - this$1.parseBindingListItem(elem); - elts.push(elem); - } - } - return elts -}; - -pp$2.parseBindingListItem = function(param) { - return param -}; - -// Parses assignment pattern around given atom if possible. - -pp$2.parseMaybeDefault = function(startPos, startLoc, left) { - left = left || this.parseBindingAtom(); - if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left } - var node = this.startNodeAt(startPos, startLoc); - node.left = left; - node.right = this.parseMaybeAssign(); - return this.finishNode(node, "AssignmentPattern") -}; - -// Verify that a node is an lval — something that can be assigned -// to. -// bindingType can be either: -// 'var' indicating that the lval creates a 'var' binding -// 'let' indicating that the lval creates a lexical ('let' or 'const') binding -// 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references - -pp$2.checkLVal = function(expr, bindingType, checkClashes) { - var this$1 = this; - - switch (expr.type) { - case "Identifier": - if (this.strict && this.reservedWordsStrictBind.test(expr.name)) - { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } - if (checkClashes) { - if (has(checkClashes, expr.name)) - { this.raiseRecoverable(expr.start, "Argument name clash"); } - checkClashes[expr.name] = true; - } - if (bindingType && bindingType !== "none") { - if ( - bindingType === "var" && !this.canDeclareVarName(expr.name) || - bindingType !== "var" && !this.canDeclareLexicalName(expr.name) - ) { - this.raiseRecoverable(expr.start, ("Identifier '" + (expr.name) + "' has already been declared")); - } - if (bindingType === "var") { - this.declareVarName(expr.name); - } else { - this.declareLexicalName(expr.name); - } - } - break - - case "MemberExpression": - if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); } - break - - case "ObjectPattern": - for (var i = 0, list = expr.properties; i < list.length; i += 1) - { - var prop = list[i]; - - this$1.checkLVal(prop, bindingType, checkClashes); - } - break - - case "Property": - // AssignmentProperty has type == "Property" - this.checkLVal(expr.value, bindingType, checkClashes); - break - - case "ArrayPattern": - for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { - var elem = list$1[i$1]; - - if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); } - } - break - - case "AssignmentPattern": - this.checkLVal(expr.left, bindingType, checkClashes); - break - - case "RestElement": - this.checkLVal(expr.argument, bindingType, checkClashes); - break - - case "ParenthesizedExpression": - this.checkLVal(expr.expression, bindingType, checkClashes); - break - - default: - this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue"); - } -}; - -// A recursive descent parser operates by defining functions for all -// syntactic elements, and recursively calling those, each function -// advancing the input stream and returning an AST node. Precedence -// of constructs (for example, the fact that `!x[1]` means `!(x[1])` -// instead of `(!x)[1]` is handled by the fact that the parser -// function that parses unary prefix operators is called first, and -// in turn calls the function that parses `[]` subscripts — that -// way, it'll receive the node for `x[1]` already parsed, and wraps -// *that* in the unary operator node. -// -// Acorn uses an [operator precedence parser][opp] to handle binary -// operator precedence, because it is much more compact than using -// the technique outlined above, which uses different, nesting -// functions to specify precedence, for all of the ten binary -// precedence levels that JavaScript defines. -// -// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser - -var pp$3 = Parser.prototype; - -// Check if property name clashes with already added. -// Object/class getters and setters are not allowed to clash — -// either with each other or with an init property — and in -// strict mode, init properties are also not allowed to be repeated. - -pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) { - if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") - { return } - if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) - { return } - var key = prop.key; - var name; - switch (key.type) { - case "Identifier": name = key.name; break - case "Literal": name = String(key.value); break - default: return - } - var kind = prop.kind; - if (this.options.ecmaVersion >= 6) { - if (name === "__proto__" && kind === "init") { - if (propHash.proto) { - if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; } - // Backwards-compat kludge. Can be removed in version 6.0 - else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } - } - propHash.proto = true; - } - return - } - name = "$" + name; - var other = propHash[name]; - if (other) { - var redefinition; - if (kind === "init") { - redefinition = this.strict && other.init || other.get || other.set; - } else { - redefinition = other.init || other[kind]; - } - if (redefinition) - { this.raiseRecoverable(key.start, "Redefinition of property"); } - } else { - other = propHash[name] = { - init: false, - get: false, - set: false - }; - } - other[kind] = true; -}; - -// ### Expression parsing - -// These nest, from the most general expression type at the top to -// 'atomic', nondivisible expression types at the bottom. Most of -// the functions will simply let the function(s) below them parse, -// and, *if* the syntactic construct they handle is present, wrap -// the AST node that the inner parser gave them in another node. - -// Parse a full expression. The optional arguments are used to -// forbid the `in` operator (in for loops initalization expressions) -// and provide reference for storing '=' operator inside shorthand -// property assignment in contexts where both object expression -// and object pattern might appear (so it's possible to raise -// delayed syntax error at correct position). - -pp$3.parseExpression = function(noIn, refDestructuringErrors) { - var this$1 = this; - - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseMaybeAssign(noIn, refDestructuringErrors); - if (this.type === types.comma) { - var node = this.startNodeAt(startPos, startLoc); - node.expressions = [expr]; - while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); } - return this.finishNode(node, "SequenceExpression") - } - return expr -}; - -// Parse an assignment expression. This includes applications of -// operators like `+=`. - -pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { - if (this.inGenerator && this.isContextual("yield")) { return this.parseYield() } - - var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1; - if (refDestructuringErrors) { - oldParenAssign = refDestructuringErrors.parenthesizedAssign; - oldTrailingComma = refDestructuringErrors.trailingComma; - refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; - } else { - refDestructuringErrors = new DestructuringErrors; - ownDestructuringErrors = true; - } - - var startPos = this.start, startLoc = this.startLoc; - if (this.type == types.parenL || this.type == types.name) - { this.potentialArrowAt = this.start; } - var left = this.parseMaybeConditional(noIn, refDestructuringErrors); - if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } - if (this.type.isAssign) { - var node = this.startNodeAt(startPos, startLoc); - node.operator = this.value; - node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left; - if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); } - refDestructuringErrors.shorthandAssign = -1; // reset because shorthand default was used correctly - this.checkLVal(left); - this.next(); - node.right = this.parseMaybeAssign(noIn); - return this.finishNode(node, "AssignmentExpression") - } else { - if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } - } - if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } - if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } - return left -}; - -// Parse a ternary conditional (`?:`) operator. - -pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseExprOps(noIn, refDestructuringErrors); - if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } - if (this.eat(types.question)) { - var node = this.startNodeAt(startPos, startLoc); - node.test = expr; - node.consequent = this.parseMaybeAssign(); - this.expect(types.colon); - node.alternate = this.parseMaybeAssign(noIn); - return this.finishNode(node, "ConditionalExpression") - } - return expr -}; - -// Start the precedence parser. - -pp$3.parseExprOps = function(noIn, refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseMaybeUnary(refDestructuringErrors, false); - if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } - return expr.start == startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn) -}; - -// Parse binary operators with the operator precedence parsing -// algorithm. `left` is the left-hand side of the operator. -// `minPrec` provides context that allows the function to stop and -// defer further parser to one of its callers when it encounters an -// operator that has a lower precedence than the set it is parsing. - -pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { - var prec = this.type.binop; - if (prec != null && (!noIn || this.type !== types._in)) { - if (prec > minPrec) { - var logical = this.type === types.logicalOR || this.type === types.logicalAND; - var op = this.value; - this.next(); - var startPos = this.start, startLoc = this.startLoc; - var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn); - var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical); - return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) - } - } - return left -}; - -pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { - var node = this.startNodeAt(startPos, startLoc); - node.left = left; - node.operator = op; - node.right = right; - return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") -}; - -// Parse unary operators, both prefix and postfix. - -pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { - var this$1 = this; - - var startPos = this.start, startLoc = this.startLoc, expr; - if (this.inAsync && this.isContextual("await")) { - expr = this.parseAwait(); - sawUnary = true; - } else if (this.type.prefix) { - var node = this.startNode(), update = this.type === types.incDec; - node.operator = this.value; - node.prefix = true; - this.next(); - node.argument = this.parseMaybeUnary(null, true); - this.checkExpressionErrors(refDestructuringErrors, true); - if (update) { this.checkLVal(node.argument); } - else if (this.strict && node.operator === "delete" && - node.argument.type === "Identifier") - { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } - else { sawUnary = true; } - expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); - } else { - expr = this.parseExprSubscripts(refDestructuringErrors); - if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } - while (this.type.postfix && !this.canInsertSemicolon()) { - var node$1 = this$1.startNodeAt(startPos, startLoc); - node$1.operator = this$1.value; - node$1.prefix = false; - node$1.argument = expr; - this$1.checkLVal(expr); - this$1.next(); - expr = this$1.finishNode(node$1, "UpdateExpression"); - } - } - - if (!sawUnary && this.eat(types.starstar)) - { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) } - else - { return expr } -}; - -// Parse call, dot, and `[]`-subscript expressions. - -pp$3.parseExprSubscripts = function(refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseExprAtom(refDestructuringErrors); - var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")"; - if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr } - var result = this.parseSubscripts(expr, startPos, startLoc); - if (refDestructuringErrors && result.type === "MemberExpression") { - if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } - if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } - } - return result -}; - -pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { - var this$1 = this; - - var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && - this.lastTokEnd == base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async"; - for (var computed = (void 0);;) { - if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) { - var node = this$1.startNodeAt(startPos, startLoc); - node.object = base; - node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true); - node.computed = !!computed; - if (computed) { this$1.expect(types.bracketR); } - base = this$1.finishNode(node, "MemberExpression"); - } else if (!noCalls && this$1.eat(types.parenL)) { - var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos; - this$1.yieldPos = 0; - this$1.awaitPos = 0; - var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors); - if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) { - this$1.checkPatternErrors(refDestructuringErrors, false); - this$1.checkYieldAwaitInDefaultParams(); - this$1.yieldPos = oldYieldPos; - this$1.awaitPos = oldAwaitPos; - return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true) - } - this$1.checkExpressionErrors(refDestructuringErrors, true); - this$1.yieldPos = oldYieldPos || this$1.yieldPos; - this$1.awaitPos = oldAwaitPos || this$1.awaitPos; - var node$1 = this$1.startNodeAt(startPos, startLoc); - node$1.callee = base; - node$1.arguments = exprList; - base = this$1.finishNode(node$1, "CallExpression"); - } else if (this$1.type === types.backQuote) { - var node$2 = this$1.startNodeAt(startPos, startLoc); - node$2.tag = base; - node$2.quasi = this$1.parseTemplate({isTagged: true}); - base = this$1.finishNode(node$2, "TaggedTemplateExpression"); - } else { - return base - } - } -}; - -// Parse an atomic expression — either a single token that is an -// expression, an expression started by a keyword like `function` or -// `new`, or an expression wrapped in punctuation like `()`, `[]`, -// or `{}`. - -pp$3.parseExprAtom = function(refDestructuringErrors) { - var node, canBeArrow = this.potentialArrowAt == this.start; - switch (this.type) { - case types._super: - if (!this.inFunction) - { this.raise(this.start, "'super' outside of function or class"); } - node = this.startNode(); - this.next(); - // The `super` keyword can appear at below: - // SuperProperty: - // super [ Expression ] - // super . IdentifierName - // SuperCall: - // super Arguments - if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL) - { this.unexpected(); } - return this.finishNode(node, "Super") - - case types._this: - node = this.startNode(); - this.next(); - return this.finishNode(node, "ThisExpression") - - case types.name: - var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; - var id = this.parseIdent(this.type !== types.name); - if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function)) - { return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) } - if (canBeArrow && !this.canInsertSemicolon()) { - if (this.eat(types.arrow)) - { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) } - if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) { - id = this.parseIdent(); - if (this.canInsertSemicolon() || !this.eat(types.arrow)) - { this.unexpected(); } - return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) - } - } - return id - - case types.regexp: - var value = this.value; - node = this.parseLiteral(value.value); - node.regex = {pattern: value.pattern, flags: value.flags}; - return node - - case types.num: case types.string: - return this.parseLiteral(this.value) - - case types._null: case types._true: case types._false: - node = this.startNode(); - node.value = this.type === types._null ? null : this.type === types._true; - node.raw = this.type.keyword; - this.next(); - return this.finishNode(node, "Literal") - - case types.parenL: - var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow); - if (refDestructuringErrors) { - if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) - { refDestructuringErrors.parenthesizedAssign = start; } - if (refDestructuringErrors.parenthesizedBind < 0) - { refDestructuringErrors.parenthesizedBind = start; } - } - return expr - - case types.bracketL: - node = this.startNode(); - this.next(); - node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors); - return this.finishNode(node, "ArrayExpression") - - case types.braceL: - return this.parseObj(false, refDestructuringErrors) - - case types._function: - node = this.startNode(); - this.next(); - return this.parseFunction(node, false) - - case types._class: - return this.parseClass(this.startNode(), false) - - case types._new: - return this.parseNew() - - case types.backQuote: - return this.parseTemplate() - - default: - this.unexpected(); - } -}; - -pp$3.parseLiteral = function(value) { - var node = this.startNode(); - node.value = value; - node.raw = this.input.slice(this.start, this.end); - this.next(); - return this.finishNode(node, "Literal") -}; - -pp$3.parseParenExpression = function() { - this.expect(types.parenL); - var val = this.parseExpression(); - this.expect(types.parenR); - return val -}; - -pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { - var this$1 = this; - - var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; - if (this.options.ecmaVersion >= 6) { - this.next(); - - var innerStartPos = this.start, innerStartLoc = this.startLoc; - var exprList = [], first = true, lastIsComma = false; - var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; - this.yieldPos = 0; - this.awaitPos = 0; - while (this.type !== types.parenR) { - first ? first = false : this$1.expect(types.comma); - if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) { - lastIsComma = true; - break - } else if (this$1.type === types.ellipsis) { - spreadStart = this$1.start; - exprList.push(this$1.parseParenItem(this$1.parseRestBinding())); - if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } - break - } else { - exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)); - } - } - var innerEndPos = this.start, innerEndLoc = this.startLoc; - this.expect(types.parenR); - - if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) { - this.checkPatternErrors(refDestructuringErrors, false); - this.checkYieldAwaitInDefaultParams(); - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - return this.parseParenArrowList(startPos, startLoc, exprList) - } - - if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } - if (spreadStart) { this.unexpected(spreadStart); } - this.checkExpressionErrors(refDestructuringErrors, true); - this.yieldPos = oldYieldPos || this.yieldPos; - this.awaitPos = oldAwaitPos || this.awaitPos; - - if (exprList.length > 1) { - val = this.startNodeAt(innerStartPos, innerStartLoc); - val.expressions = exprList; - this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); - } else { - val = exprList[0]; - } - } else { - val = this.parseParenExpression(); - } - - if (this.options.preserveParens) { - var par = this.startNodeAt(startPos, startLoc); - par.expression = val; - return this.finishNode(par, "ParenthesizedExpression") - } else { - return val - } -}; - -pp$3.parseParenItem = function(item) { - return item -}; - -pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { - return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) -}; - -// New's precedence is slightly tricky. It must allow its argument to -// be a `[]` or dot subscript expression, but not a call — at least, -// not without wrapping it in parentheses. Thus, it uses the noCalls -// argument to parseSubscripts to prevent it from consuming the -// argument list. - -var empty$1 = []; - -pp$3.parseNew = function() { - var node = this.startNode(); - var meta = this.parseIdent(true); - if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) { - node.meta = meta; - var containsEsc = this.containsEsc; - node.property = this.parseIdent(true); - if (node.property.name !== "target" || containsEsc) - { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); } - if (!this.inFunction) - { this.raiseRecoverable(node.start, "new.target can only be used in functions"); } - return this.finishNode(node, "MetaProperty") - } - var startPos = this.start, startLoc = this.startLoc; - node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); - if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); } - else { node.arguments = empty$1; } - return this.finishNode(node, "NewExpression") -}; - -// Parse template expression. - -pp$3.parseTemplateElement = function(ref) { - var isTagged = ref.isTagged; - - var elem = this.startNode(); - if (this.type === types.invalidTemplate) { - if (!isTagged) { - this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); - } - elem.value = { - raw: this.value, - cooked: null - }; - } else { - elem.value = { - raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), - cooked: this.value - }; - } - this.next(); - elem.tail = this.type === types.backQuote; - return this.finishNode(elem, "TemplateElement") -}; - -pp$3.parseTemplate = function(ref) { - var this$1 = this; - if ( ref === void 0 ) ref = {}; - var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; - - var node = this.startNode(); - this.next(); - node.expressions = []; - var curElt = this.parseTemplateElement({isTagged: isTagged}); - node.quasis = [curElt]; - while (!curElt.tail) { - this$1.expect(types.dollarBraceL); - node.expressions.push(this$1.parseExpression()); - this$1.expect(types.braceR); - node.quasis.push(curElt = this$1.parseTemplateElement({isTagged: isTagged})); - } - this.next(); - return this.finishNode(node, "TemplateLiteral") -}; - -pp$3.isAsyncProp = function(prop) { - return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && - (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) && - !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) -}; - -// Parse an object literal or binding pattern. - -pp$3.parseObj = function(isPattern, refDestructuringErrors) { - var this$1 = this; - - var node = this.startNode(), first = true, propHash = {}; - node.properties = []; - this.next(); - while (!this.eat(types.braceR)) { - if (!first) { - this$1.expect(types.comma); - if (this$1.afterTrailingComma(types.braceR)) { break } - } else { first = false; } - - var prop = this$1.parseProperty(isPattern, refDestructuringErrors); - if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); } - node.properties.push(prop); - } - return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") -}; - -pp$3.parseProperty = function(isPattern, refDestructuringErrors) { - var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; - if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) { - if (isPattern) { - prop.argument = this.parseIdent(false); - if (this.type === types.comma) { - this.raise(this.start, "Comma is not permitted after the rest element"); - } - return this.finishNode(prop, "RestElement") - } - // To disallow parenthesized identifier via `this.toAssignable()`. - if (this.type === types.parenL && refDestructuringErrors) { - if (refDestructuringErrors.parenthesizedAssign < 0) { - refDestructuringErrors.parenthesizedAssign = this.start; - } - if (refDestructuringErrors.parenthesizedBind < 0) { - refDestructuringErrors.parenthesizedBind = this.start; - } - } - // Parse argument. - prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); - // To disallow trailing comma via `this.toAssignable()`. - if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { - refDestructuringErrors.trailingComma = this.start; - } - // Finish - return this.finishNode(prop, "SpreadElement") - } - if (this.options.ecmaVersion >= 6) { - prop.method = false; - prop.shorthand = false; - if (isPattern || refDestructuringErrors) { - startPos = this.start; - startLoc = this.startLoc; - } - if (!isPattern) - { isGenerator = this.eat(types.star); } - } - var containsEsc = this.containsEsc; - this.parsePropertyName(prop); - if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { - isAsync = true; - isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); - this.parsePropertyName(prop, refDestructuringErrors); - } else { - isAsync = false; - } - this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); - return this.finishNode(prop, "Property") -}; - -pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { - if ((isGenerator || isAsync) && this.type === types.colon) - { this.unexpected(); } - - if (this.eat(types.colon)) { - prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); - prop.kind = "init"; - } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) { - if (isPattern) { this.unexpected(); } - prop.kind = "init"; - prop.method = true; - prop.value = this.parseMethod(isGenerator, isAsync); - } else if (!isPattern && !containsEsc && - this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && - (prop.key.name === "get" || prop.key.name === "set") && - (this.type != types.comma && this.type != types.braceR)) { - if (isGenerator || isAsync) { this.unexpected(); } - prop.kind = prop.key.name; - this.parsePropertyName(prop); - prop.value = this.parseMethod(false); - var paramCount = prop.kind === "get" ? 0 : 1; - if (prop.value.params.length !== paramCount) { - var start = prop.value.start; - if (prop.kind === "get") - { this.raiseRecoverable(start, "getter should have no params"); } - else - { this.raiseRecoverable(start, "setter should have exactly one param"); } - } else { - if (prop.kind === "set" && prop.value.params[0].type === "RestElement") - { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } - } - } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { - this.checkUnreserved(prop.key); - prop.kind = "init"; - if (isPattern) { - prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); - } else if (this.type === types.eq && refDestructuringErrors) { - if (refDestructuringErrors.shorthandAssign < 0) - { refDestructuringErrors.shorthandAssign = this.start; } - prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); - } else { - prop.value = prop.key; - } - prop.shorthand = true; - } else { this.unexpected(); } -}; - -pp$3.parsePropertyName = function(prop) { - if (this.options.ecmaVersion >= 6) { - if (this.eat(types.bracketL)) { - prop.computed = true; - prop.key = this.parseMaybeAssign(); - this.expect(types.bracketR); - return prop.key - } else { - prop.computed = false; - } - } - return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true) -}; - -// Initialize empty function node. - -pp$3.initFunction = function(node) { - node.id = null; - if (this.options.ecmaVersion >= 6) { - node.generator = false; - node.expression = false; - } - if (this.options.ecmaVersion >= 8) - { node.async = false; } -}; - -// Parse object or class method. - -pp$3.parseMethod = function(isGenerator, isAsync) { - var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync, - oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; - - this.initFunction(node); - if (this.options.ecmaVersion >= 6) - { node.generator = isGenerator; } - if (this.options.ecmaVersion >= 8) - { node.async = !!isAsync; } - - this.inGenerator = node.generator; - this.inAsync = node.async; - this.yieldPos = 0; - this.awaitPos = 0; - this.inFunction = true; - this.enterFunctionScope(); - - this.expect(types.parenL); - node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); - this.checkYieldAwaitInDefaultParams(); - this.parseFunctionBody(node, false); - - this.inGenerator = oldInGen; - this.inAsync = oldInAsync; - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - this.inFunction = oldInFunc; - return this.finishNode(node, "FunctionExpression") -}; - -// Parse arrow function expression with given parameters. - -pp$3.parseArrowExpression = function(node, params, isAsync) { - var oldInGen = this.inGenerator, oldInAsync = this.inAsync, - oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; - - this.enterFunctionScope(); - this.initFunction(node); - if (this.options.ecmaVersion >= 8) - { node.async = !!isAsync; } - - this.inGenerator = false; - this.inAsync = node.async; - this.yieldPos = 0; - this.awaitPos = 0; - this.inFunction = true; - - node.params = this.toAssignableList(params, true); - this.parseFunctionBody(node, true); - - this.inGenerator = oldInGen; - this.inAsync = oldInAsync; - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - this.inFunction = oldInFunc; - return this.finishNode(node, "ArrowFunctionExpression") -}; - -// Parse function body and check parameters. - -pp$3.parseFunctionBody = function(node, isArrowFunction) { - var isExpression = isArrowFunction && this.type !== types.braceL; - var oldStrict = this.strict, useStrict = false; - - if (isExpression) { - node.body = this.parseMaybeAssign(); - node.expression = true; - this.checkParams(node, false); - } else { - var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); - if (!oldStrict || nonSimple) { - useStrict = this.strictDirective(this.end); - // If this is a strict mode function, verify that argument names - // are not repeated, and it does not try to bind the words `eval` - // or `arguments`. - if (useStrict && nonSimple) - { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } - } - // Start a new scope with regard to labels and the `inFunction` - // flag (restore them to their old value afterwards). - var oldLabels = this.labels; - this.labels = []; - if (useStrict) { this.strict = true; } - - // Add the params to varDeclaredNames to ensure that an error is thrown - // if a let/const declaration in the function clashes with one of the params. - this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params)); - node.body = this.parseBlock(false); - node.expression = false; - this.adaptDirectivePrologue(node.body.body); - this.labels = oldLabels; - } - this.exitFunctionScope(); - - if (this.strict && node.id) { - // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' - this.checkLVal(node.id, "none"); - } - this.strict = oldStrict; -}; - -pp$3.isSimpleParamList = function(params) { - for (var i = 0, list = params; i < list.length; i += 1) - { - var param = list[i]; - - if (param.type !== "Identifier") { return false - } } - return true -}; - -// Checks function params for various disallowed patterns such as using "eval" -// or "arguments" and duplicate parameters. - -pp$3.checkParams = function(node, allowDuplicates) { - var this$1 = this; - - var nameHash = {}; - for (var i = 0, list = node.params; i < list.length; i += 1) - { - var param = list[i]; - - this$1.checkLVal(param, "var", allowDuplicates ? null : nameHash); - } -}; - -// Parses a comma-separated list of expressions, and returns them as -// an array. `close` is the token type that ends the list, and -// `allowEmpty` can be turned on to allow subsequent commas with -// nothing in between them to be parsed as `null` (which is needed -// for array literals). - -pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { - var this$1 = this; - - var elts = [], first = true; - while (!this.eat(close)) { - if (!first) { - this$1.expect(types.comma); - if (allowTrailingComma && this$1.afterTrailingComma(close)) { break } - } else { first = false; } - - var elt = (void 0); - if (allowEmpty && this$1.type === types.comma) - { elt = null; } - else if (this$1.type === types.ellipsis) { - elt = this$1.parseSpread(refDestructuringErrors); - if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0) - { refDestructuringErrors.trailingComma = this$1.start; } - } else { - elt = this$1.parseMaybeAssign(false, refDestructuringErrors); - } - elts.push(elt); - } - return elts -}; - -pp$3.checkUnreserved = function(ref) { - var start = ref.start; - var end = ref.end; - var name = ref.name; - - if (this.inGenerator && name === "yield") - { this.raiseRecoverable(start, "Can not use 'yield' as identifier inside a generator"); } - if (this.inAsync && name === "await") - { this.raiseRecoverable(start, "Can not use 'await' as identifier inside an async function"); } - if (this.isKeyword(name)) - { this.raise(start, ("Unexpected keyword '" + name + "'")); } - if (this.options.ecmaVersion < 6 && - this.input.slice(start, end).indexOf("\\") != -1) { return } - var re = this.strict ? this.reservedWordsStrict : this.reservedWords; - if (re.test(name)) { - if (!this.inAsync && name === "await") - { this.raiseRecoverable(start, "Can not use keyword 'await' outside an async function"); } - this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); - } -}; - -// Parse the next token as an identifier. If `liberal` is true (used -// when parsing properties), it will also convert keywords into -// identifiers. - -pp$3.parseIdent = function(liberal, isBinding) { - var node = this.startNode(); - if (liberal && this.options.allowReserved == "never") { liberal = false; } - if (this.type === types.name) { - node.name = this.value; - } else if (this.type.keyword) { - node.name = this.type.keyword; - - // To fix https://github.com/acornjs/acorn/issues/575 - // `class` and `function` keywords push new context into this.context. - // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. - // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword - if ((node.name === "class" || node.name === "function") && - (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { - this.context.pop(); - } - } else { - this.unexpected(); - } - this.next(); - this.finishNode(node, "Identifier"); - if (!liberal) { this.checkUnreserved(node); } - return node -}; - -// Parses yield expression inside generator. - -pp$3.parseYield = function() { - if (!this.yieldPos) { this.yieldPos = this.start; } - - var node = this.startNode(); - this.next(); - if (this.type == types.semi || this.canInsertSemicolon() || (this.type != types.star && !this.type.startsExpr)) { - node.delegate = false; - node.argument = null; - } else { - node.delegate = this.eat(types.star); - node.argument = this.parseMaybeAssign(); - } - return this.finishNode(node, "YieldExpression") -}; - -pp$3.parseAwait = function() { - if (!this.awaitPos) { this.awaitPos = this.start; } - - var node = this.startNode(); - this.next(); - node.argument = this.parseMaybeUnary(null, true); - return this.finishNode(node, "AwaitExpression") -}; - -var pp$4 = Parser.prototype; - -// This function is used to raise exceptions on parse errors. It -// takes an offset integer (into the current `input`) to indicate -// the location of the error, attaches the position to the end -// of the error message, and then raises a `SyntaxError` with that -// message. - -pp$4.raise = function(pos, message) { - var loc = getLineInfo(this.input, pos); - message += " (" + loc.line + ":" + loc.column + ")"; - var err = new SyntaxError(message); - err.pos = pos; err.loc = loc; err.raisedAt = this.pos; - throw err -}; - -pp$4.raiseRecoverable = pp$4.raise; - -pp$4.curPosition = function() { - if (this.options.locations) { - return new Position(this.curLine, this.pos - this.lineStart) - } -}; - -var pp$5 = Parser.prototype; - -// Object.assign polyfill -var assign = Object.assign || function(target) { - var sources = [], len = arguments.length - 1; - while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ]; - - for (var i = 0, list = sources; i < list.length; i += 1) { - var source = list[i]; - - for (var key in source) { - if (has(source, key)) { - target[key] = source[key]; - } - } - } - return target -}; - -// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. - -pp$5.enterFunctionScope = function() { - // var: a hash of var-declared names in the current lexical scope - // lexical: a hash of lexically-declared names in the current lexical scope - // childVar: a hash of var-declared names in all child lexical scopes of the current lexical scope (within the current function scope) - // parentLexical: a hash of lexically-declared names in all parent lexical scopes of the current lexical scope (within the current function scope) - this.scopeStack.push({var: {}, lexical: {}, childVar: {}, parentLexical: {}}); -}; - -pp$5.exitFunctionScope = function() { - this.scopeStack.pop(); -}; - -pp$5.enterLexicalScope = function() { - var parentScope = this.scopeStack[this.scopeStack.length - 1]; - var childScope = {var: {}, lexical: {}, childVar: {}, parentLexical: {}}; - - this.scopeStack.push(childScope); - assign(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical); -}; - -pp$5.exitLexicalScope = function() { - var childScope = this.scopeStack.pop(); - var parentScope = this.scopeStack[this.scopeStack.length - 1]; - - assign(parentScope.childVar, childScope.var, childScope.childVar); -}; - -/** - * A name can be declared with `var` if there are no variables with the same name declared with `let`/`const` - * in the current lexical scope or any of the parent lexical scopes in this function. - */ -pp$5.canDeclareVarName = function(name) { - var currentScope = this.scopeStack[this.scopeStack.length - 1]; - - return !has(currentScope.lexical, name) && !has(currentScope.parentLexical, name) -}; - -/** - * A name can be declared with `let`/`const` if there are no variables with the same name declared with `let`/`const` - * in the current scope, and there are no variables with the same name declared with `var` in the current scope or in - * any child lexical scopes in this function. - */ -pp$5.canDeclareLexicalName = function(name) { - var currentScope = this.scopeStack[this.scopeStack.length - 1]; - - return !has(currentScope.lexical, name) && !has(currentScope.var, name) && !has(currentScope.childVar, name) -}; - -pp$5.declareVarName = function(name) { - this.scopeStack[this.scopeStack.length - 1].var[name] = true; -}; - -pp$5.declareLexicalName = function(name) { - this.scopeStack[this.scopeStack.length - 1].lexical[name] = true; -}; - -var Node = function Node(parser, pos, loc) { - this.type = ""; - this.start = pos; - this.end = 0; - if (parser.options.locations) - { this.loc = new SourceLocation(parser, loc); } - if (parser.options.directSourceFile) - { this.sourceFile = parser.options.directSourceFile; } - if (parser.options.ranges) - { this.range = [pos, 0]; } -}; - -// Start an AST node, attaching a start offset. - -var pp$6 = Parser.prototype; - -pp$6.startNode = function() { - return new Node(this, this.start, this.startLoc) -}; - -pp$6.startNodeAt = function(pos, loc) { - return new Node(this, pos, loc) -}; - -// Finish an AST node, adding `type` and `end` properties. - -function finishNodeAt(node, type, pos, loc) { - node.type = type; - node.end = pos; - if (this.options.locations) - { node.loc.end = loc; } - if (this.options.ranges) - { node.range[1] = pos; } - return node -} - -pp$6.finishNode = function(node, type) { - return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) -}; - -// Finish node at given position - -pp$6.finishNodeAt = function(node, type, pos, loc) { - return finishNodeAt.call(this, node, type, pos, loc) -}; - -// The algorithm used to determine whether a regexp can appear at a -// given point in the program is loosely based on sweet.js' approach. -// See https://github.com/mozilla/sweet.js/wiki/design - -var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { - this.token = token; - this.isExpr = !!isExpr; - this.preserveSpace = !!preserveSpace; - this.override = override; - this.generator = !!generator; -}; - -var types$1 = { - b_stat: new TokContext("{", false), - b_expr: new TokContext("{", true), - b_tmpl: new TokContext("${", false), - p_stat: new TokContext("(", false), - p_expr: new TokContext("(", true), - q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), - f_stat: new TokContext("function", false), - f_expr: new TokContext("function", true), - f_expr_gen: new TokContext("function", true, false, null, true), - f_gen: new TokContext("function", false, false, null, true) -}; - -var pp$7 = Parser.prototype; - -pp$7.initialContext = function() { - return [types$1.b_stat] -}; - -pp$7.braceIsBlock = function(prevType) { - var parent = this.curContext(); - if (parent === types$1.f_expr || parent === types$1.f_stat) - { return true } - if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr)) - { return !parent.isExpr } - - // The check for `tt.name && exprAllowed` detects whether we are - // after a `yield` or `of` construct. See the `updateContext` for - // `tt.name`. - if (prevType === types._return || prevType == types.name && this.exprAllowed) - { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } - if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType == types.arrow) - { return true } - if (prevType == types.braceL) - { return parent === types$1.b_stat } - if (prevType == types._var || prevType == types.name) - { return false } - return !this.exprAllowed -}; - -pp$7.inGeneratorContext = function() { - var this$1 = this; - - for (var i = this.context.length - 1; i >= 1; i--) { - var context = this$1.context[i]; - if (context.token === "function") - { return context.generator } - } - return false -}; - -pp$7.updateContext = function(prevType) { - var update, type = this.type; - if (type.keyword && prevType == types.dot) - { this.exprAllowed = false; } - else if (update = type.updateContext) - { update.call(this, prevType); } - else - { this.exprAllowed = type.beforeExpr; } -}; - -// Token-specific context update code - -types.parenR.updateContext = types.braceR.updateContext = function() { - if (this.context.length == 1) { - this.exprAllowed = true; - return - } - var out = this.context.pop(); - if (out === types$1.b_stat && this.curContext().token === "function") { - out = this.context.pop(); - } - this.exprAllowed = !out.isExpr; -}; - -types.braceL.updateContext = function(prevType) { - this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr); - this.exprAllowed = true; -}; - -types.dollarBraceL.updateContext = function() { - this.context.push(types$1.b_tmpl); - this.exprAllowed = true; -}; - -types.parenL.updateContext = function(prevType) { - var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while; - this.context.push(statementParens ? types$1.p_stat : types$1.p_expr); - this.exprAllowed = true; -}; - -types.incDec.updateContext = function() { - // tokExprAllowed stays unchanged -}; - -types._function.updateContext = types._class.updateContext = function(prevType) { - if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && - !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat)) - { this.context.push(types$1.f_expr); } - else - { this.context.push(types$1.f_stat); } - this.exprAllowed = false; -}; - -types.backQuote.updateContext = function() { - if (this.curContext() === types$1.q_tmpl) - { this.context.pop(); } - else - { this.context.push(types$1.q_tmpl); } - this.exprAllowed = false; -}; - -types.star.updateContext = function(prevType) { - if (prevType == types._function) { - var index = this.context.length - 1; - if (this.context[index] === types$1.f_expr) - { this.context[index] = types$1.f_expr_gen; } - else - { this.context[index] = types$1.f_gen; } - } - this.exprAllowed = true; -}; - -types.name.updateContext = function(prevType) { - var allowed = false; - if (this.options.ecmaVersion >= 6) { - if (this.value == "of" && !this.exprAllowed || - this.value == "yield" && this.inGeneratorContext()) - { allowed = true; } - } - this.exprAllowed = allowed; -}; +types.name.updateContext = function(prevType) { + var allowed = false; + if (this.options.ecmaVersion >= 6) { + if (this.value === "of" && !this.exprAllowed || + this.value === "yield" && this.inGeneratorContext()) + { allowed = true; } + } + this.exprAllowed = allowed; +}; var data = { "$LONE": [ @@ -20324,1861 +8842,13949 @@ var data = { "Zanb" ] }; -Array.prototype.push.apply(data.$LONE, data.General_Category); -data.gc = data.General_Category; -data.sc = data.Script_Extensions = data.scx = data.Script; +Array.prototype.push.apply(data.$LONE, data.General_Category); +data.gc = data.General_Category; +data.sc = data.Script_Extensions = data.scx = data.Script; + +var pp$9 = Parser.prototype; + +var RegExpValidationState = function RegExpValidationState(parser) { + this.parser = parser; + this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : ""); + this.source = ""; + this.flags = ""; + this.start = 0; + this.switchU = false; + this.switchN = false; + this.pos = 0; + this.lastIntValue = 0; + this.lastStringValue = ""; + this.lastAssertionIsQuantifiable = false; + this.numCapturingParens = 0; + this.maxBackReference = 0; + this.groupNames = []; + this.backReferenceNames = []; +}; + +RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { + var unicode = flags.indexOf("u") !== -1; + this.start = start | 0; + this.source = pattern + ""; + this.flags = flags; + this.switchU = unicode && this.parser.options.ecmaVersion >= 6; + this.switchN = unicode && this.parser.options.ecmaVersion >= 9; +}; + +RegExpValidationState.prototype.raise = function raise (message) { + this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message)); +}; + +// If u flag is given, this returns the code point at the index (it combines a surrogate pair). +// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). +RegExpValidationState.prototype.at = function at (i) { + var s = this.source; + var l = s.length; + if (i >= l) { + return -1 + } + var c = s.charCodeAt(i); + if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return c + } + return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00 +}; + +RegExpValidationState.prototype.nextIndex = function nextIndex (i) { + var s = this.source; + var l = s.length; + if (i >= l) { + return l + } + var c = s.charCodeAt(i); + if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return i + 1 + } + return i + 2 +}; + +RegExpValidationState.prototype.current = function current () { + return this.at(this.pos) +}; + +RegExpValidationState.prototype.lookahead = function lookahead () { + return this.at(this.nextIndex(this.pos)) +}; + +RegExpValidationState.prototype.advance = function advance () { + this.pos = this.nextIndex(this.pos); +}; + +RegExpValidationState.prototype.eat = function eat (ch) { + if (this.current() === ch) { + this.advance(); + return true + } + return false +}; + +function codePointToString$1(ch) { + if (ch <= 0xFFFF) { return String.fromCharCode(ch) } + ch -= 0x10000; + return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00) +} + +/** + * Validate the flags part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ +pp$9.validateRegExpFlags = function(state) { + var this$1 = this; + + var validFlags = state.validFlags; + var flags = state.flags; + + for (var i = 0; i < flags.length; i++) { + var flag = flags.charAt(i); + if (validFlags.indexOf(flag) === -1) { + this$1.raise(state.start, "Invalid regular expression flag"); + } + if (flags.indexOf(flag, i + 1) > -1) { + this$1.raise(state.start, "Duplicate regular expression flag"); + } + } +}; + +/** + * Validate the pattern part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ +pp$9.validateRegExpPattern = function(state) { + this.regexp_pattern(state); + + // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of + // parsing contains a |GroupName|, reparse with the goal symbol + // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* + // exception if _P_ did not conform to the grammar, if any elements of _P_ + // were not matched by the parse, or if any Early Error conditions exist. + if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { + state.switchN = true; + this.regexp_pattern(state); + } +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern +pp$9.regexp_pattern = function(state) { + state.pos = 0; + state.lastIntValue = 0; + state.lastStringValue = ""; + state.lastAssertionIsQuantifiable = false; + state.numCapturingParens = 0; + state.maxBackReference = 0; + state.groupNames.length = 0; + state.backReferenceNames.length = 0; + + this.regexp_disjunction(state); + + if (state.pos !== state.source.length) { + // Make the same messages as V8. + if (state.eat(0x29 /* ) */)) { + state.raise("Unmatched ')'"); + } + if (state.eat(0x5D /* [ */) || state.eat(0x7D /* } */)) { + state.raise("Lone quantifier brackets"); + } + } + if (state.maxBackReference > state.numCapturingParens) { + state.raise("Invalid escape"); + } + for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { + var name = list[i]; + + if (state.groupNames.indexOf(name) === -1) { + state.raise("Invalid named capture referenced"); + } + } +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction +pp$9.regexp_disjunction = function(state) { + var this$1 = this; + + this.regexp_alternative(state); + while (state.eat(0x7C /* | */)) { + this$1.regexp_alternative(state); + } + + // Make the same message as V8. + if (this.regexp_eatQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + if (state.eat(0x7B /* { */)) { + state.raise("Lone quantifier brackets"); + } +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative +pp$9.regexp_alternative = function(state) { + while (state.pos < state.source.length && this.regexp_eatTerm(state)) + { } +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term +pp$9.regexp_eatTerm = function(state) { + if (this.regexp_eatAssertion(state)) { + // Handle `QuantifiableAssertion Quantifier` alternative. + // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion + // is a QuantifiableAssertion. + if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { + // Make the same message as V8. + if (state.switchU) { + state.raise("Invalid quantifier"); + } + } + return true + } + + if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { + this.regexp_eatQuantifier(state); + return true + } + + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion +pp$9.regexp_eatAssertion = function(state) { + var start = state.pos; + state.lastAssertionIsQuantifiable = false; + + // ^, $ + if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) { + return true + } + + // \b \B + if (state.eat(0x5C /* \ */)) { + if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) { + return true + } + state.pos = start; + } + + // Lookahead / Lookbehind + if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) { + var lookbehind = false; + if (this.options.ecmaVersion >= 9) { + lookbehind = state.eat(0x3C /* < */); + } + if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) { + this.regexp_disjunction(state); + if (!state.eat(0x29 /* ) */)) { + state.raise("Unterminated group"); + } + state.lastAssertionIsQuantifiable = !lookbehind; + return true + } + } + + state.pos = start; + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier +pp$9.regexp_eatQuantifier = function(state, noError) { + if ( noError === void 0 ) noError = false; + + if (this.regexp_eatQuantifierPrefix(state, noError)) { + state.eat(0x3F /* ? */); + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix +pp$9.regexp_eatQuantifierPrefix = function(state, noError) { + return ( + state.eat(0x2A /* * */) || + state.eat(0x2B /* + */) || + state.eat(0x3F /* ? */) || + this.regexp_eatBracedQuantifier(state, noError) + ) +}; +pp$9.regexp_eatBracedQuantifier = function(state, noError) { + var start = state.pos; + if (state.eat(0x7B /* { */)) { + var min = 0, max = -1; + if (this.regexp_eatDecimalDigits(state)) { + min = state.lastIntValue; + if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) { + max = state.lastIntValue; + } + if (state.eat(0x7D /* } */)) { + // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term + if (max !== -1 && max < min && !noError) { + state.raise("numbers out of order in {} quantifier"); + } + return true + } + } + if (state.switchU && !noError) { + state.raise("Incomplete quantifier"); + } + state.pos = start; + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom +pp$9.regexp_eatAtom = function(state) { + return ( + this.regexp_eatPatternCharacters(state) || + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) + ) +}; +pp$9.regexp_eatReverseSolidusAtomEscape = function(state) { + var start = state.pos; + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatAtomEscape(state)) { + return true + } + state.pos = start; + } + return false +}; +pp$9.regexp_eatUncapturingGroup = function(state) { + var start = state.pos; + if (state.eat(0x28 /* ( */)) { + if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) { + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + return true + } + state.raise("Unterminated group"); + } + state.pos = start; + } + return false +}; +pp$9.regexp_eatCapturingGroup = function(state) { + if (state.eat(0x28 /* ( */)) { + if (this.options.ecmaVersion >= 9) { + this.regexp_groupSpecifier(state); + } else if (state.current() === 0x3F /* ? */) { + state.raise("Invalid group"); + } + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + state.numCapturingParens += 1; + return true + } + state.raise("Unterminated group"); + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom +pp$9.regexp_eatExtendedAtom = function(state) { + return ( + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) || + this.regexp_eatInvalidBracedQuantifier(state) || + this.regexp_eatExtendedPatternCharacter(state) + ) +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier +pp$9.regexp_eatInvalidBracedQuantifier = function(state) { + if (this.regexp_eatBracedQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter +pp$9.regexp_eatSyntaxCharacter = function(state) { + var ch = state.current(); + if (isSyntaxCharacter(ch)) { + state.lastIntValue = ch; + state.advance(); + return true + } + return false +}; +function isSyntaxCharacter(ch) { + return ( + ch === 0x24 /* $ */ || + ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ || + ch === 0x2E /* . */ || + ch === 0x3F /* ? */ || + ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ || + ch >= 0x7B /* { */ && ch <= 0x7D /* } */ + ) +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter +// But eat eager. +pp$9.regexp_eatPatternCharacters = function(state) { + var start = state.pos; + var ch = 0; + while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { + state.advance(); + } + return state.pos !== start +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter +pp$9.regexp_eatExtendedPatternCharacter = function(state) { + var ch = state.current(); + if ( + ch !== -1 && + ch !== 0x24 /* $ */ && + !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) && + ch !== 0x2E /* . */ && + ch !== 0x3F /* ? */ && + ch !== 0x5B /* [ */ && + ch !== 0x5E /* ^ */ && + ch !== 0x7C /* | */ + ) { + state.advance(); + return true + } + return false +}; + +// GroupSpecifier[U] :: +// [empty] +// `?` GroupName[?U] +pp$9.regexp_groupSpecifier = function(state) { + if (state.eat(0x3F /* ? */)) { + if (this.regexp_eatGroupName(state)) { + if (state.groupNames.indexOf(state.lastStringValue) !== -1) { + state.raise("Duplicate capture group name"); + } + state.groupNames.push(state.lastStringValue); + return + } + state.raise("Invalid group"); + } +}; + +// GroupName[U] :: +// `<` RegExpIdentifierName[?U] `>` +// Note: this updates `state.lastStringValue` property with the eaten name. +pp$9.regexp_eatGroupName = function(state) { + state.lastStringValue = ""; + if (state.eat(0x3C /* < */)) { + if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) { + return true + } + state.raise("Invalid capture group name"); + } + return false +}; + +// RegExpIdentifierName[U] :: +// RegExpIdentifierStart[?U] +// RegExpIdentifierName[?U] RegExpIdentifierPart[?U] +// Note: this updates `state.lastStringValue` property with the eaten name. +pp$9.regexp_eatRegExpIdentifierName = function(state) { + state.lastStringValue = ""; + if (this.regexp_eatRegExpIdentifierStart(state)) { + state.lastStringValue += codePointToString$1(state.lastIntValue); + while (this.regexp_eatRegExpIdentifierPart(state)) { + state.lastStringValue += codePointToString$1(state.lastIntValue); + } + return true + } + return false +}; + +// RegExpIdentifierStart[U] :: +// UnicodeIDStart +// `$` +// `_` +// `\` RegExpUnicodeEscapeSequence[?U] +pp$9.regexp_eatRegExpIdentifierStart = function(state) { + var start = state.pos; + var ch = state.current(); + state.advance(); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierStart(ch)) { + state.lastIntValue = ch; + return true + } + + state.pos = start; + return false +}; +function isRegExpIdentifierStart(ch) { + return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ +} + +// RegExpIdentifierPart[U] :: +// UnicodeIDContinue +// `$` +// `_` +// `\` RegExpUnicodeEscapeSequence[?U] +// +// +pp$9.regexp_eatRegExpIdentifierPart = function(state) { + var start = state.pos; + var ch = state.current(); + state.advance(); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierPart(ch)) { + state.lastIntValue = ch; + return true + } + + state.pos = start; + return false +}; +function isRegExpIdentifierPart(ch) { + return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D /* */ +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape +pp$9.regexp_eatAtomEscape = function(state) { + if ( + this.regexp_eatBackReference(state) || + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) || + (state.switchN && this.regexp_eatKGroupName(state)) + ) { + return true + } + if (state.switchU) { + // Make the same message as V8. + if (state.current() === 0x63 /* c */) { + state.raise("Invalid unicode escape"); + } + state.raise("Invalid escape"); + } + return false +}; +pp$9.regexp_eatBackReference = function(state) { + var start = state.pos; + if (this.regexp_eatDecimalEscape(state)) { + var n = state.lastIntValue; + if (state.switchU) { + // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape + if (n > state.maxBackReference) { + state.maxBackReference = n; + } + return true + } + if (n <= state.numCapturingParens) { + return true + } + state.pos = start; + } + return false +}; +pp$9.regexp_eatKGroupName = function(state) { + if (state.eat(0x6B /* k */)) { + if (this.regexp_eatGroupName(state)) { + state.backReferenceNames.push(state.lastStringValue); + return true + } + state.raise("Invalid named reference"); + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape +pp$9.regexp_eatCharacterEscape = function(state) { + return ( + this.regexp_eatControlEscape(state) || + this.regexp_eatCControlLetter(state) || + this.regexp_eatZero(state) || + this.regexp_eatHexEscapeSequence(state) || + this.regexp_eatRegExpUnicodeEscapeSequence(state) || + (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || + this.regexp_eatIdentityEscape(state) + ) +}; +pp$9.regexp_eatCControlLetter = function(state) { + var start = state.pos; + if (state.eat(0x63 /* c */)) { + if (this.regexp_eatControlLetter(state)) { + return true + } + state.pos = start; + } + return false +}; +pp$9.regexp_eatZero = function(state) { + if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) { + state.lastIntValue = 0; + state.advance(); + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape +pp$9.regexp_eatControlEscape = function(state) { + var ch = state.current(); + if (ch === 0x74 /* t */) { + state.lastIntValue = 0x09; /* \t */ + state.advance(); + return true + } + if (ch === 0x6E /* n */) { + state.lastIntValue = 0x0A; /* \n */ + state.advance(); + return true + } + if (ch === 0x76 /* v */) { + state.lastIntValue = 0x0B; /* \v */ + state.advance(); + return true + } + if (ch === 0x66 /* f */) { + state.lastIntValue = 0x0C; /* \f */ + state.advance(); + return true + } + if (ch === 0x72 /* r */) { + state.lastIntValue = 0x0D; /* \r */ + state.advance(); + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter +pp$9.regexp_eatControlLetter = function(state) { + var ch = state.current(); + if (isControlLetter(ch)) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false +}; +function isControlLetter(ch) { + return ( + (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) || + (ch >= 0x61 /* a */ && ch <= 0x7A /* z */) + ) +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence +pp$9.regexp_eatRegExpUnicodeEscapeSequence = function(state) { + var start = state.pos; + + if (state.eat(0x75 /* u */)) { + if (this.regexp_eatFixedHexDigits(state, 4)) { + var lead = state.lastIntValue; + if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) { + var leadSurrogateEnd = state.pos; + if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) { + var trail = state.lastIntValue; + if (trail >= 0xDC00 && trail <= 0xDFFF) { + state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; + return true + } + } + state.pos = leadSurrogateEnd; + state.lastIntValue = lead; + } + return true + } + if ( + state.switchU && + state.eat(0x7B /* { */) && + this.regexp_eatHexDigits(state) && + state.eat(0x7D /* } */) && + isValidUnicode(state.lastIntValue) + ) { + return true + } + if (state.switchU) { + state.raise("Invalid unicode escape"); + } + state.pos = start; + } + + return false +}; +function isValidUnicode(ch) { + return ch >= 0 && ch <= 0x10FFFF +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape +pp$9.regexp_eatIdentityEscape = function(state) { + if (state.switchU) { + if (this.regexp_eatSyntaxCharacter(state)) { + return true + } + if (state.eat(0x2F /* / */)) { + state.lastIntValue = 0x2F; /* / */ + return true + } + return false + } + + var ch = state.current(); + if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape +pp$9.regexp_eatDecimalEscape = function(state) { + state.lastIntValue = 0; + var ch = state.current(); + if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) { + do { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape +pp$9.regexp_eatCharacterClassEscape = function(state) { + var ch = state.current(); + + if (isCharacterClassEscape(ch)) { + state.lastIntValue = -1; + state.advance(); + return true + } + + if ( + state.switchU && + this.options.ecmaVersion >= 9 && + (ch === 0x50 /* P */ || ch === 0x70 /* p */) + ) { + state.lastIntValue = -1; + state.advance(); + if ( + state.eat(0x7B /* { */) && + this.regexp_eatUnicodePropertyValueExpression(state) && + state.eat(0x7D /* } */) + ) { + return true + } + state.raise("Invalid property name"); + } + + return false +}; +function isCharacterClassEscape(ch) { + return ( + ch === 0x64 /* d */ || + ch === 0x44 /* D */ || + ch === 0x73 /* s */ || + ch === 0x53 /* S */ || + ch === 0x77 /* w */ || + ch === 0x57 /* W */ + ) +} + +// UnicodePropertyValueExpression :: +// UnicodePropertyName `=` UnicodePropertyValue +// LoneUnicodePropertyNameOrValue +pp$9.regexp_eatUnicodePropertyValueExpression = function(state) { + var start = state.pos; + + // UnicodePropertyName `=` UnicodePropertyValue + if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) { + var name = state.lastStringValue; + if (this.regexp_eatUnicodePropertyValue(state)) { + var value = state.lastStringValue; + this.regexp_validateUnicodePropertyNameAndValue(state, name, value); + return true + } + } + state.pos = start; + + // LoneUnicodePropertyNameOrValue + if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { + var nameOrValue = state.lastStringValue; + this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue); + return true + } + return false +}; +pp$9.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { + if (!data.hasOwnProperty(name) || data[name].indexOf(value) === -1) { + state.raise("Invalid property name"); + } +}; +pp$9.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { + if (data.$LONE.indexOf(nameOrValue) === -1) { + state.raise("Invalid property name"); + } +}; + +// UnicodePropertyName :: +// UnicodePropertyNameCharacters +pp$9.regexp_eatUnicodePropertyName = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyNameCharacter(ch = state.current())) { + state.lastStringValue += codePointToString$1(ch); + state.advance(); + } + return state.lastStringValue !== "" +}; +function isUnicodePropertyNameCharacter(ch) { + return isControlLetter(ch) || ch === 0x5F /* _ */ +} + +// UnicodePropertyValue :: +// UnicodePropertyValueCharacters +pp$9.regexp_eatUnicodePropertyValue = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyValueCharacter(ch = state.current())) { + state.lastStringValue += codePointToString$1(ch); + state.advance(); + } + return state.lastStringValue !== "" +}; +function isUnicodePropertyValueCharacter(ch) { + return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) +} + +// LoneUnicodePropertyNameOrValue :: +// UnicodePropertyValueCharacters +pp$9.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { + return this.regexp_eatUnicodePropertyValue(state) +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass +pp$9.regexp_eatCharacterClass = function(state) { + if (state.eat(0x5B /* [ */)) { + state.eat(0x5E /* ^ */); + this.regexp_classRanges(state); + if (state.eat(0x5D /* [ */)) { + return true + } + // Unreachable since it threw "unterminated regular expression" error before. + state.raise("Unterminated character class"); + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges +// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges +// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash +pp$9.regexp_classRanges = function(state) { + var this$1 = this; + + while (this.regexp_eatClassAtom(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D /* - */) && this$1.regexp_eatClassAtom(state)) { + var right = state.lastIntValue; + if (state.switchU && (left === -1 || right === -1)) { + state.raise("Invalid character class"); + } + if (left !== -1 && right !== -1 && left > right) { + state.raise("Range out of order in character class"); + } + } + } +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom +// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash +pp$9.regexp_eatClassAtom = function(state) { + var start = state.pos; + + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatClassEscape(state)) { + return true + } + if (state.switchU) { + // Make the same message as V8. + var ch$1 = state.current(); + if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) { + state.raise("Invalid class escape"); + } + state.raise("Invalid escape"); + } + state.pos = start; + } + + var ch = state.current(); + if (ch !== 0x5D /* [ */) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape +pp$9.regexp_eatClassEscape = function(state) { + var start = state.pos; + + if (state.eat(0x62 /* b */)) { + state.lastIntValue = 0x08; /* */ + return true + } + + if (state.switchU && state.eat(0x2D /* - */)) { + state.lastIntValue = 0x2D; /* - */ + return true + } + + if (!state.switchU && state.eat(0x63 /* c */)) { + if (this.regexp_eatClassControlLetter(state)) { + return true + } + state.pos = start; + } + + return ( + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) + ) +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter +pp$9.regexp_eatClassControlLetter = function(state) { + var ch = state.current(); + if (isDecimalDigit(ch) || ch === 0x5F /* _ */) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence +pp$9.regexp_eatHexEscapeSequence = function(state) { + var start = state.pos; + if (state.eat(0x78 /* x */)) { + if (this.regexp_eatFixedHexDigits(state, 2)) { + return true + } + if (state.switchU) { + state.raise("Invalid escape"); + } + state.pos = start; + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits +pp$9.regexp_eatDecimalDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isDecimalDigit(ch = state.current())) { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } + return state.pos !== start +}; +function isDecimalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */ +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits +pp$9.regexp_eatHexDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isHexDigit(ch = state.current())) { + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return state.pos !== start +}; +function isHexDigit(ch) { + return ( + (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) || + (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) || + (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) + ) +} +function hexToInt(ch) { + if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) { + return 10 + (ch - 0x41 /* A */) + } + if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) { + return 10 + (ch - 0x61 /* a */) + } + return ch - 0x30 /* 0 */ +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence +// Allows only 0-377(octal) i.e. 0-255(decimal). +pp$9.regexp_eatLegacyOctalEscapeSequence = function(state) { + if (this.regexp_eatOctalDigit(state)) { + var n1 = state.lastIntValue; + if (this.regexp_eatOctalDigit(state)) { + var n2 = state.lastIntValue; + if (n1 <= 3 && this.regexp_eatOctalDigit(state)) { + state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue; + } else { + state.lastIntValue = n1 * 8 + n2; + } + } else { + state.lastIntValue = n1; + } + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit +pp$9.regexp_eatOctalDigit = function(state) { + var ch = state.current(); + if (isOctalDigit(ch)) { + state.lastIntValue = ch - 0x30; /* 0 */ + state.advance(); + return true + } + state.lastIntValue = 0; + return false +}; +function isOctalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */ +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits +// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit +// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence +pp$9.regexp_eatFixedHexDigits = function(state, length) { + var start = state.pos; + state.lastIntValue = 0; + for (var i = 0; i < length; ++i) { + var ch = state.current(); + if (!isHexDigit(ch)) { + state.pos = start; + return false + } + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return true +}; + +// Object type used to represent tokens. Note that normally, tokens +// simply exist as properties on the parser object. This is only +// used for the onToken callback and the external tokenizer. + +var Token = function Token(p) { + this.type = p.type; + this.value = p.value; + this.start = p.start; + this.end = p.end; + if (p.options.locations) + { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); } + if (p.options.ranges) + { this.range = [p.start, p.end]; } +}; + +// ## Tokenizer + +var pp$8 = Parser.prototype; + +// Move to the next token + +pp$8.next = function() { + if (this.options.onToken) + { this.options.onToken(new Token(this)); } + + this.lastTokEnd = this.end; + this.lastTokStart = this.start; + this.lastTokEndLoc = this.endLoc; + this.lastTokStartLoc = this.startLoc; + this.nextToken(); +}; + +pp$8.getToken = function() { + this.next(); + return new Token(this) +}; + +// If we're in an ES6 environment, make parsers iterable +if (typeof Symbol !== "undefined") + { pp$8[Symbol.iterator] = function() { + var this$1 = this; + + return { + next: function () { + var token = this$1.getToken(); + return { + done: token.type === types.eof, + value: token + } + } + } + }; } + +// Toggle strict mode. Re-reads the next number or string to please +// pedantic tests (`"use strict"; 010;` should fail). + +pp$8.curContext = function() { + return this.context[this.context.length - 1] +}; + +// Read a single token, updating the parser object's token-related +// properties. + +pp$8.nextToken = function() { + var curContext = this.curContext(); + if (!curContext || !curContext.preserveSpace) { this.skipSpace(); } + + this.start = this.pos; + if (this.options.locations) { this.startLoc = this.curPosition(); } + if (this.pos >= this.input.length) { return this.finishToken(types.eof) } + + if (curContext.override) { return curContext.override(this) } + else { this.readToken(this.fullCharCodeAtPos()); } +}; + +pp$8.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + { return this.readWord() } + + return this.getTokenFromCode(code) +}; + +pp$8.fullCharCodeAtPos = function() { + var code = this.input.charCodeAt(this.pos); + if (code <= 0xd7ff || code >= 0xe000) { return code } + var next = this.input.charCodeAt(this.pos + 1); + return (code << 10) + next - 0x35fdc00 +}; + +pp$8.skipBlockComment = function() { + var this$1 = this; + + var startLoc = this.options.onComment && this.curPosition(); + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2); + if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); } + this.pos = end + 2; + if (this.options.locations) { + lineBreakG.lastIndex = start; + var match; + while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { + ++this$1.curLine; + this$1.lineStart = match.index + match[0].length; + } + } + if (this.options.onComment) + { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()); } +}; + +pp$8.skipLineComment = function(startSkip) { + var this$1 = this; + + var start = this.pos; + var startLoc = this.options.onComment && this.curPosition(); + var ch = this.input.charCodeAt(this.pos += startSkip); + while (this.pos < this.input.length && !isNewLine(ch)) { + ch = this$1.input.charCodeAt(++this$1.pos); + } + if (this.options.onComment) + { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()); } +}; + +// Called at the start of the parse and after every token. Skips +// whitespace and comments, and. + +pp$8.skipSpace = function() { + var this$1 = this; + + loop: while (this.pos < this.input.length) { + var ch = this$1.input.charCodeAt(this$1.pos); + switch (ch) { + case 32: case 160: // ' ' + ++this$1.pos; + break + case 13: + if (this$1.input.charCodeAt(this$1.pos + 1) === 10) { + ++this$1.pos; + } + case 10: case 8232: case 8233: + ++this$1.pos; + if (this$1.options.locations) { + ++this$1.curLine; + this$1.lineStart = this$1.pos; + } + break + case 47: // '/' + switch (this$1.input.charCodeAt(this$1.pos + 1)) { + case 42: // '*' + this$1.skipBlockComment(); + break + case 47: + this$1.skipLineComment(2); + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this$1.pos; + } else { + break loop + } + } + } +}; + +// Called at the end of every token. Sets `end`, `val`, and +// maintains `context` and `exprAllowed`, and skips the space after +// the token, so that the next one's `start` will point at the +// right position. + +pp$8.finishToken = function(type, val) { + this.end = this.pos; + if (this.options.locations) { this.endLoc = this.curPosition(); } + var prevType = this.type; + this.type = type; + this.value = val; + + this.updateContext(prevType); +}; + +// ### Token reading + +// This is the function that is called to fetch the next token. It +// is somewhat obscure, because it works in character codes rather +// than characters, and because operator parsing has been inlined +// into it. +// +// All in the name of speed. +// +pp$8.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1); + if (next >= 48 && next <= 57) { return this.readNumber(true) } + var next2 = this.input.charCodeAt(this.pos + 2); + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3; + return this.finishToken(types.ellipsis) + } else { + ++this.pos; + return this.finishToken(types.dot) + } +}; + +pp$8.readToken_slash = function() { // '/' + var next = this.input.charCodeAt(this.pos + 1); + if (this.exprAllowed) { ++this.pos; return this.readRegexp() } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.slash, 1) +}; + +pp$8.readToken_mult_modulo_exp = function(code) { // '%*' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + var tokentype = code === 42 ? types.star : types.modulo; + + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) { + ++size; + tokentype = types.starstar; + next = this.input.charCodeAt(this.pos + 2); + } + + if (next === 61) { return this.finishOp(types.assign, size + 1) } + return this.finishOp(tokentype, size) +}; + +pp$8.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1) +}; + +pp$8.readToken_caret = function() { // '^' + var next = this.input.charCodeAt(this.pos + 1); + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.bitwiseXOR, 1) +}; + +pp$8.readToken_plus_min = function(code) { // '+-' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && + (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { + // A `-->` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types.incDec, 2) + } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.plusMin, 1) +}; + +pp$8.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) } + return this.finishOp(types.bitShift, size) + } + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + // `` line comment - this.skipLineComment(3); - this.skipSpace(); - return this.nextToken() - } - return this.finishOp(types.incDec, 2) - } - if (next === 61) { return this.finishOp(types.assign, 2) } - return this.finishOp(types.plusMin, 1) -}; + return _possibleConstructorReturn(this, (Utils.__proto__ || Object.getPrototypeOf(Utils)).apply(this, arguments)); + } -pp$8.readToken_lt_gt = function(code) { // '<>' - var next = this.input.charCodeAt(this.pos + 1); - var size = 1; - if (next === code) { - size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; - if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) } - return this.finishOp(types.bitShift, size) - } - if (next == 33 && code == 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) == 45 && - this.input.charCodeAt(this.pos + 3) == 45) { - // `