summaryrefslogtreecommitdiffstats
path: root/third_party/webkit/PerformanceTests/ARES-6
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/webkit/PerformanceTests/ARES-6
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/webkit/PerformanceTests/ARES-6')
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/ARES-6.svg4
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/README.md152
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/airjs-tests.yaml28
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/all.js18
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/allocate_stack.js252
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/arg.js1064
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/basic_block.js135
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/benchmark.js85
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/code.js122
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/custom.js103
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/frequented_block.js38
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/insertion_set.js89
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/inst.js143
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/liveness.js152
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/make_dist.sh39
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/opcode.js1655
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/payload-airjs-ACLj8C.js1730
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/payload-gbemu-executeIteration.js3229
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/payload-imaging-gaussian-blur-gaussianBlur.js3107
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/payload-typescript-scanIdentifier.js1878
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/reg.js140
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/stack_slot.js102
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/stress-test.js52
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/strip-hash.rb10
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/symbols.js162
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/test.html45
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/test.js35
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/tmp.js66
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/tmp_base.js55
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Air/util.js179
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Babylon/AUTHORS41
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Babylon/air-blob.js140
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Babylon/babylon-blob.js95
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Babylon/basic-blob.js273
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Babylon/benchmark.js114
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Babylon/index.js6942
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Babylon/inspector-blob.js1146
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/ast.js273
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/basic-tests.yaml28
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/basic.js53
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/benchmark.js65
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/caseless_map.js56
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/lexer.js97
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/number.js137
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/parser.js558
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/random.js54
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/state.js98
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/stress-test.js54
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/test.html34
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/test.js16
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/Basic/util.js34
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/about.html48
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/air_benchmark.js105
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/babylon_benchmark.js68
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/basic_benchmark.js84
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/cli.js87
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/driver.js255
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/glue.js58
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/index.html155
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/ml/benchmark.js171
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/ml/index.js6330
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/ml_benchmark.js68
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/results.js77
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/stats.js122
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/styles.css337
-rw-r--r--third_party/webkit/PerformanceTests/ARES-6/swoop.svg3
66 files changed, 33145 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/ARES-6/ARES-6.svg b/third_party/webkit/PerformanceTests/ARES-6/ARES-6.svg
new file mode 100644
index 0000000000..f3a8296f28
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/ARES-6.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 335 74">
+ <title>ARES-6</title>
+ <path fill="#9B9B9B" d="M 12.837 13.785 C 6.052 13.785 0.59 19.247 0.59 26.032 L 0.59 73.366 L 13.416 73.366 L 13.416 54.168 L 47.179 54.168 L 47.179 73.366 L 60.171 73.366 L 60.171 26.032 C 60.171 19.247 54.627 13.785 47.841 13.785 L 12.837 13.785 Z M 13.416 41.259 L 13.416 26.694 L 47.179 26.694 L 47.179 41.259 L 13.416 41.259 Z M 124.854 26.115 C 124.854 19.412 119.309 13.868 112.524 13.868 L 65.273 13.868 L 65.273 73.366 L 78.099 73.366 L 78.099 54.251 C 78.182 54.333 78.347 54.333 78.347 54.333 C 78.347 54.002 78.265 53.837 78.099 53.837 L 95.146 53.754 L 111.613 73.366 L 124.854 73.366 L 124.854 68.98 C 120.716 64.015 116.165 58.719 111.944 53.754 L 112.524 53.754 C 119.309 53.754 124.854 48.21 124.854 41.507 L 124.854 26.115 Z M 78.099 26.694 L 111.862 26.694 L 111.862 40.845 L 78.099 40.845 L 78.099 26.694 Z"/><path fill="#E7B135" d="M 313.955 73.053 C 317.167 71.389 319.353 68.037 319.353 64.158 L 319.353 49.842 C 319.353 44.215 314.885 39.83 309.34 39.83 L 269.206 39.83 C 267.468 39.83 265.979 38.34 265.979 36.519 L 265.979 24.603 C 265.979 22.865 267.468 21.376 269.206 21.376 L 308.927 21.376 L 308.927 14.508 L 269.206 14.508 C 263.579 14.508 259.193 18.976 259.193 24.603 L 259.193 64.158 C 259.193 68.037 261.339 71.389 264.555 73.053 L 234.069 73.053 C 239.473 71.802 243.566 66.949 243.566 61.119 L 243.566 49.368 C 243.566 42.583 238.022 37.121 231.319 37.121 L 196.812 37.121 L 196.812 26.694 L 230.574 26.694 L 230.574 31.577 L 243.566 31.577 L 243.566 26.032 C 243.566 19.247 238.022 13.785 231.319 13.785 L 196.232 13.785 C 189.447 13.785 183.985 19.247 183.985 26.032 L 183.985 37.783 C 183.985 44.569 189.447 50.03 196.232 50.03 L 230.574 50.03 L 230.574 60.457 L 196.812 60.457 L 196.812 55.575 L 183.985 55.575 L 183.985 61.119 C 183.985 66.949 188.017 71.802 193.457 73.053 L 179.747 73.053 L 179.747 60.457 L 137.709 60.457 L 137.709 50.03 L 171.555 50.03 L 171.555 37.121 L 137.709 37.121 L 137.709 26.694 L 179.747 26.694 L 179.747 13.785 L 124.717 13.785 L 124.717 43.419 L 124.717 0.366 L 334.951 0.366 L 334.951 73.053 L 313.955 73.053 Z M 247.722 40.547 L 247.722 47.333 L 254.507 47.333 L 254.507 40.547 L 247.722 40.547 Z M 312.568 64.158 C 312.568 65.896 311.078 67.386 309.34 67.386 L 269.206 67.386 C 267.468 67.386 265.979 65.896 265.979 64.158 L 265.979 46.615 L 309.34 46.615 C 311.078 46.615 312.568 48.105 312.568 49.842 L 312.568 64.158 Z"/>
+</svg>
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/README.md b/third_party/webkit/PerformanceTests/ARES-6/Air/README.md
new file mode 100644
index 0000000000..9e45b6c580
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/README.md
@@ -0,0 +1,152 @@
+# All about Air.js
+
+Air.js is an ES6 benchmark. It tries to faithfully use new features like arrow
+functions, classes, for-of, and Map/Set, among others. Air.js doesn't avoid any
+features out of fear that they might be slow, in the hope that we might learn
+how to make those features fast by looking at how Air.js and other benchmarks
+use them.
+
+This documents the motivation, design, and license of Air.js.
+
+To run Air.js, simply open "[Air.js/test.html](test.html)" in your browser. It
+will only run correctly if your browser supports ES6.
+
+## Motivation
+
+At the time that Air.js was written, most JavaScript benchmarks used ES5 or
+older versions of the language. ES6 testing mostly relied on microbenchmarks or
+conversions of existing tests to ES6. We try to use larger benchmarks to avoid
+over-optimizing for small pieces of code, and we avoid making changes to
+existing benchmarks because that approach has no limiting principle: if it's OK
+to change a benchmark to use a feature, does that mean we can also change it to
+remove the use of a feature we don't like? We feel that the best way to avoid
+falling into the trap of creating benchmarks that reinforce what some JS engine
+is already good at is to create a new benchmark from first principles.
+
+We only recently completed our new JavaScript compiler, called
+[B3](https://webkit.org/blog/5852/introducing-the-b3-jit-compiler/). B3's
+backend, called
+[Air](https://webkit.org/docs/b3/assembly-intermediate-representation.html), is
+very CPU-intensive and uses a combination of object-oriented and functional
+idioms in C++. Additionally, it relies heavily on high speed maps and sets. It
+goes so far as to use customized map/set implementations - even more so than
+the rest of WebKit. This makes Air a great candidate for ES6 benchmarking.
+Air.js is a faithful ES6 implementation of Air. It pulls no punches: just as
+the original C++ Air was written with expressiveness as a top priority, Air.js
+is liberal in its use of modern ES6 idioms whenever this helps make the code
+more readable. Unlike the original C++ Air, Air.js doesn't exploit a deep
+understanding of compilers to make the code easy to compile.
+
+## Design
+
+Air.js runs one of the more expensive Air phases, Air::allocateStack(). This
+turns abstract stack references into concrete stack references, by selecting
+how to lay out stack slots in the stack frame. This requires liveness analysis
+and an interference graph.
+
+Air.js relies on three major ES6 features more so than most of the others:
+
+- Arrow functions. Like the C++ Air, Air.js uses a functional style of
+ iterating most non-trivial data-structures:
+
+ inst.forEachArg((arg, role, type, width) => ...)
+
+ This is because the functional style allows the callbacks to mutate the data
+ being iterated: if the callback returns a non-null value, forEachArg() will
+ replace the argument with that value. This would not have been possible with
+ for-of.
+
+- For-of. Many Air data structures are amenable to for-of iteration. While the
+ innermost loops tend to use functional iteration, pretty much all of the
+ outer logic uses for-of heavily. For example:
+
+ for (let block of code) // Iterate over the basic blocks
+ for (let inst of block) // Iterate over the instructions in a block
+ ...
+
+- Map/Set. The liveness analysis and Air::allocateStack() rely on maps and
+ sets. For example, we use a liveAtHead map that is keyed by basic block. Its
+ values are sets of live stack slots. This is a relatively crude way of doing
+ liveness, but it is exactly how the original Air::LivenessAnalysis worked, so
+ we view it as being quite faithful to how a sensible programmer might use Map
+ and Set.
+
+Air.js also uses some other ES6 features. For example, it uses a Proxy
+in one place, though we doubt that it's on a critical path. Air.js uses classes
+and let/const extensively, as well a symbols. Symbols are used as enumeration
+elements, and so they frequently show up as cases in switch statements.
+
+The workflow of an Air.js run is pretty simple: we do 150 runs of allocateStack
+on four IR payloads.
+
+Each IR payload is a large piece of ES6 code that constructs an Air.js Code
+object, complete with blocks, temporaries, stack slots, and instructions. These
+payloads are generated by running Air::dumpAsJS() phase just prior to the
+native allocateStack phase on the largest hot function in four major JS
+benchmarks according to JavaScriptCore's internal profiling:
+
+- Octane/GBEmu, the executeIteration function.
+- Kraken/imaging-gaussian-blur, the gaussianBlur function.
+- Octane/Typescript, the scanIdentifier function,
+- Air.js, an anonymous closure identified by our profiler as ACLj8C.
+
+These payloads allow Air.js to precisely replay allocateStack on those actual
+functions.
+
+It was an a priori goal of Air.js to spend most of the time in the
+allocateStack phase. This is a faithful reproduction of the C++ allocateStack
+phase, including its use of an abstract liveness analysis. It's abstract in the
+sense that the same liveness algorithm can be reused for temporaries,
+registers, or stack slots. In C++ this meant using templates, while in ES6 it
+means more run-time dynamic dispatch.
+
+Each IR payload is executable code that allocates the IR, and about 15% of
+benchmark execution time is spent in that code. This is significant, but having
+learned this, we don't feel that it would be honest to try to change the
+efficiency of payload initialization. What if the payload initialization was
+more expensive on our engine than others? If it was, then such a change would
+not be fair.
+
+Air.js validates its results. We added a Code hashing capability to both the
+C++ Air and Air.js, and we assert each payload looks identical after
+allocateStack to what it would have looked like after the original C++
+allocateStack. We also validate that payloads hash properly before
+allcoateStack, to help catch bugs during payload initialization. We have not
+measured how long hashing takes, but it's a O(N) operation, while allocateStack
+is closer to O(N^2). We suspect that barring some engine pathologies, hashing
+should be much faster than allocateStack, and allocateStack should be where the
+bulk of time is spent.
+
+## License
+
+Copyright (C) 2016 Apple Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+## Summary
+
+At the time that Air.js was written, we weren't happy with the ES6 benchmarks
+that were available to us. Air.js uses some ES6 features in anger, in the hope
+that we can learn about possible optimization strategies by looking at this and
+other benchmarks.
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/airjs-tests.yaml b/third_party/webkit/PerformanceTests/ARES-6/Air/airjs-tests.yaml
new file mode 100644
index 0000000000..6d55fbe63a
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/airjs-tests.yaml
@@ -0,0 +1,28 @@
+# Copyright (C) 2016 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+- path: .
+ tests:
+ - stress-test.js
+ cmd: defaultRunNoisyTest unless parseRunCommands
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/all.js b/third_party/webkit/PerformanceTests/ARES-6/Air/all.js
new file mode 100644
index 0000000000..825d97b0ed
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/all.js
@@ -0,0 +1,18 @@
+"use strict";
+
+load("symbols.js");
+load("tmp_base.js");
+load("arg.js");
+load("basic_block.js");
+load("code.js");
+load("frequented_block.js");
+load("inst.js");
+load("opcode.js");
+load("reg.js");
+load("stack_slot.js");
+load("tmp.js");
+load("util.js");
+load("custom.js");
+load("liveness.js");
+load("insertion_set.js");
+load("allocate_stack.js");
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/allocate_stack.js b/third_party/webkit/PerformanceTests/ARES-6/Air/allocate_stack.js
new file mode 100644
index 0000000000..bada197bf1
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/allocate_stack.js
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+function allocateStack(code)
+{
+ if (code.frameSize)
+ throw new Error("Frame size already determined");
+
+ function attemptAssignment(slot, offsetFromFP, otherSlots)
+ {
+ if (offsetFromFP > 0)
+ throw new Error("Expect negative offset");
+
+ offsetFromFP = -roundUpToMultipleOf(slot.alignment, -offsetFromFP);
+
+ for (let otherSlot of otherSlots) {
+ if (!otherSlot.offsetFromFP)
+ continue;
+ let overlap = rangesOverlap(
+ offsetFromFP,
+ offsetFromFP + slot.byteSize,
+ otherSlot.offsetFromFP,
+ otherSlot.offsetFromFP + otherSlot.byteSize);
+ if (overlap)
+ return false;
+ }
+
+ slot.setOffsetFromFP(offsetFromFP);
+ return true;
+ }
+
+ function assign(slot, otherSlots)
+ {
+ if (attemptAssignment(slot, -slot.byteSize, otherSlots))
+ return;
+
+ for (let otherSlot of otherSlots) {
+ if (!otherSlot.offsetFromFP)
+ continue;
+ if (attemptAssignment(slot, otherSlot.offsetFromFP - slot.byteSize, otherSlots))
+ return;
+ }
+
+ throw new Error("Assignment failed");
+ }
+
+ // Allocate all of the escaped slots in order. This is kind of a crazy algorithm to allow for
+ // the possibility of stack slots being assigned frame offsets before we even get here.
+ let assignedEscapedStackSlots = [];
+ let escapedStackSlotsWorklist = [];
+ for (let slot of code.stackSlots) {
+ if (slot.isLocked) {
+ if (slot.offsetFromFP)
+ assignedEscapedStackSlots.push(slot);
+ else
+ escapedStackSlotsWorklist.push(slot);
+ } else {
+ if (slot.offsetFromFP)
+ throw new Error("Offset already assigned");
+ }
+ }
+
+ // This is a fairly espensive loop, but it's OK because we'll usually only have a handful of
+ // escaped stack slots.
+ while (escapedStackSlotsWorklist.length) {
+ let slot = escapedStackSlotsWorklist.pop();
+ assign(slot, assignedEscapedStackSlots);
+ assignedEscapedStackSlots.push(slot);
+ }
+
+ // Now we handle the spill slots.
+ let liveness = new Liveness(StackSlot, code);
+ let interference = new Map();
+ for (let slot of code.stackSlots)
+ interference.set(slot, new Set());
+ let slots = [];
+
+ for (let block of code) {
+ let localCalc = liveness.localCalc(block);
+
+ function interfere(instIndex)
+ {
+ Inst.forEachDef(
+ StackSlot, block.get(instIndex), block.get(instIndex + 1),
+ (slot, role, type, width) => {
+ if (!slot.isSpill)
+ return;
+
+ for (let otherSlot of localCalc.liveSet) {
+ interference.get(slot).add(otherSlot);
+ interference.get(otherSlot).add(slot);
+ }
+ });
+ }
+
+ for (let instIndex = block.size; instIndex--;) {
+ // Kill dead stores. For simplicity we say that a store is killable if it has only late
+ // defs and those late defs are to things that are dead right now. We only do that
+ // because that's the only kind of dead stack store we will see here.
+ let inst = block.at(instIndex);
+ if (!inst.hasNonArgEffects) {
+ let ok = true;
+ inst.forEachArg((arg, role, type, width) => {
+ if (Arg.isEarlyDef(role)) {
+ ok = false;
+ return;
+ }
+ if (!Arg.isLateDef(role))
+ return;
+ if (!arg.isStack) {
+ ok = false;
+ return;
+ }
+
+ let slot = arg.stackSlot;
+ if (!slot.isSpill) {
+ ok = false;
+ return;
+ }
+
+ if (localCalc.liveSet.has(slot)) {
+ ok = false;
+ return;
+ }
+ });
+ if (ok)
+ inst.clear();
+ }
+
+ interfere(instIndex);
+ localCalc.execute(instIndex);
+ }
+ interfere(-1);
+
+ removeAllMatching(block.insts, inst => inst.opcode == Nop);
+ }
+
+ // Now we assign stack locations. At its heart this algorithm is just first-fit. For each
+ // StackSlot we just want to find the offsetFromFP that is closest to zero while ensuring no
+ // overlap with other StackSlots that this overlaps with.
+ for (let slot of code.stackSlots) {
+ if (slot.offsetFromFP)
+ continue;
+
+ assign(slot, assignedEscapedStackSlots.concat(Array.from(interference.get(slot))));
+ }
+
+ // Figure out how much stack we're using for stack slots.
+ let frameSizeForStackSlots = 0;
+ for (let slot of code.stackSlots) {
+ frameSizeForStackSlots = Math.max(
+ frameSizeForStackSlots,
+ -slot.offsetFromFP);
+ }
+
+ frameSizeForStackSlots = roundUpToMultipleOf(stackAlignmentBytes, frameSizeForStackSlots);
+
+ // No we need to deduce how much argument area we need.
+ for (let block of code) {
+ for (let inst of block) {
+ for (let arg of inst.args) {
+ if (arg.isCallArg) {
+ // For now, we assume that we use 8 bytes of the call arg. But that's not
+ // such an awesome assumption.
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=150454
+ if (arg.offset < 0)
+ throw new Error("Did not expect negative offset for callArg");
+ code.requestCallArgAreaSize(arg.offset + 8);
+ }
+ }
+ }
+ }
+
+ code.setFrameSize(frameSizeForStackSlots + code.callArgAreaSize);
+
+ // Finally transform the code to use Addrs instead of StackSlots. This is a lossless
+ // transformation since we can search the StackSlots array to figure out which StackSlot any
+ // offset-from-FP refers to.
+
+ // FIXME: This may produce addresses that aren't valid if we end up with a ginormous stack frame.
+ // We would have to scavenge for temporaries if this happened. Fortunately, this case will be
+ // extremely rare so we can do crazy things when it arises.
+ // https://bugs.webkit.org/show_bug.cgi?id=152530
+
+ let insertionSet = new InsertionSet();
+ for (let block of code) {
+ for (let instIndex = 0; instIndex < block.size; ++instIndex) {
+ let inst = block.at(instIndex);
+ inst.forEachArg((arg, role, type, width) => {
+ function stackAddr(offset)
+ {
+ return Arg.createStackAddr(offset, code.frameSize, width);
+ }
+
+ switch (arg.kind) {
+ case Arg.Stack: {
+ let slot = arg.stackSlot;
+ if (Arg.isZDef(role)
+ && slot.isSpill
+ && slot.byteSize > Arg.bytes(width)) {
+ // Currently we only handle this simple case because it's the only one
+ // that arises: ZDef's are only 32-bit right now. So, when we hit these
+ // assertions it means that we need to implement those other kinds of
+ // zero fills.
+ if (slot.byteSize != 8) {
+ throw new Error(
+ `Bad spill slot size for ZDef: ${slot.byteSize}, width is ${width}`);
+ }
+ if (width != 32)
+ throw new Error("Bad width for ZDef");
+
+ insertionSet.insert(
+ instIndex + 1,
+ new Inst(
+ StoreZero32,
+ [stackAddr(arg.offset + 4 + slot.offsetFromFP)]));
+ }
+ return stackAddr(arg.offset + slot.offsetFromFP);
+ }
+ case Arg.CallArg:
+ return stackAddr(arg.offset - code.frameSize);
+ default:
+ break;
+ }
+ });
+ }
+ insertionSet.execute(block.insts);
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/arg.js b/third_party/webkit/PerformanceTests/ARES-6/Air/arg.js
new file mode 100644
index 0000000000..07aceda8d5
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/arg.js
@@ -0,0 +1,1064 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class Arg {
+ constructor()
+ {
+ this._kind = Arg.Invalid;
+ }
+
+ static isAnyUse(role)
+ {
+ switch (role) {
+ case Arg.Use:
+ case Arg.ColdUse:
+ case Arg.UseDef:
+ case Arg.UseZDef:
+ case Arg.LateUse:
+ case Arg.LateColdUse:
+ case Arg.Scratch:
+ return true;
+ case Arg.Def:
+ case Arg.ZDef:
+ case Arg.UseAddr:
+ case Arg.EarlyDef:
+ return false;
+ default:
+ throw new Error("Bad role");
+ }
+ }
+
+ static isColdUse(role)
+ {
+ switch (role) {
+ case Arg.ColdUse:
+ case Arg.LateColdUse:
+ return true;
+ case Arg.Use:
+ case Arg.UseDef:
+ case Arg.UseZDef:
+ case Arg.LateUse:
+ case Arg.Def:
+ case Arg.ZDef:
+ case Arg.UseAddr:
+ case Arg.Scratch:
+ case Arg.EarlyDef:
+ return false;
+ default:
+ throw new Error("Bad role");
+ }
+ }
+
+ static isWarmUse(role)
+ {
+ return Arg.isAnyUse(role) && !Arg.isColdUse(role);
+ }
+
+ static cooled(role)
+ {
+ switch (role) {
+ case Arg.ColdUse:
+ case Arg.LateColdUse:
+ case Arg.UseDef:
+ case Arg.UseZDef:
+ case Arg.Def:
+ case Arg.ZDef:
+ case Arg.UseAddr:
+ case Arg.Scratch:
+ case Arg.EarlyDef:
+ return role;
+ case Arg.Use:
+ return Arg.ColdUse;
+ case Arg.LateUse:
+ return Arg.LateColdUse;
+ default:
+ throw new Error("Bad role");
+ }
+ }
+
+ static isEarlyUse(role)
+ {
+ switch (role) {
+ case Arg.Use:
+ case Arg.ColdUse:
+ case Arg.UseDef:
+ case Arg.UseZDef:
+ return true;
+ case Arg.Def:
+ case Arg.ZDef:
+ case Arg.UseAddr:
+ case Arg.LateUse:
+ case Arg.LateColdUse:
+ case Arg.Scratch:
+ case Arg.EarlyDef:
+ return false;
+ default:
+ throw new Error("Bad role");
+ }
+ }
+
+ static isLateUse(role)
+ {
+ switch (role) {
+ case Arg.LateUse:
+ case Arg.LateColdUse:
+ case Arg.Scratch:
+ return true;
+ case Arg.ColdUse:
+ case Arg.Use:
+ case Arg.UseDef:
+ case Arg.UseZDef:
+ case Arg.Def:
+ case Arg.ZDef:
+ case Arg.UseAddr:
+ case Arg.EarlyDef:
+ return false;
+ default:
+ throw new Error("Bad role");
+ }
+ }
+
+ static isAnyDef(role)
+ {
+ switch (role) {
+ case Arg.Use:
+ case Arg.ColdUse:
+ case Arg.UseAddr:
+ case Arg.LateUse:
+ case Arg.LateColdUse:
+ return false;
+ case Arg.Def:
+ case Arg.UseDef:
+ case Arg.ZDef:
+ case Arg.UseZDef:
+ case Arg.EarlyDef:
+ case Arg.Scratch:
+ return true;
+ default:
+ throw new Error("Bad role");
+ }
+ }
+
+ static isEarlyDef(role)
+ {
+ switch (role) {
+ case Arg.Use:
+ case Arg.ColdUse:
+ case Arg.UseAddr:
+ case Arg.LateUse:
+ case Arg.Def:
+ case Arg.UseDef:
+ case Arg.ZDef:
+ case Arg.UseZDef:
+ case Arg.LateColdUse:
+ return false;
+ case Arg.EarlyDef:
+ case Arg.Scratch:
+ return true;
+ default:
+ throw new Error("Bad role");
+ }
+ }
+
+ static isLateDef(role)
+ {
+ switch (role) {
+ case Arg.Use:
+ case Arg.ColdUse:
+ case Arg.UseAddr:
+ case Arg.LateUse:
+ case Arg.EarlyDef:
+ case Arg.Scratch:
+ case Arg.LateColdUse:
+ return false;
+ case Arg.Def:
+ case Arg.UseDef:
+ case Arg.ZDef:
+ case Arg.UseZDef:
+ return true;
+ default:
+ throw new Error("Bad role");
+ }
+ }
+
+ static isZDef(role)
+ {
+ switch (role) {
+ case Arg.Use:
+ case Arg.ColdUse:
+ case Arg.UseAddr:
+ case Arg.LateUse:
+ case Arg.Def:
+ case Arg.UseDef:
+ case Arg.EarlyDef:
+ case Arg.Scratch:
+ case Arg.LateColdUse:
+ return false;
+ case Arg.ZDef:
+ case Arg.UseZDef:
+ return true;
+ default:
+ throw new Error("Bad role");
+ }
+ }
+
+ static typeForB3Type(type)
+ {
+ switch (type) {
+ case Int32:
+ case Int64:
+ return GP;
+ case Float:
+ case Double:
+ return FP;
+ default:
+ throw new Error("Bad B3 type");
+ }
+ }
+
+ static widthForB3Type(type)
+ {
+ switch (type) {
+ case Int32:
+ case Float:
+ return 32;
+ case Int64:
+ case Double:
+ return 64;
+ default:
+ throw new Error("Bad B3 type");
+ }
+ }
+
+ static conservativeWidth(type)
+ {
+ return type == GP ? Ptr : 64;
+ }
+
+ static minimumWidth(type)
+ {
+ return type == GP ? 8 : 32;
+ }
+
+ static bytes(width)
+ {
+ return width / 8;
+ }
+
+ static widthForBytes(bytes)
+ {
+ switch (bytes) {
+ case 0:
+ case 1:
+ return 8;
+ case 2:
+ return 16;
+ case 3:
+ case 4:
+ return 32;
+ default:
+ if (bytes > 8)
+ throw new Error("Bad number of bytes");
+ return 64;
+ }
+ }
+
+ static createTmp(tmp)
+ {
+ let result = new Arg();
+ result._kind = Arg.Tmp;
+ result._tmp = tmp;
+ return result;
+ }
+
+ static fromReg(reg)
+ {
+ return Arg.createTmp(reg);
+ }
+
+ static createImm(value)
+ {
+ let result = new Arg();
+ result._kind = Arg.Imm;
+ result._value = value;
+ return result;
+ }
+
+ static createBigImm(lowValue, highValue = 0)
+ {
+ let result = new Arg();
+ result._kind = Arg.BigImm;
+ result._lowValue = lowValue;
+ result._highValue = highValue;
+ return result;
+ }
+
+ static createBitImm(value)
+ {
+ let result = new Arg();
+ result._kind = Arg.BitImm;
+ result._value = value;
+ return result;
+ }
+
+ static createBitImm64(lowValue, highValue = 0)
+ {
+ let result = new Arg();
+ result._kind = Arg.BitImm64;
+ result._lowValue = lowValue;
+ result._highValue = highValue;
+ return result;
+ }
+
+ static createAddr(base, offset = 0)
+ {
+ let result = new Arg();
+ result._kind = Arg.Addr;
+ result._base = base;
+ result._offset = offset;
+ return result;
+ }
+
+ static createStack(slot, offset = 0)
+ {
+ let result = new Arg();
+ result._kind = Arg.Stack;
+ result._slot = slot;
+ result._offset = offset;
+ return result;
+ }
+
+ static createCallArg(offset)
+ {
+ let result = new Arg();
+ result._kind = Arg.CallArg;
+ result._offset = offset;
+ return result;
+ }
+
+ static createStackAddr(offsetFromFP, frameSize, width)
+ {
+ let result = Arg.createAddr(Reg.callFrameRegister, offsetFromFP);
+ if (!result.isValidForm(width))
+ result = Arg.createAddr(Reg.stackPointerRegister, offsetFromFP + frameSize);
+ return result;
+ }
+
+ static isValidScale(scale, width)
+ {
+ switch (scale) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ static logScale(scale)
+ {
+ switch (scale) {
+ case 1:
+ return 0;
+ case 2:
+ return 1;
+ case 4:
+ return 2;
+ case 8:
+ return 3;
+ default:
+ throw new Error("Bad scale");
+ }
+ }
+
+ static createIndex(base, index, scale = 1, offset = 0)
+ {
+ let result = new Arg();
+ result._kind = Arg.Index;
+ result._base = base;
+ result._index = index;
+ result._scale = scale;
+ result._offset = offset;
+ return result;
+ }
+
+ static createRelCond(condition)
+ {
+ let result = new Arg();
+ result._kind = Arg.RelCond;
+ result._condition = condition;
+ return result;
+ }
+
+ static createResCond(condition)
+ {
+ let result = new Arg();
+ result._kind = Arg.ResCond;
+ result._condition = condition;
+ return result;
+ }
+
+ static createDoubleCond(condition)
+ {
+ let result = new Arg();
+ result._kind = Arg.DoubleCond;
+ result._condition = condition;
+ return result;
+ }
+
+ static createWidth(width)
+ {
+ let result = new Arg();
+ result._kind = Arg.Width;
+ result._width = width;
+ return result;
+ }
+
+ static createSpecial()
+ {
+ let result = new Arg();
+ result._kind = Arg.Special;
+ return result;
+ }
+
+ get kind() { return this._kind; }
+ get isTmp() { return this._kind == Arg.Tmp; }
+ get isImm() { return this._kind == Arg.Imm; }
+ get isBigImm() { return this._kind == Arg.BigImm; }
+ get isBitImm() { return this._kind == Arg.BitImm; }
+ get isBitImm64() { return this._kind == Arg.BitImm64; }
+ get isSomeImm()
+ {
+ switch (this._kind) {
+ case Arg.Imm:
+ case Arg.BitImm:
+ return true;
+ default:
+ return false;
+ }
+ }
+ get isSomeBigImm()
+ {
+ switch (this._kind) {
+ case Arg.BigImm:
+ case Arg.BitImm64:
+ return true;
+ default:
+ return false;
+ }
+ }
+ get isAddr() { return this._kind == Arg.Addr; }
+ get isStack() { return this._kind == Arg.Stack; }
+ get isCallArg() { return this._kind == Arg.CallArg; }
+ get isIndex() { return this._kind == Arg.Index; }
+ get isMemory()
+ {
+ switch (this._kind) {
+ case Arg.Addr:
+ case Arg.Stack:
+ case Arg.CallArg:
+ case Arg.Index:
+ return true;
+ default:
+ return false;
+ }
+ }
+ get isStackMemory()
+ {
+ switch (this._kind) {
+ case Arg.Addr:
+ return this._base == Reg.callFrameRegister
+ || this._base == Reg.stackPointerRegister;
+ case Arg.Stack:
+ case Arg.CallArg:
+ return true;
+ default:
+ return false;
+ }
+ }
+ get isRelCond() { return this._kind == Arg.RelCond; }
+ get isResCond() { return this._kind == Arg.ResCond; }
+ get isDoubleCond() { return this._kind == Arg.DoubleCond; }
+ get isCondition()
+ {
+ switch (this._kind) {
+ case Arg.RelCond:
+ case Arg.ResCond:
+ case Arg.DoubleCond:
+ return true;
+ default:
+ return false;
+ }
+ }
+ get isWidth() { return this._kind == Arg.Width; }
+ get isSpecial() { return this._kind == Arg.Special; }
+ get isAlive() { return this.isTmp || this.isStack; }
+
+ get tmp()
+ {
+ if (this._kind != Arg.Tmp)
+ throw new Error("Called .tmp for non-tmp");
+ return this._tmp;
+ }
+
+ get value()
+ {
+ if (!this.isSomeImm)
+ throw new Error("Called .value for non-imm");
+ return this._value;
+ }
+
+ get lowValue()
+ {
+ if (!this.isSomeBigImm)
+ throw new Error("Called .lowValue for non-big-imm");
+ return this._lowValue;
+ }
+
+ get highValue()
+ {
+ if (!this.isSomeBigImm)
+ throw new Error("Called .highValue for non-big-imm");
+ return this._highValue;
+ }
+
+ get base()
+ {
+ switch (this._kind) {
+ case Arg.Addr:
+ case Arg.Index:
+ return this._base;
+ default:
+ throw new Error("Called .base for non-address");
+ }
+ }
+
+ get hasOffset() { return this.isMemory; }
+
+ get offset()
+ {
+ switch (this._kind) {
+ case Arg.Addr:
+ case Arg.Index:
+ case Arg.Stack:
+ case Arg.CallArg:
+ return this._offset;
+ default:
+ throw new Error("Called .offset for non-address");
+ }
+ }
+
+ get stackSlot()
+ {
+ if (this._kind != Arg.Stack)
+ throw new Error("Called .stackSlot for non-address");
+ return this._slot;
+ }
+
+ get index()
+ {
+ if (this._kind != Arg.Index)
+ throw new Error("Called .index for non-Index");
+ return this._index;
+ }
+
+ get scale()
+ {
+ if (this._kind != Arg.Index)
+ throw new Error("Called .scale for non-Index");
+ return this._scale;
+ }
+
+ get logScale()
+ {
+ return Arg.logScale(this.scale);
+ }
+
+ get width()
+ {
+ if (this._kind != Arg.Width)
+ throw new Error("Called .width for non-Width");
+ return this._width;
+ }
+
+ get isGPTmp() { return this.isTmp && this.tmp.isGP; }
+ get isFPTmp() { return this.isTmp && this.tmp.isFP; }
+
+ get isGP()
+ {
+ switch (this._kind) {
+ case Arg.Imm:
+ case Arg.BigImm:
+ case Arg.BitImm:
+ case Arg.BitImm64:
+ case Arg.Addr:
+ case Arg.Index:
+ case Arg.Stack:
+ case Arg.CallArg:
+ case Arg.RelCond:
+ case Arg.ResCond:
+ case Arg.DoubleCond:
+ case Arg.Width:
+ case Arg.Special:
+ return true;
+ case Arg.Tmp:
+ return this.isGPTmp;
+ case Arg.Invalid:
+ return false;
+ default:
+ throw new Error("Bad kind");
+ }
+ }
+
+ get isFP()
+ {
+ switch (this._kind) {
+ case Arg.Imm:
+ case Arg.BitImm:
+ case Arg.BitImm64:
+ case Arg.RelCond:
+ case Arg.ResCond:
+ case Arg.DoubleCond:
+ case Arg.Width:
+ case Arg.Special:
+ case Arg.Invalid:
+ return false;
+ case Arg.Addr:
+ case Arg.Index:
+ case Arg.Stack:
+ case Arg.CallArg:
+ case Arg.BigImm:
+ return true;
+ case Arg.Tmp:
+ return this.isFPTmp;
+ default:
+ throw new Error("Bad kind");
+ }
+ }
+
+ get hasType()
+ {
+ switch (this._kind) {
+ case Arg.Imm:
+ case Arg.BitImm:
+ case Arg.BitImm64:
+ case Arg.Tmp:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ get type()
+ {
+ return this.isGP ? GP : FP;
+ }
+
+ isType(type)
+ {
+ switch (type) {
+ case Arg.GP:
+ return this.isGP;
+ case Arg.FP:
+ return this.isFP;
+ default:
+ throw new Error("Bad type");
+ }
+ }
+
+ isCompatibleType(other)
+ {
+ if (this.hasType)
+ return other.isType(this.type);
+ if (other.hasType)
+ return this.isType(other.type);
+ return true;
+ }
+
+ get isGPR() { return this.isTmp && this.tmp.isGPR; }
+ get gpr() { return this.tmp.gpr; }
+ get isFPR() { return this.isTmp && this.tmp.isFPR; }
+ get fpr() { return this.tmp.fpr; }
+ get isReg() { return this.isTmp && this.tmp.isReg; }
+ get reg() { return this.tmp.reg; }
+
+ static isValidImmForm(value)
+ {
+ return isRepresentableAsInt32(value);
+ }
+ static isValidBitImmForm(value)
+ {
+ return isRepresentableAsInt32(value);
+ }
+ static isValidBitImm64Form(value)
+ {
+ return isRepresentableAsInt32(value);
+ }
+
+ static isValidAddrForm(offset, width)
+ {
+ return true;
+ }
+
+ static isValidIndexForm(scale, offset, width)
+ {
+ if (!isValidScale(scale, width))
+ return false;
+ return true;
+ }
+
+ isValidForm(width)
+ {
+ switch (this._kind) {
+ case Arg.Invalid:
+ return false;
+ case Arg.Tmp:
+ return true;
+ case Arg.Imm:
+ return Arg.isValidImmForm(this.value);
+ case Arg.BigImm:
+ return true;
+ case Arg.BitImm:
+ return Arg.isValidBitImmForm(this.value);
+ case Arg.BitImm64:
+ return Arg.isValidBitImm64Form(this.value);
+ case Arg.Addr:
+ case Arg.Stack:
+ case Arg.CallArg:
+ return Arg.isValidAddrForm(this.offset, width);
+ case Arg.Index:
+ return Arg.isValidIndexForm(this.scale, this.offset, width);
+ case Arg.RelCond:
+ case Arg.ResCond:
+ case Arg.DoubleCond:
+ case Arg.Width:
+ case Arg.Special:
+ return true;
+ default:
+ throw new Error("Bad kind");
+ }
+ }
+
+ forEachTmpFast(func)
+ {
+ switch (this._kind) {
+ case Arg.Tmp: {
+ let replacement;
+ if (replacement = func(this._tmp))
+ return Arg.createTmp(replacement);
+ break;
+ }
+ case Arg.Addr: {
+ let replacement;
+ if (replacement = func(this._base))
+ return Arg.createAddr(replacement, this._offset);
+ break;
+ }
+ case Arg.Index: {
+ let baseReplacement = func(this._base);
+ let indexReplacement = func(this._index);
+ if (baseReplacement || indexReplacement) {
+ return Arg.createIndex(
+ baseReplacement ? baseReplacement : this._base,
+ indexReplacement ? indexReplacement : this._index,
+ this._scale, this._offset);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ usesTmp(expectedTmp)
+ {
+ let usesTmp = false;
+ forEachTmpFast(tmp => {
+ usesTmp |= tmp == expectedTmp;
+ });
+ return usesTmp;
+ }
+
+ forEachTmp(role, type, width, func)
+ {
+ switch (this._kind) {
+ case Arg.Tmp: {
+ let replacement;
+ if (replacement = func(this._tmp, role, type, width))
+ return Arg.createTmp(replacement);
+ break;
+ }
+ case Arg.Addr: {
+ let replacement;
+ if (replacement = func(this._base, Arg.Use, GP, role == Arg.UseAddr ? width : Ptr))
+ return Arg.createAddr(replacement, this._offset);
+ break;
+ }
+ case Arg.Index: {
+ let baseReplacement = func(this._base, Arg.Use, GP, role == Arg.UseAddr ? width : Ptr);
+ let indexReplacement = func(this._index, Arg.Use, GP, role == Arg.UseAddr ? width : Ptr);
+ if (baseReplacement || indexReplacement) {
+ return Arg.createIndex(
+ baseReplacement ? baseReplacement : this._base,
+ indexReplacement ? indexReplacement : this._index,
+ this._scale, this._offset);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ is(thing) { return !!thing.extract(this); }
+ as(thing) { return thing.extract(this); }
+
+ // This lets you say things like:
+ // arg.forEach(Tmp | Reg | Arg | StackSlot, ...)
+ //
+ // It's used for abstract liveness analysis.
+ forEachFast(thing, func)
+ {
+ return thing.forEachFast(this, func);
+ }
+ forEach(thing, role, type, width, func)
+ {
+ return thing.forEach(this, role, type, width, func);
+ }
+
+ static extract(arg) { return arg; }
+ static forEachFast(arg, func) { return func(arg); }
+ static forEach(arg, role, type, width, func) { return func(arg, role, type, width); }
+
+ get condition()
+ {
+ switch (this._kind) {
+ case Arg.RelCond:
+ case Arg.ResCond:
+ case Arg.DoubleCond:
+ return this._condition;
+ default:
+ throw new Error("Called .condition for non-condition");
+ }
+ }
+
+ get isInvertible()
+ {
+ switch (this._kind) {
+ case Arg.RelCond:
+ case Arg.DoubleCold:
+ return true;
+ case Arg.ResCond:
+ switch (this._condition) {
+ case Zero:
+ case NonZero:
+ case Signed:
+ case PositiveOrZero:
+ return true;
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+ }
+
+ static kindCode(kind)
+ {
+ switch (kind) {
+ case Arg.Invalid:
+ return 0;
+ case Arg.Tmp:
+ return 1;
+ case Arg.Imm:
+ return 2;
+ case Arg.BigImm:
+ return 3;
+ case Arg.BitImm:
+ return 4;
+ case Arg.BitImm64:
+ return 5;
+ case Arg.Addr:
+ return 6;
+ case Arg.Stack:
+ return 7;
+ case Arg.CallArg:
+ return 8;
+ case Arg.Index:
+ return 9;
+ case Arg.RelCond:
+ return 10;
+ case Arg.ResCond:
+ return 11;
+ case Arg.DoubleCond:
+ return 12;
+ case Arg.Special:
+ return 13;
+ case Arg.WidthArg:
+ return 14;
+ default:
+ throw new Error("Bad kind");
+ }
+ }
+
+ hash()
+ {
+ let result = Arg.kindCode(this._kind);
+
+ switch (this._kind) {
+ case Arg.Invalid:
+ case Arg.Special:
+ break;
+ case Arg.Tmp:
+ result += this._tmp.hash();
+ result |= 0;
+ break;
+ case Arg.Imm:
+ case Arg.BitImm:
+ result += this._value;
+ result |= 0;
+ break;
+ case Arg.BigImm:
+ case Arg.BitImm64:
+ result += this._lowValue;
+ result |= 0;
+ result += this._highValue;
+ result |= 0;
+ break;
+ case Arg.CallArg:
+ result += this._offset;
+ result |= 0;
+ break;
+ case Arg.RelCond:
+ result += relCondCode(this._condition);
+ result |= 0;
+ break;
+ case Arg.ResCond:
+ result += resCondCode(this._condition);
+ result |= 0;
+ break;
+ case Arg.DoubleCond:
+ result += doubleCondCode(this._condition);
+ result |= 0;
+ break;
+ case Arg.WidthArg:
+ result += this._width;
+ result |= 0;
+ break;
+ case Arg.Addr:
+ result += this._offset;
+ result |= 0;
+ result += this._base.hash();
+ result |= 0;
+ break;
+ case Arg.Index:
+ result += this._offset;
+ result |= 0;
+ result += this._scale;
+ result |= 0;
+ result += this._base.hash();
+ result |= 0;
+ result += this._index.hash();
+ result |= 0;
+ break;
+ case Arg.Stack:
+ result += this._offset;
+ result |= 0;
+ result += this.stackSlot.index;
+ result |= 0;
+ break;
+ }
+
+ return result >>> 0;
+ }
+
+ toString()
+ {
+ switch (this._kind) {
+ case Arg.Invalid:
+ return "<invalid>";
+ case Arg.Tmp:
+ return this._tmp.toString();
+ case Arg.Imm:
+ return "$" + this._value;
+ case Arg.BigImm:
+ case Arg.BitImm64:
+ return "$0x" + this._highValue.toString(16) + ":" + this._lowValue.toString(16);
+ case Arg.Addr:
+ return "" + (this._offset ? this._offset : "") + "(" + this._base + ")";
+ case Arg.Index:
+ return "" + (this._offset ? this._offset : "") + "(" + this._base +
+ "," + this._index + (this._scale == 1 ? "" : "," + this._scale) + ")";
+ case Arg.Stack:
+ return "" + (this._offset ? this._offset : "") + "(" + this._slot + ")";
+ case Arg.CallArg:
+ return "" + (this._offset ? this._offset : "") + "(callArg)";
+ case Arg.RelCond:
+ case Arg.ResCond:
+ case Arg.DoubleCond:
+ return symbolName(this._condition);
+ case Arg.Special:
+ return "special";
+ case Arg.Width:
+ return "" + this._value;
+ default:
+ throw new Error("Bad kind");
+ }
+ }
+}
+
+// Arg kinds
+Arg.Invalid = Symbol("Invalid");
+Arg.Tmp = Symbol("Tmp");
+Arg.Imm = Symbol("Imm");
+Arg.BigImm = Symbol("BigImm");
+Arg.BitImm = Symbol("BitImm");
+Arg.BitImm64 = Symbol("BitImm64");
+Arg.Addr = Symbol("Addr");
+Arg.Stack = Symbol("Stack");
+Arg.CallArg = Symbol("CallArg");
+Arg.Index = Symbol("Index");
+Arg.RelCond = Symbol("RelCond");
+Arg.ResCond = Symbol("ResCond");
+Arg.DoubleCond = Symbol("DoubleCond");
+Arg.Special = Symbol("Special");
+Arg.Width = Symbol("Width");
+
+// Arg roles
+Arg.Use = Symbol("Use");
+Arg.ColdUse = Symbol("ColdUse");
+Arg.LateUse = Symbol("LateUse");
+Arg.LateColdUse = Symbol("LateColdUse");
+Arg.Def = Symbol("Def");
+Arg.ZDef = Symbol("ZDef");
+Arg.UseDef = Symbol("UseDef");
+Arg.UseZDef = Symbol("UseZDef");
+Arg.EarlyDef = Symbol("EarlyDef");
+Arg.Scratch = Symbol("Scratch");
+Arg.UseAddr = Symbol("UseAddr");
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/basic_block.js b/third_party/webkit/PerformanceTests/ARES-6/Air/basic_block.js
new file mode 100644
index 0000000000..dd9cea61f8
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/basic_block.js
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class BasicBlock {
+ constructor(index, frequency)
+ {
+ this._index = index;
+ this._frequency = frequency;
+ this._insts = [];
+ this._successors = [];
+ this._predecessors = [];
+ }
+
+ get index() { return this._index; }
+ get size() { return this._insts.length; }
+
+ [Symbol.iterator]()
+ {
+ return this._insts[Symbol.iterator]();
+ }
+
+ at(index)
+ {
+ if (index >= this._insts.length)
+ throw new Error("Out of bounds access");
+ return this._insts[index];
+ }
+
+ get(index)
+ {
+ if (index < 0 || index >= this._insts.length)
+ return null;
+ return this._insts[index];
+ }
+
+ get last()
+ {
+ return this._insts[this._insts.length - 1];
+ }
+
+ get insts() { return this._insts; }
+
+ append(inst) { this._insts.push(inst); }
+
+ get numSuccessors() { return this._successors.length; }
+ successor(index) { return this._successors[index]; }
+ get successors() { return this._successors; }
+
+ successorBlock(index) { return this._successors[index].block; }
+ get successorBlocks()
+ {
+ return new Proxy(this._successors, {
+ get(target, property) {
+ if (typeof property == "string"
+ && (property | 0) == property)
+ return target[property].block;
+ return target[property];
+ },
+
+ set(target, property, value) {
+ if (typeof property == "string"
+ && (property | 0) == property) {
+ var oldValue = target[property];
+ target[property] = new FrequentedBlock(
+ value, oldValue ? oldValue.frequency : Normal);
+ return;
+ }
+
+ target[property] = value;
+ }
+ });
+ }
+
+ get numPredecessors() { return this._predecessors.length; }
+ predecessor(index) { return this._predecessors[index]; }
+ get predecessors() { return this._predecessors; }
+
+ get frequency() { return this._frequency; }
+
+ toString()
+ {
+ return "#" + this._index;
+ }
+
+ get headerString()
+ {
+ let result = "";
+ result += `BB${this}: ; frequency = ${this._frequency}\n`;
+ if (this._predecessors.length)
+ result += " Predecessors: " + this._predecessors.join(", ") + "\n";
+ return result;
+ }
+
+ get footerString()
+ {
+ let result = "";
+ if (this._successors.length)
+ result += " Successors: " + this._successors.join(", ") + "\n";
+ return result;
+ }
+
+ toStringDeep()
+ {
+ let result = "";
+ result += this.headerString;
+ for (let inst of this)
+ result += ` ${inst}\n`;
+ result += this.footerString;
+ return result;
+ }
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/benchmark.js b/third_party/webkit/PerformanceTests/ARES-6/Air/benchmark.js
new file mode 100644
index 0000000000..1c8cc614a6
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/benchmark.js
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class AirBenchmark {
+ constructor(verbose = 0)
+ {
+ this._verbose = verbose;
+
+ this._payloads = [
+ {generate: createPayloadGbemuExecuteIteration, earlyHash: 632653144, lateHash: 372715518},
+ {generate: createPayloadImagingGaussianBlurGaussianBlur, earlyHash: 3677819581, lateHash: 1252116304},
+ {generate: createPayloadTypescriptScanIdentifier, earlyHash: 1914852601, lateHash: 837339551},
+ {generate: createPayloadAirJSACLj8C, earlyHash: 1373599940, lateHash: 3981283600}
+ ];
+ }
+
+ runIteration()
+ {
+ for (let payload of this._payloads) {
+ // Sadly about 17% of our time is in generate. I don't think that's really avoidable,
+ // and I don't mind testing VMs' ability to run such "data definition" code quickly. I
+ // would not have expected it to be so slow from first principles!
+ let code = payload.generate();
+
+ if (this._verbose) {
+ print("Before allocateStack:");
+ print(code);
+ }
+
+ let hash = code.hash();
+ if (hash != payload.earlyHash)
+ throw new Error(`Wrong early hash for ${payload.generate.name}: ${hash}`);
+
+ allocateStack(code);
+
+ if (this._verbose) {
+ print("After allocateStack:");
+ print(code);
+ }
+
+ hash = code.hash();
+ if (hash != payload.lateHash)
+ throw new Error(`Wrong late hash for ${payload.generate.name}: ${hash}`);
+ }
+ }
+}
+
+function runBenchmark()
+{
+ const verbose = 0;
+ const numIterations = 150;
+
+ let before = currentTime();
+
+ let benchmark = new AirBenchmark(verbose);
+
+ for (let iteration = 0; iteration < numIterations; ++iteration)
+ benchmark.runIteration();
+
+ let after = currentTime();
+ return after - before;
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/code.js b/third_party/webkit/PerformanceTests/ARES-6/Air/code.js
new file mode 100644
index 0000000000..013814aa5b
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/code.js
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class Code {
+ constructor()
+ {
+ this._blocks = [];
+ this._stackSlots = [];
+ this._gpTmps = [];
+ this._fpTmps = [];
+ this._callArgAreaSize = 0;
+ this._frameSize = 0;
+ }
+
+ addBlock(frequency = 1)
+ {
+ return addIndexed(this._blocks, BasicBlock, frequency);
+ }
+
+ addStackSlot(byteSize, kind)
+ {
+ return addIndexed(this._stackSlots, StackSlot, byteSize, kind);
+ }
+
+ newTmp(type)
+ {
+ return addIndexed(this[`_${lowerSymbolName(type)}Tmps`], Tmp, type);
+ }
+
+ get size() { return this._blocks.length; }
+ at(index) { return this._blocks[index]; }
+
+ [Symbol.iterator]()
+ {
+ return this._blocks[Symbol.iterator]();
+ }
+
+ get blocks() { return this._blocks; }
+ get stackSlots() { return this._stackSlots; }
+
+ tmps(type) { return this[`_${lowerSymbolName(type)}Tmps`]; }
+
+ get callArgAreaSize() { return this._callArgAreaSize; }
+
+ requestCallArgAreaSize(size)
+ {
+ this._callArgAreaSize = Math.max(this._callArgAreaSize, roundUpToMultipleOf(stackAlignmentBytes, size));
+ }
+
+ get frameSize() { return this._frameSize; }
+
+ setFrameSize(frameSize) { this._frameSize = frameSize; }
+
+ hash()
+ {
+ let result = 0;
+ for (let block of this) {
+ result *= 1000001;
+ result |= 0;
+ for (let inst of block) {
+ result *= 97;
+ result |= 0;
+ result += inst.hash();
+ result |= 0;
+ }
+ for (let successor of block.successorBlocks) {
+ result *= 7;
+ result |= 0;
+ result += successor.index;
+ result |= 0;
+ }
+ }
+ for (let slot of this.stackSlots) {
+ result *= 101;
+ result |= 0;
+ result += slot.hash();
+ result |= 0;
+ }
+ return result >>> 0;
+ }
+
+ toString()
+ {
+ let result = "";
+ for (let block of this) {
+ result += block.toStringDeep();
+ }
+ if (this.stackSlots.length) {
+ result += "Stack slots:\n";
+ for (let slot of this.stackSlots)
+ result += ` ${slot}\n`;
+ }
+ if (this._frameSize)
+ result += `Frame size: ${this._frameSize}\n`;
+ if (this._callArgAreaSize)
+ result += `Call arg area size: ${this._callArgAreaSize}\n`;
+ return result;
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/custom.js b/third_party/webkit/PerformanceTests/ARES-6/Air/custom.js
new file mode 100644
index 0000000000..04c73cbb63
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/custom.js
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+const ShuffleCustom = {
+ forEachArg(inst, func)
+ {
+ var limit = Math.floor(inst.args.length / 3) * 3;
+ for (let i = 0; i < limit; i += 3) {
+ let src = inst.args[i + 0];
+ let dst = inst.args[i + 1];
+ let widthArg = inst.args[i + 2];
+ let width = widthArg.width;
+ let type = src.isGP && dst.isGP ? GP : FP;
+ inst.visitArg(i + 0, func, Arg.Use, type, width);
+ inst.visitArg(i + 1, func, Arg.Def, type, width);
+ inst.visitArg(i + 2, func, Arg.Use, GP, 8);
+ }
+ },
+
+ hasNonArgNonControlEffects(inst)
+ {
+ return false;
+ }
+};
+
+const PatchCustom = {
+ forEachArg(inst, func)
+ {
+ for (let i = 0; i < inst.args.length; ++i) {
+ let {type, role, width} = inst.patchArgData[i];
+ inst.visitArg(i, func, role, type, width);
+ }
+ },
+
+ hasNonArgNonControlEffects(inst)
+ {
+ return inst.patchHasNonArgEffects;
+ }
+};
+
+const CCallCustom = {
+ forEachArg(inst, func)
+ {
+ let index = 0;
+ inst.visitArg(index++, func, Arg.Use, GP, Ptr); // callee
+
+ if (inst.cCallType != Void) {
+ inst.visitArg(
+ index++, func, Arg.Def, Arg.typeForB3Type(inst.cCallType),
+ Arg.widthForB3Type(inst.cCallType));
+ }
+
+ for (let type of inst.cCallArgTypes) {
+ inst.visitArg(
+ index++, func, Arg.Use, Arg.typeForB3Type(type), Arg.widthForB3Type(type));
+ }
+ },
+
+ hasNonArgNonControlEffects(inst)
+ {
+ return true;
+ }
+};
+
+const ColdCCallCustom = {
+ forEachArg(inst, func)
+ {
+ CCallCustom.forEachArg(
+ inst,
+ (arg, role, type, width) => {
+ return func(arg, Arg.cooled(role), type, width);
+ });
+ },
+
+ hasNonArgNonControlEffects(inst)
+ {
+ return true;
+ }
+};
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/frequented_block.js b/third_party/webkit/PerformanceTests/ARES-6/Air/frequented_block.js
new file mode 100644
index 0000000000..6e0fa1fee8
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/frequented_block.js
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class FrequentedBlock {
+ constructor(block, frequency)
+ {
+ this.block = block;
+ this.frequency = frequency;
+ }
+
+ toString()
+ {
+ return (this.frequency == Normal ? "" : "Rare:") + this.block;
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/insertion_set.js b/third_party/webkit/PerformanceTests/ARES-6/Air/insertion_set.js
new file mode 100644
index 0000000000..b070a15dd1
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/insertion_set.js
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class Insertion {
+ constructor(index, element)
+ {
+ this._index = index;
+ this._element = element;
+ }
+
+ get index() { return this._index; }
+ get element() { return this._element; }
+
+ lessThan(other)
+ {
+ return this._index < other._index;
+ }
+}
+
+class InsertionSet {
+ constructor()
+ {
+ this._insertions = []
+ }
+
+ appendInsertion(insertion)
+ {
+ this._insertions.push(insertion);
+ }
+
+ append(index, element)
+ {
+ this.appendInsertion(new Insertion(index, element));
+ }
+
+ execute(target)
+ {
+ // We bubble-sort because that's what the C++ code, and for the same reason as we do it:
+ // the stdlib doesn't have a stable sort and mergesort is slower in the common case of the
+ // array usually being sorted. This array is usually sorted.
+ bubbleSort(this._insertions, (a, b) => (a.lessThan(b)));
+
+ let numInsertions = this._insertions.length;
+ if (!numInsertions)
+ return 0;
+ let originalTargetSize = target.length;
+ target.length += numInsertions;
+ let lastIndex = target.length;
+ for (let indexInInsertions = numInsertions; indexInInsertions--;) {
+ let insertion = this._insertions[indexInInsertions];
+ if (indexInInsertions && insertion.index < this._insertions[indexInInsertions - 1].index)
+ throw new Error("Insertions out of order");
+ if (insertion.index > originalTargetSize)
+ throw new Error("Out-of-bounds insertion");
+ let firstIndex = insertion.index + indexInInsertions;
+ let indexOffset = indexInInsertions + 1;
+ for (let i = lastIndex; --i > firstIndex;)
+ target[i] = target[i - indexOffset];
+ target[firstIndex] = insertion.element;
+ lastIndex = firstIndex;
+ }
+ this._insertions = [];
+ return numInsertions;
+ }
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/inst.js b/third_party/webkit/PerformanceTests/ARES-6/Air/inst.js
new file mode 100644
index 0000000000..2af570614c
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/inst.js
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class Inst {
+ constructor(opcode, args = [])
+ {
+ this._opcode = opcode;
+ this._args = args;
+ }
+
+ append(...args)
+ {
+ this._args.push(...args);
+ }
+
+ clear()
+ {
+ this._opcode = Nop;
+ this._args = [];
+ }
+
+ get opcode() { return this._opcode; }
+ get args() { return this._args; }
+
+ visitArg(index, func, ...args)
+ {
+ let replacement = func(this._args[index], ...args);
+ if (replacement)
+ this._args[index] = replacement;
+ }
+
+ forEachTmpFast(func)
+ {
+ for (let i = 0; i < this._args.length; ++i) {
+ let replacement;
+ if (replacement = this._args[i].forEachTmpFast(func))
+ this._args[i] = replacement;
+ }
+ }
+
+ forEachArg(func)
+ {
+ Inst_forEachArg(this, func);
+ }
+
+ forEachTmp(func)
+ {
+ this.forEachArg((arg, role, type, width) => {
+ return arg.forEachTmp(role, type, width, func);
+ });
+ }
+
+ forEach(thing, func)
+ {
+ this.forEachArg((arg, role, type, width) => {
+ return arg.forEach(thing, role, type, width, func);
+ });
+ }
+
+ static forEachDef(thing, prevInst, nextInst, func)
+ {
+ if (prevInst) {
+ prevInst.forEach(
+ thing,
+ (value, role, type, width) => {
+ if (Arg.isLateDef(role))
+ return func(value, role, type, width);
+ });
+ }
+
+ if (nextInst) {
+ nextInst.forEach(
+ thing,
+ (value, role, type, width) => {
+ if (Arg.isEarlyDef(role))
+ return func(value, role, type, width);
+ });
+ }
+ }
+
+ static forEachDefWithExtraClobberedRegs(thing, prevInst, nextInst, func)
+ {
+ forEachDef(thing, prevInst, nextInst, func);
+
+ let regDefRole;
+
+ let reportReg = reg => {
+ let type = reg.isGPR ? GP : FP;
+ func(thing.fromReg(reg), regDefRole, type, Arg.conservativeWidth(type));
+ };
+
+ if (prevInst && prevInst.opcode == Patch) {
+ regDefRole = Arg.Def;
+ prevInst.extraClobberedRegs.forEach(reportReg);
+ }
+
+ if (nextInst && nextInst.opcode == Patch) {
+ regDefRole = Arg.EarlyDef;
+ nextInst.extraEarlyClobberedRegs.forEach(reportReg);
+ }
+ }
+
+ get hasNonArgEffects() { return Inst_hasNonArgEffects(this); }
+
+ hash()
+ {
+ let result = opcodeCode(this.opcode);
+ for (let arg of this.args) {
+ result += arg.hash();
+ result |= 0;
+ }
+ return result >>> 0;
+ }
+
+ toString()
+ {
+ return "" + symbolName(this._opcode) + " " + this._args.join(", ");
+ }
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/liveness.js b/third_party/webkit/PerformanceTests/ARES-6/Air/liveness.js
new file mode 100644
index 0000000000..f0ea319734
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/liveness.js
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class Liveness {
+ constructor(thing, code)
+ {
+ this._thing = thing;
+ this._code = code;
+
+ this._liveAtHead = new Map();
+ this._liveAtTail = new Map();
+
+ for (let block of code) {
+ this._liveAtHead.set(block, new Set());
+
+ let liveAtTail = new Set();
+ this._liveAtTail.set(block, liveAtTail);
+
+ block.last.forEach(
+ thing,
+ (value, role, type, width) => {
+ if (Arg.isLateUse(role))
+ liveAtTail.add(value);
+ });
+ }
+
+ let dirtyBlocks = new Set(code);
+
+ let changed;
+ do {
+ changed = false;
+
+ for (let blockIndex = code.size; blockIndex--;) {
+ let block = code.at(blockIndex);
+ if (!block)
+ continue;
+
+ if (!dirtyBlocks.delete(block))
+ continue;
+
+ let localCalc = this.localCalc(block);
+ for (let instIndex = block.size; instIndex--;)
+ localCalc.execute(instIndex);
+
+ // Handle the early def's of the first instruction.
+ block.at(0).forEach(
+ thing,
+ (value, role, type, width) => {
+ if (Arg.isEarlyDef(role))
+ localCalc.liveSet.remove(value);
+ });
+
+ let liveAtHead = this._liveAtHead.get(block);
+
+ if (!mergeIntoSet(liveAtHead, localCalc.liveSet))
+ continue;
+
+ for (let predecessor of block.predecessors) {
+ if (mergeIntoSet(this._liveAtTail.get(predecessor), liveAtHead)) {
+ dirtyBlocks.add(predecessor);
+ changed = true;
+ }
+ }
+ }
+ } while (changed);
+ }
+
+ get thing() { return this._thing; }
+ get code() { return this._code; }
+ get liveAtHead() { return this._liveAtHead; }
+ get liveAtTail() { return this._liveAtTail; }
+
+ localCalc(block)
+ {
+ let liveness = this;
+ class LocalCalc {
+ constructor()
+ {
+ this._liveSet = new Set(liveness.liveAtTail.get(block));
+ }
+
+ get liveSet() { return this._liveSet; }
+
+ execute(instIndex)
+ {
+ let inst = block.at(instIndex);
+
+ // First handle the early defs of the next instruction.
+ if (instIndex + 1 < block.size) {
+ block.at(instIndex + 1).forEach(
+ liveness.thing,
+ (value, role, type, width) => {
+ if (Arg.isEarlyDef(role))
+ this._liveSet.delete(value);
+ });
+ }
+
+ // Then handle defs.
+ inst.forEach(
+ liveness.thing,
+ (value, role, type, width) => {
+ if (Arg.isLateDef(role))
+ this._liveSet.delete(value);
+ });
+
+ // Then handle uses.
+ inst.forEach(
+ liveness.thing,
+ (value, role, type, width) => {
+ if (Arg.isEarlyUse(role))
+ this._liveSet.add(value);
+ });
+
+ // Finally handle the late uses of the previous instruction.
+ if (instIndex - 1 >= 0) {
+ block.at(instIndex - 1).forEach(
+ liveness.thing,
+ (value, role, type, width) => {
+ if (Arg.isLateUse(role))
+ this._liveSet.add(value);
+ });
+ }
+ }
+ }
+
+ return new LocalCalc();
+ }
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/make_dist.sh b/third_party/webkit/PerformanceTests/ARES-6/Air/make_dist.sh
new file mode 100644
index 0000000000..fe4c9a7f06
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/make_dist.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+set -e
+set -x
+
+MARKDOWN="perl $HOME/Documents/Markdown.pl"
+
+rm -rf Air.js
+mkdir Air.js
+${MARKDOWN} < README.md > Air.js/index.html
+cp \
+ all.js \
+ allocate_stack.js \
+ arg.js \
+ basic_block.js \
+ benchmark.js \
+ code.js \
+ custom.js \
+ frequented_block.js \
+ insertion_set.js \
+ inst.js \
+ liveness.js \
+ opcode.js \
+ payload-airjs-ACLj8C.js \
+ payload-gbemu-executeIteration.js \
+ payload-imaging-gaussian-blur-gaussianBlur.js \
+ payload-typescript-scanIdentifier.js \
+ reg.js \
+ stack_slot.js \
+ symbols.js \
+ test.html \
+ test.js \
+ tmp.js \
+ tmp_base.js \
+ util.js \
+ Air.js/
+
+tar -czvf Air.js.tar.gz Air.js
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/opcode.js b/third_party/webkit/PerformanceTests/ARES-6/Air/opcode.js
new file mode 100644
index 0000000000..0f05c31e9e
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/opcode.js
@@ -0,0 +1,1655 @@
+"use strict";
+// Generated by opcode_generator.rb from JavaScriptCore/b3/air/AirOpcode.opcodes -- do not edit!
+const Nop = Symbol("Nop");
+const Add32 = Symbol("Add32");
+const Add8 = Symbol("Add8");
+const Add16 = Symbol("Add16");
+const Add64 = Symbol("Add64");
+const AddDouble = Symbol("AddDouble");
+const AddFloat = Symbol("AddFloat");
+const Sub32 = Symbol("Sub32");
+const Sub64 = Symbol("Sub64");
+const SubDouble = Symbol("SubDouble");
+const SubFloat = Symbol("SubFloat");
+const Neg32 = Symbol("Neg32");
+const Neg64 = Symbol("Neg64");
+const NegateDouble = Symbol("NegateDouble");
+const Mul32 = Symbol("Mul32");
+const Mul64 = Symbol("Mul64");
+const MultiplyAdd32 = Symbol("MultiplyAdd32");
+const MultiplyAdd64 = Symbol("MultiplyAdd64");
+const MultiplySub32 = Symbol("MultiplySub32");
+const MultiplySub64 = Symbol("MultiplySub64");
+const MultiplyNeg32 = Symbol("MultiplyNeg32");
+const MultiplyNeg64 = Symbol("MultiplyNeg64");
+const Div32 = Symbol("Div32");
+const Div64 = Symbol("Div64");
+const MulDouble = Symbol("MulDouble");
+const MulFloat = Symbol("MulFloat");
+const DivDouble = Symbol("DivDouble");
+const DivFloat = Symbol("DivFloat");
+const X86ConvertToDoubleWord32 = Symbol("X86ConvertToDoubleWord32");
+const X86ConvertToQuadWord64 = Symbol("X86ConvertToQuadWord64");
+const X86Div32 = Symbol("X86Div32");
+const X86Div64 = Symbol("X86Div64");
+const Lea = Symbol("Lea");
+const And32 = Symbol("And32");
+const And64 = Symbol("And64");
+const AndDouble = Symbol("AndDouble");
+const AndFloat = Symbol("AndFloat");
+const XorDouble = Symbol("XorDouble");
+const XorFloat = Symbol("XorFloat");
+const Lshift32 = Symbol("Lshift32");
+const Lshift64 = Symbol("Lshift64");
+const Rshift32 = Symbol("Rshift32");
+const Rshift64 = Symbol("Rshift64");
+const Urshift32 = Symbol("Urshift32");
+const Urshift64 = Symbol("Urshift64");
+const Or32 = Symbol("Or32");
+const Or64 = Symbol("Or64");
+const Xor32 = Symbol("Xor32");
+const Xor64 = Symbol("Xor64");
+const Not32 = Symbol("Not32");
+const Not64 = Symbol("Not64");
+const AbsDouble = Symbol("AbsDouble");
+const AbsFloat = Symbol("AbsFloat");
+const CeilDouble = Symbol("CeilDouble");
+const CeilFloat = Symbol("CeilFloat");
+const FloorDouble = Symbol("FloorDouble");
+const FloorFloat = Symbol("FloorFloat");
+const SqrtDouble = Symbol("SqrtDouble");
+const SqrtFloat = Symbol("SqrtFloat");
+const ConvertInt32ToDouble = Symbol("ConvertInt32ToDouble");
+const ConvertInt64ToDouble = Symbol("ConvertInt64ToDouble");
+const ConvertInt32ToFloat = Symbol("ConvertInt32ToFloat");
+const ConvertInt64ToFloat = Symbol("ConvertInt64ToFloat");
+const CountLeadingZeros32 = Symbol("CountLeadingZeros32");
+const CountLeadingZeros64 = Symbol("CountLeadingZeros64");
+const ConvertDoubleToFloat = Symbol("ConvertDoubleToFloat");
+const ConvertFloatToDouble = Symbol("ConvertFloatToDouble");
+const Move = Symbol("Move");
+const Swap32 = Symbol("Swap32");
+const Swap64 = Symbol("Swap64");
+const Move32 = Symbol("Move32");
+const StoreZero32 = Symbol("StoreZero32");
+const SignExtend32ToPtr = Symbol("SignExtend32ToPtr");
+const ZeroExtend8To32 = Symbol("ZeroExtend8To32");
+const SignExtend8To32 = Symbol("SignExtend8To32");
+const ZeroExtend16To32 = Symbol("ZeroExtend16To32");
+const SignExtend16To32 = Symbol("SignExtend16To32");
+const MoveFloat = Symbol("MoveFloat");
+const MoveDouble = Symbol("MoveDouble");
+const MoveZeroToDouble = Symbol("MoveZeroToDouble");
+const Move64ToDouble = Symbol("Move64ToDouble");
+const Move32ToFloat = Symbol("Move32ToFloat");
+const MoveDoubleTo64 = Symbol("MoveDoubleTo64");
+const MoveFloatTo32 = Symbol("MoveFloatTo32");
+const Load8 = Symbol("Load8");
+const Store8 = Symbol("Store8");
+const Load8SignedExtendTo32 = Symbol("Load8SignedExtendTo32");
+const Load16 = Symbol("Load16");
+const Load16SignedExtendTo32 = Symbol("Load16SignedExtendTo32");
+const Store16 = Symbol("Store16");
+const Compare32 = Symbol("Compare32");
+const Compare64 = Symbol("Compare64");
+const Test32 = Symbol("Test32");
+const Test64 = Symbol("Test64");
+const CompareDouble = Symbol("CompareDouble");
+const CompareFloat = Symbol("CompareFloat");
+const Branch8 = Symbol("Branch8");
+const Branch32 = Symbol("Branch32");
+const Branch64 = Symbol("Branch64");
+const BranchTest8 = Symbol("BranchTest8");
+const BranchTest32 = Symbol("BranchTest32");
+const BranchTest64 = Symbol("BranchTest64");
+const BranchDouble = Symbol("BranchDouble");
+const BranchFloat = Symbol("BranchFloat");
+const BranchAdd32 = Symbol("BranchAdd32");
+const BranchAdd64 = Symbol("BranchAdd64");
+const BranchMul32 = Symbol("BranchMul32");
+const BranchMul64 = Symbol("BranchMul64");
+const BranchSub32 = Symbol("BranchSub32");
+const BranchSub64 = Symbol("BranchSub64");
+const BranchNeg32 = Symbol("BranchNeg32");
+const BranchNeg64 = Symbol("BranchNeg64");
+const MoveConditionally32 = Symbol("MoveConditionally32");
+const MoveConditionally64 = Symbol("MoveConditionally64");
+const MoveConditionallyTest32 = Symbol("MoveConditionallyTest32");
+const MoveConditionallyTest64 = Symbol("MoveConditionallyTest64");
+const MoveConditionallyDouble = Symbol("MoveConditionallyDouble");
+const MoveConditionallyFloat = Symbol("MoveConditionallyFloat");
+const MoveDoubleConditionally32 = Symbol("MoveDoubleConditionally32");
+const MoveDoubleConditionally64 = Symbol("MoveDoubleConditionally64");
+const MoveDoubleConditionallyTest32 = Symbol("MoveDoubleConditionallyTest32");
+const MoveDoubleConditionallyTest64 = Symbol("MoveDoubleConditionallyTest64");
+const MoveDoubleConditionallyDouble = Symbol("MoveDoubleConditionallyDouble");
+const MoveDoubleConditionallyFloat = Symbol("MoveDoubleConditionallyFloat");
+const Jump = Symbol("Jump");
+const Ret32 = Symbol("Ret32");
+const Ret64 = Symbol("Ret64");
+const RetFloat = Symbol("RetFloat");
+const RetDouble = Symbol("RetDouble");
+const Oops = Symbol("Oops");
+const Shuffle = Symbol("Shuffle");
+const Patch = Symbol("Patch");
+const CCall = Symbol("CCall");
+const ColdCCall = Symbol("ColdCCall");
+function Inst_forEachArg(inst, func)
+{
+ let replacement;
+ switch (inst.opcode) {
+ case Nop:
+ break;
+ break;
+ case Add32:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.ZDef, GP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Add8:
+ inst.visitArg(0, func, Arg.Use, GP, 8);
+ inst.visitArg(1, func, Arg.UseDef, GP, 8);
+ break;
+ break;
+ case Add16:
+ inst.visitArg(0, func, Arg.Use, GP, 16);
+ inst.visitArg(1, func, Arg.UseDef, GP, 16);
+ break;
+ break;
+ case Add64:
+ switch (inst.args.length) {
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.UseDef, GP, 64);
+ break;
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Def, GP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case AddDouble:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Use, FP, 64);
+ inst.visitArg(2, func, Arg.Def, FP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.UseDef, FP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case AddFloat:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Def, FP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.UseDef, FP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Sub32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 32);
+ break;
+ break;
+ case Sub64:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.UseDef, GP, 64);
+ break;
+ break;
+ case SubDouble:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Use, FP, 64);
+ inst.visitArg(2, func, Arg.Def, FP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.UseDef, FP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case SubFloat:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Def, FP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.UseDef, FP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Neg32:
+ inst.visitArg(0, func, Arg.UseZDef, GP, 32);
+ break;
+ break;
+ case Neg64:
+ inst.visitArg(0, func, Arg.UseDef, GP, 64);
+ break;
+ break;
+ case NegateDouble:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case Mul32:
+ switch (inst.args.length) {
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 32);
+ break;
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.ZDef, GP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Mul64:
+ switch (inst.args.length) {
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.UseDef, GP, 64);
+ break;
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Def, GP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case MultiplyAdd32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case MultiplyAdd64:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ inst.visitArg(3, func, Arg.Def, GP, 64);
+ break;
+ break;
+ case MultiplySub32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case MultiplySub64:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ inst.visitArg(3, func, Arg.Def, GP, 64);
+ break;
+ break;
+ case MultiplyNeg32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case MultiplyNeg64:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.ZDef, GP, 64);
+ break;
+ break;
+ case Div32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case Div64:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Def, GP, 64);
+ break;
+ break;
+ case MulDouble:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Use, FP, 64);
+ inst.visitArg(2, func, Arg.Def, FP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.UseDef, FP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case MulFloat:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Def, FP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.UseDef, FP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case DivDouble:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Def, FP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.UseDef, FP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case DivFloat:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Def, FP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.UseDef, FP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case X86ConvertToDoubleWord32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case X86ConvertToQuadWord64:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Def, GP, 64);
+ break;
+ break;
+ case X86Div32:
+ inst.visitArg(0, func, Arg.UseZDef, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ break;
+ break;
+ case X86Div64:
+ inst.visitArg(0, func, Arg.UseZDef, GP, 64);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ break;
+ break;
+ case Lea:
+ inst.visitArg(0, func, Arg.UseAddr, GP, Ptr);
+ inst.visitArg(1, func, Arg.Def, GP, Ptr);
+ break;
+ break;
+ case And32:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.ZDef, GP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case And64:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Def, GP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.UseDef, GP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case AndDouble:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Use, FP, 64);
+ inst.visitArg(2, func, Arg.Def, FP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.UseDef, FP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case AndFloat:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Def, FP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.UseDef, FP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case XorDouble:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Use, FP, 64);
+ inst.visitArg(2, func, Arg.Def, FP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.UseDef, FP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case XorFloat:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Def, FP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.UseDef, FP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Lshift32:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.ZDef, GP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Lshift64:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.ZDef, GP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.UseDef, GP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Rshift32:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.ZDef, GP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Rshift64:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.ZDef, GP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.UseDef, GP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Urshift32:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.ZDef, GP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Urshift64:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.ZDef, GP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.UseDef, GP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Or32:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.ZDef, GP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Or64:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Def, GP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.UseDef, GP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Xor32:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.ZDef, GP, 32);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Xor64:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Def, GP, 64);
+ break;
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.UseDef, GP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Not32:
+ switch (inst.args.length) {
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ case 1:
+ inst.visitArg(0, func, Arg.UseZDef, GP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case Not64:
+ switch (inst.args.length) {
+ case 2:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Def, GP, 64);
+ break;
+ case 1:
+ inst.visitArg(0, func, Arg.UseDef, GP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case AbsDouble:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case AbsFloat:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Def, FP, 32);
+ break;
+ break;
+ case CeilDouble:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case CeilFloat:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Def, FP, 32);
+ break;
+ break;
+ case FloorDouble:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case FloorFloat:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Def, FP, 32);
+ break;
+ break;
+ case SqrtDouble:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case SqrtFloat:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Def, FP, 32);
+ break;
+ break;
+ case ConvertInt32ToDouble:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case ConvertInt64ToDouble:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case ConvertInt32ToFloat:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Def, FP, 32);
+ break;
+ break;
+ case ConvertInt64ToFloat:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Def, FP, 32);
+ break;
+ break;
+ case CountLeadingZeros32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case CountLeadingZeros64:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Def, GP, 64);
+ break;
+ break;
+ case ConvertDoubleToFloat:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Def, FP, 32);
+ break;
+ break;
+ case ConvertFloatToDouble:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case Move:
+ inst.visitArg(0, func, Arg.Use, GP, Ptr);
+ inst.visitArg(1, func, Arg.Def, GP, Ptr);
+ break;
+ break;
+ case Swap32:
+ inst.visitArg(0, func, Arg.UseDef, GP, 32);
+ inst.visitArg(1, func, Arg.UseDef, GP, 32);
+ break;
+ break;
+ case Swap64:
+ inst.visitArg(0, func, Arg.UseDef, GP, 64);
+ inst.visitArg(1, func, Arg.UseDef, GP, 64);
+ break;
+ break;
+ case Move32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case StoreZero32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ break;
+ break;
+ case SignExtend32ToPtr:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Def, GP, Ptr);
+ break;
+ break;
+ case ZeroExtend8To32:
+ inst.visitArg(0, func, Arg.Use, GP, 8);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case SignExtend8To32:
+ inst.visitArg(0, func, Arg.Use, GP, 8);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case ZeroExtend16To32:
+ inst.visitArg(0, func, Arg.Use, GP, 16);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case SignExtend16To32:
+ inst.visitArg(0, func, Arg.Use, GP, 16);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case MoveFloat:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Def, FP, 32);
+ break;
+ break;
+ case MoveDouble:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case MoveZeroToDouble:
+ inst.visitArg(0, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case Move64ToDouble:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ inst.visitArg(1, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case Move32ToFloat:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Def, FP, 32);
+ break;
+ break;
+ case MoveDoubleTo64:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ inst.visitArg(1, func, Arg.Def, GP, 64);
+ break;
+ break;
+ case MoveFloatTo32:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ inst.visitArg(1, func, Arg.Def, GP, 32);
+ break;
+ break;
+ case Load8:
+ inst.visitArg(0, func, Arg.Use, GP, 8);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case Store8:
+ inst.visitArg(0, func, Arg.Use, GP, 8);
+ inst.visitArg(1, func, Arg.Def, GP, 8);
+ break;
+ break;
+ case Load8SignedExtendTo32:
+ inst.visitArg(0, func, Arg.Use, GP, 8);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case Load16:
+ inst.visitArg(0, func, Arg.Use, GP, 16);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case Load16SignedExtendTo32:
+ inst.visitArg(0, func, Arg.Use, GP, 16);
+ inst.visitArg(1, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case Store16:
+ inst.visitArg(0, func, Arg.Use, GP, 16);
+ inst.visitArg(1, func, Arg.Def, GP, 16);
+ break;
+ break;
+ case Compare32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case Compare64:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ inst.visitArg(3, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case Test32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case Test64:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ inst.visitArg(3, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case CompareDouble:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 64);
+ inst.visitArg(2, func, Arg.Use, FP, 64);
+ inst.visitArg(3, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case CompareFloat:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Use, FP, 32);
+ inst.visitArg(3, func, Arg.ZDef, GP, 32);
+ break;
+ break;
+ case Branch8:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 8);
+ inst.visitArg(2, func, Arg.Use, GP, 8);
+ break;
+ break;
+ case Branch32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ break;
+ break;
+ case Branch64:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ break;
+ break;
+ case BranchTest8:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 8);
+ inst.visitArg(2, func, Arg.Use, GP, 8);
+ break;
+ break;
+ case BranchTest32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ break;
+ break;
+ case BranchTest64:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ break;
+ break;
+ case BranchDouble:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 64);
+ inst.visitArg(2, func, Arg.Use, FP, 64);
+ break;
+ break;
+ case BranchFloat:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Use, FP, 32);
+ break;
+ break;
+ case BranchAdd32:
+ switch (inst.args.length) {
+ case 4:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.ZDef, GP, 32);
+ break;
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.UseZDef, GP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case BranchAdd64:
+ switch (inst.args.length) {
+ case 4:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ inst.visitArg(3, func, Arg.ZDef, GP, 64);
+ break;
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.UseDef, GP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case BranchMul32:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.UseZDef, GP, 32);
+ break;
+ case 4:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.ZDef, GP, 32);
+ break;
+ case 6:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.Scratch, GP, 32);
+ inst.visitArg(4, func, Arg.Scratch, GP, 32);
+ inst.visitArg(5, func, Arg.ZDef, GP, 32);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case BranchMul64:
+ switch (inst.args.length) {
+ case 3:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.UseZDef, GP, 64);
+ break;
+ case 6:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ inst.visitArg(3, func, Arg.Scratch, GP, 64);
+ inst.visitArg(4, func, Arg.Scratch, GP, 64);
+ inst.visitArg(5, func, Arg.ZDef, GP, 64);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case BranchSub32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.UseZDef, GP, 32);
+ break;
+ break;
+ case BranchSub64:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.UseDef, GP, 64);
+ break;
+ break;
+ case BranchNeg32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 32);
+ break;
+ break;
+ case BranchNeg64:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.UseZDef, GP, 64);
+ break;
+ break;
+ case MoveConditionally32:
+ switch (inst.args.length) {
+ case 5:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
+ break;
+ case 6:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.Use, GP, Ptr);
+ inst.visitArg(5, func, Arg.Def, GP, Ptr);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case MoveConditionally64:
+ switch (inst.args.length) {
+ case 5:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
+ break;
+ case 6:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.Use, GP, Ptr);
+ inst.visitArg(5, func, Arg.Def, GP, Ptr);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case MoveConditionallyTest32:
+ switch (inst.args.length) {
+ case 5:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
+ break;
+ case 6:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.Use, GP, Ptr);
+ inst.visitArg(5, func, Arg.Def, GP, Ptr);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case MoveConditionallyTest64:
+ switch (inst.args.length) {
+ case 5:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
+ break;
+ case 6:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.Use, GP, Ptr);
+ inst.visitArg(5, func, Arg.Def, GP, Ptr);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case MoveConditionallyDouble:
+ switch (inst.args.length) {
+ case 6:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 64);
+ inst.visitArg(2, func, Arg.Use, FP, 64);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.Use, GP, Ptr);
+ inst.visitArg(5, func, Arg.Def, GP, Ptr);
+ break;
+ case 5:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 64);
+ inst.visitArg(2, func, Arg.Use, FP, 64);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case MoveConditionallyFloat:
+ switch (inst.args.length) {
+ case 6:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Use, FP, 32);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.Use, GP, Ptr);
+ inst.visitArg(5, func, Arg.Def, GP, Ptr);
+ break;
+ case 5:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Use, FP, 32);
+ inst.visitArg(3, func, Arg.Use, GP, Ptr);
+ inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
+ break;
+ default:
+ throw new Error("Bad overload");
+ break;
+ }
+ break;
+ case MoveDoubleConditionally32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.Use, FP, 64);
+ inst.visitArg(4, func, Arg.Use, FP, 64);
+ inst.visitArg(5, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case MoveDoubleConditionally64:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ inst.visitArg(3, func, Arg.Use, FP, 64);
+ inst.visitArg(4, func, Arg.Use, FP, 64);
+ inst.visitArg(5, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case MoveDoubleConditionallyTest32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 32);
+ inst.visitArg(2, func, Arg.Use, GP, 32);
+ inst.visitArg(3, func, Arg.Use, FP, 64);
+ inst.visitArg(4, func, Arg.Use, FP, 64);
+ inst.visitArg(5, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case MoveDoubleConditionallyTest64:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, GP, 64);
+ inst.visitArg(2, func, Arg.Use, GP, 64);
+ inst.visitArg(3, func, Arg.Use, FP, 64);
+ inst.visitArg(4, func, Arg.Use, FP, 64);
+ inst.visitArg(5, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case MoveDoubleConditionallyDouble:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 64);
+ inst.visitArg(2, func, Arg.Use, FP, 64);
+ inst.visitArg(3, func, Arg.Use, FP, 64);
+ inst.visitArg(4, func, Arg.Use, FP, 64);
+ inst.visitArg(5, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case MoveDoubleConditionallyFloat:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ inst.visitArg(1, func, Arg.Use, FP, 32);
+ inst.visitArg(2, func, Arg.Use, FP, 32);
+ inst.visitArg(3, func, Arg.Use, FP, 64);
+ inst.visitArg(4, func, Arg.Use, FP, 64);
+ inst.visitArg(5, func, Arg.Def, FP, 64);
+ break;
+ break;
+ case Jump:
+ break;
+ break;
+ case Ret32:
+ inst.visitArg(0, func, Arg.Use, GP, 32);
+ break;
+ break;
+ case Ret64:
+ inst.visitArg(0, func, Arg.Use, GP, 64);
+ break;
+ break;
+ case RetFloat:
+ inst.visitArg(0, func, Arg.Use, FP, 32);
+ break;
+ break;
+ case RetDouble:
+ inst.visitArg(0, func, Arg.Use, FP, 64);
+ break;
+ break;
+ case Oops:
+ break;
+ break;
+ case Shuffle:
+ ShuffleCustom.forEachArg(inst, func);
+ break;
+ case Patch:
+ PatchCustom.forEachArg(inst, func);
+ break;
+ case CCall:
+ CCallCustom.forEachArg(inst, func);
+ break;
+ case ColdCCall:
+ ColdCCallCustom.forEachArg(inst, func);
+ break;
+ default:
+ throw "Bad opcode";
+ }
+}
+function Inst_hasNonArgEffects(inst)
+{
+ switch (inst.opcode) {
+ case Branch8:
+ case Branch32:
+ case Branch64:
+ case BranchTest8:
+ case BranchTest32:
+ case BranchTest64:
+ case BranchDouble:
+ case BranchFloat:
+ case BranchAdd32:
+ case BranchAdd64:
+ case BranchMul32:
+ case BranchMul64:
+ case BranchSub32:
+ case BranchSub64:
+ case BranchNeg32:
+ case BranchNeg64:
+ case Jump:
+ case Ret32:
+ case Ret64:
+ case RetFloat:
+ case RetDouble:
+ case Oops:
+ return true;
+ case Shuffle:
+ return ShuffleCustom.hasNonArgNonControlEffects(inst);
+ case Patch:
+ return PatchCustom.hasNonArgNonControlEffects(inst);
+ case CCall:
+ return CCallCustom.hasNonArgNonControlEffects(inst);
+ case ColdCCall:
+ return ColdCCallCustom.hasNonArgNonControlEffects(inst);
+ default:
+ return false;
+ }
+}
+function opcodeCode(opcode)
+{
+ switch (opcode) {
+ case AbsDouble:
+ return 0
+ case AbsFloat:
+ return 1
+ case Add16:
+ return 2
+ case Add32:
+ return 3
+ case Add64:
+ return 4
+ case Add8:
+ return 5
+ case AddDouble:
+ return 6
+ case AddFloat:
+ return 7
+ case And32:
+ return 8
+ case And64:
+ return 9
+ case AndDouble:
+ return 10
+ case AndFloat:
+ return 11
+ case Branch32:
+ return 12
+ case Branch64:
+ return 13
+ case Branch8:
+ return 14
+ case BranchAdd32:
+ return 15
+ case BranchAdd64:
+ return 16
+ case BranchDouble:
+ return 17
+ case BranchFloat:
+ return 18
+ case BranchMul32:
+ return 19
+ case BranchMul64:
+ return 20
+ case BranchNeg32:
+ return 21
+ case BranchNeg64:
+ return 22
+ case BranchSub32:
+ return 23
+ case BranchSub64:
+ return 24
+ case BranchTest32:
+ return 25
+ case BranchTest64:
+ return 26
+ case BranchTest8:
+ return 27
+ case CCall:
+ return 28
+ case CeilDouble:
+ return 29
+ case CeilFloat:
+ return 30
+ case ColdCCall:
+ return 31
+ case Compare32:
+ return 32
+ case Compare64:
+ return 33
+ case CompareDouble:
+ return 34
+ case CompareFloat:
+ return 35
+ case ConvertDoubleToFloat:
+ return 36
+ case ConvertFloatToDouble:
+ return 37
+ case ConvertInt32ToDouble:
+ return 38
+ case ConvertInt32ToFloat:
+ return 39
+ case ConvertInt64ToDouble:
+ return 40
+ case ConvertInt64ToFloat:
+ return 41
+ case CountLeadingZeros32:
+ return 42
+ case CountLeadingZeros64:
+ return 43
+ case Div32:
+ return 44
+ case Div64:
+ return 45
+ case DivDouble:
+ return 46
+ case DivFloat:
+ return 47
+ case FloorDouble:
+ return 48
+ case FloorFloat:
+ return 49
+ case Jump:
+ return 50
+ case Lea:
+ return 51
+ case Load16:
+ return 52
+ case Load16SignedExtendTo32:
+ return 53
+ case Load8:
+ return 54
+ case Load8SignedExtendTo32:
+ return 55
+ case Lshift32:
+ return 56
+ case Lshift64:
+ return 57
+ case Move:
+ return 58
+ case Move32:
+ return 59
+ case Move32ToFloat:
+ return 60
+ case Move64ToDouble:
+ return 61
+ case MoveConditionally32:
+ return 62
+ case MoveConditionally64:
+ return 63
+ case MoveConditionallyDouble:
+ return 64
+ case MoveConditionallyFloat:
+ return 65
+ case MoveConditionallyTest32:
+ return 66
+ case MoveConditionallyTest64:
+ return 67
+ case MoveDouble:
+ return 68
+ case MoveDoubleConditionally32:
+ return 69
+ case MoveDoubleConditionally64:
+ return 70
+ case MoveDoubleConditionallyDouble:
+ return 71
+ case MoveDoubleConditionallyFloat:
+ return 72
+ case MoveDoubleConditionallyTest32:
+ return 73
+ case MoveDoubleConditionallyTest64:
+ return 74
+ case MoveDoubleTo64:
+ return 75
+ case MoveFloat:
+ return 76
+ case MoveFloatTo32:
+ return 77
+ case MoveZeroToDouble:
+ return 78
+ case Mul32:
+ return 79
+ case Mul64:
+ return 80
+ case MulDouble:
+ return 81
+ case MulFloat:
+ return 82
+ case MultiplyAdd32:
+ return 83
+ case MultiplyAdd64:
+ return 84
+ case MultiplyNeg32:
+ return 85
+ case MultiplyNeg64:
+ return 86
+ case MultiplySub32:
+ return 87
+ case MultiplySub64:
+ return 88
+ case Neg32:
+ return 89
+ case Neg64:
+ return 90
+ case NegateDouble:
+ return 91
+ case Nop:
+ return 92
+ case Not32:
+ return 93
+ case Not64:
+ return 94
+ case Oops:
+ return 95
+ case Or32:
+ return 96
+ case Or64:
+ return 97
+ case Patch:
+ return 98
+ case Ret32:
+ return 99
+ case Ret64:
+ return 100
+ case RetDouble:
+ return 101
+ case RetFloat:
+ return 102
+ case Rshift32:
+ return 103
+ case Rshift64:
+ return 104
+ case Shuffle:
+ return 105
+ case SignExtend16To32:
+ return 106
+ case SignExtend32ToPtr:
+ return 107
+ case SignExtend8To32:
+ return 108
+ case SqrtDouble:
+ return 109
+ case SqrtFloat:
+ return 110
+ case Store16:
+ return 111
+ case Store8:
+ return 112
+ case StoreZero32:
+ return 113
+ case Sub32:
+ return 114
+ case Sub64:
+ return 115
+ case SubDouble:
+ return 116
+ case SubFloat:
+ return 117
+ case Swap32:
+ return 118
+ case Swap64:
+ return 119
+ case Test32:
+ return 120
+ case Test64:
+ return 121
+ case Urshift32:
+ return 122
+ case Urshift64:
+ return 123
+ case X86ConvertToDoubleWord32:
+ return 124
+ case X86ConvertToQuadWord64:
+ return 125
+ case X86Div32:
+ return 126
+ case X86Div64:
+ return 127
+ case Xor32:
+ return 128
+ case Xor64:
+ return 129
+ case XorDouble:
+ return 130
+ case XorFloat:
+ return 131
+ case ZeroExtend16To32:
+ return 132
+ case ZeroExtend8To32:
+ return 133
+ default:
+ throw new Error("bad opcode");
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/payload-airjs-ACLj8C.js b/third_party/webkit/PerformanceTests/ARES-6/Air/payload-airjs-ACLj8C.js
new file mode 100644
index 0000000000..013b87a773
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/payload-airjs-ACLj8C.js
@@ -0,0 +1,1730 @@
+"use strict";
+// Generated by Air::dumpAsJS from #ACLj8C in Air.js
+function createPayloadAirJSACLj8C()
+{
+ let code = new Code();
+ let bb0 = code.addBlock();
+ let bb1 = code.addBlock();
+ let bb2 = code.addBlock();
+ let bb3 = code.addBlock();
+ let bb4 = code.addBlock();
+ let bb5 = code.addBlock();
+ let bb6 = code.addBlock();
+ let bb7 = code.addBlock();
+ let bb8 = code.addBlock();
+ let bb9 = code.addBlock();
+ let bb10 = code.addBlock();
+ let bb11 = code.addBlock();
+ let bb12 = code.addBlock();
+ let bb13 = code.addBlock();
+ let bb14 = code.addBlock();
+ let bb15 = code.addBlock();
+ let slot0 = code.addStackSlot(160, Locked);
+ let slot1 = code.addStackSlot(8, Spill);
+ let slot2 = code.addStackSlot(8, Spill);
+ let slot3 = code.addStackSlot(8, Spill);
+ let slot4 = code.addStackSlot(40, Locked);
+ slot4.setOffsetFromFP(-40);
+ let tmp61 = code.newTmp(GP);
+ let tmp60 = code.newTmp(GP);
+ let tmp59 = code.newTmp(GP);
+ let tmp58 = code.newTmp(GP);
+ let tmp57 = code.newTmp(GP);
+ let tmp56 = code.newTmp(GP);
+ let tmp55 = code.newTmp(GP);
+ let tmp54 = code.newTmp(GP);
+ let tmp53 = code.newTmp(GP);
+ let tmp52 = code.newTmp(GP);
+ let tmp51 = code.newTmp(GP);
+ let tmp50 = code.newTmp(GP);
+ let tmp49 = code.newTmp(GP);
+ let tmp48 = code.newTmp(GP);
+ let tmp47 = code.newTmp(GP);
+ let tmp46 = code.newTmp(GP);
+ let tmp45 = code.newTmp(GP);
+ let tmp44 = code.newTmp(GP);
+ let tmp43 = code.newTmp(GP);
+ let tmp42 = code.newTmp(GP);
+ let tmp41 = code.newTmp(GP);
+ let tmp40 = code.newTmp(GP);
+ let tmp39 = code.newTmp(GP);
+ let tmp38 = code.newTmp(GP);
+ let tmp37 = code.newTmp(GP);
+ let tmp36 = code.newTmp(GP);
+ let tmp35 = code.newTmp(GP);
+ let tmp34 = code.newTmp(GP);
+ let tmp33 = code.newTmp(GP);
+ let tmp32 = code.newTmp(GP);
+ let tmp31 = code.newTmp(GP);
+ let tmp30 = code.newTmp(GP);
+ let tmp29 = code.newTmp(GP);
+ let tmp28 = code.newTmp(GP);
+ let tmp27 = code.newTmp(GP);
+ let tmp26 = code.newTmp(GP);
+ let tmp25 = code.newTmp(GP);
+ let tmp24 = code.newTmp(GP);
+ let tmp23 = code.newTmp(GP);
+ let tmp22 = code.newTmp(GP);
+ let tmp21 = code.newTmp(GP);
+ let tmp20 = code.newTmp(GP);
+ let tmp19 = code.newTmp(GP);
+ let tmp18 = code.newTmp(GP);
+ let tmp17 = code.newTmp(GP);
+ let tmp16 = code.newTmp(GP);
+ let tmp15 = code.newTmp(GP);
+ let tmp14 = code.newTmp(GP);
+ let tmp13 = code.newTmp(GP);
+ let tmp12 = code.newTmp(GP);
+ let tmp11 = code.newTmp(GP);
+ let tmp10 = code.newTmp(GP);
+ let tmp9 = code.newTmp(GP);
+ let tmp8 = code.newTmp(GP);
+ let tmp7 = code.newTmp(GP);
+ let tmp6 = code.newTmp(GP);
+ let tmp5 = code.newTmp(GP);
+ let tmp4 = code.newTmp(GP);
+ let tmp3 = code.newTmp(GP);
+ let tmp2 = code.newTmp(GP);
+ let tmp1 = code.newTmp(GP);
+ let tmp0 = code.newTmp(GP);
+ let inst;
+ let arg;
+ bb0.successors.push(new FrequentedBlock(bb1, Normal));
+ bb0.successors.push(new FrequentedBlock(bb15, Normal));
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(276424800, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbp, 16);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbp);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Scratch, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbp, 72);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbp, 64);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbp, 56);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbp, 48);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(2, -65536);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbp, 24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 16);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(0, -65536);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rcx, 32);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rcx, 40);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(276327648, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.r8, 5);
+ inst.args.push(arg);
+ arg = Arg.createImm(21);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.r12, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(372);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.r12, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, -40);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(276321024, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 72);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 64);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 56);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 48);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 40);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Xor64);
+ arg = Arg.createImm(6);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(-2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot2, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(-2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot3, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ bb1.successors.push(new FrequentedBlock(bb3, Normal));
+ bb1.successors.push(new FrequentedBlock(bb2, Normal));
+ bb1.predecessors.push(bb0);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.r8, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(468);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb1.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.r8, 16);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb1.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(276741160, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb1.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rcx, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb1.append(inst);
+ inst = new Inst(Branch64);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rax, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb1.append(inst);
+ bb2.predecessors.push(bb1);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb2.append(inst);
+ inst = new Inst(Oops);
+ bb2.append(inst);
+ bb3.successors.push(new FrequentedBlock(bb4, Normal));
+ bb3.successors.push(new FrequentedBlock(bb7, Normal));
+ bb3.predecessors.push(bb1);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.r8, 24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ bb3.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 5);
+ inst.args.push(arg);
+ arg = Arg.createImm(23);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb3.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(275739616, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb3.append(inst);
+ inst = new Inst(Branch64);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb3.append(inst);
+ bb4.successors.push(new FrequentedBlock(bb5, Normal));
+ bb4.successors.push(new FrequentedBlock(bb6, Normal));
+ bb4.predecessors.push(bb3);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 0);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 16);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 32);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 32);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 24);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 16);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 8);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(276645872, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(276646496, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rdx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm0);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb4.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Xor64);
+ arg = Arg.createImm(6);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(-2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb4.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb4.append(inst);
+ bb5.successors.push(new FrequentedBlock(bb8, Normal));
+ bb5.predecessors.push(bb4);
+ inst = new Inst(Move);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateUse, type: GP, width: 64});
+ bb5.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb5.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb5.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rcx, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(419);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb5.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(276168608, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rdx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm0);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb5.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb5.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Jump);
+ bb5.append(inst);
+ bb6.successors.push(new FrequentedBlock(bb8, Normal));
+ bb6.predecessors.push(bb4);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Jump);
+ bb6.append(inst);
+ bb7.successors.push(new FrequentedBlock(bb12, Normal));
+ bb7.successors.push(new FrequentedBlock(bb9, Normal));
+ bb7.predecessors.push(bb3);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb7.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ bb7.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(5);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ bb7.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ bb7.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ bb7.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(40);
+ inst.args.push(arg);
+ bb7.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(48);
+ inst.args.push(arg);
+ bb7.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(56);
+ inst.args.push(arg);
+ bb7.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(40);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(48);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(56);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rdx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm0);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb7.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb7.append(inst);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ bb7.append(inst);
+ bb8.successors.push(new FrequentedBlock(bb13, Normal));
+ bb8.successors.push(new FrequentedBlock(bb10, Normal));
+ bb8.predecessors.push(bb6);
+ bb8.predecessors.push(bb5);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ bb8.append(inst);
+ bb9.successors.push(new FrequentedBlock(bb11, Normal));
+ bb9.predecessors.push(bb7);
+ inst = new Inst(Jump);
+ bb9.append(inst);
+ bb10.successors.push(new FrequentedBlock(bb11, Normal));
+ bb10.predecessors.push(bb8);
+ inst = new Inst(Jump);
+ bb10.append(inst);
+ bb11.predecessors.push(bb9);
+ bb11.predecessors.push(bb10);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rax, 5);
+ inst.args.push(arg);
+ arg = Arg.createImm(20);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb11.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb11.append(inst);
+ inst = new Inst(Oops);
+ bb11.append(inst);
+ bb12.successors.push(new FrequentedBlock(bb14, Normal));
+ bb12.predecessors.push(bb7);
+ inst = new Inst(Jump);
+ bb12.append(inst);
+ bb13.successors.push(new FrequentedBlock(bb14, Normal));
+ bb13.predecessors.push(bb8);
+ inst = new Inst(Jump);
+ bb13.append(inst);
+ bb14.predecessors.push(bb12);
+ bb14.predecessors.push(bb13);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb14.append(inst);
+ inst = new Inst(And64);
+ arg = Arg.createImm(-9);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb14.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb14.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb14.append(inst);
+ inst = new Inst(Ret64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb14.append(inst);
+ bb15.predecessors.push(bb0);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb15.append(inst);
+ inst = new Inst(Ret64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb15.append(inst);
+ return code;
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/payload-gbemu-executeIteration.js b/third_party/webkit/PerformanceTests/ARES-6/Air/payload-gbemu-executeIteration.js
new file mode 100644
index 0000000000..2b0b80b3a1
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/payload-gbemu-executeIteration.js
@@ -0,0 +1,3229 @@
+"use strict";
+// Generated by Air::dumpAsJS from executeIteration#EVx8pJ in Octane/gbemu
+function createPayloadGbemuExecuteIteration()
+{
+ let code = new Code();
+ let bb0 = code.addBlock();
+ let bb1 = code.addBlock();
+ let bb2 = code.addBlock();
+ let bb3 = code.addBlock();
+ let bb4 = code.addBlock();
+ let bb5 = code.addBlock();
+ let bb6 = code.addBlock();
+ let bb7 = code.addBlock();
+ let bb8 = code.addBlock();
+ let bb9 = code.addBlock();
+ let bb10 = code.addBlock();
+ let bb11 = code.addBlock();
+ let bb12 = code.addBlock();
+ let bb13 = code.addBlock();
+ let bb14 = code.addBlock();
+ let bb15 = code.addBlock();
+ let bb16 = code.addBlock();
+ let bb17 = code.addBlock();
+ let bb18 = code.addBlock();
+ let bb19 = code.addBlock();
+ let bb20 = code.addBlock();
+ let bb21 = code.addBlock();
+ let bb22 = code.addBlock();
+ let bb23 = code.addBlock();
+ let bb24 = code.addBlock();
+ let bb25 = code.addBlock();
+ let bb26 = code.addBlock();
+ let bb27 = code.addBlock();
+ let bb28 = code.addBlock();
+ let bb29 = code.addBlock();
+ let bb30 = code.addBlock();
+ let bb31 = code.addBlock();
+ let bb32 = code.addBlock();
+ let bb33 = code.addBlock();
+ let bb34 = code.addBlock();
+ let bb35 = code.addBlock();
+ let bb36 = code.addBlock();
+ let bb37 = code.addBlock();
+ let bb38 = code.addBlock();
+ let bb39 = code.addBlock();
+ let bb40 = code.addBlock();
+ let bb41 = code.addBlock();
+ let bb42 = code.addBlock();
+ let slot0 = code.addStackSlot(64, Locked);
+ let slot1 = code.addStackSlot(8, Spill);
+ let slot2 = code.addStackSlot(8, Spill);
+ let slot3 = code.addStackSlot(8, Spill);
+ let slot4 = code.addStackSlot(8, Spill);
+ let slot5 = code.addStackSlot(8, Spill);
+ let slot6 = code.addStackSlot(8, Spill);
+ let slot7 = code.addStackSlot(8, Spill);
+ let slot8 = code.addStackSlot(8, Spill);
+ let slot9 = code.addStackSlot(8, Spill);
+ let slot10 = code.addStackSlot(8, Spill);
+ let slot11 = code.addStackSlot(8, Spill);
+ let slot12 = code.addStackSlot(40, Locked);
+ slot12.setOffsetFromFP(-40);
+ let tmp190 = code.newTmp(GP);
+ let tmp189 = code.newTmp(GP);
+ let tmp188 = code.newTmp(GP);
+ let tmp187 = code.newTmp(GP);
+ let tmp186 = code.newTmp(GP);
+ let tmp185 = code.newTmp(GP);
+ let tmp184 = code.newTmp(GP);
+ let tmp183 = code.newTmp(GP);
+ let tmp182 = code.newTmp(GP);
+ let tmp181 = code.newTmp(GP);
+ let tmp180 = code.newTmp(GP);
+ let tmp179 = code.newTmp(GP);
+ let tmp178 = code.newTmp(GP);
+ let tmp177 = code.newTmp(GP);
+ let tmp176 = code.newTmp(GP);
+ let tmp175 = code.newTmp(GP);
+ let tmp174 = code.newTmp(GP);
+ let tmp173 = code.newTmp(GP);
+ let tmp172 = code.newTmp(GP);
+ let tmp171 = code.newTmp(GP);
+ let tmp170 = code.newTmp(GP);
+ let tmp169 = code.newTmp(GP);
+ let tmp168 = code.newTmp(GP);
+ let tmp167 = code.newTmp(GP);
+ let tmp166 = code.newTmp(GP);
+ let tmp165 = code.newTmp(GP);
+ let tmp164 = code.newTmp(GP);
+ let tmp163 = code.newTmp(GP);
+ let tmp162 = code.newTmp(GP);
+ let tmp161 = code.newTmp(GP);
+ let tmp160 = code.newTmp(GP);
+ let tmp159 = code.newTmp(GP);
+ let tmp158 = code.newTmp(GP);
+ let tmp157 = code.newTmp(GP);
+ let tmp156 = code.newTmp(GP);
+ let tmp155 = code.newTmp(GP);
+ let tmp154 = code.newTmp(GP);
+ let tmp153 = code.newTmp(GP);
+ let tmp152 = code.newTmp(GP);
+ let tmp151 = code.newTmp(GP);
+ let tmp150 = code.newTmp(GP);
+ let tmp149 = code.newTmp(GP);
+ let tmp148 = code.newTmp(GP);
+ let tmp147 = code.newTmp(GP);
+ let tmp146 = code.newTmp(GP);
+ let tmp145 = code.newTmp(GP);
+ let tmp144 = code.newTmp(GP);
+ let tmp143 = code.newTmp(GP);
+ let tmp142 = code.newTmp(GP);
+ let tmp141 = code.newTmp(GP);
+ let tmp140 = code.newTmp(GP);
+ let tmp139 = code.newTmp(GP);
+ let tmp138 = code.newTmp(GP);
+ let tmp137 = code.newTmp(GP);
+ let tmp136 = code.newTmp(GP);
+ let tmp135 = code.newTmp(GP);
+ let tmp134 = code.newTmp(GP);
+ let tmp133 = code.newTmp(GP);
+ let tmp132 = code.newTmp(GP);
+ let tmp131 = code.newTmp(GP);
+ let tmp130 = code.newTmp(GP);
+ let tmp129 = code.newTmp(GP);
+ let tmp128 = code.newTmp(GP);
+ let tmp127 = code.newTmp(GP);
+ let tmp126 = code.newTmp(GP);
+ let tmp125 = code.newTmp(GP);
+ let tmp124 = code.newTmp(GP);
+ let tmp123 = code.newTmp(GP);
+ let tmp122 = code.newTmp(GP);
+ let tmp121 = code.newTmp(GP);
+ let tmp120 = code.newTmp(GP);
+ let tmp119 = code.newTmp(GP);
+ let tmp118 = code.newTmp(GP);
+ let tmp117 = code.newTmp(GP);
+ let tmp116 = code.newTmp(GP);
+ let tmp115 = code.newTmp(GP);
+ let tmp114 = code.newTmp(GP);
+ let tmp113 = code.newTmp(GP);
+ let tmp112 = code.newTmp(GP);
+ let tmp111 = code.newTmp(GP);
+ let tmp110 = code.newTmp(GP);
+ let tmp109 = code.newTmp(GP);
+ let tmp108 = code.newTmp(GP);
+ let tmp107 = code.newTmp(GP);
+ let tmp106 = code.newTmp(GP);
+ let tmp105 = code.newTmp(GP);
+ let tmp104 = code.newTmp(GP);
+ let tmp103 = code.newTmp(GP);
+ let tmp102 = code.newTmp(GP);
+ let tmp101 = code.newTmp(GP);
+ let tmp100 = code.newTmp(GP);
+ let tmp99 = code.newTmp(GP);
+ let tmp98 = code.newTmp(GP);
+ let tmp97 = code.newTmp(GP);
+ let tmp96 = code.newTmp(GP);
+ let tmp95 = code.newTmp(GP);
+ let tmp94 = code.newTmp(GP);
+ let tmp93 = code.newTmp(GP);
+ let tmp92 = code.newTmp(GP);
+ let tmp91 = code.newTmp(GP);
+ let tmp90 = code.newTmp(GP);
+ let tmp89 = code.newTmp(GP);
+ let tmp88 = code.newTmp(GP);
+ let tmp87 = code.newTmp(GP);
+ let tmp86 = code.newTmp(GP);
+ let tmp85 = code.newTmp(GP);
+ let tmp84 = code.newTmp(GP);
+ let tmp83 = code.newTmp(GP);
+ let tmp82 = code.newTmp(GP);
+ let tmp81 = code.newTmp(GP);
+ let tmp80 = code.newTmp(GP);
+ let tmp79 = code.newTmp(GP);
+ let tmp78 = code.newTmp(GP);
+ let tmp77 = code.newTmp(GP);
+ let tmp76 = code.newTmp(GP);
+ let tmp75 = code.newTmp(GP);
+ let tmp74 = code.newTmp(GP);
+ let tmp73 = code.newTmp(GP);
+ let tmp72 = code.newTmp(GP);
+ let tmp71 = code.newTmp(GP);
+ let tmp70 = code.newTmp(GP);
+ let tmp69 = code.newTmp(GP);
+ let tmp68 = code.newTmp(GP);
+ let tmp67 = code.newTmp(GP);
+ let tmp66 = code.newTmp(GP);
+ let tmp65 = code.newTmp(GP);
+ let tmp64 = code.newTmp(GP);
+ let tmp63 = code.newTmp(GP);
+ let tmp62 = code.newTmp(GP);
+ let tmp61 = code.newTmp(GP);
+ let tmp60 = code.newTmp(GP);
+ let tmp59 = code.newTmp(GP);
+ let tmp58 = code.newTmp(GP);
+ let tmp57 = code.newTmp(GP);
+ let tmp56 = code.newTmp(GP);
+ let tmp55 = code.newTmp(GP);
+ let tmp54 = code.newTmp(GP);
+ let tmp53 = code.newTmp(GP);
+ let tmp52 = code.newTmp(GP);
+ let tmp51 = code.newTmp(GP);
+ let tmp50 = code.newTmp(GP);
+ let tmp49 = code.newTmp(GP);
+ let tmp48 = code.newTmp(GP);
+ let tmp47 = code.newTmp(GP);
+ let tmp46 = code.newTmp(GP);
+ let tmp45 = code.newTmp(GP);
+ let tmp44 = code.newTmp(GP);
+ let tmp43 = code.newTmp(GP);
+ let tmp42 = code.newTmp(GP);
+ let tmp41 = code.newTmp(GP);
+ let tmp40 = code.newTmp(GP);
+ let tmp39 = code.newTmp(GP);
+ let tmp38 = code.newTmp(GP);
+ let tmp37 = code.newTmp(GP);
+ let tmp36 = code.newTmp(GP);
+ let tmp35 = code.newTmp(GP);
+ let tmp34 = code.newTmp(GP);
+ let tmp33 = code.newTmp(GP);
+ let tmp32 = code.newTmp(GP);
+ let tmp31 = code.newTmp(GP);
+ let tmp30 = code.newTmp(GP);
+ let tmp29 = code.newTmp(GP);
+ let tmp28 = code.newTmp(GP);
+ let tmp27 = code.newTmp(GP);
+ let tmp26 = code.newTmp(GP);
+ let tmp25 = code.newTmp(GP);
+ let tmp24 = code.newTmp(GP);
+ let tmp23 = code.newTmp(GP);
+ let tmp22 = code.newTmp(GP);
+ let tmp21 = code.newTmp(GP);
+ let tmp20 = code.newTmp(GP);
+ let tmp19 = code.newTmp(GP);
+ let tmp18 = code.newTmp(GP);
+ let tmp17 = code.newTmp(GP);
+ let tmp16 = code.newTmp(GP);
+ let tmp15 = code.newTmp(GP);
+ let tmp14 = code.newTmp(GP);
+ let tmp13 = code.newTmp(GP);
+ let tmp12 = code.newTmp(GP);
+ let tmp11 = code.newTmp(GP);
+ let tmp10 = code.newTmp(GP);
+ let tmp9 = code.newTmp(GP);
+ let tmp8 = code.newTmp(GP);
+ let tmp7 = code.newTmp(GP);
+ let tmp6 = code.newTmp(GP);
+ let tmp5 = code.newTmp(GP);
+ let tmp4 = code.newTmp(GP);
+ let tmp3 = code.newTmp(GP);
+ let tmp2 = code.newTmp(GP);
+ let tmp1 = code.newTmp(GP);
+ let tmp0 = code.newTmp(GP);
+ let ftmp7 = code.newTmp(FP);
+ let ftmp6 = code.newTmp(FP);
+ let ftmp5 = code.newTmp(FP);
+ let ftmp4 = code.newTmp(FP);
+ let ftmp3 = code.newTmp(FP);
+ let ftmp2 = code.newTmp(FP);
+ let ftmp1 = code.newTmp(FP);
+ let ftmp0 = code.newTmp(FP);
+ let inst;
+ let arg;
+ bb0.successors.push(new FrequentedBlock(bb2, Normal));
+ bb0.successors.push(new FrequentedBlock(bb1, Normal));
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(286904960, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbp, 16);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbp);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Scratch, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbp, 40);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(2, -65536);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 5);
+ inst.args.push(arg);
+ arg = Arg.createImm(21);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createAddr(Reg.rbx, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(286506544, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot10, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(286455168, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot4, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(287131344, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot6, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot3, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(286474592, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot2, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(287209728, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot11, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(0, -65536);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(287112728, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot8, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(0, 65536);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot9, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(287112720, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(286506192, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot7, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(862);
+ inst.args.push(arg);
+ bb0.append(inst);
+ bb1.successors.push(new FrequentedBlock(bb41, Normal));
+ bb1.successors.push(new FrequentedBlock(bb3, Normal));
+ bb1.predecessors.push(bb0);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(881);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb1.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 224);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb1.append(inst);
+ inst = new Inst(BranchTest32);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb1.append(inst);
+ bb2.successors.push(new FrequentedBlock(bb41, Normal));
+ bb2.successors.push(new FrequentedBlock(bb3, Normal));
+ bb2.predecessors.push(bb0);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 224);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb2.append(inst);
+ inst = new Inst(BranchTest32);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb2.append(inst);
+ bb3.successors.push(new FrequentedBlock(bb5, Normal));
+ bb3.successors.push(new FrequentedBlock(bb4, Normal));
+ bb3.predecessors.push(bb1);
+ bb3.predecessors.push(bb40);
+ bb3.predecessors.push(bb39);
+ bb3.predecessors.push(bb2);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb3.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rsi, -1144);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb3.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ bb3.append(inst);
+ bb4.successors.push(new FrequentedBlock(bb6, Normal));
+ bb4.successors.push(new FrequentedBlock(bb7, Normal));
+ bb4.predecessors.push(bb3);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ bb4.append(inst);
+ bb5.successors.push(new FrequentedBlock(bb6, Normal));
+ bb5.predecessors.push(bb3);
+ inst = new Inst(Move);
+ arg = Arg.createImm(7);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 232);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 256);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 248);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(And32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(And32);
+ arg = Arg.createImm(31);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 240);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Jump);
+ bb5.append(inst);
+ bb6.successors.push(new FrequentedBlock(bb7, Normal));
+ bb6.predecessors.push(bb4);
+ bb6.predecessors.push(bb5);
+ inst = new Inst(Add32);
+ arg = Arg.createImm(-1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rsi, -1144);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Jump);
+ bb6.append(inst);
+ bb7.successors.push(new FrequentedBlock(bb8, Normal));
+ bb7.successors.push(new FrequentedBlock(bb9, Normal));
+ bb7.predecessors.push(bb4);
+ bb7.predecessors.push(bb6);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 240);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb7.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(GreaterThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(0);
+ inst.args.push(arg);
+ bb7.append(inst);
+ bb8.successors.push(new FrequentedBlock(bb9, Normal));
+ bb8.predecessors.push(bb7);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(286455168, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb8.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(286455168, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb8.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ bb8.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ bb8.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ bb8.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rdx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm0);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb8.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb8.append(inst);
+ inst = new Inst(Jump);
+ bb8.append(inst);
+ bb9.successors.push(new FrequentedBlock(bb12, Normal));
+ bb9.successors.push(new FrequentedBlock(bb10, Normal));
+ bb9.predecessors.push(bb7);
+ bb9.predecessors.push(bb8);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 304);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb9.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 128);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb9.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.r8, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(80);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb9.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.r8, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb9.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rax, -8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb9.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb9.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createIndex(Reg.rax, Reg.rsi, 8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb9.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb9.append(inst);
+ inst = new Inst(MoveConditionallyTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(-1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb9.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb9.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rcx, 5);
+ inst.args.push(arg);
+ arg = Arg.createImm(23);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb9.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rcx, 24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb9.append(inst);
+ inst = new Inst(Branch64);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot7, 0);
+ inst.args.push(arg);
+ bb9.append(inst);
+ bb10.successors.push(new FrequentedBlock(bb11, Normal));
+ bb10.successors.push(new FrequentedBlock(bb13, Normal));
+ bb10.predecessors.push(bb9);
+ inst = new Inst(Branch64);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot10, 0);
+ inst.args.push(arg);
+ bb10.append(inst);
+ bb11.successors.push(new FrequentedBlock(bb14, Normal));
+ bb11.predecessors.push(bb10);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 0);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 344);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rdi, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(502);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb11.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdi, 16);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rdi, 24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb11.append(inst);
+ inst = new Inst(Load8);
+ arg = Arg.createIndex(Reg.rsi, Reg.rax, 1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Jump);
+ bb11.append(inst);
+ bb12.successors.push(new FrequentedBlock(bb14, Normal));
+ bb12.predecessors.push(bb9);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 0);
+ inst.args.push(arg);
+ bb12.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 336);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb12.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 456);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb12.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb12.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rdi, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(502);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb12.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdi, 16);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb12.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rdi, 24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb12.append(inst);
+ inst = new Inst(Load8);
+ arg = Arg.createIndex(Reg.rsi, Reg.rax, 1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb12.append(inst);
+ inst = new Inst(Jump);
+ bb12.append(inst);
+ bb13.predecessors.push(bb10);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb13.append(inst);
+ inst = new Inst(Oops);
+ bb13.append(inst);
+ bb14.successors.push(new FrequentedBlock(bb15, Normal));
+ bb14.successors.push(new FrequentedBlock(bb16, Normal));
+ bb14.predecessors.push(bb11);
+ bb14.predecessors.push(bb12);
+ inst = new Inst(Add32);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb14.append(inst);
+ inst = new Inst(ZeroExtend16To32);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb14.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb14.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 128);
+ inst.args.push(arg);
+ bb14.append(inst);
+ inst = new Inst(BranchTest32);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 216);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ bb14.append(inst);
+ bb15.predecessors.push(bb14);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb15.append(inst);
+ inst = new Inst(Oops);
+ bb15.append(inst);
+ bb16.successors.push(new FrequentedBlock(bb18, Normal));
+ bb16.successors.push(new FrequentedBlock(bb17, Normal));
+ bb16.predecessors.push(bb14);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, -1752);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdx, 16);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rdx, 24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb16.append(inst);
+ inst = new Inst(Load8);
+ arg = Arg.createIndex(Reg.rax, Reg.rcx, 1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 272);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(287112720, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rax, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(80);
+ inst.args.push(arg);
+ arg = Arg.createBigImm(287112720, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(287112728, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rax, -8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createIndex(Reg.rax, Reg.rcx, 8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(MoveConditionallyTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(-1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(287112720, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rdx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm0);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdx, -1088);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 272);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 280);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Rshift32);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb16.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rdx, -1088);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdx, -88);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdx, -1176);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rcx, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(80);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rcx, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rax, -8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb16.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createIndex(Reg.rax, Reg.rdx, 8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(MoveConditionallyTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(-1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rax, 5);
+ inst.args.push(arg);
+ arg = Arg.createImm(23);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rdx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm0);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 272);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 280);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Rshift32);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rsi, -1048);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb16.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rsi, -1048);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rsi, -1072);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb16.append(inst);
+ inst = new Inst(Branch64);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ bb16.append(inst);
+ bb17.successors.push(new FrequentedBlock(bb19, Normal));
+ bb17.predecessors.push(bb16);
+ inst = new Inst(ConvertInt32ToDouble);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ bb17.append(inst);
+ inst = new Inst(Jump);
+ bb17.append(inst);
+ bb18.successors.push(new FrequentedBlock(bb19, Normal));
+ bb18.predecessors.push(bb16);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb18.append(inst);
+ inst = new Inst(Move64ToDouble);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ bb18.append(inst);
+ inst = new Inst(Jump);
+ bb18.append(inst);
+ bb19.successors.push(new FrequentedBlock(bb20, Normal));
+ bb19.successors.push(new FrequentedBlock(bb32, Normal));
+ bb19.predecessors.push(bb17);
+ bb19.predecessors.push(bb18);
+ inst = new Inst(ConvertInt32ToDouble);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ bb19.append(inst);
+ inst = new Inst(AddDouble);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ bb19.append(inst);
+ inst = new Inst(MoveDoubleTo64);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb19.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(0, 65536);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb19.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb19.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rsi, -1072);
+ inst.args.push(arg);
+ bb19.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rsi, -1080);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb19.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb19.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb19.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rsi, -1080);
+ inst.args.push(arg);
+ bb19.append(inst);
+ inst = new Inst(BranchTest32);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rsi, -1104);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ bb19.append(inst);
+ bb20.successors.push(new FrequentedBlock(bb21, Normal));
+ bb20.successors.push(new FrequentedBlock(bb32, Normal));
+ bb20.predecessors.push(bb19);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rsi, -1096);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb20.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rsi, -1096);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rsi, -1112);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(GreaterThanOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ bb20.append(inst);
+ bb21.successors.push(new FrequentedBlock(bb23, Normal));
+ bb21.predecessors.push(bb20);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 344);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ bb21.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.r12, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(502);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb21.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.r12, 16);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb21.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createAddr(Reg.r12, 24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ bb21.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(BelowOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ arg = Arg.createImm(65286);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb21.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 232);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ bb21.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 256);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb21.append(inst);
+ inst = new Inst(Jump);
+ bb21.append(inst);
+ bb22.successors.push(new FrequentedBlock(bb23, Normal));
+ bb22.predecessors.push(bb30);
+ bb22.predecessors.push(bb31);
+ bb22.predecessors.push(bb29);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb22.append(inst);
+ inst = new Inst(Jump);
+ bb22.append(inst);
+ bb23.successors.push(new FrequentedBlock(bb25, Normal));
+ bb23.successors.push(new FrequentedBlock(bb24, Normal));
+ bb23.predecessors.push(bb21);
+ bb23.predecessors.push(bb22);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.UseZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb23.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rsi, -1096);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Load8);
+ arg = Arg.createAddr(Reg.rdi, 65285);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.UseZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb23.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(BelowOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ arg = Arg.createImm(65285);
+ inst.args.push(arg);
+ bb23.append(inst);
+ bb24.successors.push(new FrequentedBlock(bb26, Normal));
+ bb24.successors.push(new FrequentedBlock(bb30, Normal));
+ bb24.predecessors.push(bb23);
+ inst = new Inst(Store8);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rdi, 65285);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createImm(256);
+ inst.args.push(arg);
+ bb24.append(inst);
+ bb25.successors.push(new FrequentedBlock(bb26, Normal));
+ bb25.successors.push(new FrequentedBlock(bb30, Normal));
+ bb25.predecessors.push(bb23);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createImm(256);
+ inst.args.push(arg);
+ bb25.append(inst);
+ bb26.successors.push(new FrequentedBlock(bb28, Normal));
+ bb26.successors.push(new FrequentedBlock(bb27, Normal));
+ bb26.predecessors.push(bb24);
+ bb26.predecessors.push(bb25);
+ inst = new Inst(Load8);
+ arg = Arg.createAddr(Reg.rdi, 65286);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb26.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(BelowOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ arg = Arg.createImm(65285);
+ inst.args.push(arg);
+ bb26.append(inst);
+ bb27.successors.push(new FrequentedBlock(bb28, Normal));
+ bb27.predecessors.push(bb26);
+ inst = new Inst(Store8);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rdi, 65285);
+ inst.args.push(arg);
+ bb27.append(inst);
+ inst = new Inst(Jump);
+ bb27.append(inst);
+ bb28.successors.push(new FrequentedBlock(bb29, Normal));
+ bb28.successors.push(new FrequentedBlock(bb31, Normal));
+ bb28.predecessors.push(bb26);
+ bb28.predecessors.push(bb27);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 248);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb28.append(inst);
+ inst = new Inst(Or32);
+ arg = Arg.createImm(4);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb28.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ bb28.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ bb28.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 248);
+ inst.args.push(arg);
+ bb28.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ bb28.append(inst);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ bb28.append(inst);
+ bb29.successors.push(new FrequentedBlock(bb22, Normal));
+ bb29.successors.push(new FrequentedBlock(bb32, Normal));
+ bb29.predecessors.push(bb28);
+ inst = new Inst(And32);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb29.append(inst);
+ inst = new Inst(And32);
+ arg = Arg.createImm(31);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb29.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb29.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 240);
+ inst.args.push(arg);
+ bb29.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(GreaterThanOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ bb29.append(inst);
+ bb30.successors.push(new FrequentedBlock(bb22, Normal));
+ bb30.successors.push(new FrequentedBlock(bb32, Normal));
+ bb30.predecessors.push(bb24);
+ bb30.predecessors.push(bb25);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(GreaterThanOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ bb30.append(inst);
+ bb31.successors.push(new FrequentedBlock(bb22, Normal));
+ bb31.successors.push(new FrequentedBlock(bb32, Normal));
+ bb31.predecessors.push(bb28);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(GreaterThanOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ bb31.append(inst);
+ bb32.successors.push(new FrequentedBlock(bb33, Normal));
+ bb32.successors.push(new FrequentedBlock(bb34, Normal));
+ bb32.predecessors.push(bb19);
+ bb32.predecessors.push(bb20);
+ bb32.predecessors.push(bb30);
+ bb32.predecessors.push(bb31);
+ bb32.predecessors.push(bb29);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rsi, -1120);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb32.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(GreaterThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(0);
+ inst.args.push(arg);
+ bb32.append(inst);
+ bb33.predecessors.push(bb32);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb33.append(inst);
+ inst = new Inst(Oops);
+ bb33.append(inst);
+ bb34.successors.push(new FrequentedBlock(bb36, Normal));
+ bb34.successors.push(new FrequentedBlock(bb35, Normal));
+ bb34.predecessors.push(bb32);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 136);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Branch64);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ bb34.append(inst);
+ bb35.successors.push(new FrequentedBlock(bb37, Normal));
+ bb35.successors.push(new FrequentedBlock(bb38, Normal));
+ bb35.predecessors.push(bb34);
+ inst = new Inst(ConvertInt32ToDouble);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ bb35.append(inst);
+ inst = new Inst(BranchDouble);
+ arg = Arg.createDoubleCond(DoubleGreaterThanOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ bb35.append(inst);
+ bb36.successors.push(new FrequentedBlock(bb37, Normal));
+ bb36.successors.push(new FrequentedBlock(bb38, Normal));
+ bb36.predecessors.push(bb34);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb36.append(inst);
+ inst = new Inst(Move64ToDouble);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ bb36.append(inst);
+ inst = new Inst(BranchDouble);
+ arg = Arg.createDoubleCond(DoubleGreaterThanOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ bb36.append(inst);
+ bb37.successors.push(new FrequentedBlock(bb38, Normal));
+ bb37.predecessors.push(bb35);
+ bb37.predecessors.push(bb36);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(286474592, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb37.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(286474592, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb37.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ bb37.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ bb37.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ bb37.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rdx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm0);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb37.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb37.append(inst);
+ inst = new Inst(Jump);
+ bb37.append(inst);
+ bb38.successors.push(new FrequentedBlock(bb39, Normal));
+ bb38.successors.push(new FrequentedBlock(bb40, Normal));
+ bb38.predecessors.push(bb35);
+ bb38.predecessors.push(bb37);
+ bb38.predecessors.push(bb36);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(881);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb38.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb38.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdx, -1824);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb38.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb38.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.UseZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb38.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb38.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb38.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rdx, -1824);
+ inst.args.push(arg);
+ bb38.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdx, -1832);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb38.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(GreaterThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb38.append(inst);
+ bb39.successors.push(new FrequentedBlock(bb42, Normal));
+ bb39.successors.push(new FrequentedBlock(bb3, Normal));
+ bb39.predecessors.push(bb38);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(286474592, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(286474592, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rdx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm0);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb39.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb39.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 224);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Or32);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 224);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(287131344, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(287131344, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(287209728, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rdx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm0);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb39.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb39.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 224);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb39.append(inst);
+ inst = new Inst(BranchTest32);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb39.append(inst);
+ bb40.successors.push(new FrequentedBlock(bb42, Normal));
+ bb40.successors.push(new FrequentedBlock(bb3, Normal));
+ bb40.predecessors.push(bb38);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 224);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb40.append(inst);
+ inst = new Inst(BranchTest32);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb40.append(inst);
+ bb41.predecessors.push(bb1);
+ bb41.predecessors.push(bb2);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb41.append(inst);
+ inst = new Inst(Ret64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb41.append(inst);
+ bb42.predecessors.push(bb40);
+ bb42.predecessors.push(bb39);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb42.append(inst);
+ inst = new Inst(Ret64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb42.append(inst);
+ return code;
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/payload-imaging-gaussian-blur-gaussianBlur.js b/third_party/webkit/PerformanceTests/ARES-6/Air/payload-imaging-gaussian-blur-gaussianBlur.js
new file mode 100644
index 0000000000..0f16fee65c
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/payload-imaging-gaussian-blur-gaussianBlur.js
@@ -0,0 +1,3107 @@
+"use strict";
+// Generated by Air::dumpAsJS from gaussianBlur#A8vcYg in Kraken/imaging-gaussian-blur
+function createPayloadImagingGaussianBlurGaussianBlur()
+{
+ let code = new Code();
+ let bb0 = code.addBlock();
+ let bb1 = code.addBlock();
+ let bb2 = code.addBlock();
+ let bb3 = code.addBlock();
+ let bb4 = code.addBlock();
+ let bb5 = code.addBlock();
+ let bb6 = code.addBlock();
+ let bb7 = code.addBlock();
+ let bb8 = code.addBlock();
+ let bb9 = code.addBlock();
+ let bb10 = code.addBlock();
+ let bb11 = code.addBlock();
+ let bb12 = code.addBlock();
+ let bb13 = code.addBlock();
+ let bb14 = code.addBlock();
+ let bb15 = code.addBlock();
+ let bb16 = code.addBlock();
+ let bb17 = code.addBlock();
+ let bb18 = code.addBlock();
+ let bb19 = code.addBlock();
+ let bb20 = code.addBlock();
+ let bb21 = code.addBlock();
+ let bb22 = code.addBlock();
+ let bb23 = code.addBlock();
+ let bb24 = code.addBlock();
+ let bb25 = code.addBlock();
+ let bb26 = code.addBlock();
+ let bb27 = code.addBlock();
+ let bb28 = code.addBlock();
+ let bb29 = code.addBlock();
+ let bb30 = code.addBlock();
+ let bb31 = code.addBlock();
+ let bb32 = code.addBlock();
+ let bb33 = code.addBlock();
+ let bb34 = code.addBlock();
+ let bb35 = code.addBlock();
+ let bb36 = code.addBlock();
+ let slot0 = code.addStackSlot(40, Locked);
+ let slot1 = code.addStackSlot(8, Spill);
+ let slot2 = code.addStackSlot(8, Spill);
+ let slot3 = code.addStackSlot(4, Spill);
+ let slot4 = code.addStackSlot(8, Spill);
+ let slot5 = code.addStackSlot(8, Spill);
+ let slot6 = code.addStackSlot(40, Locked);
+ slot6.setOffsetFromFP(-40);
+ let tmp141 = code.newTmp(GP);
+ let tmp140 = code.newTmp(GP);
+ let tmp139 = code.newTmp(GP);
+ let tmp138 = code.newTmp(GP);
+ let tmp137 = code.newTmp(GP);
+ let tmp136 = code.newTmp(GP);
+ let tmp135 = code.newTmp(GP);
+ let tmp134 = code.newTmp(GP);
+ let tmp133 = code.newTmp(GP);
+ let tmp132 = code.newTmp(GP);
+ let tmp131 = code.newTmp(GP);
+ let tmp130 = code.newTmp(GP);
+ let tmp129 = code.newTmp(GP);
+ let tmp128 = code.newTmp(GP);
+ let tmp127 = code.newTmp(GP);
+ let tmp126 = code.newTmp(GP);
+ let tmp125 = code.newTmp(GP);
+ let tmp124 = code.newTmp(GP);
+ let tmp123 = code.newTmp(GP);
+ let tmp122 = code.newTmp(GP);
+ let tmp121 = code.newTmp(GP);
+ let tmp120 = code.newTmp(GP);
+ let tmp119 = code.newTmp(GP);
+ let tmp118 = code.newTmp(GP);
+ let tmp117 = code.newTmp(GP);
+ let tmp116 = code.newTmp(GP);
+ let tmp115 = code.newTmp(GP);
+ let tmp114 = code.newTmp(GP);
+ let tmp113 = code.newTmp(GP);
+ let tmp112 = code.newTmp(GP);
+ let tmp111 = code.newTmp(GP);
+ let tmp110 = code.newTmp(GP);
+ let tmp109 = code.newTmp(GP);
+ let tmp108 = code.newTmp(GP);
+ let tmp107 = code.newTmp(GP);
+ let tmp106 = code.newTmp(GP);
+ let tmp105 = code.newTmp(GP);
+ let tmp104 = code.newTmp(GP);
+ let tmp103 = code.newTmp(GP);
+ let tmp102 = code.newTmp(GP);
+ let tmp101 = code.newTmp(GP);
+ let tmp100 = code.newTmp(GP);
+ let tmp99 = code.newTmp(GP);
+ let tmp98 = code.newTmp(GP);
+ let tmp97 = code.newTmp(GP);
+ let tmp96 = code.newTmp(GP);
+ let tmp95 = code.newTmp(GP);
+ let tmp94 = code.newTmp(GP);
+ let tmp93 = code.newTmp(GP);
+ let tmp92 = code.newTmp(GP);
+ let tmp91 = code.newTmp(GP);
+ let tmp90 = code.newTmp(GP);
+ let tmp89 = code.newTmp(GP);
+ let tmp88 = code.newTmp(GP);
+ let tmp87 = code.newTmp(GP);
+ let tmp86 = code.newTmp(GP);
+ let tmp85 = code.newTmp(GP);
+ let tmp84 = code.newTmp(GP);
+ let tmp83 = code.newTmp(GP);
+ let tmp82 = code.newTmp(GP);
+ let tmp81 = code.newTmp(GP);
+ let tmp80 = code.newTmp(GP);
+ let tmp79 = code.newTmp(GP);
+ let tmp78 = code.newTmp(GP);
+ let tmp77 = code.newTmp(GP);
+ let tmp76 = code.newTmp(GP);
+ let tmp75 = code.newTmp(GP);
+ let tmp74 = code.newTmp(GP);
+ let tmp73 = code.newTmp(GP);
+ let tmp72 = code.newTmp(GP);
+ let tmp71 = code.newTmp(GP);
+ let tmp70 = code.newTmp(GP);
+ let tmp69 = code.newTmp(GP);
+ let tmp68 = code.newTmp(GP);
+ let tmp67 = code.newTmp(GP);
+ let tmp66 = code.newTmp(GP);
+ let tmp65 = code.newTmp(GP);
+ let tmp64 = code.newTmp(GP);
+ let tmp63 = code.newTmp(GP);
+ let tmp62 = code.newTmp(GP);
+ let tmp61 = code.newTmp(GP);
+ let tmp60 = code.newTmp(GP);
+ let tmp59 = code.newTmp(GP);
+ let tmp58 = code.newTmp(GP);
+ let tmp57 = code.newTmp(GP);
+ let tmp56 = code.newTmp(GP);
+ let tmp55 = code.newTmp(GP);
+ let tmp54 = code.newTmp(GP);
+ let tmp53 = code.newTmp(GP);
+ let tmp52 = code.newTmp(GP);
+ let tmp51 = code.newTmp(GP);
+ let tmp50 = code.newTmp(GP);
+ let tmp49 = code.newTmp(GP);
+ let tmp48 = code.newTmp(GP);
+ let tmp47 = code.newTmp(GP);
+ let tmp46 = code.newTmp(GP);
+ let tmp45 = code.newTmp(GP);
+ let tmp44 = code.newTmp(GP);
+ let tmp43 = code.newTmp(GP);
+ let tmp42 = code.newTmp(GP);
+ let tmp41 = code.newTmp(GP);
+ let tmp40 = code.newTmp(GP);
+ let tmp39 = code.newTmp(GP);
+ let tmp38 = code.newTmp(GP);
+ let tmp37 = code.newTmp(GP);
+ let tmp36 = code.newTmp(GP);
+ let tmp35 = code.newTmp(GP);
+ let tmp34 = code.newTmp(GP);
+ let tmp33 = code.newTmp(GP);
+ let tmp32 = code.newTmp(GP);
+ let tmp31 = code.newTmp(GP);
+ let tmp30 = code.newTmp(GP);
+ let tmp29 = code.newTmp(GP);
+ let tmp28 = code.newTmp(GP);
+ let tmp27 = code.newTmp(GP);
+ let tmp26 = code.newTmp(GP);
+ let tmp25 = code.newTmp(GP);
+ let tmp24 = code.newTmp(GP);
+ let tmp23 = code.newTmp(GP);
+ let tmp22 = code.newTmp(GP);
+ let tmp21 = code.newTmp(GP);
+ let tmp20 = code.newTmp(GP);
+ let tmp19 = code.newTmp(GP);
+ let tmp18 = code.newTmp(GP);
+ let tmp17 = code.newTmp(GP);
+ let tmp16 = code.newTmp(GP);
+ let tmp15 = code.newTmp(GP);
+ let tmp14 = code.newTmp(GP);
+ let tmp13 = code.newTmp(GP);
+ let tmp12 = code.newTmp(GP);
+ let tmp11 = code.newTmp(GP);
+ let tmp10 = code.newTmp(GP);
+ let tmp9 = code.newTmp(GP);
+ let tmp8 = code.newTmp(GP);
+ let tmp7 = code.newTmp(GP);
+ let tmp6 = code.newTmp(GP);
+ let tmp5 = code.newTmp(GP);
+ let tmp4 = code.newTmp(GP);
+ let tmp3 = code.newTmp(GP);
+ let tmp2 = code.newTmp(GP);
+ let tmp1 = code.newTmp(GP);
+ let tmp0 = code.newTmp(GP);
+ let ftmp74 = code.newTmp(FP);
+ let ftmp73 = code.newTmp(FP);
+ let ftmp72 = code.newTmp(FP);
+ let ftmp71 = code.newTmp(FP);
+ let ftmp70 = code.newTmp(FP);
+ let ftmp69 = code.newTmp(FP);
+ let ftmp68 = code.newTmp(FP);
+ let ftmp67 = code.newTmp(FP);
+ let ftmp66 = code.newTmp(FP);
+ let ftmp65 = code.newTmp(FP);
+ let ftmp64 = code.newTmp(FP);
+ let ftmp63 = code.newTmp(FP);
+ let ftmp62 = code.newTmp(FP);
+ let ftmp61 = code.newTmp(FP);
+ let ftmp60 = code.newTmp(FP);
+ let ftmp59 = code.newTmp(FP);
+ let ftmp58 = code.newTmp(FP);
+ let ftmp57 = code.newTmp(FP);
+ let ftmp56 = code.newTmp(FP);
+ let ftmp55 = code.newTmp(FP);
+ let ftmp54 = code.newTmp(FP);
+ let ftmp53 = code.newTmp(FP);
+ let ftmp52 = code.newTmp(FP);
+ let ftmp51 = code.newTmp(FP);
+ let ftmp50 = code.newTmp(FP);
+ let ftmp49 = code.newTmp(FP);
+ let ftmp48 = code.newTmp(FP);
+ let ftmp47 = code.newTmp(FP);
+ let ftmp46 = code.newTmp(FP);
+ let ftmp45 = code.newTmp(FP);
+ let ftmp44 = code.newTmp(FP);
+ let ftmp43 = code.newTmp(FP);
+ let ftmp42 = code.newTmp(FP);
+ let ftmp41 = code.newTmp(FP);
+ let ftmp40 = code.newTmp(FP);
+ let ftmp39 = code.newTmp(FP);
+ let ftmp38 = code.newTmp(FP);
+ let ftmp37 = code.newTmp(FP);
+ let ftmp36 = code.newTmp(FP);
+ let ftmp35 = code.newTmp(FP);
+ let ftmp34 = code.newTmp(FP);
+ let ftmp33 = code.newTmp(FP);
+ let ftmp32 = code.newTmp(FP);
+ let ftmp31 = code.newTmp(FP);
+ let ftmp30 = code.newTmp(FP);
+ let ftmp29 = code.newTmp(FP);
+ let ftmp28 = code.newTmp(FP);
+ let ftmp27 = code.newTmp(FP);
+ let ftmp26 = code.newTmp(FP);
+ let ftmp25 = code.newTmp(FP);
+ let ftmp24 = code.newTmp(FP);
+ let ftmp23 = code.newTmp(FP);
+ let ftmp22 = code.newTmp(FP);
+ let ftmp21 = code.newTmp(FP);
+ let ftmp20 = code.newTmp(FP);
+ let ftmp19 = code.newTmp(FP);
+ let ftmp18 = code.newTmp(FP);
+ let ftmp17 = code.newTmp(FP);
+ let ftmp16 = code.newTmp(FP);
+ let ftmp15 = code.newTmp(FP);
+ let ftmp14 = code.newTmp(FP);
+ let ftmp13 = code.newTmp(FP);
+ let ftmp12 = code.newTmp(FP);
+ let ftmp11 = code.newTmp(FP);
+ let ftmp10 = code.newTmp(FP);
+ let ftmp9 = code.newTmp(FP);
+ let ftmp8 = code.newTmp(FP);
+ let ftmp7 = code.newTmp(FP);
+ let ftmp6 = code.newTmp(FP);
+ let ftmp5 = code.newTmp(FP);
+ let ftmp4 = code.newTmp(FP);
+ let ftmp3 = code.newTmp(FP);
+ let ftmp2 = code.newTmp(FP);
+ let ftmp1 = code.newTmp(FP);
+ let ftmp0 = code.newTmp(FP);
+ let inst;
+ let arg;
+ bb0.successors.push(new FrequentedBlock(bb2, Normal));
+ bb0.successors.push(new FrequentedBlock(bb1, Rare));
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(144305904, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbp, 16);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbp);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Scratch, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(142547168, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(142547184, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(142547192, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(142547200, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(142547208, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(142547216, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(142547224, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(142547232, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(142547240, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdi, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(0, -65536);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move64ToDouble);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(BranchDouble);
+ arg = Arg.createDoubleCond(DoubleEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ bb0.append(inst);
+ bb1.successors.push(new FrequentedBlock(bb2, Normal));
+ bb1.predecessors.push(bb0);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb1.append(inst);
+ inst = new Inst(ConvertInt32ToDouble);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ bb1.append(inst);
+ inst = new Inst(Jump);
+ bb1.append(inst);
+ bb2.successors.push(new FrequentedBlock(bb4, Normal));
+ bb2.successors.push(new FrequentedBlock(bb3, Rare));
+ bb2.predecessors.push(bb0);
+ bb2.predecessors.push(bb1);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb2.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb2.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb2.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb2.append(inst);
+ inst = new Inst(Move64ToDouble);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ bb2.append(inst);
+ inst = new Inst(BranchDouble);
+ arg = Arg.createDoubleCond(DoubleEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ bb2.append(inst);
+ bb3.successors.push(new FrequentedBlock(bb4, Normal));
+ bb3.predecessors.push(bb2);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb3.append(inst);
+ inst = new Inst(ConvertInt32ToDouble);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ bb3.append(inst);
+ inst = new Inst(Jump);
+ bb3.append(inst);
+ bb4.successors.push(new FrequentedBlock(bb6, Normal));
+ bb4.successors.push(new FrequentedBlock(bb5, Rare));
+ bb4.predecessors.push(bb2);
+ bb4.predecessors.push(bb3);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(Move64ToDouble);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ bb4.append(inst);
+ inst = new Inst(BranchDouble);
+ arg = Arg.createDoubleCond(DoubleEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ bb4.append(inst);
+ bb5.successors.push(new FrequentedBlock(bb6, Normal));
+ bb5.predecessors.push(bb4);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb5.append(inst);
+ inst = new Inst(ConvertInt32ToDouble);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Jump);
+ bb5.append(inst);
+ bb6.successors.push(new FrequentedBlock(bb8, Normal));
+ bb6.successors.push(new FrequentedBlock(bb7, Rare));
+ bb6.predecessors.push(bb4);
+ bb6.predecessors.push(bb5);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb6.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Move64ToDouble);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(BranchDouble);
+ arg = Arg.createDoubleCond(DoubleEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ bb6.append(inst);
+ bb7.successors.push(new FrequentedBlock(bb8, Normal));
+ bb7.predecessors.push(bb6);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb7.append(inst);
+ inst = new Inst(ConvertInt32ToDouble);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ bb7.append(inst);
+ inst = new Inst(Jump);
+ bb7.append(inst);
+ bb8.successors.push(new FrequentedBlock(bb10, Normal));
+ bb8.successors.push(new FrequentedBlock(bb9, Rare));
+ bb8.predecessors.push(bb6);
+ bb8.predecessors.push(bb7);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(117076488, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb8.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.r8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ bb8.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb8.append(inst);
+ inst = new Inst(Move64ToDouble);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm6);
+ inst.args.push(arg);
+ bb8.append(inst);
+ inst = new Inst(BranchDouble);
+ arg = Arg.createDoubleCond(DoubleEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm6);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm6);
+ inst.args.push(arg);
+ bb8.append(inst);
+ bb9.successors.push(new FrequentedBlock(bb10, Normal));
+ bb9.predecessors.push(bb8);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(Below);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb9.append(inst);
+ inst = new Inst(ConvertInt32ToDouble);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm6);
+ inst.args.push(arg);
+ bb9.append(inst);
+ inst = new Inst(Jump);
+ bb9.append(inst);
+ bb10.successors.push(new FrequentedBlock(bb18, Normal));
+ bb10.predecessors.push(bb8);
+ bb10.predecessors.push(bb9);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(144506584, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdi, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createAddr(Reg.r9, -8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(144506544, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rdi, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(80);
+ inst.args.push(arg);
+ arg = Arg.createBigImm(144506544, 1);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb10.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(144506552, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdi, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot2, 0);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createAddr(Reg.rdi, -8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot3, 0);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(MoveZeroToDouble);
+ arg = Arg.createTmp(Reg.xmm7);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot4, 0);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(2, -65536);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Jump);
+ bb10.append(inst);
+ bb11.successors.push(new FrequentedBlock(bb13, Normal));
+ bb11.predecessors.push(bb35);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Jump);
+ bb11.append(inst);
+ bb12.successors.push(new FrequentedBlock(bb13, Normal));
+ bb12.predecessors.push(bb34);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb12.append(inst);
+ inst = new Inst(Jump);
+ bb12.append(inst);
+ bb13.successors.push(new FrequentedBlock(bb15, Normal));
+ bb13.predecessors.push(bb11);
+ bb13.predecessors.push(bb12);
+ inst = new Inst(Move);
+ arg = Arg.createImm(-6);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb13.append(inst);
+ inst = new Inst(MoveDouble);
+ arg = Arg.createTmp(Reg.xmm7);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ bb13.append(inst);
+ inst = new Inst(MoveDouble);
+ arg = Arg.createTmp(Reg.xmm7);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ bb13.append(inst);
+ inst = new Inst(MoveDouble);
+ arg = Arg.createTmp(Reg.xmm7);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ bb13.append(inst);
+ inst = new Inst(MoveDouble);
+ arg = Arg.createTmp(Reg.xmm7);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ bb13.append(inst);
+ inst = new Inst(Jump);
+ bb13.append(inst);
+ bb14.successors.push(new FrequentedBlock(bb15, Normal));
+ bb14.predecessors.push(bb31);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb14.append(inst);
+ inst = new Inst(Jump);
+ bb14.append(inst);
+ bb15.successors.push(new FrequentedBlock(bb28, Normal));
+ bb15.successors.push(new FrequentedBlock(bb16, Normal));
+ bb15.predecessors.push(bb13);
+ bb15.predecessors.push(bb14);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ bb15.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(LessThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(0);
+ inst.args.push(arg);
+ bb15.append(inst);
+ bb16.successors.push(new FrequentedBlock(bb29, Normal));
+ bb16.successors.push(new FrequentedBlock(bb17, Normal));
+ bb16.predecessors.push(bb15);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(GreaterThanOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(267);
+ inst.args.push(arg);
+ bb16.append(inst);
+ bb17.successors.push(new FrequentedBlock(bb18, Normal));
+ bb17.predecessors.push(bb16);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb17.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(-6);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb17.append(inst);
+ inst = new Inst(Jump);
+ bb17.append(inst);
+ bb18.successors.push(new FrequentedBlock(bb20, Normal));
+ bb18.successors.push(new FrequentedBlock(bb19, Rare));
+ bb18.predecessors.push(bb10);
+ bb18.predecessors.push(bb17);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ bb18.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ bb18.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(400);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ bb18.append(inst);
+ inst = new Inst(BranchTest32);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ bb18.append(inst);
+ bb19.successors.push(new FrequentedBlock(bb20, Normal));
+ bb19.predecessors.push(bb18);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(LessThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(0);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb19.append(inst);
+ inst = new Inst(Jump);
+ bb19.append(inst);
+ bb20.successors.push(new FrequentedBlock(bb22, Normal));
+ bb20.predecessors.push(bb18);
+ bb20.predecessors.push(bb19);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Rshift32);
+ arg = Arg.createImm(31);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Add32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Xor32);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(LessThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createImm(0);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb20.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot3, 0);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb20.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createStack(slot2, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createIndex(Reg.rsi, Reg.rdi, 8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(MoveConditionallyTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(-1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb20.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rdi, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(79);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb20.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rdi, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createAddr(Reg.r12, -8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ bb20.append(inst);
+ inst = new Inst(Jump);
+ bb20.append(inst);
+ bb21.successors.push(new FrequentedBlock(bb22, Normal));
+ bb21.predecessors.push(bb27);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb21.append(inst);
+ inst = new Inst(Jump);
+ bb21.append(inst);
+ bb22.successors.push(new FrequentedBlock(bb25, Normal));
+ bb22.successors.push(new FrequentedBlock(bb23, Normal));
+ bb22.predecessors.push(bb20);
+ bb22.predecessors.push(bb21);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ bb22.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(LessThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(0);
+ inst.args.push(arg);
+ bb22.append(inst);
+ bb23.successors.push(new FrequentedBlock(bb26, Normal));
+ bb23.successors.push(new FrequentedBlock(bb24, Normal));
+ bb23.predecessors.push(bb22);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(GreaterThanOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(400);
+ inst.args.push(arg);
+ bb23.append(inst);
+ bb24.successors.push(new FrequentedBlock(bb27, Normal));
+ bb24.predecessors.push(bb23);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb24.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createImm(4);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb24.append(inst);
+ inst = new Inst(Add32);
+ arg = Arg.createImm(3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb24.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb24.append(inst);
+ inst = new Inst(MoveDouble);
+ arg = Arg.createIndex(Reg.r9, Reg.r15, 8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(Rshift32);
+ arg = Arg.createImm(31);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(Add32);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(Xor32);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(LessThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createImm(0);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb24.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb24.append(inst);
+ inst = new Inst(MoveDouble);
+ arg = Arg.createIndex(Reg.r12, Reg.rbx, 8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm4);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(MulDouble);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm4);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(AddDouble);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(Add32);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(MulDouble);
+ arg = Arg.createIndex(Reg.r9, Reg.rsi, 8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm4);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(AddDouble);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(Add32);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(MulDouble);
+ arg = Arg.createIndex(Reg.r9, Reg.r15, 8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm4);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(AddDouble);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(MulDouble);
+ arg = Arg.createIndex(Reg.r9, Reg.r14, 8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm4);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm4);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(AddDouble);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm4);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ bb24.append(inst);
+ inst = new Inst(Jump);
+ bb24.append(inst);
+ bb25.successors.push(new FrequentedBlock(bb27, Normal));
+ bb25.predecessors.push(bb22);
+ inst = new Inst(Jump);
+ bb25.append(inst);
+ bb26.successors.push(new FrequentedBlock(bb27, Normal));
+ bb26.predecessors.push(bb23);
+ inst = new Inst(Jump);
+ bb26.append(inst);
+ bb27.successors.push(new FrequentedBlock(bb21, Normal));
+ bb27.successors.push(new FrequentedBlock(bb30, Normal));
+ bb27.predecessors.push(bb24);
+ bb27.predecessors.push(bb26);
+ bb27.predecessors.push(bb25);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb27.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.UseZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ bb27.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(LessThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(7);
+ inst.args.push(arg);
+ bb27.append(inst);
+ bb28.successors.push(new FrequentedBlock(bb31, Normal));
+ bb28.predecessors.push(bb15);
+ inst = new Inst(Jump);
+ bb28.append(inst);
+ bb29.successors.push(new FrequentedBlock(bb31, Normal));
+ bb29.predecessors.push(bb16);
+ inst = new Inst(Jump);
+ bb29.append(inst);
+ bb30.successors.push(new FrequentedBlock(bb31, Normal));
+ bb30.predecessors.push(bb27);
+ inst = new Inst(Move);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb30.append(inst);
+ inst = new Inst(Jump);
+ bb30.append(inst);
+ bb31.successors.push(new FrequentedBlock(bb14, Normal));
+ bb31.successors.push(new FrequentedBlock(bb32, Normal));
+ bb31.predecessors.push(bb30);
+ bb31.predecessors.push(bb29);
+ bb31.predecessors.push(bb28);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb31.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.UseZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ bb31.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(LessThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(7);
+ inst.args.push(arg);
+ bb31.append(inst);
+ bb32.successors.push(new FrequentedBlock(bb34, Normal));
+ bb32.successors.push(new FrequentedBlock(bb33, Rare));
+ bb32.predecessors.push(bb31);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createImm(400);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ bb32.append(inst);
+ inst = new Inst(BranchTest32);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb32.append(inst);
+ bb33.successors.push(new FrequentedBlock(bb34, Normal));
+ bb33.predecessors.push(bb32);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(LessThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createImm(0);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb33.append(inst);
+ inst = new Inst(Jump);
+ bb33.append(inst);
+ bb34.successors.push(new FrequentedBlock(bb12, Normal));
+ bb34.successors.push(new FrequentedBlock(bb35, Normal));
+ bb34.predecessors.push(bb32);
+ bb34.predecessors.push(bb33);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createImm(4);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb34.append(inst);
+ inst = new Inst(DivDouble);
+ arg = Arg.createTmp(Reg.xmm6);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createDoubleCond(DoubleNotEqualOrUnordered);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb34.append(inst);
+ inst = new Inst(MoveDouble);
+ arg = Arg.createTmp(Reg.xmm1);
+ inst.args.push(arg);
+ arg = Arg.createIndex(Reg.r9, Reg.rsi, 8, 0);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.UseZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb34.append(inst);
+ inst = new Inst(DivDouble);
+ arg = Arg.createTmp(Reg.xmm6);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Add32);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Add32);
+ arg = Arg.createImm(3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createDoubleCond(DoubleNotEqualOrUnordered);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb34.append(inst);
+ inst = new Inst(MoveDouble);
+ arg = Arg.createTmp(Reg.xmm2);
+ inst.args.push(arg);
+ arg = Arg.createIndex(Reg.r9, Reg.rdi, 8, 0);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Add32);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(DivDouble);
+ arg = Arg.createTmp(Reg.xmm6);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createDoubleCond(DoubleNotEqualOrUnordered);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb34.append(inst);
+ inst = new Inst(MoveDouble);
+ arg = Arg.createTmp(Reg.xmm3);
+ inst.args.push(arg);
+ arg = Arg.createIndex(Reg.r9, Reg.rsi, 8, 0);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(DivDouble);
+ arg = Arg.createTmp(Reg.xmm6);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createDoubleCond(DoubleNotEqualOrUnordered);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: FP, width: 64});
+ bb34.append(inst);
+ inst = new Inst(MoveDouble);
+ arg = Arg.createTmp(Reg.xmm5);
+ inst.args.push(arg);
+ arg = Arg.createIndex(Reg.r9, Reg.rax, 8, 0);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.UseZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb34.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(LessThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(400);
+ inst.args.push(arg);
+ bb34.append(inst);
+ bb35.successors.push(new FrequentedBlock(bb11, Normal));
+ bb35.successors.push(new FrequentedBlock(bb36, Normal));
+ bb35.predecessors.push(bb34);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb35.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.UseZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb35.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(LessThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(267);
+ inst.args.push(arg);
+ bb35.append(inst);
+ bb36.predecessors.push(bb35);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(144506576, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb36.append(inst);
+ inst = new Inst(Ret64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb36.append(inst);
+ return code;
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/payload-typescript-scanIdentifier.js b/third_party/webkit/PerformanceTests/ARES-6/Air/payload-typescript-scanIdentifier.js
new file mode 100644
index 0000000000..8c8becc77e
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/payload-typescript-scanIdentifier.js
@@ -0,0 +1,1878 @@
+"use strict";
+// Generated by Air::dumpAsJS from scanIdentifier#EPcFQe in Octane/typescript
+function createPayloadTypescriptScanIdentifier()
+{
+ let code = new Code();
+ let bb0 = code.addBlock();
+ let bb1 = code.addBlock();
+ let bb2 = code.addBlock();
+ let bb3 = code.addBlock();
+ let bb4 = code.addBlock();
+ let bb5 = code.addBlock();
+ let bb6 = code.addBlock();
+ let bb7 = code.addBlock();
+ let bb8 = code.addBlock();
+ let bb9 = code.addBlock();
+ let bb10 = code.addBlock();
+ let bb11 = code.addBlock();
+ let bb12 = code.addBlock();
+ let bb13 = code.addBlock();
+ let bb14 = code.addBlock();
+ let bb15 = code.addBlock();
+ let bb16 = code.addBlock();
+ let bb17 = code.addBlock();
+ let bb18 = code.addBlock();
+ let bb19 = code.addBlock();
+ let bb20 = code.addBlock();
+ let bb21 = code.addBlock();
+ let bb22 = code.addBlock();
+ let bb23 = code.addBlock();
+ let bb24 = code.addBlock();
+ let bb25 = code.addBlock();
+ let bb26 = code.addBlock();
+ let bb27 = code.addBlock();
+ let bb28 = code.addBlock();
+ let bb29 = code.addBlock();
+ let bb30 = code.addBlock();
+ let bb31 = code.addBlock();
+ let bb32 = code.addBlock();
+ let bb33 = code.addBlock();
+ let bb34 = code.addBlock();
+ let slot0 = code.addStackSlot(56, Locked);
+ let slot1 = code.addStackSlot(8, Spill);
+ let slot2 = code.addStackSlot(8, Spill);
+ let slot3 = code.addStackSlot(8, Spill);
+ let slot4 = code.addStackSlot(8, Spill);
+ let slot5 = code.addStackSlot(4, Spill);
+ let slot6 = code.addStackSlot(8, Spill);
+ let slot7 = code.addStackSlot(8, Spill);
+ let slot8 = code.addStackSlot(8, Spill);
+ let slot9 = code.addStackSlot(40, Locked);
+ slot9.setOffsetFromFP(-40);
+ let tmp98 = code.newTmp(GP);
+ let tmp97 = code.newTmp(GP);
+ let tmp96 = code.newTmp(GP);
+ let tmp95 = code.newTmp(GP);
+ let tmp94 = code.newTmp(GP);
+ let tmp93 = code.newTmp(GP);
+ let tmp92 = code.newTmp(GP);
+ let tmp91 = code.newTmp(GP);
+ let tmp90 = code.newTmp(GP);
+ let tmp89 = code.newTmp(GP);
+ let tmp88 = code.newTmp(GP);
+ let tmp87 = code.newTmp(GP);
+ let tmp86 = code.newTmp(GP);
+ let tmp85 = code.newTmp(GP);
+ let tmp84 = code.newTmp(GP);
+ let tmp83 = code.newTmp(GP);
+ let tmp82 = code.newTmp(GP);
+ let tmp81 = code.newTmp(GP);
+ let tmp80 = code.newTmp(GP);
+ let tmp79 = code.newTmp(GP);
+ let tmp78 = code.newTmp(GP);
+ let tmp77 = code.newTmp(GP);
+ let tmp76 = code.newTmp(GP);
+ let tmp75 = code.newTmp(GP);
+ let tmp74 = code.newTmp(GP);
+ let tmp73 = code.newTmp(GP);
+ let tmp72 = code.newTmp(GP);
+ let tmp71 = code.newTmp(GP);
+ let tmp70 = code.newTmp(GP);
+ let tmp69 = code.newTmp(GP);
+ let tmp68 = code.newTmp(GP);
+ let tmp67 = code.newTmp(GP);
+ let tmp66 = code.newTmp(GP);
+ let tmp65 = code.newTmp(GP);
+ let tmp64 = code.newTmp(GP);
+ let tmp63 = code.newTmp(GP);
+ let tmp62 = code.newTmp(GP);
+ let tmp61 = code.newTmp(GP);
+ let tmp60 = code.newTmp(GP);
+ let tmp59 = code.newTmp(GP);
+ let tmp58 = code.newTmp(GP);
+ let tmp57 = code.newTmp(GP);
+ let tmp56 = code.newTmp(GP);
+ let tmp55 = code.newTmp(GP);
+ let tmp54 = code.newTmp(GP);
+ let tmp53 = code.newTmp(GP);
+ let tmp52 = code.newTmp(GP);
+ let tmp51 = code.newTmp(GP);
+ let tmp50 = code.newTmp(GP);
+ let tmp49 = code.newTmp(GP);
+ let tmp48 = code.newTmp(GP);
+ let tmp47 = code.newTmp(GP);
+ let tmp46 = code.newTmp(GP);
+ let tmp45 = code.newTmp(GP);
+ let tmp44 = code.newTmp(GP);
+ let tmp43 = code.newTmp(GP);
+ let tmp42 = code.newTmp(GP);
+ let tmp41 = code.newTmp(GP);
+ let tmp40 = code.newTmp(GP);
+ let tmp39 = code.newTmp(GP);
+ let tmp38 = code.newTmp(GP);
+ let tmp37 = code.newTmp(GP);
+ let tmp36 = code.newTmp(GP);
+ let tmp35 = code.newTmp(GP);
+ let tmp34 = code.newTmp(GP);
+ let tmp33 = code.newTmp(GP);
+ let tmp32 = code.newTmp(GP);
+ let tmp31 = code.newTmp(GP);
+ let tmp30 = code.newTmp(GP);
+ let tmp29 = code.newTmp(GP);
+ let tmp28 = code.newTmp(GP);
+ let tmp27 = code.newTmp(GP);
+ let tmp26 = code.newTmp(GP);
+ let tmp25 = code.newTmp(GP);
+ let tmp24 = code.newTmp(GP);
+ let tmp23 = code.newTmp(GP);
+ let tmp22 = code.newTmp(GP);
+ let tmp21 = code.newTmp(GP);
+ let tmp20 = code.newTmp(GP);
+ let tmp19 = code.newTmp(GP);
+ let tmp18 = code.newTmp(GP);
+ let tmp17 = code.newTmp(GP);
+ let tmp16 = code.newTmp(GP);
+ let tmp15 = code.newTmp(GP);
+ let tmp14 = code.newTmp(GP);
+ let tmp13 = code.newTmp(GP);
+ let tmp12 = code.newTmp(GP);
+ let tmp11 = code.newTmp(GP);
+ let tmp10 = code.newTmp(GP);
+ let tmp9 = code.newTmp(GP);
+ let tmp8 = code.newTmp(GP);
+ let tmp7 = code.newTmp(GP);
+ let tmp6 = code.newTmp(GP);
+ let tmp5 = code.newTmp(GP);
+ let tmp4 = code.newTmp(GP);
+ let tmp3 = code.newTmp(GP);
+ let tmp2 = code.newTmp(GP);
+ let tmp1 = code.newTmp(GP);
+ let tmp0 = code.newTmp(GP);
+ let inst;
+ let arg;
+ bb0.successors.push(new FrequentedBlock(bb5, Normal));
+ bb0.successors.push(new FrequentedBlock(bb4, Normal));
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(177329888, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbp, 16);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbp);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Scratch, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbp, 40);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(2, -65536);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 5);
+ inst.args.push(arg);
+ arg = Arg.createImm(21);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 8});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(2540);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 72);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Compare32);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(92);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(154991936, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(NotEqual);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rcx, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(80);
+ inst.args.push(arg);
+ arg = Arg.createBigImm(154991936, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(154991944, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rcx, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createAddr(Reg.r12, -8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb0.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createIndex(Reg.r12, Reg.rax, 8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(MoveConditionallyTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(-1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Xor64);
+ arg = Arg.createImm(6);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(-2);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot2, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(-2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot1, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(129987312, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot4, 0);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(108418352, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(0, -65536);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb0.append(inst);
+ bb1.predecessors.push(bb6);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb1.append(inst);
+ inst = new Inst(Oops);
+ bb1.append(inst);
+ bb2.predecessors.push(bb23);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb2.append(inst);
+ inst = new Inst(Oops);
+ bb2.append(inst);
+ bb3.predecessors.push(bb32);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb3.append(inst);
+ inst = new Inst(Oops);
+ bb3.append(inst);
+ bb4.predecessors.push(bb0);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb4.append(inst);
+ inst = new Inst(Oops);
+ bb4.append(inst);
+ bb5.successors.push(new FrequentedBlock(bb8, Normal));
+ bb5.successors.push(new FrequentedBlock(bb6, Rare));
+ bb5.predecessors.push(bb0);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 56);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, -24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.r10, 16);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb5.append(inst);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb5.append(inst);
+ bb6.successors.push(new FrequentedBlock(bb1, Rare));
+ bb6.successors.push(new FrequentedBlock(bb7, Normal));
+ bb6.predecessors.push(bb5);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbp, 36);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot8, 0);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot7, 0);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot6, 0);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbp);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb6.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createStack(slot8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createStack(slot7, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createStack(slot6, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(129987312, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb6.append(inst);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rcx, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(-1);
+ inst.args.push(arg);
+ bb6.append(inst);
+ bb7.successors.push(new FrequentedBlock(bb11, Normal));
+ bb7.predecessors.push(bb6);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb7.append(inst);
+ inst = new Inst(Jump);
+ bb7.append(inst);
+ bb8.successors.push(new FrequentedBlock(bb11, Normal));
+ bb8.predecessors.push(bb5);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb8.append(inst);
+ inst = new Inst(Jump);
+ bb8.append(inst);
+ bb9.successors.push(new FrequentedBlock(bb11, Normal));
+ bb9.predecessors.push(bb15);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb9.append(inst);
+ inst = new Inst(Jump);
+ bb9.append(inst);
+ bb10.successors.push(new FrequentedBlock(bb11, Normal));
+ bb10.predecessors.push(bb18);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb10.append(inst);
+ inst = new Inst(Jump);
+ bb10.append(inst);
+ bb11.successors.push(new FrequentedBlock(bb12, Normal));
+ bb11.successors.push(new FrequentedBlock(bb16, Normal));
+ bb11.predecessors.push(bb7);
+ bb11.predecessors.push(bb10);
+ bb11.predecessors.push(bb9);
+ bb11.predecessors.push(bb8);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r9);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 40);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.UseZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb11.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 40);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 32);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(Overflow);
+ inst.args.push(arg);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.UseZDef, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.LateColdUse, type: GP, width: 32});
+ bb11.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 32);
+ inst.args.push(arg);
+ bb11.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(LessThan);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb11.append(inst);
+ bb12.successors.push(new FrequentedBlock(bb13, Normal));
+ bb12.successors.push(new FrequentedBlock(bb14, Normal));
+ bb12.predecessors.push(bb11);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.r10, 12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb12.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.r10, 16);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb12.append(inst);
+ inst = new Inst(BranchTest32);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rax, 16);
+ inst.args.push(arg);
+ arg = Arg.createImm(8);
+ inst.args.push(arg);
+ bb12.append(inst);
+ bb13.successors.push(new FrequentedBlock(bb15, Normal));
+ bb13.predecessors.push(bb12);
+ inst = new Inst(Load8);
+ arg = Arg.createIndex(Reg.r9, Reg.rdx, 1, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb13.append(inst);
+ inst = new Inst(Jump);
+ bb13.append(inst);
+ bb14.successors.push(new FrequentedBlock(bb15, Normal));
+ bb14.predecessors.push(bb12);
+ inst = new Inst(Load16);
+ arg = Arg.createIndex(Reg.r9, Reg.rdx, 2, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb14.append(inst);
+ inst = new Inst(Jump);
+ bb14.append(inst);
+ bb15.successors.push(new FrequentedBlock(bb9, Normal));
+ bb15.successors.push(new FrequentedBlock(bb17, Normal));
+ bb15.predecessors.push(bb14);
+ bb15.predecessors.push(bb13);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb15.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb15.append(inst);
+ inst = new Inst(Add64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb15.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbx, 72);
+ inst.args.push(arg);
+ bb15.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createRelCond(AboveOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r8);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb15.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createIndex(Reg.r12, Reg.rax, 8, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb15.append(inst);
+ inst = new Inst(MoveConditionallyTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createImm(-1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb15.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb15.append(inst);
+ inst = new Inst(Xor64);
+ arg = Arg.createImm(6);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb15.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(-2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb15.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb15.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb15.append(inst);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb15.append(inst);
+ bb16.predecessors.push(bb11);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb16.append(inst);
+ inst = new Inst(Oops);
+ bb16.append(inst);
+ bb17.successors.push(new FrequentedBlock(bb18, Normal));
+ bb17.successors.push(new FrequentedBlock(bb19, Normal));
+ bb17.predecessors.push(bb15);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(GreaterThanOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(48);
+ inst.args.push(arg);
+ bb17.append(inst);
+ bb18.successors.push(new FrequentedBlock(bb10, Normal));
+ bb18.successors.push(new FrequentedBlock(bb19, Normal));
+ bb18.predecessors.push(bb17);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(LessThanOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(57);
+ inst.args.push(arg);
+ bb18.append(inst);
+ bb19.successors.push(new FrequentedBlock(bb20, Normal));
+ bb19.successors.push(new FrequentedBlock(bb21, Normal));
+ bb19.predecessors.push(bb17);
+ bb19.predecessors.push(bb18);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(GreaterThanOrEqual);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(128);
+ inst.args.push(arg);
+ bb19.append(inst);
+ bb20.predecessors.push(bb19);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb20.append(inst);
+ inst = new Inst(Oops);
+ bb20.append(inst);
+ bb21.successors.push(new FrequentedBlock(bb22, Normal));
+ bb21.successors.push(new FrequentedBlock(bb23, Normal));
+ bb21.predecessors.push(bb19);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ bb21.append(inst);
+ inst = new Inst(Branch32);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createImm(92);
+ inst.args.push(arg);
+ bb21.append(inst);
+ bb22.predecessors.push(bb21);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot5, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb22.append(inst);
+ inst = new Inst(Oops);
+ bb22.append(inst);
+ bb23.successors.push(new FrequentedBlock(bb2, Rare));
+ bb23.successors.push(new FrequentedBlock(bb24, Normal));
+ bb23.predecessors.push(bb21);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rbx, 48);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(155021568, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(3);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r10);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r11);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(40);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(40);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rdx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm0);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(155041288, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, 0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.rax, -1336);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createAddr(Reg.r13, 24);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot0, 0);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbp, 36);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(108356304, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createStack(slot3, 0);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbp);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb23.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(129987312, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb23.append(inst);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rcx, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(-1);
+ inst.args.push(arg);
+ bb23.append(inst);
+ bb24.successors.push(new FrequentedBlock(bb25, Normal));
+ bb24.successors.push(new FrequentedBlock(bb26, Normal));
+ bb24.predecessors.push(bb23);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r13);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb24.append(inst);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ bb24.append(inst);
+ bb25.successors.push(new FrequentedBlock(bb27, Normal));
+ bb25.successors.push(new FrequentedBlock(bb26, Normal));
+ bb25.predecessors.push(bb24);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb25.append(inst);
+ inst = new Inst(And64);
+ arg = Arg.createImm(-9);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb25.append(inst);
+ inst = new Inst(Branch64);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ bb25.append(inst);
+ bb26.successors.push(new FrequentedBlock(bb29, Normal));
+ bb26.successors.push(new FrequentedBlock(bb28, Normal));
+ bb26.predecessors.push(bb24);
+ bb26.predecessors.push(bb25);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ bb26.append(inst);
+ bb27.successors.push(new FrequentedBlock(bb30, Normal));
+ bb27.predecessors.push(bb25);
+ inst = new Inst(Move);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb27.append(inst);
+ inst = new Inst(Jump);
+ bb27.append(inst);
+ bb28.successors.push(new FrequentedBlock(bb32, Normal));
+ bb28.predecessors.push(bb26);
+ inst = new Inst(Jump);
+ bb28.append(inst);
+ bb29.successors.push(new FrequentedBlock(bb30, Normal));
+ bb29.predecessors.push(bb26);
+ inst = new Inst(Jump);
+ bb29.append(inst);
+ bb30.successors.push(new FrequentedBlock(bb34, Normal));
+ bb30.successors.push(new FrequentedBlock(bb31, Normal));
+ bb30.predecessors.push(bb29);
+ bb30.predecessors.push(bb27);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb30.append(inst);
+ inst = new Inst(And64);
+ arg = Arg.createImm(-9);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb30.append(inst);
+ inst = new Inst(Branch64);
+ arg = Arg.createRelCond(Equal);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createImm(2);
+ inst.args.push(arg);
+ bb30.append(inst);
+ bb31.successors.push(new FrequentedBlock(bb32, Normal));
+ bb31.predecessors.push(bb30);
+ inst = new Inst(Jump);
+ bb31.append(inst);
+ bb32.successors.push(new FrequentedBlock(bb3, Rare));
+ bb32.successors.push(new FrequentedBlock(bb33, Normal));
+ bb32.predecessors.push(bb28);
+ bb32.predecessors.push(bb31);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(3);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rbp, 36);
+ inst.args.push(arg);
+ bb32.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(154991632, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb32.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ bb32.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ bb32.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rbp);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ bb32.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createBigImm(108356304, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.xmm0);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rsi);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rdx);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: FP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb32.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(129987312, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rcx);
+ inst.args.push(arg);
+ bb32.append(inst);
+ inst = new Inst(BranchTest64);
+ arg = Arg.createResCond(NonZero);
+ inst.args.push(arg);
+ arg = Arg.createAddr(Reg.rcx, 0);
+ inst.args.push(arg);
+ arg = Arg.createImm(-1);
+ inst.args.push(arg);
+ bb32.append(inst);
+ bb33.predecessors.push(bb32);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb33.append(inst);
+ inst = new Inst(Ret64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb33.append(inst);
+ bb34.predecessors.push(bb30);
+ inst = new Inst(Move);
+ arg = Arg.createBigImm(153835296, 1);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Move32);
+ arg = Arg.createImm(3);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createTmp(Reg.r12);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Move);
+ arg = Arg.createImm(6);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(40);
+ inst.args.push(arg);
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(8);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(16);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(24);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(32);
+ inst.args.push(arg);
+ arg = Arg.createCallArg(40);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r15);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.r14);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.extraEarlyClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.rcx);
+ inst.extraClobberedRegs.add(Reg.rdx);
+ inst.extraClobberedRegs.add(Reg.rsi);
+ inst.extraClobberedRegs.add(Reg.rdi);
+ inst.extraClobberedRegs.add(Reg.r8);
+ inst.extraClobberedRegs.add(Reg.r9);
+ inst.extraClobberedRegs.add(Reg.r10);
+ inst.extraClobberedRegs.add(Reg.r11);
+ inst.extraClobberedRegs.add(Reg.xmm0);
+ inst.extraClobberedRegs.add(Reg.xmm1);
+ inst.extraClobberedRegs.add(Reg.xmm2);
+ inst.extraClobberedRegs.add(Reg.xmm3);
+ inst.extraClobberedRegs.add(Reg.xmm4);
+ inst.extraClobberedRegs.add(Reg.xmm5);
+ inst.extraClobberedRegs.add(Reg.xmm6);
+ inst.extraClobberedRegs.add(Reg.xmm7);
+ inst.extraClobberedRegs.add(Reg.xmm8);
+ inst.extraClobberedRegs.add(Reg.xmm9);
+ inst.extraClobberedRegs.add(Reg.xmm10);
+ inst.extraClobberedRegs.add(Reg.xmm11);
+ inst.extraClobberedRegs.add(Reg.xmm12);
+ inst.extraClobberedRegs.add(Reg.xmm13);
+ inst.extraClobberedRegs.add(Reg.xmm14);
+ inst.extraClobberedRegs.add(Reg.xmm15);
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Def, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 32});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ bb34.append(inst);
+ inst = new Inst(Patch);
+ arg = Arg.createSpecial();
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rbx);
+ inst.args.push(arg);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ inst.patchHasNonArgEffects = true;
+ inst.extraEarlyClobberedRegs = new Set();
+ inst.extraClobberedRegs = new Set();
+ inst.patchArgData = [];
+ inst.patchArgData.push({role: Arg.Use, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ inst.patchArgData.push({role: Arg.ColdUse, type: GP, width: 64});
+ bb34.append(inst);
+ inst = new Inst(Ret64);
+ arg = Arg.createTmp(Reg.rax);
+ inst.args.push(arg);
+ bb34.append(inst);
+ return code;
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/reg.js b/third_party/webkit/PerformanceTests/ARES-6/Air/reg.js
new file mode 100644
index 0000000000..502b564cb4
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/reg.js
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class Reg extends TmpBase {
+ constructor(index, type, name, isCalleeSave)
+ {
+ super();
+ this._index = index;
+ this._type = type;
+ this._name = name;
+ this._isCalleeSave = !!isCalleeSave;
+ }
+
+ static fromReg(reg)
+ {
+ return reg;
+ }
+
+ get index() { return this._index; }
+ get type() { return this._type; }
+ get name() { return this._name; }
+ get isCalleeSave() { return this._isCalleeSave; }
+
+ get isReg() { return true; }
+
+ hash()
+ {
+ if (this.isGP)
+ return 1 + this._index;
+ return -1 - this._index;
+ }
+
+ toString()
+ {
+ return `%${this._name}`;
+ }
+
+ static extract(arg)
+ {
+ if (arg.isReg)
+ return arg.reg;
+ return null;
+ }
+
+ static forEachFast(arg, func)
+ {
+ return arg.forEachTmpFast(tmp => {
+ if (!tmp.isReg)
+ return;
+ return func(tmp);
+ });
+ }
+
+ static forEach(arg, argRole, argType, argWidth, func)
+ {
+ return arg.forEachTmp(
+ argRole, argType, argWidth,
+ (tmp, role, type, width) => {
+ if (!tmp.isReg)
+ return;
+ return func(tmp, role, type, width);
+ });
+ }
+}
+
+{
+ Reg.regs = [];
+ function newReg(...args)
+ {
+ let result = new Reg(...args);
+ Reg.regs.push(result);
+ return result;
+ }
+
+ // Define X86_64 GPRs
+ {
+ let index = 0;
+ function newGPR(name, isCalleeSave) { return newReg(index++, GP, name, isCalleeSave); }
+
+ Reg.rax = newGPR("rax");
+ Reg.rcx = newGPR("rcx");
+ Reg.rdx = newGPR("rdx");
+ Reg.rbx = newGPR("rbx", true);
+ Reg.rsp = newGPR("rsp");
+ Reg.rbp = newGPR("rbp", true);
+ Reg.rsi = newGPR("rsi");
+ Reg.rdi = newGPR("rdi");
+ for (let i = 8; i <= 15; ++i)
+ Reg[`r${i}`] = newGPR(`r${i}`, i >= 12);
+ }
+
+ // Define X86_64 FPRs.
+ for (let i = 0; i <= 15; ++i)
+ Reg[`xmm${i}`] = newReg(i, FP, `xmm${i}`);
+
+ Reg.gprs = []
+ Reg.fprs = []
+ Reg.calleeSaveGPRs = []
+ Reg.calleeSaveFPRs = []
+ Reg.calleeSaves = []
+ for (let reg of Reg.regs) {
+ if (reg.isGP) {
+ Reg.gprs.push(reg);
+ if (reg.isCalleeSave)
+ Reg.calleeSaveGPRs.push(reg);
+ } else {
+ Reg.fprs.push(reg);
+ if (reg.isCalleeSave)
+ Reg.calleeSaveFPRS.push(reg);
+ }
+ if (reg.isCalleeSave)
+ Reg.calleeSaves.push(reg);
+ }
+
+ Reg.callFrameRegister = Reg.rbp;
+ Reg.stackPointerRegister = Reg.rsp;
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/stack_slot.js b/third_party/webkit/PerformanceTests/ARES-6/Air/stack_slot.js
new file mode 100644
index 0000000000..dafd87a5d2
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/stack_slot.js
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class StackSlot {
+ constructor(index, byteSize, kind)
+ {
+ this._index = index;
+ this._byteSize = byteSize;
+ this._kind = kind;
+ }
+
+ get byteSize() { return this._byteSize; }
+ get kind() { return this._kind; }
+
+ get isLocked() { return this._kind == Locked; }
+ get isSpill() { return this._kind == Spill; }
+
+ get index() { return this._index; }
+
+ ensureSize(size)
+ {
+ if (this._offsetFromFP)
+ throw new Error("Stack slot already allocated");
+ this._byteSize = Math.max(this._byteSize, size);
+ }
+
+ get alignment()
+ {
+ if (this._byteSize <= 1)
+ return 1;
+ if (this._byteSize <= 2)
+ return 2;
+ if (this._byteSize <= 4)
+ return 4;
+ return 8;
+ }
+
+ get offsetFromFP() { return this._offsetFromFP; }
+
+ setOffsetFromFP(value) { this._offsetFromFP = value; }
+
+ hash()
+ {
+ return ((this._kind == Spill ? 1 : 0) + this._byteSize * 3 + (this._offsetFromFP ? this._offsetFromFP * 7 : 0)) >>> 0;
+ }
+
+ toString()
+ {
+ return "" + (this.isSpill ? "spill" : "stack") + this._index + "<" + this._byteSize +
+ (this._offsetFromFP ? ", offset = " + this._offsetFromFP : "") + ">";
+ }
+
+ static extract(arg)
+ {
+ if (arg.isStack)
+ return arg.stackSlot;
+ return null;
+ }
+
+ static forEachFast(arg, func)
+ {
+ if (!arg.isStack)
+ return;
+
+ let replacement;
+ if (replacement = func(arg.stackSlot))
+ return Arg.createStack(replacement, this._offset);
+ }
+
+ static forEach(arg, role, type, width, func)
+ {
+ if (!arg.isStack)
+ return;
+
+ let replacement;
+ if (replacement = func(arg.stackSlot, role, type, width))
+ return Arg.createStack(replacement, this._offset);
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/stress-test.js b/third_party/webkit/PerformanceTests/ARES-6/Air/stress-test.js
new file mode 100644
index 0000000000..b2cfa4303f
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/stress-test.js
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+load("all.js");
+load("payload-gbemu-executeIteration.js");
+load("payload-imaging-gaussian-blur-gaussianBlur.js");
+load("payload-airjs-ACLj8C.js");
+load("payload-typescript-scanIdentifier.js");
+load("benchmark.js");
+
+let benchmark = new AirBenchmark();
+let before = preciseTime();
+
+// Run for at least 10 iterations.
+for (let i = 0; i < 10; ++i) {
+ print("Running mandatory iteration #" + (i + 1) + ":");
+ benchmark.runIteration();
+}
+
+// Run until we have been running for two seconds.
+while (preciseTime() < before + 2) {
+ print("Running bonus iteration:");
+ benchmark.runIteration();
+}
+
+print("Success!");
+
+
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/strip-hash.rb b/third_party/webkit/PerformanceTests/ARES-6/Air/strip-hash.rb
new file mode 100644
index 0000000000..b5c239386f
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/strip-hash.rb
@@ -0,0 +1,10 @@
+# This is a useful hack for cleaning up the payloads generated by Air::dumpAsJS(). That will
+# generate code that computes the hash of insts and stack slots and checks it. This is useful for
+# debugging, but we probably don't want that overhead in the payloads we deploy. So, you can run
+# this script to remove all of the hashing code.
+
+ARGV.each {
+ | filename |
+ IO::write(filename, IO::read(filename).lines.reject{|v| v =~ /hash/i}.join())
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/symbols.js b/third_party/webkit/PerformanceTests/ARES-6/Air/symbols.js
new file mode 100644
index 0000000000..4ef7c63f73
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/symbols.js
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+// This file is for misc symbols.
+
+// B3 types
+const Void = Symbol("Void");
+const Int32 = Symbol("Int32");
+const Int64 = Symbol("Int64");
+const Float = Symbol("Float");
+const Double = Symbol("Double");
+
+// Arg type
+const GP = Symbol("GP");
+const FP = Symbol("FP");
+
+// Stack slot kind
+const Locked = Symbol("Locked");
+const Spill = Symbol("Spill");
+
+// Frequency class
+const Normal = Symbol("Normal");
+const Rare = Symbol("Rare");
+
+// Relational conditions
+const Equal = Symbol("Equal");
+const NotEqual = Symbol("NotEqual");
+const Above = Symbol("Above");
+const AboveOrEqual = Symbol("AboveOrEqual");
+const Below = Symbol("Below");
+const BelowOrEqual = Symbol("BelowOrEqual");
+const GreaterThan = Symbol("GreaterThan");
+const GreaterThanOrEqual = Symbol("GreaterThanOrEqual");
+const LessThan = Symbol("LessThan");
+const LessThanOrEqual = Symbol("LessThanOrEqual");
+
+function relCondCode(cond)
+{
+ switch (cond) {
+ case Equal:
+ return 4;
+ case NotEqual:
+ return 5;
+ case Above:
+ return 7;
+ case AboveOrEqual:
+ return 3;
+ case Below:
+ return 2;
+ case BelowOrEqual:
+ return 6;
+ case GreaterThan:
+ return 15;
+ case GreaterThanOrEqual:
+ return 13;
+ case LessThan:
+ return 12;
+ case LessThanOrEqual:
+ return 14;
+ default:
+ throw new Error("Bad rel cond");
+ }
+}
+
+// Result conditions
+const Overflow = Symbol("Overflow");
+const Signed = Symbol("Signed");
+const PositiveOrZero = Symbol("PositiveOrZero");
+const Zero = Symbol("Zero");
+const NonZero = Symbol("NonZero");
+
+function resCondCode(cond)
+{
+ switch (cond) {
+ case Overflow:
+ return 0;
+ case Signed:
+ return 8;
+ case PositiveOrZero:
+ return 9;
+ case Zero:
+ return 4;
+ case NonZero:
+ return 5;
+ default:
+ throw new Error("Bad res cond: " + cond.toString());
+ }
+}
+
+// Double conditions
+const DoubleEqual = Symbol("DoubleEqual");
+const DoubleNotEqual = Symbol("DoubleNotEqual");
+const DoubleGreaterThan = Symbol("DoubleGreaterThan");
+const DoubleGreaterThanOrEqual = Symbol("DoubleGreaterThanOrEqual");
+const DoubleLessThan = Symbol("DoubleLessThan");
+const DoubleLessThanOrEqual = Symbol("DoubleLessThanOrEqual");
+const DoubleEqualOrUnordered = Symbol("DoubleEqualOrUnordered");
+const DoubleNotEqualOrUnordered = Symbol("DoubleNotEqualOrUnordered");
+const DoubleGreaterThanOrUnordered = Symbol("DoubleGreaterThanOrUnordered");
+const DoubleGreaterThanOrEqualOrUnordered = Symbol("DoubleGreaterThanOrEqualOrUnordered");
+const DoubleLessThanOrUnordered = Symbol("DoubleLessThanOrUnordered");
+const DoubleLessThanOrEqualOrUnordered = Symbol("DoubleLessThanOrEqualOrUnordered");
+
+function doubleCondCode(cond)
+{
+ const bitInvert = 0x10;
+ const bitSpecial = 0x20;
+ switch (cond) {
+ case DoubleEqual:
+ return 4 | bitSpecial;
+ case DoubleNotEqual:
+ return 5;
+ case DoubleGreaterThan:
+ return 7;
+ case DoubleGreaterThanOrEqual:
+ return 3;
+ case DoubleLessThan:
+ return 7 | bitInvert;
+ case DoubleLessThanOrEqual:
+ return 3 | bitInvert;
+ case DoubleEqualOrUnordered:
+ return 4;
+ case DoubleNotEqualOrUnordered:
+ return 5 | bitSpecial;
+ case DoubleGreaterThanOrUnordered:
+ return 2 | bitInvert;
+ case DoubleGreaterThanOrEqualOrUnordered:
+ return 6 | bitInvert;
+ case DoubleLessThanOrUnordered:
+ return 2;
+ case DoubleLessThanOrEqualOrUnordered:
+ return 6;
+ default:
+ throw new Error("Bad cond");
+ }
+}
+
+// Define pointerType()
+const Ptr = 64;
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/test.html b/third_party/webkit/PerformanceTests/ARES-6/Air/test.html
new file mode 100644
index 0000000000..506ef3d823
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/test.html
@@ -0,0 +1,45 @@
+<html>
+<head>
+<title>Air.js</title>
+<script src="symbols.js"></script>
+<script src="tmp_base.js"></script>
+<script src="arg.js"></script>
+<script src="basic_block.js"></script>
+<script src="code.js"></script>
+<script src="frequented_block.js"></script>
+<script src="inst.js"></script>
+<script src="opcode.js"></script>
+<script src="reg.js"></script>
+<script src="stack_slot.js"></script>
+<script src="tmp.js"></script>
+<script src="util.js"></script>
+<script src="custom.js"></script>
+<script src="liveness.js"></script>
+<script src="insertion_set.js"></script>
+<script src="allocate_stack.js"></script>
+<script src="payload-gbemu-executeIteration.js"></script>
+<script src="payload-imaging-gaussian-blur-gaussianBlur.js"></script>
+<script src="payload-airjs-ACLj8C.js"></script>
+<script src="payload-typescript-scanIdentifier.js"></script>
+<script src="benchmark.js"></script>
+<script>
+ function runTest() {
+ try {
+ var result = runBenchmark();
+ document.getElementById("result-summary").innerHTML = "That took " + result + " ms.";
+ } catch (e) {
+ document.getElementById("result-summary").innerHTML = "Failed: " + e;
+ }
+ }
+</script>
+</head>
+<body>
+<h1>Air.js</h1>
+<p>
+ <div id="result-summary"></div>
+ <div><a href="javascript:runTest()">Start Test</a></div>
+</p>
+</body>
+</html>
+
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/test.js b/third_party/webkit/PerformanceTests/ARES-6/Air/test.js
new file mode 100644
index 0000000000..02c011a1d7
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/test.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+load("all.js");
+load("payload-gbemu-executeIteration.js");
+load("payload-imaging-gaussian-blur-gaussianBlur.js");
+load("payload-airjs-ACLj8C.js");
+load("payload-typescript-scanIdentifier.js");
+load("benchmark.js");
+
+let result = runBenchmark();
+print("That took " + result + " ms.");
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/tmp.js b/third_party/webkit/PerformanceTests/ARES-6/Air/tmp.js
new file mode 100644
index 0000000000..997219ab7c
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/tmp.js
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class Tmp extends TmpBase {
+ constructor(index, type)
+ {
+ super();
+ this._index = index;
+ this._type = type;
+ }
+
+ static fromReg(reg)
+ {
+ return reg;
+ }
+
+ get index() { return this._index; }
+ get type() { return this._type; }
+
+ get isReg() { return false; }
+
+ hash()
+ {
+ if (isGP)
+ return Reg.gprs[Reg.gprs.length - 1].hash() + 1 + this._index;
+ return Reg.fprs[Reg.fprs.length - 1].hash() - 1 - this._index;
+ }
+
+ toString()
+ {
+ return "%" + (this.isGP ? "" : "f") + "tmp" + this._index;
+ }
+
+ static extract(arg)
+ {
+ if (arg.isTmp)
+ return arg.tmp;
+ return null;
+ }
+
+ static forEachFast(arg, func) { return arg.forEachTmpFast(func); }
+ static forEach(arg, role, type, width, func) { return arg.forEachTmp(role, type, width, func); }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/tmp_base.js b/third_party/webkit/PerformanceTests/ARES-6/Air/tmp_base.js
new file mode 100644
index 0000000000..a5ec75cf8a
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/tmp_base.js
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class TmpBase {
+ get isGP() { return this.type == GP; }
+ get isFP() { return this.type == FP; }
+
+ get isGPR() { return this.isReg && this.isGP; }
+ get isFPR() { return this.isReg && this.isFP; }
+
+ get reg()
+ {
+ if (!this.isReg)
+ throw new Error("Called .reg on non-Reg");
+ return this;
+ }
+
+ get gpr()
+ {
+ if (!this.isGPR)
+ throw new Error("Called .gpr on non-GPR");
+ return this;
+ }
+
+ get fpr()
+ {
+ if (!this.isFPR)
+ throw new Error("Called .fpr on non-FPR");
+ return this;
+ }
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Air/util.js b/third_party/webkit/PerformanceTests/ARES-6/Air/util.js
new file mode 100644
index 0000000000..a2c7de9be4
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Air/util.js
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+function isRepresentableAsInt32(value)
+{
+ return (value | 0) === value;
+}
+
+function addIndexed(list, cons, ...args)
+{
+ let result = new cons(list.length, ...args);
+ list.push(result);
+ return result;
+}
+
+const stackAlignmentBytes = 16;
+
+function roundUpToMultipleOf(amount, value)
+{
+ return Math.ceil(value / amount) * amount;
+}
+
+function symbolName(symbol)
+{
+ let fullString = symbol.toString();
+ return fullString.substring("Symbol(".length, fullString.length - ")".length);
+}
+
+function lowerSymbolName(symbol)
+{
+ return symbolName(symbol).toLowerCase();
+}
+
+function setToString(set)
+{
+ let result = "";
+ for (let value of set) {
+ if (result)
+ result += ", ";
+ result += value;
+ }
+ return result;
+}
+
+function mergeIntoSet(target, source)
+{
+ let didAdd = false;
+ for (let value of source) {
+ if (target.has(value))
+ continue;
+ target.add(value);
+ didAdd = true;
+ }
+ return didAdd;
+}
+
+function nonEmptyRangesOverlap(leftMin, leftMax, rightMin, rightMax)
+{
+ if (leftMin >= leftMax)
+ throw new Error("Bad left range");
+ if (rightMin >= rightMax)
+ throw new Error("Bad right range");
+
+ if (leftMin <= rightMin && leftMax > rightMin)
+ return true;
+ if (rightMin <= leftMin && rightMax > leftMin)
+ return true;
+ return false;
+}
+
+function rangesOverlap(leftMin, leftMax, rightMin, rightMax)
+{
+ if (leftMin > leftMax)
+ throw new Error("Bad left range");
+ if (rightMin > rightMax)
+ throw new Error("Bad right range");
+
+ if (leftMin == leftMax)
+ return false;
+ if (rightMin == rightMax)
+ return false;
+
+ return nonEmptyRangesOverlap(leftMin, leftMax, rightMin, rightMax);
+}
+
+function removeAllMatching(array, func)
+{
+ let srcIndex = 0;
+ let dstIndex = 0;
+ while (srcIndex < array.length) {
+ let value = array[srcIndex++];
+ if (!func(value))
+ array[dstIndex++] = value;
+ }
+ array.length = dstIndex;
+}
+
+function bubbleSort(array, lessThan)
+{
+ function swap(i, j)
+ {
+ var tmp = array[i];
+ array[i] = array[j];
+ array[j] = tmp;
+ }
+
+ let begin = 0;
+ let end = array.length;
+ for (;;) {
+ let changed = false;
+
+ function bubble(i, j)
+ {
+ if (lessThan(array[i], array[j])) {
+ swap(i, j);
+ changed = true;
+ }
+ }
+
+ if (end < begin)
+ throw new Error("Begin and end are messed up");
+
+ let limit = end - begin;
+ for (let i = limit; i-- > 1;)
+ bubble(begin + i, begin + i - 1);
+ if (!changed)
+ return;
+
+ // After one run, the first element in the list is guaranteed to be the smallest.
+ begin++;
+
+ // Now go in the other direction. This eliminates most sorting pathologies.
+ changed = false;
+
+ if (end < begin)
+ throw new Error("Begin and end are messed up");
+
+ limit = end - begin;
+ for (let i = 1; i < limit; ++i)
+ bubble(begin + i, begin + i - 1);
+ if (!changed)
+ return;
+
+ // Now the last element is guaranteed to be the largest.
+ end--;
+ }
+}
+
+let currentTime;
+if (this.performance && performance.now)
+ currentTime = function() { return performance.now() };
+else if (this.preciseTime)
+ currentTime = function() { return preciseTime() * 1000; };
+else
+ currentTime = function() { return +new Date(); };
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Babylon/AUTHORS b/third_party/webkit/PerformanceTests/ARES-6/Babylon/AUTHORS
new file mode 100644
index 0000000000..2f39deff4b
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Babylon/AUTHORS
@@ -0,0 +1,41 @@
+List of Acorn contributors. Updated before every release.
+
+Adrian Rakovsky
+Alistair Braidwood
+Andres Suarez
+Aparajita Fishman
+Arian Stolwijk
+Artem Govorov
+Brandon Mills
+Charles Hughes
+Conrad Irwin
+David Bonnet
+Forbes Lindesay
+Gilad Peleg
+impinball
+Ingvar Stepanyan
+Jesse McCarthy
+Jiaxing Wang
+Joel Kemp
+Johannes Herr
+Jürg Lehni
+keeyipchan
+Kevin Kwok
+krator
+Marijn Haverbeke
+Martin Carlberg
+Mathias Bynens
+Mathieu 'p01' Henri
+Max Schaefer
+Max Zerzouri
+Mihai Bazon
+Mike Rennie
+Nick Fitzgerald
+Oskar Schöldström
+Paul Harper
+Peter Rust
+PlNG
+r-e-d
+Rich Harris
+Sebastian McKenzie
+zsjforcn
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Babylon/air-blob.js b/third_party/webkit/PerformanceTests/ARES-6/Babylon/air-blob.js
new file mode 100644
index 0000000000..2b8f125f18
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Babylon/air-blob.js
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class Reg extends TmpBase {
+ constructor(index, type, name, isCalleeSave)
+ {
+ super();
+ this._index = index;
+ this._type = type;
+ this._name = name;
+ this._isCalleeSave = !!isCalleeSave;
+ }
+
+ static fromReg(reg)
+ {
+ return reg;
+ }
+
+ get index() { return this._index; }
+ get type() { return this._type; }
+ get name() { return this._name; }
+ get isCalleeSave() { return this._isCalleeSave; }
+
+ get isReg() { return true; }
+
+ hash()
+ {
+ if (this.isGP)
+ return 1 + this._index;
+ return -1 - this._index;
+ }
+
+ toString()
+ {
+ return `%${this._name}`;
+ }
+
+ static extract(arg)
+ {
+ if (arg.isReg)
+ return arg.reg;
+ return null;
+ }
+
+ static forEachFast(arg, func)
+ {
+ return arg.forEachTmpFast(tmp => {
+ if (!tmp.isReg)
+ return;
+ return func(tmp);
+ });
+ }
+
+ static forEach(arg, argRole, argType, argWidth, func)
+ {
+ return arg.forEachTmp(
+ argRole, argType, argWidth,
+ (tmp, role, type, width) => {
+ if (!tmp.isReg)
+ return;
+ return func(tmp, role, type, width);
+ });
+ }
+}
+
+{
+ Reg.regs = [];
+ function newReg(...args)
+ {
+ let result = new Reg(...args);
+ Reg.regs.push(result);
+ return result;
+ }
+
+ // Define X86_64 GPRs
+ {
+ let index = 0;
+ function newGPR(name, isCalleeSave) { return newReg(index++, GP, name, isCalleeSave); }
+
+ Reg.rax = newGPR("rax");
+ Reg.rcx = newGPR("rcx");
+ Reg.rdx = newGPR("rdx");
+ Reg.rbx = newGPR("rbx", true);
+ Reg.rsp = newGPR("rsp");
+ Reg.rbp = newGPR("rbp", true);
+ Reg.rsi = newGPR("rsi");
+ Reg.rdi = newGPR("rdi");
+ for (let i = 8; i <= 15; ++i)
+ Reg[`r${i}`] = newGPR(`r${i}`, i >= 12);
+ }
+
+ // Define X86_64 FPRs.
+ for (let i = 0; i <= 15; ++i)
+ Reg[`xmm${i}`] = newReg(i, FP, `xmm${i}`);
+
+ Reg.gprs = []
+ Reg.fprs = []
+ Reg.calleeSaveGPRs = []
+ Reg.calleeSaveFPRs = []
+ Reg.calleeSaves = []
+ for (let reg of Reg.regs) {
+ if (reg.isGP) {
+ Reg.gprs.push(reg);
+ if (reg.isCalleeSave)
+ Reg.calleeSaveGPRs.push(reg);
+ } else {
+ Reg.fprs.push(reg);
+ if (reg.isCalleeSave)
+ Reg.calleeSaveFPRS.push(reg);
+ }
+ if (reg.isCalleeSave)
+ Reg.calleeSaves.push(reg);
+ }
+
+ Reg.callFrameRegister = Reg.rbp;
+ Reg.stackPointerRegister = Reg.rsp;
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Babylon/babylon-blob.js b/third_party/webkit/PerformanceTests/ARES-6/Babylon/babylon-blob.js
new file mode 100644
index 0000000000..38c4443c89
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Babylon/babylon-blob.js
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2012-2014 by various contributors (see AUTHORS)
+ *
+ * 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.
+*/
+
+import { reservedWords } from "../util/identifier";
+import { getOptions } from "../options";
+import Tokenizer from "../tokenizer";
+
+export const plugins = {};
+
+export default class Parser extends Tokenizer {
+ constructor(options, input) {
+ options = getOptions(options);
+ super(options, input);
+
+ this.options = options;
+ this.inModule = this.options.sourceType === "module";
+ this.input = input;
+ this.plugins = this.loadPlugins(this.options.plugins);
+ this.filename = options.sourceFilename;
+
+ // If enabled, skip leading hashbang line.
+ if (this.state.pos === 0 && this.input[0] === "#" && this.input[1] === "!") {
+ this.skipLineComment(2);
+ }
+ }
+
+ isReservedWord(word) {
+ if (word === "await") {
+ return this.inModule;
+ } else {
+ return reservedWords[6](word);
+ }
+ }
+
+ hasPlugin(name) {
+ return !!this.plugins[name];
+ }
+
+ extend(name, f) {
+ this[name] = f(this[name]);
+ }
+
+ loadPlugins(pluginList) {
+ const pluginMap = {};
+
+ if (pluginList.indexOf("flow") >= 0) {
+ // ensure flow plugin loads last
+ pluginList = pluginList.filter((plugin) => plugin !== "flow");
+ pluginList.push("flow");
+ }
+
+ if (pluginList.indexOf("estree") >= 0) {
+ // ensure estree plugin loads first
+ pluginList = pluginList.filter((plugin) => plugin !== "estree");
+ pluginList.unshift("estree");
+ }
+
+ for (const name of pluginList) {
+ if (!pluginMap[name]) {
+ pluginMap[name] = true;
+
+ const plugin = plugins[name];
+ if (plugin) plugin(this);
+ }
+ }
+
+ return pluginMap;
+ }
+
+ parse() {
+ const file = this.startNode();
+ const program = this.startNode();
+ this.nextToken();
+ return this.parseTopLevel(file, program);
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Babylon/basic-blob.js b/third_party/webkit/PerformanceTests/ARES-6/Babylon/basic-blob.js
new file mode 100644
index 0000000000..bebd9f6359
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Babylon/basic-blob.js
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+const Basic = {};
+
+Basic.NumberApply = function(state)
+{
+ // I'd call this arguments but we're in strict mode.
+ let parameters = this.parameters.map(value => value.evaluate(state));
+
+ return state.getValue(this.name, parameters.length).apply(state, parameters);
+};
+
+Basic.Variable = function(state)
+{
+ let parameters = this.parameters.map(value => value.evaluate(state));
+
+ return state.getValue(this.name, parameters.length).leftApply(state, parameters);
+}
+
+Basic.Const = function(state)
+{
+ return this.value;
+}
+
+Basic.NumberPow = function(state)
+{
+ return Math.pow(this.left.evaluate(state), this.right.evaluate(state));
+}
+
+Basic.NumberMul = function(state)
+{
+ return this.left.evaluate(state) * this.right.evaluate(state);
+}
+
+Basic.NumberDiv = function(state)
+{
+ return this.left.evaluate(state) / this.right.evaluate(state);
+}
+
+Basic.NumberNeg = function(state)
+{
+ return -this.term.evaluate(state);
+}
+
+Basic.NumberAdd = function(state)
+{
+ return this.left.evaluate(state) + this.right.evaluate(state);
+}
+
+Basic.NumberSub = function(state)
+{
+ return this.left.evaluate(state) - this.right.evaluate(state);
+}
+
+Basic.StringVar = function(state)
+{
+ let value = state.stringValues.get(this.name);
+ if (value == null)
+ state.abort("Could not find string variable " + this.name);
+ return value;
+}
+
+Basic.Equals = function(state)
+{
+ return this.left.evaluate(state) == this.right.evaluate(state);
+}
+
+Basic.NotEquals = function(state)
+{
+ return this.left.evaluate(state) != this.right.evaluate(state);
+}
+
+Basic.LessThan = function(state)
+{
+ return this.left.evaluate(state) < this.right.evaluate(state);
+}
+
+Basic.GreaterThan = function(state)
+{
+ return this.left.evaluate(state) > this.right.evaluate(state);
+}
+
+Basic.LessEqual = function(state)
+{
+ return this.left.evaluate(state) <= this.right.evaluate(state);
+}
+
+Basic.GreaterEqual = function(state)
+{
+ return this.left.evaluate(state) >= this.right.evaluate(state);
+}
+
+Basic.GoTo = function*(state)
+{
+ state.nextLineNumber = this.target;
+}
+
+Basic.GoSub = function*(state)
+{
+ state.subStack.push(state.nextLineNumber);
+ state.nextLineNumber = this.target;
+}
+
+Basic.Def = function*(state)
+{
+ state.validate(!state.values.has(this.name), "Cannot redefine function");
+ state.values.set(this.name, new NumberFunction(this.parameters, this.expression));
+}
+
+Basic.Let = function*(state)
+{
+ this.variable.evaluate(state).assign(this.expression.evaluate(state));
+}
+
+Basic.If = function*(state)
+{
+ if (this.condition.evaluate(state))
+ state.nextLineNumber = this.target;
+}
+
+Basic.Return = function*(state)
+{
+ this.validate(state.subStack.length, "Not in a subroutine");
+ this.nextLineNumber = state.subStack.pop();
+}
+
+Basic.Stop = function*(state)
+{
+ state.nextLineNumber = null;
+}
+
+Basic.On = function*(state)
+{
+ let index = this.expression.evaluate(state);
+ if (!(index >= 1) || !(index <= this.targets.length))
+ state.abort("Index out of bounds: " + index);
+ this.nextLineNumber = this.targets[Math.floor(index)];
+}
+
+Basic.For = function*(state)
+{
+ let sideState = state.getSideState(this);
+ sideState.variable = state.getValue(this.variable, 0).leftApply(state, []);
+ sideState.initialValue = this.initial.evaluate(state);
+ sideState.limitValue = this.limit.evaluate(state);
+ sideState.stepValue = this.step.evaluate(state);
+ sideState.variable.assign(sideState.initialValue);
+ sideState.shouldStop = function() {
+ return (sideState.variable.value - sideState.limitValue) * Math.sign(sideState.stepValue) > 0;
+ };
+ if (sideState.shouldStop())
+ this.nextLineNumber = this.target.lineNumber + 1;
+}
+
+Basic.Next = function*(state)
+{
+ let sideState = state.getSideState(this.target);
+ sideState.variable.assign(sideState.variable.value + sideState.stepValue);
+ if (sideState.shouldStop())
+ return;
+ state.nextLineNumber = this.target.lineNumber + 1;
+}
+
+Basic.Next.isBlockEnd = true;
+
+Basic.Print = function*(state)
+{
+ let string = "";
+ for (let item of this.items) {
+ switch (item.kind) {
+ case "comma":
+ while (string.length % 14)
+ string += " ";
+ break;
+ case "tab": {
+ let value = item.value.evaluate(state);
+ value = Math.max(Math.round(value), 1);
+ while (string.length % value)
+ string += " ";
+ break;
+ }
+ case "string":
+ case "number":
+ string += item.value.evaluate(state);
+ break;
+ default:
+ throw new Error("Bad item kind: " + item.kind);
+ }
+ }
+
+ yield {kind: "output", string};
+}
+
+Basic.Input = function*(state)
+{
+ let results = yield {kind: "input", numItems: this.items.length};
+ state.validate(results != null && results.length == this.items.length, "Input did not get the right number of items");
+ for (let i = 0; i < results.length; ++i)
+ this.items[i].evaluate(state).assign(results[i]);
+}
+
+Basic.Read = function*(state)
+{
+ for (let item of this.items) {
+ state.validate(state.dataIndex < state.program.data.length, "Attempting to read past the end of data");
+ item.assign(state.program.data[state.dataIndex++]);
+ }
+}
+
+Basic.Restore = function*(state)
+{
+ state.dataIndex = 0;
+}
+
+Basic.Dim = function*(state)
+{
+ for (let item of this.items) {
+ state.validate(!state.values.has(item.name), "Variable " + item.name + " already exists");
+ state.validate(item.bounds.length, "Dim statement is for arrays");
+ state.values.set(item.name, new NumberArray(item.bounds.map(bound => bound + 1)));
+ }
+}
+
+Basic.Randomize = function*(state)
+{
+ state.rng = createRNGWithRandomSeed();
+}
+
+Basic.End = function*(state)
+{
+ state.nextLineNumber = null;
+}
+
+Basic.End.isBlockEnd = true;
+
+Basic.Program = function* programGenerator(state)
+{
+ state.validate(state.program == this, "State must match program");
+ let maxLineNumber = Math.max(...this.statements.keys());
+ while (state.nextLineNumber != null) {
+ state.validate(state.nextLineNumber <= maxLineNumber, "Went out of bounds of the program");
+ let statement = this.statements.get(state.nextLineNumber++);
+ if (statement == null || statement.process == null)
+ continue;
+ state.statement = statement;
+ yield* statement.process(state);
+ }
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Babylon/benchmark.js b/third_party/webkit/PerformanceTests/ARES-6/Babylon/benchmark.js
new file mode 100644
index 0000000000..72f96766e5
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Babylon/benchmark.js
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+let currentTime;
+if (this.performance && performance.now)
+ currentTime = function() { return performance.now() };
+else if (this.preciseTime)
+ currentTime = function() { return preciseTime() * 1000; };
+else
+ currentTime = function() { return +new Date(); };
+
+class BabylonBenchmark {
+ constructor(verbose = 0)
+ {
+ let sources = [];
+
+ const files = [
+ ["./Babylon/air-blob.js", {}]
+ , ["./Babylon/basic-blob.js", {}]
+ , ["./Babylon/inspector-blob.js", {}]
+ , ["./Babylon/babylon-blob.js", {sourceType: "module"}]
+ ];
+
+ for (let [file, options] of files) {
+ function appendSource(s) {
+ sources.push([file, s, options]);
+ }
+
+ let s;
+ const isInBrowser = typeof window !== "undefined";
+ if (isInBrowser) {
+ let request = new XMLHttpRequest();
+ request.open('GET', file, false);
+ request.send(null);
+ if (!request.responseText.length)
+ throw new Error("Expect non-empty sources");
+ appendSource(request.responseText);
+ } else {
+ appendSource(read(file));
+ }
+ }
+
+ this.sources = sources;
+ }
+
+ runIteration()
+ {
+ const Parser = parserIndexJS;
+ const { plugins } = parserIndexJS;
+ const { types : tokTypes } = tokenizerTypesJS;
+ const estreePlugin = pluginsEstreeJS;
+ const flowPlugin = pluginsFlowJS;
+ const jsxPlugin = pluginsJsxIndexJS;
+ plugins.estree = estreePlugin;
+ plugins.flow = flowPlugin;
+ plugins.jsx = jsxPlugin;
+
+ function parse(input, options) {
+ return new Parser(options, input).parse();
+ }
+
+ function parseExpression(input, options) {
+ const parser = new Parser(options, input);
+ if (parser.options.strictMode) {
+ parser.state.strict = true;
+ }
+ return parser.getExpression();
+ }
+
+ for (let [fileName, source, options] of this.sources) {
+ parse(source, options);
+ }
+ }
+}
+
+function runBenchmark()
+{
+ const verbose = 0;
+ const numIterations = 150;
+
+ let before = currentTime();
+
+ let benchmark = new Benchmark(verbose);
+
+ for (let iteration = 0; iteration < numIterations; ++iteration)
+ benchmark.runIteration();
+
+ let after = currentTime();
+ return after - before;
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Babylon/index.js b/third_party/webkit/PerformanceTests/ARES-6/Babylon/index.js
new file mode 100644
index 0000000000..8bd1478ce0
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Babylon/index.js
@@ -0,0 +1,6942 @@
+/*
+ * Copyright (C) 2012-2014 by various contributors (see AUTHORS)
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * 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.
+*/
+
+"use strict";
+
+// util/identifier.js
+
+const utilIdentifierJS = { };
+{
+ /* eslint max-len: 0 */
+
+ // This is a trick taken from Esprima. It turns out that, on
+ // non-Chrome browsers, to check whether a string is in a set, a
+ // predicate containing a big ugly `switch` statement is faster than
+ // a regular expression, and on Chrome the two are about on par.
+ // This function uses `eval` (non-lexical) to produce such a
+ // predicate from a space-separated string of words.
+ //
+ // It starts by sorting the words by length.
+
+ function makePredicate(words) {
+ words = words.split(" ");
+ return function (str) {
+ return words.indexOf(str) >= 0;
+ };
+ }
+
+ // Reserved word lists for various dialects of the language
+
+ const reservedWords = {
+ 6: makePredicate("enum await"),
+ strict: makePredicate("implements interface let package private protected public static yield"),
+ strictBind: makePredicate("eval arguments")
+ };
+ utilIdentifierJS.reservedWords = reservedWords;
+
+ // And the keywords
+
+ const isKeyword = makePredicate("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 let const class extends export import yield super");
+ utilIdentifierJS.isKeyword = isKeyword;
+
+ // ## 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`.
+
+ let 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\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\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-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\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";
+ let 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\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\u0d01-\u0d03\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\u1cf8\u1cf9\u1dc0-\u1df5\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";
+
+ const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
+ const 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
+ const astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,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,449,56,264,8,2,36,18,0,50,29,881,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,0,32,6124,20,754,9486,1,3071,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,10591,541];
+ // eslint-disable-next-line comma-spacing
+ const 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,838,7,2,7,17,9,57,21,2,13,19882,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) {
+ let pos = 0x10000;
+ for (let 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) {
+ 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));
+ return isInAstralSet(code, astralIdentifierStartCodes);
+ }
+ utilIdentifierJS.isIdentifierStart = isIdentifierStart;
+
+ // Test whether a given character is part of an identifier.
+
+ function isIdentifierChar(code) {
+ 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));
+ return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
+ }
+ utilIdentifierJS.isIdentifierChar = isIdentifierChar;
+}
+
+// util/whitespace.js
+const utilWhitespaceJS = {};
+{
+ const lineBreak = /\r\n?|\n|\u2028|\u2029/;
+ utilWhitespaceJS.lineBreak = lineBreak;
+ const lineBreakG = new RegExp(lineBreak.source, "g");
+ utilWhitespaceJS.lineBreakG = lineBreakG;
+
+ function isNewLine(code){
+ return code === 10 || code === 13 || code === 0x2028 || code === 0x2029;
+ }
+ utilWhitespaceJS.isNewLine = isNewLine;
+
+ const nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
+ utilWhitespaceJS.nonASCIIwhitespace = nonASCIIwhitespace;
+}
+
+// util/location.js
+const utilLocationJS = {};
+{
+ const lineBreakG = utilWhitespaceJS.lineBreakG;
+
+ // These are used when `options.locations` is on, for the
+ // `startLoc` and `endLoc` properties.
+
+ class Position {
+ constructor(line, col) {
+ this.line = line;
+ this.column = col;
+ }
+ }
+ utilLocationJS.Position = Position;
+
+ class SourceLocation {
+ constructor(start, end) {
+ this.start = start;
+ this.end = end;
+ }
+ }
+ utilLocationJS.SourceLocation = SourceLocation;
+
+ // 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 (let line = 1, cur = 0; ;) {
+ lineBreakG.lastIndex = cur;
+ const match = lineBreakG.exec(input);
+ if (match && match.index < offset) {
+ ++line;
+ cur = match.index + match[0].length;
+ } else {
+ return new Position(line, offset - cur);
+ }
+ }
+ }
+ utilLocationJS.getLineInfo = getLineInfo;
+}
+
+
+// tokenizer/types.js
+const tokenizerTypesJS = {};
+{
+ // ## 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).
+ //
+ // `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.
+
+ const beforeExpr = true;
+ const startsExpr = true;
+ const isLoop = true;
+ const isAssign = true;
+ const prefix = true;
+ const postfix = true;
+
+ class TokenType {
+ constructor(label, conf = {}) {
+ this.label = label;
+ this.keyword = conf.keyword;
+ this.beforeExpr = !!conf.beforeExpr;
+ this.startsExpr = !!conf.startsExpr;
+ this.rightAssociative = !!conf.rightAssociative;
+ this.isLoop = !!conf.isLoop;
+ this.isAssign = !!conf.isAssign;
+ this.prefix = !!conf.prefix;
+ this.postfix = !!conf.postfix;
+ this.binop = conf.binop || null;
+ this.updateContext = null;
+ }
+ }
+ tokenizerTypesJS.TokenType = TokenType;
+
+ class KeywordTokenType extends TokenType {
+ constructor(name, options = {}) {
+ options.keyword = name;
+
+ super(name, options);
+ }
+ }
+
+ class BinopTokenType extends TokenType {
+ constructor(name, prec) {
+ super(name, { beforeExpr, binop: prec });
+ }
+ }
+ tokenizerTypesJS.BinopTokenType = BinopTokenType;
+
+ const 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, startsExpr }),
+ bracketR: new TokenType("]"),
+ braceL: new TokenType("{", { beforeExpr, startsExpr }),
+ braceBarL: new TokenType("{|", { beforeExpr, startsExpr }),
+ braceR: new TokenType("}"),
+ braceBarR: new TokenType("|}"),
+ parenL: new TokenType("(", { beforeExpr, startsExpr }),
+ parenR: new TokenType(")"),
+ comma: new TokenType(",", { beforeExpr }),
+ semi: new TokenType(";", { beforeExpr }),
+ colon: new TokenType(":", { beforeExpr }),
+ doubleColon: new TokenType("::", { beforeExpr }),
+ dot: new TokenType("."),
+ question: new TokenType("?", { beforeExpr }),
+ arrow: new TokenType("=>", { beforeExpr }),
+ template: new TokenType("template"),
+ ellipsis: new TokenType("...", { beforeExpr }),
+ backQuote: new TokenType("`", { startsExpr }),
+ dollarBraceL: new TokenType("${", { beforeExpr, startsExpr }),
+ at: new TokenType("@"),
+
+ // 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, isAssign }),
+ assign: new TokenType("_=", { beforeExpr, isAssign }),
+ incDec: new TokenType("++/--", { prefix, postfix, startsExpr }),
+ prefix: new TokenType("prefix", { beforeExpr, prefix, startsExpr }),
+ logicalOR: new BinopTokenType("||", 1),
+ logicalAND: new BinopTokenType("&&", 2),
+ bitwiseOR: new BinopTokenType("|", 3),
+ bitwiseXOR: new BinopTokenType("^", 4),
+ bitwiseAND: new BinopTokenType("&", 5),
+ equality: new BinopTokenType("==/!=", 6),
+ relational: new BinopTokenType("</>", 7),
+ bitShift: new BinopTokenType("<</>>", 8),
+ plusMin: new TokenType("+/-", { beforeExpr, binop: 9, prefix, startsExpr }),
+ modulo: new BinopTokenType("%", 10),
+ star: new BinopTokenType("*", 10),
+ slash: new BinopTokenType("/", 10),
+ exponent: new TokenType("**", { beforeExpr, binop: 11, rightAssociative: true })
+ };
+ tokenizerTypesJS.types = types;
+
+ const keywords = {
+ "break": new KeywordTokenType("break"),
+ "case": new KeywordTokenType("case", { beforeExpr }),
+ "catch": new KeywordTokenType("catch"),
+ "continue": new KeywordTokenType("continue"),
+ "debugger": new KeywordTokenType("debugger"),
+ "default": new KeywordTokenType("default", { beforeExpr }),
+ "do": new KeywordTokenType("do", { isLoop, beforeExpr }),
+ "else": new KeywordTokenType("else", { beforeExpr }),
+ "finally": new KeywordTokenType("finally"),
+ "for": new KeywordTokenType("for", { isLoop }),
+ "function": new KeywordTokenType("function", { startsExpr }),
+ "if": new KeywordTokenType("if"),
+ "return": new KeywordTokenType("return", { beforeExpr }),
+ "switch": new KeywordTokenType("switch"),
+ "throw": new KeywordTokenType("throw", { beforeExpr }),
+ "try": new KeywordTokenType("try"),
+ "var": new KeywordTokenType("var"),
+ "let": new KeywordTokenType("let"),
+ "const": new KeywordTokenType("const"),
+ "while": new KeywordTokenType("while", { isLoop }),
+ "with": new KeywordTokenType("with"),
+ "new": new KeywordTokenType("new", { beforeExpr, startsExpr }),
+ "this": new KeywordTokenType("this", { startsExpr }),
+ "super": new KeywordTokenType("super", { startsExpr }),
+ "class": new KeywordTokenType("class"),
+ "extends": new KeywordTokenType("extends", { beforeExpr }),
+ "export": new KeywordTokenType("export"),
+ "import": new KeywordTokenType("import", { startsExpr }),
+ "yield": new KeywordTokenType("yield", { beforeExpr, startsExpr }),
+ "null": new KeywordTokenType("null", { startsExpr }),
+ "true": new KeywordTokenType("true", { startsExpr }),
+ "false": new KeywordTokenType("false", { startsExpr }),
+ "in": new KeywordTokenType("in", { beforeExpr, binop: 7 }),
+ "instanceof": new KeywordTokenType("instanceof", { beforeExpr, binop: 7 }),
+ "typeof": new KeywordTokenType("typeof", { beforeExpr, prefix, startsExpr }),
+ "void": new KeywordTokenType("void", { beforeExpr, prefix, startsExpr }),
+ "delete": new KeywordTokenType("delete", { beforeExpr, prefix, startsExpr })
+ };
+ tokenizerTypesJS.keywords = keywords;
+
+ // Map keyword names to token types.
+ Object.keys(keywords).forEach((name) => {
+ types["_" + name] = keywords[name];
+ });
+}
+
+// tokenizer/context.js
+const tokenizerContextJS = {};
+{
+ // 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
+
+ const tt = tokenizerTypesJS.types;
+ const lineBreak = utilWhitespaceJS.lineBreak;
+
+ class TokContext {
+ constructor(
+ token,
+ isExpr,
+ preserveSpace,
+ override,
+ ) {
+ this.token = token;
+ this.isExpr = !!isExpr;
+ this.preserveSpace = !!preserveSpace;
+ this.override = override;
+ }
+
+ //token: string;
+ //isExpr: boolean;
+ //preserveSpace: boolean;
+ //override: ?Function;
+ }
+ tokenizerContextJS.TokContext = TokContext;
+
+ const types = {
+ braceStatement: new TokContext("{", false),
+ braceExpression: new TokContext("{", true),
+ templateQuasi: new TokContext("${", true),
+ parenStatement: new TokContext("(", false),
+ parenExpression: new TokContext("(", true),
+ template: new TokContext("`", true, true, (p) => p.readTmplToken()),
+ functionExpression: new TokContext("function", true)
+ };
+ tokenizerContextJS.types = types;
+
+ // Token-specific context update code
+
+ tt.parenR.updateContext = tt.braceR.updateContext = function () {
+ if (this.state.context.length === 1) {
+ this.state.exprAllowed = true;
+ return;
+ }
+
+ const out = this.state.context.pop();
+ if (out === types.braceStatement && this.curContext() === types.functionExpression) {
+ this.state.context.pop();
+ this.state.exprAllowed = false;
+ } else if (out === types.templateQuasi) {
+ this.state.exprAllowed = true;
+ } else {
+ this.state.exprAllowed = !out.isExpr;
+ }
+ };
+
+ tt.name.updateContext = function (prevType) {
+ this.state.exprAllowed = false;
+
+ if (prevType === tt._let || prevType === tt._const || prevType === tt._var) {
+ if (lineBreak.test(this.input.slice(this.state.end))) {
+ this.state.exprAllowed = true;
+ }
+ }
+ };
+
+ tt.braceL.updateContext = function (prevType) {
+ this.state.context.push(this.braceIsBlock(prevType) ? types.braceStatement : types.braceExpression);
+ this.state.exprAllowed = true;
+ };
+
+ tt.dollarBraceL.updateContext = function () {
+ this.state.context.push(types.templateQuasi);
+ this.state.exprAllowed = true;
+ };
+
+ tt.parenL.updateContext = function (prevType) {
+ const statementParens = prevType === tt._if || prevType === tt._for ||
+ prevType === tt._with || prevType === tt._while;
+ this.state.context.push(statementParens ? types.parenStatement : types.parenExpression);
+ this.state.exprAllowed = true;
+ };
+
+ tt.incDec.updateContext = function () {
+ // tokExprAllowed stays unchanged
+ };
+
+ tt._function.updateContext = function () {
+ if (this.curContext() !== types.braceStatement) {
+ this.state.context.push(types.functionExpression);
+ }
+
+ this.state.exprAllowed = false;
+ };
+
+ tt.backQuote.updateContext = function () {
+ if (this.curContext() === types.template) {
+ this.state.context.pop();
+ } else {
+ this.state.context.push(types.template);
+ }
+ this.state.exprAllowed = false;
+ };
+}
+
+// tokenizer/state.js
+let tokenizerStateJS = {};
+{
+ const TokContext = tokenizerContextJS.TokContext;
+ const TokenType = tokenizerTypesJS.TokenType;
+ const Position = utilLocationJS.Position;
+ const ct = tokenizerContextJS.types;
+ const tt = tokenizerTypesJS.types;
+
+ //export default class State {
+ class State {
+ init(options, input) {
+ this.strict = options.strictMode === false ? false : options.sourceType === "module";
+
+ this.input = input;
+
+ this.potentialArrowAt = -1;
+
+ this.inMethod =
+ this.inFunction =
+ this.inGenerator =
+ this.inAsync =
+ this.inPropertyName =
+ this.inType =
+ this.noAnonFunctionType =
+ false;
+
+ this.labels = [];
+
+ this.decorators = [];
+
+ this.tokens = [];
+
+ this.comments = [];
+
+ this.trailingComments = [];
+ this.leadingComments = [];
+ this.commentStack = [];
+
+ this.pos = this.lineStart = 0;
+ this.curLine = options.startLine;
+
+ this.type = tt.eof;
+ this.value = null;
+ this.start = this.end = this.pos;
+ this.startLoc = this.endLoc = this.curPosition();
+
+ this.lastTokEndLoc = this.lastTokStartLoc = null;
+ this.lastTokStart = this.lastTokEnd = this.pos;
+
+ this.context = [ct.braceStatement];
+ this.exprAllowed = true;
+
+ this.containsEsc = this.containsOctal = false;
+ this.octalPosition = null;
+
+ this.invalidTemplateEscapePosition = null;
+
+ this.exportedIdentifiers = [];
+
+ return this;
+ }
+
+ //// TODO
+ //strict: boolean;
+
+ //// TODO
+ //input: string;
+
+ //// Used to signify the start of a potential arrow function
+ //potentialArrowAt: number;
+
+ //// Flags to track whether we are in a function, a generator.
+ //inFunction: boolean;
+ //inGenerator: boolean;
+ //inMethod: boolean;
+ //inAsync: boolean;
+ //inType: boolean;
+ //inPropertyName: boolean;
+
+ //// Labels in scope.
+ //labels: Array<Object>;
+
+ //// Leading decorators.
+ //decorators: Array<Object>;
+
+ //// Token store.
+ //tokens: Array<Object>;
+
+ //// Comment store.
+ //comments: Array<Object>;
+
+ //// Comment attachment store
+ //trailingComments: Array<Object>;
+ //leadingComments: Array<Object>;
+ //commentStack: Array<Object>;
+
+ //// The current position of the tokenizer in the input.
+ //pos: number;
+ //lineStart: number;
+ //curLine: number;
+
+ //// Properties of the current token:
+ //// Its type
+ //type: TokenType;
+
+ //// For tokens that include more information than their type, the value
+ //value: any;
+
+ //// Its start and end offset
+ //start: number;
+ //end: number;
+
+ //// And, if locations are used, the {line, column} object
+ //// corresponding to those offsets
+ //startLoc: Position;
+ //endLoc: Position;
+
+ //// Position information for the previous token
+ //lastTokEndLoc: ?Position;
+ //lastTokStartLoc: ?Position;
+ //lastTokStart: number;
+ //lastTokEnd: number;
+
+ //// The context stack is used to superficially track syntactic
+ //// context to predict whether a regular expression is allowed in a
+ //// given position.
+ //context: Array<TokContext>;
+ //exprAllowed: boolean;
+
+ //// 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.
+ //containsEsc: boolean;
+
+ //// TODO
+ //containsOctal: boolean;
+ //octalPosition: ?number;
+
+ //// Names of exports store. `default` is stored as a name for both
+ //// `export default foo;` and `export { foo as default };`.
+ //exportedIdentifiers: Array<string>;
+
+ curPosition() {
+ return new Position(this.curLine, this.pos - this.lineStart);
+ }
+
+ clone(skipArrays) {
+ const state = new State;
+ for (const key in this) {
+ let val = this[key];
+
+ if ((!skipArrays || key === "context") && Array.isArray(val)) {
+ val = val.slice();
+ }
+
+ state[key] = val;
+ }
+ return state;
+ }
+ }
+ tokenizerStateJS = State;
+}
+
+// tokenizer/index.js
+let tokenizerIndexJS = {};
+{
+ /* eslint max-len: 0 */
+
+ const TokenType = tokenizerTypesJS.TokenType;
+ const {isIdentifierStart, isIdentifierChar, isKeyword} = utilIdentifierJS;
+
+ const { types: tt , keywords: keywordTypes } = tokenizerTypesJS;
+ const { types: ct } = tokenizerContextJS;
+ const { SourceLocation } = utilLocationJS;
+ const { lineBreak, lineBreakG, isNewLine, nonASCIIwhitespace } = utilWhitespaceJS;
+ const State = tokenizerStateJS;
+
+ // 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.
+
+ //export class Token {
+ class Token {
+ constructor(state) {
+ this.type = state.type;
+ this.value = state.value;
+ this.start = state.start;
+ this.end = state.end;
+ this.loc = new SourceLocation(state.startLoc, state.endLoc);
+ }
+ }
+
+ // ## Tokenizer
+
+ function codePointToString(code) {
+ // UTF-16 Decoding
+ if (code <= 0xFFFF) {
+ return String.fromCharCode(code);
+ } else {
+ return String.fromCharCode(((code - 0x10000) >> 10) + 0xD800, ((code - 0x10000) & 1023) + 0xDC00);
+ }
+ }
+
+ class Tokenizer {
+ constructor(options, input) {
+ this.state = new State;
+ this.state.init(options, input);
+ }
+
+ // Move to the next token
+
+ next() {
+ if (!this.isLookahead) {
+ this.state.tokens.push(new Token(this.state));
+ }
+
+ this.state.lastTokEnd = this.state.end;
+ this.state.lastTokStart = this.state.start;
+ this.state.lastTokEndLoc = this.state.endLoc;
+ this.state.lastTokStartLoc = this.state.startLoc;
+ this.nextToken();
+ }
+
+ // TODO
+
+ eat(type) {
+ if (this.match(type)) {
+ this.next();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // TODO
+
+ match(type) {
+ return this.state.type === type;
+ }
+
+ // TODO
+
+ isKeyword(word) {
+ return isKeyword(word);
+ }
+
+ // TODO
+
+ lookahead() {
+ const old = this.state;
+ this.state = old.clone(true);
+
+ this.isLookahead = true;
+ this.next();
+ this.isLookahead = false;
+
+ const curr = this.state.clone(true);
+ this.state = old;
+ return curr;
+ }
+
+ // Toggle strict mode. Re-reads the next number or string to please
+ // pedantic tests (`"use strict"; 010;` should fail).
+
+ setStrict(strict) {
+ this.state.strict = strict;
+ if (!this.match(tt.num) && !this.match(tt.string)) return;
+ this.state.pos = this.state.start;
+ while (this.state.pos < this.state.lineStart) {
+ this.state.lineStart = this.input.lastIndexOf("\n", this.state.lineStart - 2) + 1;
+ --this.state.curLine;
+ }
+ this.nextToken();
+ }
+
+ curContext() {
+ return this.state.context[this.state.context.length - 1];
+ }
+
+ // Read a single token, updating the parser object's token-related
+ // properties.
+
+ nextToken() {
+ const curContext = this.curContext();
+ if (!curContext || !curContext.preserveSpace) this.skipSpace();
+
+ this.state.containsOctal = false;
+ this.state.octalPosition = null;
+ this.state.start = this.state.pos;
+ this.state.startLoc = this.state.curPosition();
+ if (this.state.pos >= this.input.length) return this.finishToken(tt.eof);
+
+ if (curContext.override) {
+ return curContext.override(this);
+ } else {
+ return this.readToken(this.fullCharCodeAtPos());
+ }
+ }
+
+ readToken(code) {
+ // Identifier or keyword. '\uXXXX' sequences are allowed in
+ // identifiers, so '\' also dispatches to that.
+ if (isIdentifierStart(code) || code === 92 /* '\' */) {
+ return this.readWord();
+ } else {
+ return this.getTokenFromCode(code);
+ }
+ }
+
+ fullCharCodeAtPos() {
+ const code = this.input.charCodeAt(this.state.pos);
+ if (code <= 0xd7ff || code >= 0xe000) return code;
+
+ const next = this.input.charCodeAt(this.state.pos + 1);
+ return (code << 10) + next - 0x35fdc00;
+ }
+
+ pushComment(block, text, start, end, startLoc, endLoc) {
+ const comment = {
+ type: block ? "CommentBlock" : "CommentLine",
+ value: text,
+ start: start,
+ end: end,
+ loc: new SourceLocation(startLoc, endLoc)
+ };
+
+ if (!this.isLookahead) {
+ this.state.tokens.push(comment);
+ this.state.comments.push(comment);
+ this.addComment(comment);
+ }
+ }
+
+ skipBlockComment() {
+ const startLoc = this.state.curPosition();
+ const start = this.state.pos;
+ const end = this.input.indexOf("*/", this.state.pos += 2);
+ if (end === -1) this.raise(this.state.pos - 2, "Unterminated comment");
+
+ this.state.pos = end + 2;
+ lineBreakG.lastIndex = start;
+ let match;
+ while ((match = lineBreakG.exec(this.input)) && match.index < this.state.pos) {
+ ++this.state.curLine;
+ this.state.lineStart = match.index + match[0].length;
+ }
+
+ this.pushComment(true, this.input.slice(start + 2, end), start, this.state.pos, startLoc, this.state.curPosition());
+ }
+
+ skipLineComment(startSkip) {
+ const start = this.state.pos;
+ const startLoc = this.state.curPosition();
+ let ch = this.input.charCodeAt(this.state.pos += startSkip);
+ while (this.state.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
+ ++this.state.pos;
+ ch = this.input.charCodeAt(this.state.pos);
+ }
+
+ this.pushComment(false, this.input.slice(start + startSkip, this.state.pos), start, this.state.pos, startLoc, this.state.curPosition());
+ }
+
+ // Called at the start of the parse and after every token. Skips
+ // whitespace and comments, and.
+
+ skipSpace() {
+ loop: while (this.state.pos < this.input.length) {
+ const ch = this.input.charCodeAt(this.state.pos);
+ switch (ch) {
+ case 32: case 160: // ' '
+ ++this.state.pos;
+ break;
+
+ case 13:
+ if (this.input.charCodeAt(this.state.pos + 1) === 10) {
+ ++this.state.pos;
+ }
+
+ case 10: case 8232: case 8233:
+ ++this.state.pos;
+ ++this.state.curLine;
+ this.state.lineStart = this.state.pos;
+ break;
+
+ case 47: // '/'
+ switch (this.input.charCodeAt(this.state.pos + 1)) {
+ case 42: // '*'
+ this.skipBlockComment();
+ break;
+
+ case 47:
+ this.skipLineComment(2);
+ break;
+
+ default:
+ break loop;
+ }
+ break;
+
+ default:
+ if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
+ ++this.state.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.
+
+ finishToken(type, val) {
+ this.state.end = this.state.pos;
+ this.state.endLoc = this.state.curPosition();
+ const prevType = this.state.type;
+ this.state.type = type;
+ this.state.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.
+ //
+ readToken_dot() {
+ const next = this.input.charCodeAt(this.state.pos + 1);
+ if (next >= 48 && next <= 57) {
+ return this.readNumber(true);
+ }
+
+ const next2 = this.input.charCodeAt(this.state.pos + 2);
+ if (next === 46 && next2 === 46) { // 46 = dot '.'
+ this.state.pos += 3;
+ return this.finishToken(tt.ellipsis);
+ } else {
+ ++this.state.pos;
+ return this.finishToken(tt.dot);
+ }
+ }
+
+ readToken_slash() { // '/'
+ if (this.state.exprAllowed) {
+ ++this.state.pos;
+ return this.readRegexp();
+ }
+
+ const next = this.input.charCodeAt(this.state.pos + 1);
+ if (next === 61) {
+ return this.finishOp(tt.assign, 2);
+ } else {
+ return this.finishOp(tt.slash, 1);
+ }
+ }
+
+ readToken_mult_modulo(code) { // '%*'
+ let type = code === 42 ? tt.star : tt.modulo;
+ let width = 1;
+ let next = this.input.charCodeAt(this.state.pos + 1);
+
+ if (next === 42) { // '*'
+ width++;
+ next = this.input.charCodeAt(this.state.pos + 2);
+ type = tt.exponent;
+ }
+
+ if (next === 61) {
+ width++;
+ type = tt.assign;
+ }
+
+ return this.finishOp(type, width);
+ }
+
+ readToken_pipe_amp(code) { // '|&'
+ const next = this.input.charCodeAt(this.state.pos + 1);
+ if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2);
+ if (next === 61) return this.finishOp(tt.assign, 2);
+ if (code === 124 && next === 125 && this.hasPlugin("flow")) return this.finishOp(tt.braceBarR, 2);
+ return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1);
+ }
+
+ readToken_caret() { // '^'
+ const next = this.input.charCodeAt(this.state.pos + 1);
+ if (next === 61) {
+ return this.finishOp(tt.assign, 2);
+ } else {
+ return this.finishOp(tt.bitwiseXOR, 1);
+ }
+ }
+
+ readToken_plus_min(code) { // '+-'
+ const next = this.input.charCodeAt(this.state.pos + 1);
+
+ if (next === code) {
+ if (next === 45 && this.input.charCodeAt(this.state.pos + 2) === 62 && lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.pos))) {
+ // A `-->` line comment
+ this.skipLineComment(3);
+ this.skipSpace();
+ return this.nextToken();
+ }
+ return this.finishOp(tt.incDec, 2);
+ }
+
+ if (next === 61) {
+ return this.finishOp(tt.assign, 2);
+ } else {
+ return this.finishOp(tt.plusMin, 1);
+ }
+ }
+
+ readToken_lt_gt(code) { // '<>'
+ const next = this.input.charCodeAt(this.state.pos + 1);
+ let size = 1;
+
+ if (next === code) {
+ size = code === 62 && this.input.charCodeAt(this.state.pos + 2) === 62 ? 3 : 2;
+ if (this.input.charCodeAt(this.state.pos + size) === 61) return this.finishOp(tt.assign, size + 1);
+ return this.finishOp(tt.bitShift, size);
+ }
+
+ if (next === 33 && code === 60 && this.input.charCodeAt(this.state.pos + 2) === 45 && this.input.charCodeAt(this.state.pos + 3) === 45) {
+ if (this.inModule) this.unexpected();
+ // `<!--`, an XML-style comment that should be interpreted as a line comment
+ this.skipLineComment(4);
+ this.skipSpace();
+ return this.nextToken();
+ }
+
+ if (next === 61) {
+ // <= | >=
+ size = 2;
+ }
+
+ return this.finishOp(tt.relational, size);
+ }
+
+ readToken_eq_excl(code) { // '=!'
+ const next = this.input.charCodeAt(this.state.pos + 1);
+ if (next === 61) return this.finishOp(tt.equality, this.input.charCodeAt(this.state.pos + 2) === 61 ? 3 : 2);
+ if (code === 61 && next === 62) { // '=>'
+ this.state.pos += 2;
+ return this.finishToken(tt.arrow);
+ }
+ return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1);
+ }
+
+ getTokenFromCode(code) {
+ switch (code) {
+ // The interpretation of a dot depends on whether it is followed
+ // by a digit or another two dots.
+ case 46: // '.'
+ return this.readToken_dot();
+
+ // Punctuation tokens.
+ case 40: ++this.state.pos; return this.finishToken(tt.parenL);
+ case 41: ++this.state.pos; return this.finishToken(tt.parenR);
+ case 59: ++this.state.pos; return this.finishToken(tt.semi);
+ case 44: ++this.state.pos; return this.finishToken(tt.comma);
+ case 91: ++this.state.pos; return this.finishToken(tt.bracketL);
+ case 93: ++this.state.pos; return this.finishToken(tt.bracketR);
+
+ case 123:
+ if (this.hasPlugin("flow") && this.input.charCodeAt(this.state.pos + 1) === 124) {
+ return this.finishOp(tt.braceBarL, 2);
+ } else {
+ ++this.state.pos;
+ return this.finishToken(tt.braceL);
+ }
+
+ case 125:
+ ++this.state.pos; return this.finishToken(tt.braceR);
+
+ case 58:
+ if (this.hasPlugin("functionBind") && this.input.charCodeAt(this.state.pos + 1) === 58) {
+ return this.finishOp(tt.doubleColon, 2);
+ } else {
+ ++this.state.pos;
+ return this.finishToken(tt.colon);
+ }
+
+ case 63: ++this.state.pos; return this.finishToken(tt.question);
+ case 64: ++this.state.pos; return this.finishToken(tt.at);
+
+ case 96: // '`'
+ ++this.state.pos;
+ return this.finishToken(tt.backQuote);
+
+ case 48: // '0'
+ const next = this.input.charCodeAt(this.state.pos + 1);
+ if (next === 120 || next === 88) return this.readRadixNumber(16); // '0x', '0X' - hex number
+ if (next === 111 || next === 79) return this.readRadixNumber(8); // '0o', '0O' - octal number
+ if (next === 98 || next === 66) return this.readRadixNumber(2); // '0b', '0B' - binary number
+ // Anything else beginning with a digit is an integer, octal
+ // number, or float.
+ case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
+ return this.readNumber(false);
+
+ // Quotes produce strings.
+ case 34: case 39: // '"', "'"
+ return this.readString(code);
+
+ // Operators are parsed inline in tiny state machines. '=' (61) is
+ // often referred to. `finishOp` simply skips the amount of
+ // characters it is given as second argument, and returns a token
+ // of the type given by its first argument.
+
+ case 47: // '/'
+ return this.readToken_slash();
+
+ case 37: case 42: // '%*'
+ return this.readToken_mult_modulo(code);
+
+ case 124: case 38: // '|&'
+ return this.readToken_pipe_amp(code);
+
+ case 94: // '^'
+ return this.readToken_caret();
+
+ case 43: case 45: // '+-'
+ return this.readToken_plus_min(code);
+
+ case 60: case 62: // '<>'
+ return this.readToken_lt_gt(code);
+
+ case 61: case 33: // '=!'
+ return this.readToken_eq_excl(code);
+
+ case 126: // '~'
+ return this.finishOp(tt.prefix, 1);
+ }
+
+ this.raise(this.state.pos, `Unexpected character '${codePointToString(code)}'`);
+ }
+
+ finishOp(type, size) {
+ const str = this.input.slice(this.state.pos, this.state.pos + size);
+ this.state.pos += size;
+ return this.finishToken(type, str);
+ }
+
+ readRegexp() {
+ const start = this.state.pos;
+ let escaped, inClass;
+ for (;;) {
+ if (this.state.pos >= this.input.length) this.raise(start, "Unterminated regular expression");
+ const ch = this.input.charAt(this.state.pos);
+ if (lineBreak.test(ch)) {
+ this.raise(start, "Unterminated regular expression");
+ }
+ if (escaped) {
+ escaped = false;
+ } else {
+ if (ch === "[") {
+ inClass = true;
+ } else if (ch === "]" && inClass) {
+ inClass = false;
+ } else if (ch === "/" && !inClass) {
+ break;
+ }
+ escaped = ch === "\\";
+ }
+ ++this.state.pos;
+ }
+ const content = this.input.slice(start, this.state.pos);
+ ++this.state.pos;
+ // Need to use `readWord1` because '\uXXXX' sequences are allowed
+ // here (don't ask).
+ const mods = this.readWord1();
+ if (mods) {
+ const validFlags = /^[gmsiyu]*$/;
+ if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag");
+ }
+ return this.finishToken(tt.regexp, {
+ pattern: content,
+ flags: mods
+ });
+ }
+
+ // Read an integer in the given radix. Return null if zero digits
+ // were read, the integer value otherwise. When `len` is given, this
+ // will return `null` unless the integer has exactly `len` digits.
+
+ readInt(radix, len) {
+ const start = this.state.pos;
+ let total = 0;
+
+ for (let i = 0, e = len == null ? Infinity : len; i < e; ++i) {
+ const code = this.input.charCodeAt(this.state.pos);
+ let val;
+ if (code >= 97) {
+ val = code - 97 + 10; // a
+ } else if (code >= 65) {
+ val = code - 65 + 10; // A
+ } else if (code >= 48 && code <= 57) {
+ val = code - 48; // 0-9
+ } else {
+ val = Infinity;
+ }
+ if (val >= radix) break;
+ ++this.state.pos;
+ total = total * radix + val;
+ }
+ if (this.state.pos === start || len != null && this.state.pos - start !== len) return null;
+
+ return total;
+ }
+
+ readRadixNumber(radix) {
+ this.state.pos += 2; // 0x
+ const val = this.readInt(radix);
+ if (val == null) this.raise(this.state.start + 2, "Expected number in radix " + radix);
+ if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.state.pos, "Identifier directly after number");
+ return this.finishToken(tt.num, val);
+ }
+
+ // Read an integer, octal integer, or floating-point number.
+
+ readNumber(startsWithDot) {
+ const start = this.state.pos;
+ const octal = this.input.charCodeAt(this.state.pos) === 48;
+ let isFloat = false;
+
+ if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number");
+ let next = this.input.charCodeAt(this.state.pos);
+ if (next === 46) { // '.'
+ ++this.state.pos;
+ this.readInt(10);
+ isFloat = true;
+ next = this.input.charCodeAt(this.state.pos);
+ }
+ if (next === 69 || next === 101) { // 'eE'
+ next = this.input.charCodeAt(++this.state.pos);
+ if (next === 43 || next === 45) ++this.state.pos; // '+-'
+ if (this.readInt(10) === null) this.raise(start, "Invalid number");
+ isFloat = true;
+ }
+ if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.state.pos, "Identifier directly after number");
+
+ const str = this.input.slice(start, this.state.pos);
+ let val;
+ if (isFloat) {
+ val = parseFloat(str);
+ } else if (!octal || str.length === 1) {
+ val = parseInt(str, 10);
+ } else if (/[89]/.test(str) || this.state.strict) {
+ this.raise(start, "Invalid number");
+ } else {
+ val = parseInt(str, 8);
+ }
+ return this.finishToken(tt.num, val);
+ }
+
+ // Read a string value, interpreting backslash-escapes.
+
+ readCodePoint(throwOnInvalid) {
+ const ch = this.input.charCodeAt(this.state.pos);
+ let code;
+
+ if (ch === 123) { // '{'
+ const codePos = ++this.state.pos;
+ code = this.readHexChar(this.input.indexOf("}", this.state.pos) - this.state.pos, throwOnInvalid);
+ ++this.state.pos;
+ if (code === null) {
+ --this.state.invalidTemplateEscapePosition; // to point to the '\'' instead of the 'u'
+ } else if (code > 0x10FFFF) {
+ if (throwOnInvalid) {
+ this.raise(codePos, "Code point out of bounds");
+ } else {
+ this.state.invalidTemplateEscapePosition = codePos - 2;
+ return null;
+ }
+ }
+ } else {
+ code = this.readHexChar(4, throwOnInvalid);
+ }
+ return code;
+ }
+
+ readString(quote) {
+ let out = "", chunkStart = ++this.state.pos;
+ for (;;) {
+ if (this.state.pos >= this.input.length) this.raise(this.state.start, "Unterminated string constant");
+ const ch = this.input.charCodeAt(this.state.pos);
+ if (ch === quote) break;
+ if (ch === 92) { // '\'
+ out += this.input.slice(chunkStart, this.state.pos);
+ out += this.readEscapedChar(false);
+ chunkStart = this.state.pos;
+ } else {
+ if (isNewLine(ch)) this.raise(this.state.start, "Unterminated string constant");
+ ++this.state.pos;
+ }
+ }
+ out += this.input.slice(chunkStart, this.state.pos++);
+ return this.finishToken(tt.string, out);
+ }
+
+ // Reads template string tokens.
+
+ readTmplToken() {
+ let out = "", chunkStart = this.state.pos, containsInvalid = false;
+ for (;;) {
+ if (this.state.pos >= this.input.length) this.raise(this.state.start, "Unterminated template");
+ const ch = this.input.charCodeAt(this.state.pos);
+ if (ch === 96 || ch === 36 && this.input.charCodeAt(this.state.pos + 1) === 123) { // '`', '${'
+ if (this.state.pos === this.state.start && this.match(tt.template)) {
+ if (ch === 36) {
+ this.state.pos += 2;
+ return this.finishToken(tt.dollarBraceL);
+ } else {
+ ++this.state.pos;
+ return this.finishToken(tt.backQuote);
+ }
+ }
+ out += this.input.slice(chunkStart, this.state.pos);
+ return this.finishToken(tt.template, containsInvalid ? null : out);
+ }
+ if (ch === 92) { // '\'
+ out += this.input.slice(chunkStart, this.state.pos);
+ const escaped = this.readEscapedChar(true);
+ if (escaped === null) {
+ containsInvalid = true;
+ } else {
+ out += escaped;
+ }
+ chunkStart = this.state.pos;
+ } else if (isNewLine(ch)) {
+ out += this.input.slice(chunkStart, this.state.pos);
+ ++this.state.pos;
+ switch (ch) {
+ case 13:
+ if (this.input.charCodeAt(this.state.pos) === 10) ++this.state.pos;
+ case 10:
+ out += "\n";
+ break;
+ default:
+ out += String.fromCharCode(ch);
+ break;
+ }
+ ++this.state.curLine;
+ this.state.lineStart = this.state.pos;
+ chunkStart = this.state.pos;
+ } else {
+ ++this.state.pos;
+ }
+ }
+ }
+
+ // Used to read escaped characters
+
+ readEscapedChar(inTemplate) {
+ const throwOnInvalid = !inTemplate;
+ const ch = this.input.charCodeAt(++this.state.pos);
+ ++this.state.pos;
+ switch (ch) {
+ case 110: return "\n"; // 'n' -> '\n'
+ case 114: return "\r"; // 'r' -> '\r'
+ case 120: { // 'x'
+ const code = this.readHexChar(2, throwOnInvalid);
+ return code === null ? null : String.fromCharCode(code);
+ }
+ case 117: { // 'u'
+ const code = this.readCodePoint(throwOnInvalid);
+ return code === null ? null : codePointToString(code);
+ }
+ case 116: return "\t"; // 't' -> '\t'
+ case 98: return "\b"; // 'b' -> '\b'
+ case 118: return "\u000b"; // 'v' -> '\u000b'
+ case 102: return "\f"; // 'f' -> '\f'
+ case 13: if (this.input.charCodeAt(this.state.pos) === 10) ++this.state.pos; // '\r\n'
+ case 10: // ' \n'
+ this.state.lineStart = this.state.pos;
+ ++this.state.curLine;
+ return "";
+ default:
+ if (ch >= 48 && ch <= 55) {
+ const codePos = this.state.pos - 1;
+ let octalStr = this.input.substr(this.state.pos - 1, 3).match(/^[0-7]+/)[0];
+ let octal = parseInt(octalStr, 8);
+ if (octal > 255) {
+ octalStr = octalStr.slice(0, -1);
+ octal = parseInt(octalStr, 8);
+ }
+ if (octal > 0) {
+ if (inTemplate) {
+ this.state.invalidTemplateEscapePosition = codePos;
+ return null;
+ } else if (this.state.strict) {
+ this.raise(codePos, "Octal literal in strict mode");
+ } else if (!this.state.containsOctal) {
+ // These properties are only used to throw an error for an octal which occurs
+ // in a directive which occurs prior to a "use strict" directive.
+ this.state.containsOctal = true;
+ this.state.octalPosition = codePos;
+ }
+ }
+ this.state.pos += octalStr.length - 1;
+ return String.fromCharCode(octal);
+ }
+ return String.fromCharCode(ch);
+ }
+ }
+
+ // Used to read character escape sequences ('\x', '\u').
+
+ readHexChar(len, throwOnInvalid) {
+ const codePos = this.state.pos;
+ const n = this.readInt(16, len);
+ if (n === null) {
+ if (throwOnInvalid) {
+ this.raise(codePos, "Bad character escape sequence");
+ } else {
+ this.state.pos = codePos - 1;
+ this.state.invalidTemplateEscapePosition = codePos - 1;
+ }
+ }
+ return n;
+ }
+
+ // Read an identifier, and return it as a string. Sets `this.state.containsEsc`
+ // to whether the word contained a '\u' escape.
+ //
+ // Incrementally adds only escaped chars, adding other chunks as-is
+ // as a micro-optimization.
+
+ readWord1() {
+ this.state.containsEsc = false;
+ let word = "", first = true, chunkStart = this.state.pos;
+ while (this.state.pos < this.input.length) {
+ const ch = this.fullCharCodeAtPos();
+ if (isIdentifierChar(ch)) {
+ this.state.pos += ch <= 0xffff ? 1 : 2;
+ } else if (ch === 92) { // "\"
+ this.state.containsEsc = true;
+
+ word += this.input.slice(chunkStart, this.state.pos);
+ const escStart = this.state.pos;
+
+ if (this.input.charCodeAt(++this.state.pos) !== 117) { // "u"
+ this.raise(this.state.pos, "Expecting Unicode escape sequence \\uXXXX");
+ }
+
+ ++this.state.pos;
+ const esc = this.readCodePoint(true);
+ if (!(first ? isIdentifierStart : isIdentifierChar)(esc, true)) {
+ this.raise(escStart, "Invalid Unicode escape");
+ }
+
+ word += codePointToString(esc);
+ chunkStart = this.state.pos;
+ } else {
+ break;
+ }
+ first = false;
+ }
+ return word + this.input.slice(chunkStart, this.state.pos);
+ }
+
+ // Read an identifier or keyword token. Will check for reserved
+ // words when necessary.
+
+ readWord() {
+ const word = this.readWord1();
+ let type = tt.name;
+ if (!this.state.containsEsc && this.isKeyword(word)) {
+ type = keywordTypes[word];
+ }
+ return this.finishToken(type, word);
+ }
+
+ braceIsBlock(prevType) {
+ if (prevType === tt.colon) {
+ const parent = this.curContext();
+ if (parent === ct.braceStatement || parent === ct.braceExpression) {
+ return !parent.isExpr;
+ }
+ }
+
+ if (prevType === tt._return) {
+ return lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start));
+ }
+
+ if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof || prevType === tt.parenR) {
+ return true;
+ }
+
+ if (prevType === tt.braceL) {
+ return this.curContext() === ct.braceStatement;
+ }
+
+ return !this.state.exprAllowed;
+ }
+
+ updateContext(prevType) {
+ const type = this.state.type;
+ let update;
+
+ if (type.keyword && prevType === tt.dot) {
+ this.state.exprAllowed = false;
+ } else if (update = type.updateContext) {
+ update.call(this, prevType);
+ } else {
+ this.state.exprAllowed = type.beforeExpr;
+ }
+ }
+ }
+
+ tokenizerIndexJS = Tokenizer;
+ tokenizerIndexJS.Token = Token;
+}
+
+
+// options.js
+const optionsJS = {};
+{
+ // A second optional argument can be given to further configure
+ // the parser process. These options are recognized:
+
+ const defaultOptions = {
+ // Source type ("script" or "module") for different semantics
+ sourceType: "script",
+ // Source filename.
+ sourceFilename: undefined,
+ // Line from which to start counting source. Useful for
+ // integration with other tools.
+ startLine: 1,
+ // 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,
+ // TODO
+ allowSuperOutsideMethod: false,
+ // An array of plugins to enable
+ plugins: [],
+ // TODO
+ strictMode: 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,
+ };
+ optionsJS.defaultOptions = defaultOptions;
+
+ // Interpret and default an options object
+
+ function getOptions(opts) {
+ const options = {};
+ for (const key in defaultOptions) {
+ options[key] = opts && key in opts ? opts[key] : defaultOptions[key];
+ }
+ return options;
+ }
+ optionsJS.getOptions = getOptions;
+}
+
+
+// parser/index.js
+let parserIndexJS = {};
+{
+ const { reservedWords } = utilIdentifierJS;
+ const { getOptions } = optionsJS;
+ const Tokenizer = tokenizerIndexJS;
+
+ const plugins = {};
+
+ class Parser extends Tokenizer {
+ constructor(options, input) {
+ options = getOptions(options);
+ super(options, input);
+
+ this.options = options;
+ this.inModule = this.options.sourceType === "module";
+ this.input = input;
+ this.plugins = this.loadPlugins(this.options.plugins);
+ this.filename = options.sourceFilename;
+
+ // If enabled, skip leading hashbang line.
+ if (this.state.pos === 0 && this.input[0] === "#" && this.input[1] === "!") {
+ this.skipLineComment(2);
+ }
+ }
+
+ isReservedWord(word) {
+ if (word === "await") {
+ return this.inModule;
+ } else {
+ return reservedWords[6](word);
+ }
+ }
+
+ hasPlugin(name) {
+ return !!this.plugins[name];
+ }
+
+ extend(name, f) {
+ this[name] = f(this[name]);
+ }
+
+ loadPlugins(pluginList) {
+ const pluginMap = {};
+
+ if (pluginList.indexOf("flow") >= 0) {
+ // ensure flow plugin loads last
+ pluginList = pluginList.filter((plugin) => plugin !== "flow");
+ pluginList.push("flow");
+ }
+
+ if (pluginList.indexOf("estree") >= 0) {
+ // ensure estree plugin loads first
+ pluginList = pluginList.filter((plugin) => plugin !== "estree");
+ pluginList.unshift("estree");
+ }
+
+ for (const name of pluginList) {
+ if (!pluginMap[name]) {
+ pluginMap[name] = true;
+
+ const plugin = plugins[name];
+ if (plugin) plugin(this);
+ }
+ }
+
+ return pluginMap;
+ }
+
+ parse() {
+ const file = this.startNode();
+ const program = this.startNode();
+ this.nextToken();
+ return this.parseTopLevel(file, program);
+ }
+ }
+
+ parserIndexJS = Parser;
+ parserIndexJS.plugins = plugins;
+}
+
+// parser/comments.js
+const parserCommentsJS = {};
+{
+ /* eslint max-len: 0 */
+
+ /**
+ * Based on the comment attachment algorithm used in espree and estraverse.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+ {
+ const Parser = parserIndexJS;
+
+ function last(stack) {
+ return stack[stack.length - 1];
+ }
+
+ const pp = Parser.prototype;
+
+ pp.addComment = function (comment) {
+ if (this.filename) comment.loc.filename = this.filename;
+ this.state.trailingComments.push(comment);
+ this.state.leadingComments.push(comment);
+ };
+
+ pp.processComment = function (node) {
+ if (node.type === "Program" && node.body.length > 0) return;
+
+ const stack = this.state.commentStack;
+
+ let lastChild, trailingComments, i, j;
+
+ if (this.state.trailingComments.length > 0) {
+ // If the first comment in trailingComments comes after the
+ // current node, then we're good - all comments in the array will
+ // come after the node and so it's safe to add them as official
+ // trailingComments.
+ if (this.state.trailingComments[0].start >= node.end) {
+ trailingComments = this.state.trailingComments;
+ this.state.trailingComments = [];
+ } else {
+ // Otherwise, if the first comment doesn't come after the
+ // current node, that means we have a mix of leading and trailing
+ // comments in the array and that leadingComments contains the
+ // same items as trailingComments. Reset trailingComments to
+ // zero items and we'll handle this by evaluating leadingComments
+ // later.
+ this.state.trailingComments.length = 0;
+ }
+ } else {
+ const lastInStack = last(stack);
+ if (stack.length > 0 && lastInStack.trailingComments && lastInStack.trailingComments[0].start >= node.end) {
+ trailingComments = lastInStack.trailingComments;
+ lastInStack.trailingComments = null;
+ }
+ }
+
+ // Eating the stack.
+ while (stack.length > 0 && last(stack).start >= node.start) {
+ lastChild = stack.pop();
+ }
+
+ if (lastChild) {
+ if (lastChild.leadingComments) {
+ if (lastChild !== node && last(lastChild.leadingComments).end <= node.start) {
+ node.leadingComments = lastChild.leadingComments;
+ lastChild.leadingComments = null;
+ } else {
+ // A leading comment for an anonymous class had been stolen by its first ClassMethod,
+ // so this takes back the leading comment.
+ // See also: https://github.com/eslint/espree/issues/158
+ for (i = lastChild.leadingComments.length - 2; i >= 0; --i) {
+ if (lastChild.leadingComments[i].end <= node.start) {
+ node.leadingComments = lastChild.leadingComments.splice(0, i + 1);
+ break;
+ }
+ }
+ }
+ }
+ } else if (this.state.leadingComments.length > 0) {
+ if (last(this.state.leadingComments).end <= node.start) {
+ if (this.state.commentPreviousNode) {
+ for (j = 0; j < this.state.leadingComments.length; j++) {
+ if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) {
+ this.state.leadingComments.splice(j, 1);
+ j--;
+ }
+ }
+ }
+ if (this.state.leadingComments.length > 0) {
+ node.leadingComments = this.state.leadingComments;
+ this.state.leadingComments = [];
+ }
+ } else {
+ // https://github.com/eslint/espree/issues/2
+ //
+ // In special cases, such as return (without a value) and
+ // debugger, all comments will end up as leadingComments and
+ // will otherwise be eliminated. This step runs when the
+ // commentStack is empty and there are comments left
+ // in leadingComments.
+ //
+ // This loop figures out the stopping point between the actual
+ // leading and trailing comments by finding the location of the
+ // first comment that comes after the given node.
+ for (i = 0; i < this.state.leadingComments.length; i++) {
+ if (this.state.leadingComments[i].end > node.start) {
+ break;
+ }
+ }
+
+ // Split the array based on the location of the first comment
+ // that comes after the node. Keep in mind that this could
+ // result in an empty array, and if so, the array must be
+ // deleted.
+ node.leadingComments = this.state.leadingComments.slice(0, i);
+ if ((node.leadingComments).length === 0) {
+ node.leadingComments = null;
+ }
+
+ // Similarly, trailing comments are attached later. The variable
+ // must be reset to null if there are no trailing comments.
+ trailingComments = this.state.leadingComments.slice(i);
+ if (trailingComments.length === 0) {
+ trailingComments = null;
+ }
+ }
+ }
+
+ this.state.commentPreviousNode = node;
+
+ if (trailingComments) {
+ if (trailingComments.length && trailingComments[0].start >= node.start && last(trailingComments).end <= node.end) {
+ node.innerComments = trailingComments;
+ } else {
+ node.trailingComments = trailingComments;
+ }
+ }
+
+ stack.push(node);
+ };
+ }
+
+}
+
+// parser/expression.js
+const parserExpressionJS = {};
+{
+ /* eslint max-len: 0 */
+
+ // 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
+
+ const { types: tt } = tokenizerTypesJS;
+ const Parser = parserIndexJS;
+ const { reservedWords } = utilIdentifierJS;
+
+ const pp = 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.checkPropClash = function (prop, propHash) {
+ if (prop.computed || prop.kind) return;
+
+ const key = prop.key;
+ // It is either an Identifier or a String/NumericLiteral
+ const name = key.type === "Identifier" ? key.name : String(key.value);
+
+ if (name === "__proto__") {
+ if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
+ propHash.proto = true;
+ }
+ };
+
+ // Convenience method to parse an Expression only
+ pp.getExpression = function() {
+ this.nextToken();
+ const expr = this.parseExpression();
+ if (!this.match(tt.eof)) {
+ this.unexpected();
+ }
+ return expr;
+ };
+
+ // ### 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 initialization 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.parseExpression = function (noIn, refShorthandDefaultPos) {
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ const expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos);
+ if (this.match(tt.comma)) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.expressions = [expr];
+ while (this.eat(tt.comma)) {
+ node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos));
+ }
+ this.toReferencedList(node.expressions);
+ return this.finishNode(node, "SequenceExpression");
+ }
+ return expr;
+ };
+
+ // Parse an assignment expression. This includes applications of
+ // operators like `+=`.
+
+ pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse, refNeedsArrowPos) {
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+
+ if (this.match(tt._yield) && this.state.inGenerator) {
+ let left = this.parseYield();
+ if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc);
+ return left;
+ }
+
+ let failOnShorthandAssign;
+ if (refShorthandDefaultPos) {
+ failOnShorthandAssign = false;
+ } else {
+ refShorthandDefaultPos = { start: 0 };
+ failOnShorthandAssign = true;
+ }
+
+ if (this.match(tt.parenL) || this.match(tt.name)) {
+ this.state.potentialArrowAt = this.state.start;
+ }
+
+ let left = this.parseMaybeConditional(noIn, refShorthandDefaultPos, refNeedsArrowPos);
+ if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc);
+ if (this.state.type.isAssign) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.operator = this.state.value;
+ node.left = this.match(tt.eq) ? this.toAssignable(left, undefined, "assignment expression") : left;
+ refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
+
+ this.checkLVal(left, undefined, undefined, "assignment expression");
+
+ if (left.extra && left.extra.parenthesized) {
+ let errorMsg;
+ if (left.type === "ObjectPattern") {
+ errorMsg = "`({a}) = 0` use `({a} = 0)`";
+ } else if (left.type === "ArrayPattern") {
+ errorMsg = "`([a]) = 0` use `([a] = 0)`";
+ }
+ if (errorMsg) {
+ this.raise(left.start, `You're trying to assign to a parenthesized expression, eg. instead of ${errorMsg}`);
+ }
+ }
+
+ this.next();
+ node.right = this.parseMaybeAssign(noIn);
+ return this.finishNode(node, "AssignmentExpression");
+ } else if (failOnShorthandAssign && refShorthandDefaultPos.start) {
+ this.unexpected(refShorthandDefaultPos.start);
+ }
+
+ return left;
+ };
+
+ // Parse a ternary conditional (`?:`) operator.
+
+ pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos, refNeedsArrowPos) {
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ const expr = this.parseExprOps(noIn, refShorthandDefaultPos);
+ if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
+
+ return this.parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos);
+ };
+
+ pp.parseConditional = function (expr, noIn, startPos, startLoc) {
+ if (this.eat(tt.question)) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.test = expr;
+ node.consequent = this.parseMaybeAssign();
+ this.expect(tt.colon);
+ node.alternate = this.parseMaybeAssign(noIn);
+ return this.finishNode(node, "ConditionalExpression");
+ }
+ return expr;
+ };
+
+ // Start the precedence parser.
+
+ pp.parseExprOps = function (noIn, refShorthandDefaultPos) {
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ const expr = this.parseMaybeUnary(refShorthandDefaultPos);
+ if (refShorthandDefaultPos && refShorthandDefaultPos.start) {
+ return expr;
+ } else {
+ return 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.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
+ const prec = this.state.type.binop;
+ if (prec != null && (!noIn || !this.match(tt._in))) {
+ if (prec > minPrec) {
+ const node = this.startNodeAt(leftStartPos, leftStartLoc);
+ node.left = left;
+ node.operator = this.state.value;
+
+ if (
+ node.operator === "**" &&
+ left.type === "UnaryExpression" &&
+ left.extra &&
+ !left.extra.parenthesizedArgument &&
+ !left.extra.parenthesized
+ ) {
+ this.raise(left.argument.start, "Illegal expression. Wrap left hand side or entire exponentiation in parentheses.");
+ }
+
+ const op = this.state.type;
+ this.next();
+
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ node.right = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, op.rightAssociative ? prec - 1 : prec, noIn);
+
+ this.finishNode(node, (op === tt.logicalOR || op === tt.logicalAND) ? "LogicalExpression" : "BinaryExpression");
+ return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn);
+ }
+ }
+ return left;
+ };
+
+ // Parse unary operators, both prefix and postfix.
+
+ pp.parseMaybeUnary = function (refShorthandDefaultPos) {
+ if (this.state.type.prefix) {
+ const node = this.startNode();
+ const update = this.match(tt.incDec);
+ node.operator = this.state.value;
+ node.prefix = true;
+ this.next();
+
+ const argType = this.state.type;
+ node.argument = this.parseMaybeUnary();
+
+ this.addExtra(node, "parenthesizedArgument", argType === tt.parenL && (!node.argument.extra || !node.argument.extra.parenthesized));
+
+ if (refShorthandDefaultPos && refShorthandDefaultPos.start) {
+ this.unexpected(refShorthandDefaultPos.start);
+ }
+
+ if (update) {
+ this.checkLVal(node.argument, undefined, undefined, "prefix operation");
+ } else if (this.state.strict && node.operator === "delete" && node.argument.type === "Identifier") {
+ this.raise(node.start, "Deleting local variable in strict mode");
+ }
+
+ return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
+ }
+
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ let expr = this.parseExprSubscripts(refShorthandDefaultPos);
+ if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
+ while (this.state.type.postfix && !this.canInsertSemicolon()) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.operator = this.state.value;
+ node.prefix = false;
+ node.argument = expr;
+ this.checkLVal(expr, undefined, undefined, "postfix operation");
+ this.next();
+ expr = this.finishNode(node, "UpdateExpression");
+ }
+ return expr;
+ };
+
+ // Parse call, dot, and `[]`-subscript expressions.
+
+ pp.parseExprSubscripts = function (refShorthandDefaultPos) {
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ const potentialArrowAt = this.state.potentialArrowAt;
+ const expr = this.parseExprAtom(refShorthandDefaultPos);
+
+ if (expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt) {
+ return expr;
+ }
+
+ if (refShorthandDefaultPos && refShorthandDefaultPos.start) {
+ return expr;
+ }
+
+ return this.parseSubscripts(expr, startPos, startLoc);
+ };
+
+ pp.parseSubscripts = function (base, startPos, startLoc, noCalls) {
+ for (;;) {
+ if (!noCalls && this.eat(tt.doubleColon)) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.object = base;
+ node.callee = this.parseNoCallExpr();
+ return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls);
+ } else if (this.eat(tt.dot)) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.object = base;
+ node.property = this.parseIdentifier(true);
+ node.computed = false;
+ base = this.finishNode(node, "MemberExpression");
+ } else if (this.eat(tt.bracketL)) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.object = base;
+ node.property = this.parseExpression();
+ node.computed = true;
+ this.expect(tt.bracketR);
+ base = this.finishNode(node, "MemberExpression");
+ } else if (!noCalls && this.match(tt.parenL)) {
+ const possibleAsync = this.state.potentialArrowAt === base.start && base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon();
+ this.next();
+
+ const node = this.startNodeAt(startPos, startLoc);
+ node.callee = base;
+ node.arguments = this.parseCallExpressionArguments(tt.parenR, possibleAsync);
+ if (node.callee.type === "Import" && node.arguments.length !== 1) {
+ this.raise(node.start, "import() requires exactly one argument");
+ }
+ base = this.finishNode(node, "CallExpression");
+
+ if (possibleAsync && this.shouldParseAsyncArrow()) {
+ return this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node);
+ } else {
+ this.toReferencedList(node.arguments);
+ }
+ } else if (this.match(tt.backQuote)) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.tag = base;
+ node.quasi = this.parseTemplate(true);
+ base = this.finishNode(node, "TaggedTemplateExpression");
+ } else {
+ return base;
+ }
+ }
+ };
+
+ pp.parseCallExpressionArguments = function (close, possibleAsyncArrow) {
+ const elts = [];
+ let innerParenStart;
+ let first = true;
+
+ while (!this.eat(close)) {
+ if (first) {
+ first = false;
+ } else {
+ this.expect(tt.comma);
+ if (this.eat(close)) break;
+ }
+
+ // we need to make sure that if this is an async arrow functions, that we don't allow inner parens inside the params
+ if (this.match(tt.parenL) && !innerParenStart) {
+ innerParenStart = this.state.start;
+ }
+
+ elts.push(this.parseExprListItem(false, possibleAsyncArrow ? { start: 0 } : undefined, possibleAsyncArrow ? { start: 0 } : undefined));
+ }
+
+ // we found an async arrow function so let's not allow any inner parens
+ if (possibleAsyncArrow && innerParenStart && this.shouldParseAsyncArrow()) {
+ this.unexpected();
+ }
+
+ return elts;
+ };
+
+ pp.shouldParseAsyncArrow = function () {
+ return this.match(tt.arrow);
+ };
+
+ pp.parseAsyncArrowFromCallExpression = function (node, call) {
+ this.expect(tt.arrow);
+ return this.parseArrowExpression(node, call.arguments, true);
+ };
+
+ // Parse a no-call expression (like argument of `new` or `::` operators).
+
+ pp.parseNoCallExpr = function () {
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
+ };
+
+ // 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.parseExprAtom = function (refShorthandDefaultPos) {
+ const canBeArrow = this.state.potentialArrowAt === this.state.start;
+ let node;
+
+ switch (this.state.type) {
+ case tt._super:
+ if (!this.state.inMethod && !this.options.allowSuperOutsideMethod) {
+ this.raise(this.state.start, "'super' outside of function or class");
+ }
+
+ node = this.startNode();
+ this.next();
+ if (!this.match(tt.parenL) && !this.match(tt.bracketL) && !this.match(tt.dot)) {
+ this.unexpected();
+ }
+ if (this.match(tt.parenL) && this.state.inMethod !== "constructor" && !this.options.allowSuperOutsideMethod) {
+ this.raise(node.start, "super() is only valid inside a class constructor. Make sure the method name is spelled exactly as 'constructor'.");
+ }
+ return this.finishNode(node, "Super");
+
+ case tt._import:
+ if (!this.hasPlugin("dynamicImport")) this.unexpected();
+
+ node = this.startNode();
+ this.next();
+ if (!this.match(tt.parenL)) {
+ this.unexpected(null, tt.parenL);
+ }
+ return this.finishNode(node, "Import");
+
+ case tt._this:
+ node = this.startNode();
+ this.next();
+ return this.finishNode(node, "ThisExpression");
+
+ case tt._yield:
+ if (this.state.inGenerator) this.unexpected();
+
+ case tt.name:
+ node = this.startNode();
+ const allowAwait = this.state.value === "await" && this.state.inAsync;
+ const allowYield = this.shouldAllowYieldIdentifier();
+ const id = this.parseIdentifier(allowAwait || allowYield);
+
+ if (id.name === "await") {
+ if (this.state.inAsync || this.inModule) {
+ return this.parseAwait(node);
+ }
+ } else if (id.name === "async" && this.match(tt._function) && !this.canInsertSemicolon()) {
+ this.next();
+ return this.parseFunction(node, false, false, true);
+ } else if (canBeArrow && id.name === "async" && this.match(tt.name)) {
+ const params = [this.parseIdentifier()];
+ this.expect(tt.arrow);
+ // let foo = bar => {};
+ return this.parseArrowExpression(node, params, true);
+ }
+
+ if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) {
+ return this.parseArrowExpression(node, [id]);
+ }
+
+ return id;
+
+ case tt._do:
+ if (this.hasPlugin("doExpressions")) {
+ const node = this.startNode();
+ this.next();
+ const oldInFunction = this.state.inFunction;
+ const oldLabels = this.state.labels;
+ this.state.labels = [];
+ this.state.inFunction = false;
+ node.body = this.parseBlock(false, true);
+ this.state.inFunction = oldInFunction;
+ this.state.labels = oldLabels;
+ return this.finishNode(node, "DoExpression");
+ }
+
+ case tt.regexp:
+ const value = this.state.value;
+ node = this.parseLiteral(value.value, "RegExpLiteral");
+ node.pattern = value.pattern;
+ node.flags = value.flags;
+ return node;
+
+ case tt.num:
+ return this.parseLiteral(this.state.value, "NumericLiteral");
+
+ case tt.string:
+ return this.parseLiteral(this.state.value, "StringLiteral");
+
+ case tt._null:
+ node = this.startNode();
+ this.next();
+ return this.finishNode(node, "NullLiteral");
+
+ case tt._true: case tt._false:
+ node = this.startNode();
+ node.value = this.match(tt._true);
+ this.next();
+ return this.finishNode(node, "BooleanLiteral");
+
+ case tt.parenL:
+ return this.parseParenAndDistinguishExpression(null, null, canBeArrow);
+
+ case tt.bracketL:
+ node = this.startNode();
+ this.next();
+ node.elements = this.parseExprList(tt.bracketR, true, refShorthandDefaultPos);
+ this.toReferencedList(node.elements);
+ return this.finishNode(node, "ArrayExpression");
+
+ case tt.braceL:
+ return this.parseObj(false, refShorthandDefaultPos);
+
+ case tt._function:
+ return this.parseFunctionExpression();
+
+ case tt.at:
+ this.parseDecorators();
+
+ case tt._class:
+ node = this.startNode();
+ this.takeDecorators(node);
+ return this.parseClass(node, false);
+
+ case tt._new:
+ return this.parseNew();
+
+ case tt.backQuote:
+ return this.parseTemplate(false);
+
+ case tt.doubleColon:
+ node = this.startNode();
+ this.next();
+ node.object = null;
+ const callee = node.callee = this.parseNoCallExpr();
+ if (callee.type === "MemberExpression") {
+ return this.finishNode(node, "BindExpression");
+ } else {
+ this.raise(callee.start, "Binding should be performed on object property.");
+ }
+
+ default:
+ this.unexpected();
+ }
+ };
+
+ pp.parseFunctionExpression = function () {
+ const node = this.startNode();
+ const meta = this.parseIdentifier(true);
+ if (this.state.inGenerator && this.eat(tt.dot) && this.hasPlugin("functionSent")) {
+ return this.parseMetaProperty(node, meta, "sent");
+ } else {
+ return this.parseFunction(node, false);
+ }
+ };
+
+ pp.parseMetaProperty = function (node, meta, propertyName) {
+ node.meta = meta;
+ node.property = this.parseIdentifier(true);
+
+ if (node.property.name !== propertyName) {
+ this.raise(node.property.start, `The only valid meta property for new is ${meta.name}.${propertyName}`);
+ }
+
+ return this.finishNode(node, "MetaProperty");
+ };
+
+ pp.parseLiteral = function (value, type, startPos, startLoc) {
+ startPos = startPos || this.state.start;
+ startLoc = startLoc || this.state.startLoc;
+
+ const node = this.startNodeAt(startPos, startLoc);
+ this.addExtra(node, "rawValue", value);
+ this.addExtra(node, "raw", this.input.slice(startPos, this.state.end));
+ node.value = value;
+ this.next();
+ return this.finishNode(node, type);
+ };
+
+ pp.parseParenExpression = function () {
+ this.expect(tt.parenL);
+ const val = this.parseExpression();
+ this.expect(tt.parenR);
+ return val;
+ };
+
+ pp.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArrow) {
+ startPos = startPos || this.state.start;
+ startLoc = startLoc || this.state.startLoc;
+
+ let val;
+ this.expect(tt.parenL);
+
+ const innerStartPos = this.state.start;
+ const innerStartLoc = this.state.startLoc;
+ const exprList = [];
+ const refShorthandDefaultPos = { start: 0 };
+ const refNeedsArrowPos = { start: 0 };
+ let first = true;
+ let spreadStart;
+ let optionalCommaStart;
+
+ while (!this.match(tt.parenR)) {
+ if (first) {
+ first = false;
+ } else {
+ this.expect(tt.comma, refNeedsArrowPos.start || null);
+ if (this.match(tt.parenR)) {
+ optionalCommaStart = this.state.start;
+ break;
+ }
+ }
+
+ if (this.match(tt.ellipsis)) {
+ const spreadNodeStartPos = this.state.start;
+ const spreadNodeStartLoc = this.state.startLoc;
+ spreadStart = this.state.start;
+ exprList.push(this.parseParenItem(this.parseRest(), spreadNodeStartPos, spreadNodeStartLoc));
+ break;
+ } else {
+ exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos));
+ }
+ }
+
+ const innerEndPos = this.state.start;
+ const innerEndLoc = this.state.startLoc;
+ this.expect(tt.parenR);
+
+ let arrowNode = this.startNodeAt(startPos, startLoc);
+ if (canBeArrow && this.shouldParseArrow() && (arrowNode = this.parseArrow(arrowNode))) {
+ for (const param of exprList) {
+ if (param.extra && param.extra.parenthesized) this.unexpected(param.extra.parenStart);
+ }
+
+ return this.parseArrowExpression(arrowNode, exprList);
+ }
+
+ if (!exprList.length) {
+ this.unexpected(this.state.lastTokStart);
+ }
+ if (optionalCommaStart) this.unexpected(optionalCommaStart);
+ if (spreadStart) this.unexpected(spreadStart);
+ if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
+ if (refNeedsArrowPos.start) this.unexpected(refNeedsArrowPos.start);
+
+ if (exprList.length > 1) {
+ val = this.startNodeAt(innerStartPos, innerStartLoc);
+ val.expressions = exprList;
+ this.toReferencedList(val.expressions);
+ this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
+ } else {
+ val = exprList[0];
+ }
+
+
+ this.addExtra(val, "parenthesized", true);
+ this.addExtra(val, "parenStart", startPos);
+
+ return val;
+ };
+
+ pp.shouldParseArrow = function () {
+ return !this.canInsertSemicolon();
+ };
+
+ pp.parseArrow = function (node) {
+ if (this.eat(tt.arrow)) {
+ return node;
+ }
+ };
+
+ pp.parseParenItem = function (node) {
+ return node;
+ };
+
+ // 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
+
+ pp.parseNew = function () {
+ const node = this.startNode();
+ const meta = this.parseIdentifier(true);
+
+ if (this.eat(tt.dot)) {
+ const metaProp = this.parseMetaProperty(node, meta, "target");
+
+ if (!this.state.inFunction) {
+ this.raise(metaProp.property.start, "new.target can only be used in functions");
+ }
+
+ return metaProp;
+ }
+
+ node.callee = this.parseNoCallExpr();
+
+ if (this.eat(tt.parenL)) {
+ node.arguments = this.parseExprList(tt.parenR);
+ this.toReferencedList(node.arguments);
+ } else {
+ node.arguments = [];
+ }
+
+ return this.finishNode(node, "NewExpression");
+ };
+
+ // Parse template expression.
+
+ pp.parseTemplateElement = function (isTagged) {
+ const elem = this.startNode();
+ if (this.state.value === null) {
+ if (!isTagged) {
+ this.raise(this.state.invalidTemplateEscapePosition, "Invalid escape sequence in template");
+ } else {
+ this.state.invalidTemplateEscapePosition = null;
+ }
+ }
+ elem.value = {
+ raw: this.input.slice(this.state.start, this.state.end).replace(/\r\n?/g, "\n"),
+ cooked: this.state.value
+ };
+ this.next();
+ elem.tail = this.match(tt.backQuote);
+ return this.finishNode(elem, "TemplateElement");
+ };
+
+ pp.parseTemplate = function (isTagged) {
+ const node = this.startNode();
+ this.next();
+ node.expressions = [];
+ let curElt = this.parseTemplateElement(isTagged);
+ node.quasis = [curElt];
+ while (!curElt.tail) {
+ this.expect(tt.dollarBraceL);
+ node.expressions.push(this.parseExpression());
+ this.expect(tt.braceR);
+ node.quasis.push(curElt = this.parseTemplateElement(isTagged));
+ }
+ this.next();
+ return this.finishNode(node, "TemplateLiteral");
+ };
+
+ // Parse an object literal or binding pattern.
+
+ pp.parseObj = function (isPattern, refShorthandDefaultPos) {
+ let decorators = [];
+ const propHash = Object.create(null);
+ let first = true;
+ const node = this.startNode();
+
+ node.properties = [];
+ this.next();
+
+ let firstRestLocation = null;
+
+ while (!this.eat(tt.braceR)) {
+ if (first) {
+ first = false;
+ } else {
+ this.expect(tt.comma);
+ if (this.eat(tt.braceR)) break;
+ }
+
+ while (this.match(tt.at)) {
+ decorators.push(this.parseDecorator());
+ }
+
+ let prop = this.startNode(), isGenerator = false, isAsync = false, startPos, startLoc;
+ if (decorators.length) {
+ prop.decorators = decorators;
+ decorators = [];
+ }
+
+ if (this.hasPlugin("objectRestSpread") && this.match(tt.ellipsis)) {
+ prop = this.parseSpread(isPattern ? { start: 0 } : undefined);
+ prop.type = isPattern ? "RestElement" : "SpreadElement";
+ if (isPattern) this.toAssignable(prop.argument, true, "object pattern");
+ node.properties.push(prop);
+ if (isPattern) {
+ const position = this.state.start;
+ if (firstRestLocation !== null) {
+ this.unexpected(firstRestLocation, "Cannot have multiple rest elements when destructuring");
+ } else if (this.eat(tt.braceR)) {
+ break;
+ } else if (this.match(tt.comma) && this.lookahead().type === tt.braceR) {
+ this.unexpected(position, "A trailing comma is not permitted after the rest element");
+ } else {
+ firstRestLocation = position;
+ continue;
+ }
+ } else {
+ continue;
+ }
+ }
+
+ prop.method = false;
+ prop.shorthand = false;
+
+ if (isPattern || refShorthandDefaultPos) {
+ startPos = this.state.start;
+ startLoc = this.state.startLoc;
+ }
+
+ if (!isPattern) {
+ isGenerator = this.eat(tt.star);
+ }
+
+ if (!isPattern && this.isContextual("async")) {
+ if (isGenerator) this.unexpected();
+
+ const asyncId = this.parseIdentifier();
+ if (this.match(tt.colon) || this.match(tt.parenL) || this.match(tt.braceR) || this.match(tt.eq) || this.match(tt.comma)) {
+ prop.key = asyncId;
+ prop.computed = false;
+ } else {
+ isAsync = true;
+ if (this.hasPlugin("asyncGenerators")) isGenerator = this.eat(tt.star);
+ this.parsePropertyName(prop);
+ }
+ } else {
+ this.parsePropertyName(prop);
+ }
+
+ this.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos);
+ this.checkPropClash(prop, propHash);
+
+ if (prop.shorthand) {
+ this.addExtra(prop, "shorthand", true);
+ }
+
+ node.properties.push(prop);
+ }
+
+ if (firstRestLocation !== null) {
+ this.unexpected(firstRestLocation, "The rest element has to be the last element when destructuring");
+ }
+
+ if (decorators.length) {
+ this.raise(this.state.start, "You have trailing decorators with no property");
+ }
+
+ return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
+ };
+
+ pp.isGetterOrSetterMethod = function (prop, isPattern) {
+ return !isPattern &&
+ !prop.computed &&
+ prop.key.type === "Identifier" &&
+ (prop.key.name === "get" || prop.key.name === "set") &&
+ (
+ this.match(tt.string) || // get "string"() {}
+ this.match(tt.num) || // get 1() {}
+ this.match(tt.bracketL) || // get ["string"]() {}
+ this.match(tt.name) || // get foo() {}
+ this.state.type.keyword // get debugger() {}
+ );
+ };
+
+ // get methods aren't allowed to have any parameters
+ // set methods must have exactly 1 parameter
+ pp.checkGetterSetterParamCount = function (method) {
+ const paramCount = method.kind === "get" ? 0 : 1;
+ if (method.params.length !== paramCount) {
+ const start = method.start;
+ if (method.kind === "get") {
+ this.raise(start, "getter should have no params");
+ } else {
+ this.raise(start, "setter should have exactly one param");
+ }
+ }
+ };
+
+ pp.parseObjectMethod = function (prop, isGenerator, isAsync, isPattern) {
+ if (isAsync || isGenerator || this.match(tt.parenL)) {
+ if (isPattern) this.unexpected();
+ prop.kind = "method";
+ prop.method = true;
+ this.parseMethod(prop, isGenerator, isAsync);
+
+ return this.finishNode(prop, "ObjectMethod");
+ }
+
+ if (this.isGetterOrSetterMethod(prop, isPattern)) {
+ if (isGenerator || isAsync) this.unexpected();
+ prop.kind = prop.key.name;
+ this.parsePropertyName(prop);
+ this.parseMethod(prop);
+ this.checkGetterSetterParamCount(prop);
+
+ return this.finishNode(prop, "ObjectMethod");
+ }
+ };
+
+ pp.parseObjectProperty = function (prop, startPos, startLoc, isPattern, refShorthandDefaultPos) {
+ if (this.eat(tt.colon)) {
+ prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos);
+
+ return this.finishNode(prop, "ObjectProperty");
+ }
+
+ if (!prop.computed && prop.key.type === "Identifier") {
+ if (isPattern) {
+ this.checkReservedWord(prop.key.name, prop.key.start, true, true);
+ prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone());
+ } else if (this.match(tt.eq) && refShorthandDefaultPos) {
+ if (!refShorthandDefaultPos.start) {
+ refShorthandDefaultPos.start = this.state.start;
+ }
+ prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone());
+ } else {
+ prop.value = prop.key.__clone();
+ }
+ prop.shorthand = true;
+
+ return this.finishNode(prop, "ObjectProperty");
+ }
+ };
+
+ pp.parseObjPropValue = function (prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos) {
+ const node =
+ this.parseObjectMethod(prop, isGenerator, isAsync, isPattern) ||
+ this.parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos);
+
+ if (!node) this.unexpected();
+
+ return node;
+ };
+
+ pp.parsePropertyName = function (prop) {
+ if (this.eat(tt.bracketL)) {
+ prop.computed = true;
+ prop.key = this.parseMaybeAssign();
+ this.expect(tt.bracketR);
+ } else {
+ prop.computed = false;
+ const oldInPropertyName = this.state.inPropertyName;
+ this.state.inPropertyName = true;
+ prop.key = (this.match(tt.num) || this.match(tt.string)) ? this.parseExprAtom() : this.parseIdentifier(true);
+ this.state.inPropertyName = oldInPropertyName;
+ }
+ return prop.key;
+ };
+
+ // Initialize empty function node.
+
+ pp.initFunction = function (node, isAsync) {
+ node.id = null;
+ node.generator = false;
+ node.expression = false;
+ node.async = !!isAsync;
+ };
+
+ // Parse object or class method.
+
+ pp.parseMethod = function (node, isGenerator, isAsync) {
+ const oldInMethod = this.state.inMethod;
+ this.state.inMethod = node.kind || true;
+ this.initFunction(node, isAsync);
+ this.expect(tt.parenL);
+ node.params = this.parseBindingList(tt.parenR);
+ node.generator = !!isGenerator;
+ this.parseFunctionBody(node);
+ this.state.inMethod = oldInMethod;
+ return node;
+ };
+
+ // Parse arrow function expression with given parameters.
+
+ pp.parseArrowExpression = function (node, params, isAsync) {
+ this.initFunction(node, isAsync);
+ node.params = this.toAssignableList(params, true, "arrow function parameters");
+ this.parseFunctionBody(node, true);
+ return this.finishNode(node, "ArrowFunctionExpression");
+ };
+
+ pp.isStrictBody = function (node, isExpression) {
+ if (!isExpression && node.body.directives.length) {
+ for (const directive of (node.body.directives)) {
+ if (directive.value.value === "use strict") {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ };
+
+ // Parse function body and check parameters.
+ pp.parseFunctionBody = function (node, allowExpression) {
+ const isExpression = allowExpression && !this.match(tt.braceL);
+
+ const oldInAsync = this.state.inAsync;
+ this.state.inAsync = node.async;
+ if (isExpression) {
+ node.body = this.parseMaybeAssign();
+ node.expression = true;
+ } else {
+ // Start a new scope with regard to labels and the `inFunction`
+ // flag (restore them to their old value afterwards).
+ const oldInFunc = this.state.inFunction;
+ const oldInGen = this.state.inGenerator;
+ const oldLabels = this.state.labels;
+ this.state.inFunction = true; this.state.inGenerator = node.generator; this.state.labels = [];
+ node.body = this.parseBlock(true);
+ node.expression = false;
+ this.state.inFunction = oldInFunc; this.state.inGenerator = oldInGen; this.state.labels = oldLabels;
+ }
+ this.state.inAsync = oldInAsync;
+
+ // 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`.
+ const isStrict = this.isStrictBody(node, isExpression);
+ // Also check when allowExpression === true for arrow functions
+ const checkLVal = this.state.strict || allowExpression || isStrict;
+
+ if (isStrict && node.id && node.id.type === "Identifier" && node.id.name === "yield") {
+ this.raise(node.id.start, "Binding yield in strict mode");
+ }
+
+ if (checkLVal) {
+ const nameHash = Object.create(null);
+ const oldStrict = this.state.strict;
+ if (isStrict) this.state.strict = true;
+ if (node.id) {
+ this.checkLVal(node.id, true, undefined, "function name");
+ }
+ for (const param of (node.params)) {
+ if (isStrict && param.type !== "Identifier") {
+ this.raise(param.start, "Non-simple parameter in strict mode");
+ }
+ this.checkLVal(param, true, nameHash, "function parameter list");
+ }
+ this.state.strict = oldStrict;
+ }
+ };
+
+ // 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.parseExprList = function (close, allowEmpty, refShorthandDefaultPos) {
+ const elts = [];
+ let first = true;
+
+ while (!this.eat(close)) {
+ if (first) {
+ first = false;
+ } else {
+ this.expect(tt.comma);
+ if (this.eat(close)) break;
+ }
+
+ elts.push(this.parseExprListItem(allowEmpty, refShorthandDefaultPos));
+ }
+ return elts;
+ };
+
+ pp.parseExprListItem = function (allowEmpty, refShorthandDefaultPos, refNeedsArrowPos) {
+ let elt;
+ if (allowEmpty && this.match(tt.comma)) {
+ elt = null;
+ } else if (this.match(tt.ellipsis)) {
+ elt = this.parseSpread(refShorthandDefaultPos);
+ } else {
+ elt = this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos);
+ }
+ return elt;
+ };
+
+ // Parse the next token as an identifier. If `liberal` is true (used
+ // when parsing properties), it will also convert keywords into
+ // identifiers.
+
+ pp.parseIdentifier = function (liberal) {
+ const node = this.startNode();
+ if (!liberal) {
+ this.checkReservedWord(this.state.value, this.state.start, !!this.state.type.keyword, false);
+ }
+
+ if (this.match(tt.name)) {
+ node.name = this.state.value;
+ } else if (this.state.type.keyword) {
+ node.name = this.state.type.keyword;
+ } else {
+ this.unexpected();
+ }
+
+ if (!liberal && node.name === "await" && this.state.inAsync) {
+ this.raise(node.start, "invalid use of await inside of an async function");
+ }
+
+ node.loc.identifierName = node.name;
+
+ this.next();
+ return this.finishNode(node, "Identifier");
+ };
+
+ pp.checkReservedWord = function (word, startLoc, checkKeywords, isBinding) {
+ if (this.isReservedWord(word) || (checkKeywords && this.isKeyword(word))) {
+ this.raise(startLoc, word + " is a reserved word");
+ }
+
+ if (this.state.strict && (reservedWords.strict(word) || (isBinding && reservedWords.strictBind(word)))) {
+ this.raise(startLoc, word + " is a reserved word in strict mode");
+ }
+ };
+
+ // Parses await expression inside async function.
+
+ pp.parseAwait = function (node) {
+ // istanbul ignore next: this condition is checked at the call site so won't be hit here
+ if (!this.state.inAsync) {
+ this.unexpected();
+ }
+ if (this.match(tt.star)) {
+ this.raise(node.start, "await* has been removed from the async functions proposal. Use Promise.all() instead.");
+ }
+ node.argument = this.parseMaybeUnary();
+ return this.finishNode(node, "AwaitExpression");
+ };
+
+ // Parses yield expression inside generator.
+
+ pp.parseYield = function () {
+ const node = this.startNode();
+ this.next();
+ if (
+ this.match(tt.semi) ||
+ this.canInsertSemicolon() ||
+ (!this.match(tt.star) && !this.state.type.startsExpr)
+ ) {
+ node.delegate = false;
+ node.argument = null;
+ } else {
+ node.delegate = this.eat(tt.star);
+ node.argument = this.parseMaybeAssign();
+ }
+ return this.finishNode(node, "YieldExpression");
+ };
+
+}
+
+// parser/location.js
+const parserLocationJS = {};
+{
+ const { getLineInfo } = utilLocationJS;
+ const Parser = parserIndexJS;
+
+ const pp = 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.raise = function (pos, message) {
+ const loc = getLineInfo(this.input, pos);
+ message += ` (${loc.line}:${loc.column})`;
+ const err = new SyntaxError(message);
+ err.pos = pos;
+ err.loc = loc;
+ throw err;
+ };
+}
+
+// parser/lval.js
+const parserLvalJS = {};
+{
+ const { types: tt } = tokenizerTypesJS;
+ const Parser = parserIndexJS;
+
+ const pp = Parser.prototype;
+
+ // Convert existing expression atom to assignable pattern
+ // if possible.
+
+ pp.toAssignable = function (node, isBinding, contextDescription) {
+ if (node) {
+ switch (node.type) {
+ case "Identifier":
+ case "ObjectPattern":
+ case "ArrayPattern":
+ case "AssignmentPattern":
+ break;
+
+ case "ObjectExpression":
+ node.type = "ObjectPattern";
+ for (const prop of (node.properties)) {
+ if (prop.type === "ObjectMethod") {
+ if (prop.kind === "get" || prop.kind === "set") {
+ this.raise(prop.key.start, "Object pattern can't contain getter or setter");
+ } else {
+ this.raise(prop.key.start, "Object pattern can't contain methods");
+ }
+ } else {
+ this.toAssignable(prop, isBinding, "object destructuring pattern");
+ }
+ }
+ break;
+
+ case "ObjectProperty":
+ this.toAssignable(node.value, isBinding, contextDescription);
+ break;
+
+ case "SpreadElement":
+ node.type = "RestElement";
+ break;
+
+ case "ArrayExpression":
+ node.type = "ArrayPattern";
+ this.toAssignableList(node.elements, isBinding, contextDescription);
+ break;
+
+ case "AssignmentExpression":
+ if (node.operator === "=") {
+ node.type = "AssignmentPattern";
+ delete node.operator;
+ } else {
+ this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
+ }
+ break;
+
+ case "MemberExpression":
+ if (!isBinding) break;
+
+ default: {
+ const message = "Invalid left-hand side" +
+ (contextDescription ? " in " + contextDescription : /* istanbul ignore next */ "expression");
+ this.raise(node.start, message);
+ }
+ }
+ }
+ return node;
+ };
+
+ // Convert list of expression atoms to binding list.
+
+ pp.toAssignableList = function (exprList, isBinding, contextDescription) {
+ let end = exprList.length;
+ if (end) {
+ const last = exprList[end - 1];
+ if (last && last.type === "RestElement") {
+ --end;
+ } else if (last && last.type === "SpreadElement") {
+ last.type = "RestElement";
+ const arg = last.argument;
+ this.toAssignable(arg, isBinding, contextDescription);
+ if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") {
+ this.unexpected(arg.start);
+ }
+ --end;
+ }
+ }
+ for (let i = 0; i < end; i++) {
+ const elt = exprList[i];
+ if (elt && elt.type === "SpreadElement")
+ this.raise(elt.start, "The rest element has to be the last element when destructuring");
+ if (elt) this.toAssignable(elt, isBinding, contextDescription);
+ }
+ return exprList;
+ };
+
+ // Convert list of expression atoms to a list of
+
+ pp.toReferencedList = function (exprList) {
+ return exprList;
+ };
+
+ // Parses spread element.
+
+ pp.parseSpread = function (refShorthandDefaultPos) {
+ const node = this.startNode();
+ this.next();
+ node.argument = this.parseMaybeAssign(false, refShorthandDefaultPos);
+ return this.finishNode(node, "SpreadElement");
+ };
+
+ pp.parseRest = function () {
+ const node = this.startNode();
+ this.next();
+ node.argument = this.parseBindingIdentifier();
+ return this.finishNode(node, "RestElement");
+ };
+
+ pp.shouldAllowYieldIdentifier = function () {
+ return this.match(tt._yield) && !this.state.strict && !this.state.inGenerator;
+ };
+
+ pp.parseBindingIdentifier = function () {
+ return this.parseIdentifier(this.shouldAllowYieldIdentifier());
+ };
+
+ // Parses lvalue (assignable) atom.
+
+ pp.parseBindingAtom = function () {
+ switch (this.state.type) {
+ case tt._yield:
+ if (this.state.strict || this.state.inGenerator) this.unexpected();
+ // fall-through
+ case tt.name:
+ return this.parseIdentifier(true);
+
+ case tt.bracketL:
+ const node = this.startNode();
+ this.next();
+ node.elements = this.parseBindingList(tt.bracketR, true);
+ return this.finishNode(node, "ArrayPattern");
+
+ case tt.braceL:
+ return this.parseObj(true);
+
+ default:
+ this.unexpected();
+ }
+ };
+
+ pp.parseBindingList = function (close, allowEmpty) {
+ const elts = [];
+ let first = true;
+ while (!this.eat(close)) {
+ if (first) {
+ first = false;
+ } else {
+ this.expect(tt.comma);
+ }
+ if (allowEmpty && this.match(tt.comma)) {
+ elts.push(null);
+ } else if (this.eat(close)) {
+ break;
+ } else if (this.match(tt.ellipsis)) {
+ elts.push(this.parseAssignableListItemTypes(this.parseRest()));
+ this.expect(close);
+ break;
+ } else {
+ const decorators = [];
+ while (this.match(tt.at)) {
+ decorators.push(this.parseDecorator());
+ }
+ const left = this.parseMaybeDefault();
+ if (decorators.length) {
+ left.decorators = decorators;
+ }
+ this.parseAssignableListItemTypes(left);
+ elts.push(this.parseMaybeDefault(left.start, left.loc.start, left));
+ }
+ }
+ return elts;
+ };
+
+ pp.parseAssignableListItemTypes = function (param) {
+ return param;
+ };
+
+ // Parses assignment pattern around given atom if possible.
+
+ pp.parseMaybeDefault = function (startPos, startLoc, left) {
+ startLoc = startLoc || this.state.startLoc;
+ startPos = startPos || this.state.start;
+ left = left || this.parseBindingAtom();
+ if (!this.eat(tt.eq)) return left;
+
+ const 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.
+
+ pp.checkLVal = function (expr, isBinding, checkClashes, contextDescription) {
+ switch (expr.type) {
+ case "Identifier":
+ this.checkReservedWord(expr.name, expr.start, false, true);
+
+ if (checkClashes) {
+ // we need to prefix this with an underscore for the cases where we have a key of
+ // `__proto__`. there's a bug in old V8 where the following wouldn't work:
+ //
+ // > var obj = Object.create(null);
+ // undefined
+ // > obj.__proto__
+ // null
+ // > obj.__proto__ = true;
+ // true
+ // > obj.__proto__
+ // null
+ const key = `_${expr.name}`;
+
+ if (checkClashes[key]) {
+ this.raise(expr.start, "Argument name clash in strict mode");
+ } else {
+ checkClashes[key] = true;
+ }
+ }
+ break;
+
+ case "MemberExpression":
+ if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
+ break;
+
+ case "ObjectPattern":
+ for (let prop of (expr.properties)) {
+ if (prop.type === "ObjectProperty") prop = prop.value;
+ this.checkLVal(prop, isBinding, checkClashes, "object destructuring pattern");
+ }
+ break;
+
+ case "ArrayPattern":
+ for (const elem of (expr.elements)) {
+ if (elem) this.checkLVal(elem, isBinding, checkClashes, "array destructuring pattern");
+ }
+ break;
+
+ case "AssignmentPattern":
+ this.checkLVal(expr.left, isBinding, checkClashes, "assignment pattern");
+ break;
+
+ case "RestElement":
+ this.checkLVal(expr.argument, isBinding, checkClashes, "rest element");
+ break;
+
+ default: {
+ const message = (isBinding ? /* istanbul ignore next */ "Binding invalid" : "Invalid") +
+ " left-hand side" +
+ (contextDescription ? " in " + contextDescription : /* istanbul ignore next */ "expression");
+ this.raise(expr.start, message);
+ }
+ }
+ };
+
+}
+
+
+// parser/node.js
+const parserNodeJS = {};
+{
+ const Parser = parserIndexJS;
+ const { SourceLocation, Position } = utilLocationJS;
+
+ // Start an AST node, attaching a start offset.
+
+ const pp = Parser.prototype;
+ const commentKeys = ["leadingComments", "trailingComments", "innerComments"];
+
+ class Node {
+ constructor(parser, pos, loc) {
+ this.type = "";
+ this.start = pos;
+ this.end = 0;
+ this.loc = new SourceLocation(loc);
+ if (parser && parser.options.ranges) this.range = [pos, 0];
+ if (parser && parser.filename) this.loc.filename = parser.filename;
+ }
+
+ //type: string;
+ //start: ?number;
+ //end: number;
+ //loc: SourceLocation;
+
+ __clone(){
+ const node2 = new Node;
+ for (const key in this) {
+ // Do not clone comments that are already attached to the node
+ if (commentKeys.indexOf(key) < 0) {
+ node2[key] = this[key];
+ }
+ }
+
+ return node2;
+ }
+ }
+
+ pp.startNode = function () {
+ return new Node(this, this.state.start, this.state.startLoc);
+ };
+
+ pp.startNodeAt = function (pos, loc) {
+ return new Node(this, pos, loc);
+ };
+
+ function finishNodeAt(node, type, pos, loc) {
+ node.type = type;
+ node.end = pos;
+ node.loc.end = loc;
+ if (this.options.ranges) node.range[1] = pos;
+ this.processComment(node);
+ return node;
+ }
+
+ // Finish an AST node, adding `type` and `end` properties.
+
+ pp.finishNode = function (node, type) {
+ return finishNodeAt.call(this, node, type, this.state.lastTokEnd, this.state.lastTokEndLoc);
+ };
+
+ // Finish node at given position
+
+ pp.finishNodeAt = function (node, type, pos, loc) {
+ return finishNodeAt.call(this, node, type, pos, loc);
+ };
+
+
+ /**
+ * Reset the start location of node to the start location of locationNode
+ */
+ pp.resetStartLocationFromNode = function (node, locationNode) {
+ node.start = locationNode.start;
+ node.loc.start = locationNode.loc.start;
+ if (this.options.ranges) node.range[0] = locationNode.range[0];
+
+ return node;
+ };
+}
+
+// parser/statement.js
+const parserStatementJS = {};
+{
+ /* eslint max-len: 0 */
+
+ const { types: tt } = tokenizerTypesJS;
+ const Parser = parserIndexJS;
+ const { lineBreak } = utilWhitespaceJS;
+
+ const pp = 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.parseTopLevel = function (file, program) {
+ program.sourceType = this.options.sourceType;
+
+ this.parseBlockBody(program, true, true, tt.eof);
+
+ file.program = this.finishNode(program, "Program");
+ file.comments = this.state.comments;
+ file.tokens = this.state.tokens;
+
+ return this.finishNode(file, "File");
+ };
+
+ const loopLabel = { kind: "loop" }, switchLabel = { kind: "switch" };
+
+ // TODO
+
+ pp.stmtToDirective = function (stmt) {
+ const expr = stmt.expression;
+
+ const directiveLiteral = this.startNodeAt(expr.start, expr.loc.start);
+ const directive = this.startNodeAt(stmt.start, stmt.loc.start);
+
+ const raw = this.input.slice(expr.start, expr.end);
+ const val = directiveLiteral.value = raw.slice(1, -1); // remove quotes
+
+ this.addExtra(directiveLiteral, "raw", raw);
+ this.addExtra(directiveLiteral, "rawValue", val);
+
+ directive.value = this.finishNodeAt(directiveLiteral, "DirectiveLiteral", expr.end, expr.loc.end);
+
+ return this.finishNodeAt(directive, "Directive", stmt.end, stmt.loc.end);
+ };
+
+ // 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.parseStatement = function (declaration, topLevel) {
+ if (this.match(tt.at)) {
+ this.parseDecorators(true);
+ }
+
+ const starttype = this.state.type;
+ const node = this.startNode();
+
+ // 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 tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword);
+ case tt._debugger: return this.parseDebuggerStatement(node);
+ case tt._do: return this.parseDoStatement(node);
+ case tt._for: return this.parseForStatement(node);
+ case tt._function:
+ if (!declaration) this.unexpected();
+ return this.parseFunctionStatement(node);
+
+ case tt._class:
+ if (!declaration) this.unexpected();
+ return this.parseClass(node, true);
+
+ case tt._if: return this.parseIfStatement(node);
+ case tt._return: return this.parseReturnStatement(node);
+ case tt._switch: return this.parseSwitchStatement(node);
+ case tt._throw: return this.parseThrowStatement(node);
+ case tt._try: return this.parseTryStatement(node);
+
+ case tt._let:
+ case tt._const:
+ if (!declaration) this.unexpected(); // NOTE: falls through to _var
+
+ case tt._var:
+ return this.parseVarStatement(node, starttype);
+
+ case tt._while: return this.parseWhileStatement(node);
+ case tt._with: return this.parseWithStatement(node);
+ case tt.braceL: return this.parseBlock();
+ case tt.semi: return this.parseEmptyStatement(node);
+ case tt._export:
+ case tt._import:
+ if (this.hasPlugin("dynamicImport") && this.lookahead().type === tt.parenL) break;
+
+ if (!this.options.allowImportExportEverywhere) {
+ if (!topLevel) {
+ this.raise(this.state.start, "'import' and 'export' may only appear at the top level");
+ }
+
+ if (!this.inModule) {
+ this.raise(this.state.start, "'import' and 'export' may appear only with 'sourceType: module'");
+ }
+ }
+ return starttype === tt._import ? this.parseImport(node) : this.parseExport(node);
+
+ case tt.name:
+ if (this.state.value === "async") {
+ // peek ahead and see if next token is a function
+ const state = this.state.clone();
+ this.next();
+ if (this.match(tt._function) && !this.canInsertSemicolon()) {
+ this.expect(tt._function);
+ return this.parseFunction(node, true, false, true);
+ } else {
+ this.state = state;
+ }
+ }
+ }
+
+ // 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.
+ const maybeName = this.state.value;
+ const expr = this.parseExpression();
+
+ if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) {
+ return this.parseLabeledStatement(node, maybeName, expr);
+ } else {
+ return this.parseExpressionStatement(node, expr);
+ }
+ };
+
+ pp.takeDecorators = function (node) {
+ if (this.state.decorators.length) {
+ node.decorators = this.state.decorators;
+ this.state.decorators = [];
+ }
+ };
+
+ pp.parseDecorators = function (allowExport) {
+ while (this.match(tt.at)) {
+ const decorator = this.parseDecorator();
+ this.state.decorators.push(decorator);
+ }
+
+ if (allowExport && this.match(tt._export)) {
+ return;
+ }
+
+ if (!this.match(tt._class)) {
+ this.raise(this.state.start, "Leading decorators must be attached to a class declaration");
+ }
+ };
+
+ pp.parseDecorator = function () {
+ if (!this.hasPlugin("decorators")) {
+ this.unexpected();
+ }
+ const node = this.startNode();
+ this.next();
+ node.expression = this.parseMaybeAssign();
+ return this.finishNode(node, "Decorator");
+ };
+
+ pp.parseBreakContinueStatement = function (node, keyword) {
+ const isBreak = keyword === "break";
+ this.next();
+
+ if (this.isLineTerminator()) {
+ node.label = null;
+ } else if (!this.match(tt.name)) {
+ this.unexpected();
+ } else {
+ node.label = this.parseIdentifier();
+ this.semicolon();
+ }
+
+ // Verify that there is an actual destination to break or
+ // continue to.
+ let i;
+ for (i = 0; i < this.state.labels.length; ++i) {
+ const lab = this.state.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.state.labels.length) this.raise(node.start, "Unsyntactic " + keyword);
+ return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
+ };
+
+ pp.parseDebuggerStatement = function (node) {
+ this.next();
+ this.semicolon();
+ return this.finishNode(node, "DebuggerStatement");
+ };
+
+ pp.parseDoStatement = function (node) {
+ this.next();
+ this.state.labels.push(loopLabel);
+ node.body = this.parseStatement(false);
+ this.state.labels.pop();
+ this.expect(tt._while);
+ node.test = this.parseParenExpression();
+ this.eat(tt.semi);
+ 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.parseForStatement = function (node) {
+ this.next();
+ this.state.labels.push(loopLabel);
+
+ let forAwait = false;
+ if (this.hasPlugin("asyncGenerators") && this.state.inAsync && this.isContextual("await")) {
+ forAwait = true;
+ this.next();
+ }
+ this.expect(tt.parenL);
+
+ if (this.match(tt.semi)) {
+ if (forAwait) {
+ this.unexpected();
+ }
+ return this.parseFor(node, null);
+ }
+
+ if (this.match(tt._var) || this.match(tt._let) || this.match(tt._const)) {
+ const init = this.startNode();
+ const varKind = this.state.type;
+ this.next();
+ this.parseVar(init, true, varKind);
+ this.finishNode(init, "VariableDeclaration");
+
+ if (this.match(tt._in) || this.isContextual("of")) {
+ if (init.declarations.length === 1 && !init.declarations[0].init) {
+ return this.parseForIn(node, init, forAwait);
+ }
+ }
+ if (forAwait) {
+ this.unexpected();
+ }
+ return this.parseFor(node, init);
+ }
+
+ const refShorthandDefaultPos = { start: 0 };
+ const init = this.parseExpression(true, refShorthandDefaultPos);
+ if (this.match(tt._in) || this.isContextual("of")) {
+ const description = this.isContextual("of") ? "for-of statement" : "for-in statement";
+ this.toAssignable(init, undefined, description);
+ this.checkLVal(init, undefined, undefined, description);
+ return this.parseForIn(node, init, forAwait);
+ } else if (refShorthandDefaultPos.start) {
+ this.unexpected(refShorthandDefaultPos.start);
+ }
+ if (forAwait) {
+ this.unexpected();
+ }
+ return this.parseFor(node, init);
+ };
+
+ pp.parseFunctionStatement = function (node) {
+ this.next();
+ return this.parseFunction(node, true);
+ };
+
+ pp.parseIfStatement = function (node) {
+ this.next();
+ node.test = this.parseParenExpression();
+ node.consequent = this.parseStatement(false);
+ node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null;
+ return this.finishNode(node, "IfStatement");
+ };
+
+ pp.parseReturnStatement = function (node) {
+ if (!this.state.inFunction && !this.options.allowReturnOutsideFunction) {
+ this.raise(this.state.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.isLineTerminator()) {
+ node.argument = null;
+ } else {
+ node.argument = this.parseExpression();
+ this.semicolon();
+ }
+
+ return this.finishNode(node, "ReturnStatement");
+ };
+
+ pp.parseSwitchStatement = function (node) {
+ this.next();
+ node.discriminant = this.parseParenExpression();
+ node.cases = [];
+ this.expect(tt.braceL);
+ this.state.labels.push(switchLabel);
+
+ // Statements under must be grouped (by label) in SwitchCase
+ // nodes. `cur` is used to keep the node that we are currently
+ // adding statements to.
+
+ let cur;
+ for (let sawDefault; !this.match(tt.braceR); ) {
+ if (this.match(tt._case) || this.match(tt._default)) {
+ const isCase = this.match(tt._case);
+ if (cur) this.finishNode(cur, "SwitchCase");
+ node.cases.push(cur = this.startNode());
+ cur.consequent = [];
+ this.next();
+ if (isCase) {
+ cur.test = this.parseExpression();
+ } else {
+ if (sawDefault) this.raise(this.state.lastTokStart, "Multiple default clauses");
+ sawDefault = true;
+ cur.test = null;
+ }
+ this.expect(tt.colon);
+ } else {
+ if (cur) {
+ cur.consequent.push(this.parseStatement(true));
+ } else {
+ this.unexpected();
+ }
+ }
+ }
+ if (cur) this.finishNode(cur, "SwitchCase");
+ this.next(); // Closing brace
+ this.state.labels.pop();
+ return this.finishNode(node, "SwitchStatement");
+ };
+
+ pp.parseThrowStatement = function (node) {
+ this.next();
+ if (lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start)))
+ this.raise(this.state.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.
+
+ const empty = [];
+
+ pp.parseTryStatement = function (node) {
+ this.next();
+
+ node.block = this.parseBlock();
+ node.handler = null;
+
+ if (this.match(tt._catch)) {
+ const clause = this.startNode();
+ this.next();
+
+ this.expect(tt.parenL);
+ clause.param = this.parseBindingAtom();
+ this.checkLVal(clause.param, true, Object.create(null), "catch clause");
+ this.expect(tt.parenR);
+
+ clause.body = this.parseBlock();
+ node.handler = this.finishNode(clause, "CatchClause");
+ }
+
+ node.guardedHandlers = empty;
+ node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null;
+
+ if (!node.handler && !node.finalizer) {
+ this.raise(node.start, "Missing catch or finally clause");
+ }
+
+ return this.finishNode(node, "TryStatement");
+ };
+
+ pp.parseVarStatement = function (node, kind) {
+ this.next();
+ this.parseVar(node, false, kind);
+ this.semicolon();
+ return this.finishNode(node, "VariableDeclaration");
+ };
+
+ pp.parseWhileStatement = function (node) {
+ this.next();
+ node.test = this.parseParenExpression();
+ this.state.labels.push(loopLabel);
+ node.body = this.parseStatement(false);
+ this.state.labels.pop();
+ return this.finishNode(node, "WhileStatement");
+ };
+
+ pp.parseWithStatement = function (node) {
+ if (this.state.strict) this.raise(this.state.start, "'with' in strict mode");
+ this.next();
+ node.object = this.parseParenExpression();
+ node.body = this.parseStatement(false);
+ return this.finishNode(node, "WithStatement");
+ };
+
+ pp.parseEmptyStatement = function (node) {
+ this.next();
+ return this.finishNode(node, "EmptyStatement");
+ };
+
+ pp.parseLabeledStatement = function (node, maybeName, expr) {
+ for (const label of (this.state.labels)) {
+ if (label.name === maybeName) {
+ this.raise(expr.start, `Label '${maybeName}' is already declared`);
+ }
+ }
+
+ const kind = this.state.type.isLoop ? "loop" : this.match(tt._switch) ? "switch" : null;
+ for (let i = this.state.labels.length - 1; i >= 0; i--) {
+ const label = this.state.labels[i];
+ if (label.statementStart === node.start) {
+ label.statementStart = this.state.start;
+ label.kind = kind;
+ } else {
+ break;
+ }
+ }
+
+ this.state.labels.push({ name: maybeName, kind: kind, statementStart: this.state.start });
+ node.body = this.parseStatement(true);
+ this.state.labels.pop();
+ node.label = expr;
+ return this.finishNode(node, "LabeledStatement");
+ };
+
+ pp.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.parseBlock = function (allowDirectives) {
+ const node = this.startNode();
+ this.expect(tt.braceL);
+ this.parseBlockBody(node, allowDirectives, false, tt.braceR);
+ return this.finishNode(node, "BlockStatement");
+ };
+
+ pp.isValidDirective = function (stmt) {
+ return stmt.type === "ExpressionStatement" &&
+ stmt.expression.type === "StringLiteral" &&
+ !stmt.expression.extra.parenthesized;
+ };
+
+ pp.parseBlockBody = function (node, allowDirectives, topLevel, end) {
+ node.body = [];
+ node.directives = [];
+
+ let parsedNonDirective = false;
+ let oldStrict;
+ let octalPosition;
+
+ while (!this.eat(end)) {
+ if (!parsedNonDirective && this.state.containsOctal && !octalPosition) {
+ octalPosition = this.state.octalPosition;
+ }
+
+ const stmt = this.parseStatement(true, topLevel);
+
+ if (allowDirectives && !parsedNonDirective && this.isValidDirective(stmt)) {
+ const directive = this.stmtToDirective(stmt);
+ node.directives.push(directive);
+
+ if (oldStrict === undefined && directive.value.value === "use strict") {
+ oldStrict = this.state.strict;
+ this.setStrict(true);
+
+ if (octalPosition) {
+ this.raise(octalPosition, "Octal literal in strict mode");
+ }
+ }
+
+ continue;
+ }
+
+ parsedNonDirective = true;
+ node.body.push(stmt);
+ }
+
+ if (oldStrict === false) {
+ this.setStrict(false);
+ }
+ };
+
+ // Parse a regular `for` loop. The disambiguation code in
+ // `parseStatement` will already have parsed the init statement or
+ // expression.
+
+ pp.parseFor = function (node, init) {
+ node.init = init;
+ this.expect(tt.semi);
+ node.test = this.match(tt.semi) ? null : this.parseExpression();
+ this.expect(tt.semi);
+ node.update = this.match(tt.parenR) ? null : this.parseExpression();
+ this.expect(tt.parenR);
+ node.body = this.parseStatement(false);
+ this.state.labels.pop();
+ return this.finishNode(node, "ForStatement");
+ };
+
+ // Parse a `for`/`in` and `for`/`of` loop, which are almost
+ // same from parser's perspective.
+
+ pp.parseForIn = function (node, init, forAwait) {
+ const type = this.match(tt._in) ? "ForInStatement" : "ForOfStatement";
+ if (forAwait) {
+ this.eatContextual("of");
+ } else {
+ this.next();
+ }
+ node.await = !!forAwait;
+ node.left = init;
+ node.right = this.parseExpression();
+ this.expect(tt.parenR);
+ node.body = this.parseStatement(false);
+ this.state.labels.pop();
+ return this.finishNode(node, type);
+ };
+
+ // Parse a list of variable declarations.
+
+ pp.parseVar = function (node, isFor, kind) {
+ node.declarations = [];
+ node.kind = kind.keyword;
+ for (;;) {
+ const decl = this.startNode();
+ this.parseVarHead(decl);
+ if (this.eat(tt.eq)) {
+ decl.init = this.parseMaybeAssign(isFor);
+ } else if (kind === tt._const && !(this.match(tt._in) || this.isContextual("of"))) {
+ this.unexpected();
+ } else if (decl.id.type !== "Identifier" && !(isFor && (this.match(tt._in) || this.isContextual("of")))) {
+ this.raise(this.state.lastTokEnd, "Complex binding patterns require an initialization value");
+ } else {
+ decl.init = null;
+ }
+ node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
+ if (!this.eat(tt.comma)) break;
+ }
+ return node;
+ };
+
+ pp.parseVarHead = function (decl) {
+ decl.id = this.parseBindingAtom();
+ this.checkLVal(decl.id, true, undefined, "variable declaration");
+ };
+
+ // Parse a function declaration or literal (depending on the
+ // `isStatement` parameter).
+
+ pp.parseFunction = function (node, isStatement, allowExpressionBody, isAsync, optionalId) {
+ const oldInMethod = this.state.inMethod;
+ this.state.inMethod = false;
+
+ this.initFunction(node, isAsync);
+
+ if (this.match(tt.star)) {
+ if (node.async && !this.hasPlugin("asyncGenerators")) {
+ this.unexpected();
+ } else {
+ node.generator = true;
+ this.next();
+ }
+ }
+
+ if (isStatement && !optionalId && !this.match(tt.name) && !this.match(tt._yield)) {
+ this.unexpected();
+ }
+
+ if (this.match(tt.name) || this.match(tt._yield)) {
+ node.id = this.parseBindingIdentifier();
+ }
+
+ this.parseFunctionParams(node);
+ this.parseFunctionBody(node, allowExpressionBody);
+
+ this.state.inMethod = oldInMethod;
+
+ return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
+ };
+
+ pp.parseFunctionParams = function (node) {
+ this.expect(tt.parenL);
+ node.params = this.parseBindingList(tt.parenR);
+ };
+
+ // Parse a class declaration or literal (depending on the
+ // `isStatement` parameter).
+
+ pp.parseClass = function (node, isStatement, optionalId) {
+ this.next();
+ this.takeDecorators(node);
+ this.parseClassId(node, isStatement, optionalId);
+ this.parseClassSuper(node);
+ this.parseClassBody(node);
+ return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
+ };
+
+ pp.isClassProperty = function () {
+ return this.match(tt.eq) || this.match(tt.semi) || this.match(tt.braceR);
+ };
+
+ pp.isClassMethod = function () {
+ return this.match(tt.parenL);
+ };
+
+ pp.isNonstaticConstructor = function (method) {
+ return !method.computed && !method.static && (
+ (method.key.name === "constructor") || // Identifier
+ (method.key.value === "constructor") // Literal
+ );
+ };
+
+ pp.parseClassBody = function (node) {
+ // class bodies are implicitly strict
+ const oldStrict = this.state.strict;
+ this.state.strict = true;
+
+ let hadConstructor = false;
+ let decorators = [];
+ const classBody = this.startNode();
+
+ classBody.body = [];
+
+ this.expect(tt.braceL);
+
+ while (!this.eat(tt.braceR)) {
+ if (this.eat(tt.semi)) {
+ if (decorators.length > 0) {
+ this.raise(this.state.lastTokEnd, "Decorators must not be followed by a semicolon");
+ }
+ continue;
+ }
+
+ if (this.match(tt.at)) {
+ decorators.push(this.parseDecorator());
+ continue;
+ }
+
+ const method = this.startNode();
+
+ // steal the decorators if there are any
+ if (decorators.length) {
+ method.decorators = decorators;
+ decorators = [];
+ }
+
+ method.static = false;
+ if (this.match(tt.name) && this.state.value === "static") {
+ const key = this.parseIdentifier(true); // eats 'static'
+ if (this.isClassMethod()) {
+ // a method named 'static'
+ method.kind = "method";
+ method.computed = false;
+ method.key = key;
+ this.parseClassMethod(classBody, method, false, false);
+ continue;
+ } else if (this.isClassProperty()) {
+ // a property named 'static'
+ method.computed = false;
+ method.key = key;
+ classBody.body.push(this.parseClassProperty(method));
+ continue;
+ }
+ // otherwise something static
+ method.static = true;
+ }
+
+ if (this.eat(tt.star)) {
+ // a generator
+ method.kind = "method";
+ this.parsePropertyName(method);
+ if (this.isNonstaticConstructor(method)) {
+ this.raise(method.key.start, "Constructor can't be a generator");
+ }
+ if (!method.computed && method.static && (method.key.name === "prototype" || method.key.value === "prototype")) {
+ this.raise(method.key.start, "Classes may not have static property named prototype");
+ }
+ this.parseClassMethod(classBody, method, true, false);
+ } else {
+ const isSimple = this.match(tt.name);
+ const key = this.parsePropertyName(method);
+ if (!method.computed && method.static && (method.key.name === "prototype" || method.key.value === "prototype")) {
+ this.raise(method.key.start, "Classes may not have static property named prototype");
+ }
+ if (this.isClassMethod()) {
+ // a normal method
+ if (this.isNonstaticConstructor(method)) {
+ if (hadConstructor) {
+ this.raise(key.start, "Duplicate constructor in the same class");
+ } else if (method.decorators) {
+ this.raise(method.start, "You can't attach decorators to a class constructor");
+ }
+ hadConstructor = true;
+ method.kind = "constructor";
+ } else {
+ method.kind = "method";
+ }
+ this.parseClassMethod(classBody, method, false, false);
+ } else if (this.isClassProperty()) {
+ // a normal property
+ if (this.isNonstaticConstructor(method)) {
+ this.raise(method.key.start, "Classes may not have a non-static field named 'constructor'");
+ }
+ classBody.body.push(this.parseClassProperty(method));
+ } else if (isSimple && key.name === "async" && !this.isLineTerminator()) {
+ // an async method
+ const isGenerator = this.hasPlugin("asyncGenerators") && this.eat(tt.star);
+ method.kind = "method";
+ this.parsePropertyName(method);
+ if (this.isNonstaticConstructor(method)) {
+ this.raise(method.key.start, "Constructor can't be an async function");
+ }
+ this.parseClassMethod(classBody, method, isGenerator, true);
+ } else if (isSimple && (key.name === "get" || key.name === "set") && !(this.isLineTerminator() && this.match(tt.star))) { // `get\n*` is an uninitialized property named 'get' followed by a generator.
+ // a getter or setter
+ method.kind = key.name;
+ this.parsePropertyName(method);
+ if (this.isNonstaticConstructor(method)) {
+ this.raise(method.key.start, "Constructor can't have get/set modifier");
+ }
+ this.parseClassMethod(classBody, method, false, false);
+ this.checkGetterSetterParamCount(method);
+ } else if (this.isLineTerminator()) {
+ // an uninitialized class property (due to ASI, since we don't otherwise recognize the next token)
+ if (this.isNonstaticConstructor(method)) {
+ this.raise(method.key.start, "Classes may not have a non-static field named 'constructor'");
+ }
+ classBody.body.push(this.parseClassProperty(method));
+ } else {
+ this.unexpected();
+ }
+ }
+ }
+
+ if (decorators.length) {
+ this.raise(this.state.start, "You have trailing decorators with no method");
+ }
+
+ node.body = this.finishNode(classBody, "ClassBody");
+
+ this.state.strict = oldStrict;
+ };
+
+ pp.parseClassProperty = function (node) {
+ const noPluginMsg = "You can only use Class Properties when the 'classProperties' plugin is enabled.";
+ if (!node.typeAnnotation && !this.hasPlugin("classProperties")) {
+ this.raise(node.start, noPluginMsg);
+ }
+
+ if (this.match(tt.eq)) {
+ if (!this.hasPlugin("classProperties")) this.raise(this.state.start, noPluginMsg);
+ this.next();
+ node.value = this.parseMaybeAssign();
+ } else {
+ node.value = null;
+ }
+ this.semicolon();
+ return this.finishNode(node, "ClassProperty");
+ };
+
+ pp.parseClassMethod = function (classBody, method, isGenerator, isAsync) {
+ this.parseMethod(method, isGenerator, isAsync);
+ classBody.body.push(this.finishNode(method, "ClassMethod"));
+ };
+
+ pp.parseClassId = function (node, isStatement, optionalId) {
+ if (this.match(tt.name)) {
+ node.id = this.parseIdentifier();
+ } else {
+ if (optionalId || !isStatement) {
+ node.id = null;
+ } else {
+ this.unexpected();
+ }
+ }
+ };
+
+ pp.parseClassSuper = function (node) {
+ node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null;
+ };
+
+ // Parses module export declaration.
+
+ pp.parseExport = function (node) {
+ this.next();
+ // export * from '...'
+ if (this.match(tt.star)) {
+ const specifier = this.startNode();
+ this.next();
+ if (this.hasPlugin("exportExtensions") && this.eatContextual("as")) {
+ specifier.exported = this.parseIdentifier();
+ node.specifiers = [this.finishNode(specifier, "ExportNamespaceSpecifier")];
+ this.parseExportSpecifiersMaybe(node);
+ this.parseExportFrom(node, true);
+ } else {
+ this.parseExportFrom(node, true);
+ return this.finishNode(node, "ExportAllDeclaration");
+ }
+ } else if (this.hasPlugin("exportExtensions") && this.isExportDefaultSpecifier()) {
+ const specifier = this.startNode();
+ specifier.exported = this.parseIdentifier(true);
+ node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
+ if (this.match(tt.comma) && this.lookahead().type === tt.star) {
+ this.expect(tt.comma);
+ const specifier = this.startNode();
+ this.expect(tt.star);
+ this.expectContextual("as");
+ specifier.exported = this.parseIdentifier();
+ node.specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier"));
+ } else {
+ this.parseExportSpecifiersMaybe(node);
+ }
+ this.parseExportFrom(node, true);
+ } else if (this.eat(tt._default)) { // export default ...
+ let expr = this.startNode();
+ let needsSemi = false;
+ if (this.eat(tt._function)) {
+ expr = this.parseFunction(expr, true, false, false, true);
+ } else if (
+ this.isContextual("async") &&
+ this.lookahead().type === tt._function
+ ) { // async function declaration
+ this.eatContextual("async");
+ this.eat(tt._function);
+ expr = this.parseFunction(expr, true, false, true, true);
+ } else if (this.match(tt._class)) {
+ expr = this.parseClass(expr, true, true);
+ } else {
+ needsSemi = true;
+ expr = this.parseMaybeAssign();
+ }
+ node.declaration = expr;
+ if (needsSemi) this.semicolon();
+ this.checkExport(node, true, true);
+ return this.finishNode(node, "ExportDefaultDeclaration");
+ } else if (this.shouldParseExportDeclaration()) {
+ node.specifiers = [];
+ node.source = null;
+ node.declaration = this.parseExportDeclaration(node);
+ } else { // export { x, y as z } [from '...']
+ node.declaration = null;
+ node.specifiers = this.parseExportSpecifiers();
+ this.parseExportFrom(node);
+ }
+ this.checkExport(node, true);
+ return this.finishNode(node, "ExportNamedDeclaration");
+ };
+
+ pp.parseExportDeclaration = function () {
+ return this.parseStatement(true);
+ };
+
+ pp.isExportDefaultSpecifier = function () {
+ if (this.match(tt.name)) {
+ return this.state.value !== "type"
+ && this.state.value !== "async"
+ && this.state.value !== "interface";
+ }
+
+ if (!this.match(tt._default)) {
+ return false;
+ }
+
+ const lookahead = this.lookahead();
+ return lookahead.type === tt.comma || (lookahead.type === tt.name && lookahead.value === "from");
+ };
+
+ pp.parseExportSpecifiersMaybe = function (node) {
+ if (this.eat(tt.comma)) {
+ node.specifiers = node.specifiers.concat(this.parseExportSpecifiers());
+ }
+ };
+
+ pp.parseExportFrom = function (node, expect) {
+ if (this.eatContextual("from")) {
+ node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected();
+ this.checkExport(node);
+ } else {
+ if (expect) {
+ this.unexpected();
+ } else {
+ node.source = null;
+ }
+ }
+
+ this.semicolon();
+ };
+
+ pp.shouldParseExportDeclaration = function () {
+ return this.state.type.keyword === "var"
+ || this.state.type.keyword === "const"
+ || this.state.type.keyword === "let"
+ || this.state.type.keyword === "function"
+ || this.state.type.keyword === "class"
+ || this.isContextual("async");
+ };
+
+ pp.checkExport = function (node, checkNames, isDefault) {
+ if (checkNames) {
+ // Check for duplicate exports
+ if (isDefault) {
+ // Default exports
+ this.checkDuplicateExports(node, "default");
+ } else if (node.specifiers && node.specifiers.length) {
+ // Named exports
+ for (const specifier of node.specifiers) {
+ this.checkDuplicateExports(specifier, specifier.exported.name);
+ }
+ } else if (node.declaration) {
+ // Exported declarations
+ if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") {
+ this.checkDuplicateExports(node, node.declaration.id.name);
+ } else if (node.declaration.type === "VariableDeclaration") {
+ for (const declaration of node.declaration.declarations) {
+ this.checkDeclaration(declaration.id);
+ }
+ }
+ }
+ }
+
+ if (this.state.decorators.length) {
+ const isClass = node.declaration && (node.declaration.type === "ClassDeclaration" || node.declaration.type === "ClassExpression");
+ if (!node.declaration || !isClass) {
+ this.raise(node.start, "You can only use decorators on an export when exporting a class");
+ }
+ this.takeDecorators(node.declaration);
+ }
+ };
+
+ pp.checkDeclaration = function(node) {
+ if (node.type === "ObjectPattern") {
+ for (const prop of node.properties) {
+ this.checkDeclaration(prop);
+ }
+ } else if (node.type === "ArrayPattern") {
+ for (const elem of node.elements) {
+ if (elem) {
+ this.checkDeclaration(elem);
+ }
+ }
+ } else if (node.type === "ObjectProperty") {
+ this.checkDeclaration(node.value);
+ } else if (node.type === "RestElement") {
+ this.checkDeclaration(node.argument);
+ } else if (node.type === "Identifier") {
+ this.checkDuplicateExports(node, node.name);
+ }
+ };
+
+ pp.checkDuplicateExports = function(node, name) {
+ if (this.state.exportedIdentifiers.indexOf(name) > -1) {
+ this.raiseDuplicateExportError(node, name);
+ }
+ this.state.exportedIdentifiers.push(name);
+ };
+
+ pp.raiseDuplicateExportError = function(node, name) {
+ this.raise(node.start, name === "default" ?
+ "Only one default export allowed per module." :
+ `\`${name}\` has already been exported. Exported identifiers must be unique.`
+ );
+ };
+
+ // Parses a comma-separated list of module exports.
+
+ pp.parseExportSpecifiers = function () {
+ const nodes = [];
+ let first = true;
+ let needsFrom;
+
+ // export { x, y as z } [from '...']
+ this.expect(tt.braceL);
+
+ while (!this.eat(tt.braceR)) {
+ if (first) {
+ first = false;
+ } else {
+ this.expect(tt.comma);
+ if (this.eat(tt.braceR)) break;
+ }
+
+ const isDefault = this.match(tt._default);
+ if (isDefault && !needsFrom) needsFrom = true;
+
+ const node = this.startNode();
+ node.local = this.parseIdentifier(isDefault);
+ node.exported = this.eatContextual("as") ? this.parseIdentifier(true) : node.local.__clone();
+ nodes.push(this.finishNode(node, "ExportSpecifier"));
+ }
+
+ // https://github.com/ember-cli/ember-cli/pull/3739
+ if (needsFrom && !this.isContextual("from")) {
+ this.unexpected();
+ }
+
+ return nodes;
+ };
+
+ // Parses import declaration.
+
+ pp.parseImport = function (node) {
+ this.eat(tt._import);
+
+ // import '...'
+ if (this.match(tt.string)) {
+ node.specifiers = [];
+ node.source = this.parseExprAtom();
+ } else {
+ node.specifiers = [];
+ this.parseImportSpecifiers(node);
+ this.expectContextual("from");
+ node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected();
+ }
+ this.semicolon();
+ return this.finishNode(node, "ImportDeclaration");
+ };
+
+ // Parses a comma-separated list of module imports.
+
+ pp.parseImportSpecifiers = function (node) {
+ let first = true;
+ if (this.match(tt.name)) {
+ // import defaultObj, { x, y as z } from '...'
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ node.specifiers.push(this.parseImportSpecifierDefault(this.parseIdentifier(), startPos, startLoc));
+ if (!this.eat(tt.comma)) return;
+ }
+
+ if (this.match(tt.star)) {
+ const specifier = this.startNode();
+ this.next();
+ this.expectContextual("as");
+ specifier.local = this.parseIdentifier();
+ this.checkLVal(specifier.local, true, undefined, "import namespace specifier");
+ node.specifiers.push(this.finishNode(specifier, "ImportNamespaceSpecifier"));
+ return;
+ }
+
+ this.expect(tt.braceL);
+ while (!this.eat(tt.braceR)) {
+ if (first) {
+ first = false;
+ } else {
+ // Detect an attempt to deep destructure
+ if (this.eat(tt.colon)) {
+ this.unexpected(null, "ES2015 named imports do not destructure. Use another statement for destructuring after the import.");
+ }
+
+ this.expect(tt.comma);
+ if (this.eat(tt.braceR)) break;
+ }
+
+ this.parseImportSpecifier(node);
+ }
+ };
+
+ pp.parseImportSpecifier = function (node) {
+ const specifier = this.startNode();
+ specifier.imported = this.parseIdentifier(true);
+ if (this.eatContextual("as")) {
+ specifier.local = this.parseIdentifier();
+ } else {
+ this.checkReservedWord(specifier.imported.name, specifier.start, true, true);
+ specifier.local = specifier.imported.__clone();
+ }
+ this.checkLVal(specifier.local, true, undefined, "import specifier");
+ node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
+ };
+
+ pp.parseImportSpecifierDefault = function (id, startPos, startLoc) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.local = id;
+ this.checkLVal(node.local, true, undefined, "default import specifier");
+ return this.finishNode(node, "ImportDefaultSpecifier");
+ };
+}
+
+// parser/util.js
+const parserUtilJS = {};
+{
+ const { types : tt } = tokenizerTypesJS;
+ const Parser = parserIndexJS;
+ const { lineBreak } = utilWhitespaceJS;
+
+ const pp = Parser.prototype;
+
+ // ## Parser utilities
+
+ // TODO
+
+ pp.addExtra = function (node, key, val) {
+ if (!node) return;
+
+ const extra = node.extra = node.extra || {};
+ extra[key] = val;
+ };
+
+ // TODO
+
+ pp.isRelational = function (op) {
+ return this.match(tt.relational) && this.state.value === op;
+ };
+
+ // TODO
+
+ pp.expectRelational = function (op) {
+ if (this.isRelational(op)) {
+ this.next();
+ } else {
+ this.unexpected(null, tt.relational);
+ }
+ };
+
+ // Tests whether parsed token is a contextual keyword.
+
+ pp.isContextual = function (name) {
+ return this.match(tt.name) && this.state.value === name;
+ };
+
+ // Consumes contextual keyword if possible.
+
+ pp.eatContextual = function (name) {
+ return this.state.value === name && this.eat(tt.name);
+ };
+
+ // Asserts that following token is given contextual keyword.
+
+ pp.expectContextual = function (name, message) {
+ if (!this.eatContextual(name)) this.unexpected(null, message);
+ };
+
+ // Test whether a semicolon can be inserted at the current position.
+
+ pp.canInsertSemicolon = function () {
+ return this.match(tt.eof) ||
+ this.match(tt.braceR) ||
+ lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start));
+ };
+
+ // TODO
+
+ pp.isLineTerminator = function () {
+ return this.eat(tt.semi) || this.canInsertSemicolon();
+ };
+
+ // 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.isLineTerminator()) this.unexpected(null, tt.semi);
+ };
+
+ // Expect a token of a given type. If found, consume it, otherwise,
+ // raise an unexpected token error at given pos.
+
+ pp.expect = function (type, pos) {
+ return this.eat(type) || this.unexpected(pos, type);
+ };
+
+ // Raise an unexpected token error. Can take the expected token type
+ // instead of a message string.
+
+ pp.unexpected = function (pos, messageOrType = "Unexpected token") {
+ if (messageOrType && typeof messageOrType === "object" && messageOrType.label) {
+ messageOrType = `Unexpected token, expected ${messageOrType.label}`;
+ }
+ this.raise(pos != null ? pos : this.state.start, messageOrType);
+ };
+}
+
+
+// plugins/estree.js
+let pluginsEstreeJS = {};
+{
+ const { types : tt } = tokenizerTypesJS;
+ const Parser = parserIndexJS;
+
+ const pp = Parser.prototype;
+
+ pp.estreeParseRegExpLiteral = function ({ pattern, flags }) {
+ let regex = null;
+ try {
+ regex = new RegExp(pattern, flags);
+ } catch (e) {
+ // In environments that don't support these flags value will
+ // be null as the regex can't be represented natively.
+ }
+ const node = this.estreeParseLiteral(regex);
+ node.regex = { pattern, flags };
+
+ return node;
+ };
+
+ pp.estreeParseLiteral = function (value) {
+ return this.parseLiteral(value, "Literal");
+ };
+
+ pp.directiveToStmt = function (directive) {
+ const directiveLiteral = directive.value;
+
+ const stmt = this.startNodeAt(directive.start, directive.loc.start);
+ const expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start);
+
+ expression.value = directiveLiteral.value;
+ expression.raw = directiveLiteral.extra.raw;
+
+ stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end);
+ stmt.directive = directiveLiteral.extra.raw.slice(1, -1);
+
+ return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end);
+ };
+
+ function isSimpleProperty(node) {
+ return node &&
+ node.type === "Property" &&
+ node.kind === "init" &&
+ node.method === false;
+ }
+
+ //export default function (instance) {
+
+ pluginsEstreeJS = function (instance) {
+ instance.extend("checkDeclaration", function(inner) {
+ return function (node) {
+ if (isSimpleProperty(node)) {
+ this.checkDeclaration(node.value);
+ } else {
+ inner.call(this, node);
+ }
+ };
+ });
+
+ instance.extend("checkGetterSetterParamCount", function() {
+ return function (prop) {
+ const paramCount = prop.kind === "get" ? 0 : 1;
+ if (prop.value.params.length !== paramCount) {
+ const start = prop.start;
+ if (prop.kind === "get") {
+ this.raise(start, "getter should have no params");
+ } else {
+ this.raise(start, "setter should have exactly one param");
+ }
+ }
+ };
+ });
+
+ instance.extend("checkLVal", function(inner) {
+ return function (expr, isBinding, checkClashes, ...args) {
+ switch (expr.type) {
+ case "ObjectPattern":
+ expr.properties.forEach((prop) => {
+ this.checkLVal(
+ prop.type === "Property" ? prop.value : prop,
+ isBinding,
+ checkClashes,
+ "object destructuring pattern"
+ );
+ });
+ break;
+ default:
+ inner.call(this, expr, isBinding, checkClashes, ...args);
+ }
+ };
+ });
+
+ instance.extend("checkPropClash", function () {
+ return function (prop, propHash) {
+ if (prop.computed || !isSimpleProperty(prop)) return;
+
+ const key = prop.key;
+ // It is either an Identifier or a String/NumericLiteral
+ const name = key.type === "Identifier" ? key.name : String(key.value);
+
+ if (name === "__proto__") {
+ if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
+ propHash.proto = true;
+ }
+ };
+ });
+
+ instance.extend("isStrictBody", function () {
+ return function (node, isExpression) {
+ if (!isExpression && node.body.body.length > 0) {
+ for (const directive of (node.body.body)) {
+ if (directive.type === "ExpressionStatement" && directive.expression.type === "Literal") {
+ if (directive.expression.value === "use strict") return true;
+ } else {
+ // Break for the first non literal expression
+ break;
+ }
+ }
+ }
+
+ return false;
+ };
+ });
+
+ instance.extend("isValidDirective", function () {
+ return function (stmt) {
+ return stmt.type === "ExpressionStatement" &&
+ stmt.expression.type === "Literal" &&
+ typeof stmt.expression.value === "string" &&
+ (!stmt.expression.extra || !stmt.expression.extra.parenthesized);
+ };
+ });
+
+ instance.extend("parseBlockBody", function (inner) {
+ return function (node, ...args) {
+ inner.call(this, node, ...args);
+
+ node.directives.reverse().forEach((directive) => {
+ node.body.unshift(this.directiveToStmt(directive));
+ });
+ delete node.directives;
+ };
+ });
+
+ instance.extend("parseClassMethod", function (inner) {
+ return function (classBody, ...args) {
+ inner.call(this, classBody, ...args);
+
+ const body = classBody.body;
+ body[body.length - 1].type = "MethodDefinition";
+ };
+ });
+
+ instance.extend("parseExprAtom", function(inner) {
+ return function (...args) {
+ switch (this.state.type) {
+ case tt.regexp:
+ return this.estreeParseRegExpLiteral(this.state.value);
+
+ case tt.num:
+ case tt.string:
+ return this.estreeParseLiteral(this.state.value);
+
+ case tt._null:
+ return this.estreeParseLiteral(null);
+
+ case tt._true:
+ return this.estreeParseLiteral(true);
+
+ case tt._false:
+ return this.estreeParseLiteral(false);
+
+ default:
+ return inner.call(this, ...args);
+ }
+ };
+ });
+
+ instance.extend("parseLiteral", function(inner) {
+ return function (...args) {
+ const node = inner.call(this, ...args);
+ node.raw = node.extra.raw;
+ delete node.extra;
+
+ return node;
+ };
+ });
+
+ instance.extend("parseMethod", function(inner) {
+ return function (node, ...args) {
+ let funcNode = this.startNode();
+ funcNode.kind = node.kind; // provide kind, so inner method correctly sets state
+ funcNode = inner.call(this, funcNode, ...args);
+ delete funcNode.kind;
+ node.value = this.finishNode(funcNode, "FunctionExpression");
+
+ return node;
+ };
+ });
+
+ instance.extend("parseObjectMethod", function(inner) {
+ return function (...args) {
+ const node = inner.call(this, ...args);
+
+ if (node) {
+ if (node.kind === "method") node.kind = "init";
+ node.type = "Property";
+ }
+
+ return node;
+ };
+ });
+
+ instance.extend("parseObjectProperty", function(inner) {
+ return function (...args) {
+ const node = inner.call(this, ...args);
+
+ if (node) {
+ node.kind = "init";
+ node.type = "Property";
+ }
+
+ return node;
+ };
+ });
+
+ instance.extend("toAssignable", function(inner) {
+ return function (node, isBinding, ...args) {
+ if (isSimpleProperty(node)) {
+ this.toAssignable(node.value, isBinding, ...args);
+
+ return node;
+ } else if (node.type === "ObjectExpression") {
+ node.type = "ObjectPattern";
+ for (const prop of (node.properties)) {
+ if (prop.kind === "get" || prop.kind === "set") {
+ this.raise(prop.key.start, "Object pattern can't contain getter or setter");
+ } else if (prop.method) {
+ this.raise(prop.key.start, "Object pattern can't contain methods");
+ } else {
+ this.toAssignable(prop, isBinding, "object destructuring pattern");
+ }
+ }
+
+ return node;
+ }
+
+ return inner.call(this, node, isBinding, ...args);
+ };
+ });
+ }
+}
+
+
+// plugins/flow.js
+let pluginsFlowJS = {};
+{
+
+ /* eslint max-len: 0 */
+
+ const { types : tt } = tokenizerTypesJS;
+ const { types : ct } = tokenizerContextJS;
+ const Parser = parserIndexJS;
+
+ const primitiveTypes = [
+ "any",
+ "mixed",
+ "empty",
+ "bool",
+ "boolean",
+ "number",
+ "string",
+ "void",
+ "null"
+ ];
+
+ const pp = Parser.prototype;
+
+ pp.flowParseTypeInitialiser = function (tok) {
+ const oldInType = this.state.inType;
+ this.state.inType = true;
+ this.expect(tok || tt.colon);
+
+ const type = this.flowParseType();
+ this.state.inType = oldInType;
+ return type;
+ };
+
+ pp.flowParsePredicate = function() {
+ const node = this.startNode();
+ const moduloLoc = this.state.startLoc;
+ const moduloPos = this.state.start;
+ this.expect(tt.modulo);
+ const checksLoc = this.state.startLoc;
+ this.expectContextual("checks");
+ // Force '%' and 'checks' to be adjacent
+ if (moduloLoc.line !== checksLoc.line || moduloLoc.column !== checksLoc.column - 1) {
+ this.raise(moduloPos, "Spaces between ´%´ and ´checks´ are not allowed here.");
+ }
+ if (this.eat(tt.parenL)) {
+ node.expression = this.parseExpression();
+ this.expect(tt.parenR);
+ return this.finishNode(node, "DeclaredPredicate");
+ } else {
+ return this.finishNode(node, "InferredPredicate");
+ }
+ };
+
+ pp.flowParseTypeAndPredicateInitialiser = function () {
+ const oldInType = this.state.inType;
+ this.state.inType = true;
+ this.expect(tt.colon);
+ let type = null;
+ let predicate = null;
+ if (this.match(tt.modulo)) {
+ this.state.inType = oldInType;
+ predicate = this.flowParsePredicate();
+ } else {
+ type = this.flowParseType();
+ this.state.inType = oldInType;
+ if (this.match(tt.modulo)) {
+ predicate = this.flowParsePredicate();
+ }
+ }
+ return [type, predicate];
+ };
+
+ pp.flowParseDeclareClass = function (node) {
+ this.next();
+ this.flowParseInterfaceish(node, true);
+ return this.finishNode(node, "DeclareClass");
+ };
+
+ pp.flowParseDeclareFunction = function (node) {
+ this.next();
+
+ const id = node.id = this.parseIdentifier();
+
+ const typeNode = this.startNode();
+ const typeContainer = this.startNode();
+
+ if (this.isRelational("<")) {
+ typeNode.typeParameters = this.flowParseTypeParameterDeclaration();
+ } else {
+ typeNode.typeParameters = null;
+ }
+
+ this.expect(tt.parenL);
+ const tmp = this.flowParseFunctionTypeParams();
+ typeNode.params = tmp.params;
+ typeNode.rest = tmp.rest;
+ this.expect(tt.parenR);
+ let predicate = null;
+ [typeNode.returnType, predicate] = this.flowParseTypeAndPredicateInitialiser();
+ typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation");
+ typeContainer.predicate = predicate;
+ id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation");
+
+ this.finishNode(id, id.type);
+
+ this.semicolon();
+
+ return this.finishNode(node, "DeclareFunction");
+ };
+
+ pp.flowParseDeclare = function (node) {
+ if (this.match(tt._class)) {
+ return this.flowParseDeclareClass(node);
+ } else if (this.match(tt._function)) {
+ return this.flowParseDeclareFunction(node);
+ } else if (this.match(tt._var)) {
+ return this.flowParseDeclareVariable(node);
+ } else if (this.isContextual("module")) {
+ if (this.lookahead().type === tt.dot) {
+ return this.flowParseDeclareModuleExports(node);
+ } else {
+ return this.flowParseDeclareModule(node);
+ }
+ } else if (this.isContextual("type")) {
+ return this.flowParseDeclareTypeAlias(node);
+ } else if (this.isContextual("interface")) {
+ return this.flowParseDeclareInterface(node);
+ } else {
+ this.unexpected();
+ }
+ };
+
+ pp.flowParseDeclareVariable = function (node) {
+ this.next();
+ node.id = this.flowParseTypeAnnotatableIdentifier();
+ this.semicolon();
+ return this.finishNode(node, "DeclareVariable");
+ };
+
+ pp.flowParseDeclareModule = function (node) {
+ this.next();
+
+ if (this.match(tt.string)) {
+ node.id = this.parseExprAtom();
+ } else {
+ node.id = this.parseIdentifier();
+ }
+
+ const bodyNode = node.body = this.startNode();
+ const body = bodyNode.body = [];
+ this.expect(tt.braceL);
+ while (!this.match(tt.braceR)) {
+ let bodyNode = this.startNode();
+
+ if (this.match(tt._import)) {
+ const lookahead = this.lookahead();
+ if (lookahead.value !== "type" && lookahead.value !== "typeof") {
+ this.unexpected(null, "Imports within a `declare module` body must always be `import type` or `import typeof`");
+ }
+
+ this.parseImport(bodyNode);
+ } else {
+ this.expectContextual("declare", "Only declares and type imports are allowed inside declare module");
+
+ bodyNode = this.flowParseDeclare(bodyNode, true);
+ }
+
+ body.push(bodyNode);
+ }
+ this.expect(tt.braceR);
+
+ this.finishNode(bodyNode, "BlockStatement");
+ return this.finishNode(node, "DeclareModule");
+ };
+
+ pp.flowParseDeclareModuleExports = function (node) {
+ this.expectContextual("module");
+ this.expect(tt.dot);
+ this.expectContextual("exports");
+ node.typeAnnotation = this.flowParseTypeAnnotation();
+ this.semicolon();
+
+ return this.finishNode(node, "DeclareModuleExports");
+ };
+
+ pp.flowParseDeclareTypeAlias = function (node) {
+ this.next();
+ this.flowParseTypeAlias(node);
+ return this.finishNode(node, "DeclareTypeAlias");
+ };
+
+ pp.flowParseDeclareInterface = function (node) {
+ this.next();
+ this.flowParseInterfaceish(node);
+ return this.finishNode(node, "DeclareInterface");
+ };
+
+ // Interfaces
+
+ pp.flowParseInterfaceish = function (node, allowStatic) {
+ node.id = this.parseIdentifier();
+
+ if (this.isRelational("<")) {
+ node.typeParameters = this.flowParseTypeParameterDeclaration();
+ } else {
+ node.typeParameters = null;
+ }
+
+ node.extends = [];
+ node.mixins = [];
+
+ if (this.eat(tt._extends)) {
+ do {
+ node.extends.push(this.flowParseInterfaceExtends());
+ } while (this.eat(tt.comma));
+ }
+
+ if (this.isContextual("mixins")) {
+ this.next();
+ do {
+ node.mixins.push(this.flowParseInterfaceExtends());
+ } while (this.eat(tt.comma));
+ }
+
+ node.body = this.flowParseObjectType(allowStatic);
+ };
+
+ pp.flowParseInterfaceExtends = function () {
+ const node = this.startNode();
+
+ node.id = this.flowParseQualifiedTypeIdentifier();
+ if (this.isRelational("<")) {
+ node.typeParameters = this.flowParseTypeParameterInstantiation();
+ } else {
+ node.typeParameters = null;
+ }
+
+ return this.finishNode(node, "InterfaceExtends");
+ };
+
+ pp.flowParseInterface = function (node) {
+ this.flowParseInterfaceish(node, false);
+ return this.finishNode(node, "InterfaceDeclaration");
+ };
+
+ pp.flowParseRestrictedIdentifier = function(liberal) {
+ if (primitiveTypes.indexOf(this.state.value) > -1) {
+ this.raise(this.state.start, `Cannot overwrite primitive type ${this.state.value}`);
+ }
+
+ return this.parseIdentifier(liberal);
+ };
+
+ // Type aliases
+
+ pp.flowParseTypeAlias = function (node) {
+ node.id = this.flowParseRestrictedIdentifier();
+
+ if (this.isRelational("<")) {
+ node.typeParameters = this.flowParseTypeParameterDeclaration();
+ } else {
+ node.typeParameters = null;
+ }
+
+ node.right = this.flowParseTypeInitialiser(tt.eq);
+ this.semicolon();
+
+ return this.finishNode(node, "TypeAlias");
+ };
+
+ // Type annotations
+
+ pp.flowParseTypeParameter = function () {
+ const node = this.startNode();
+
+ const variance = this.flowParseVariance();
+
+ const ident = this.flowParseTypeAnnotatableIdentifier();
+ node.name = ident.name;
+ node.variance = variance;
+ node.bound = ident.typeAnnotation;
+
+ if (this.match(tt.eq)) {
+ this.eat(tt.eq);
+ node.default = this.flowParseType();
+ }
+
+ return this.finishNode(node, "TypeParameter");
+ };
+
+ pp.flowParseTypeParameterDeclaration = function () {
+ const oldInType = this.state.inType;
+ const node = this.startNode();
+ node.params = [];
+
+ this.state.inType = true;
+
+ // istanbul ignore else: this condition is already checked at all call sites
+ if (this.isRelational("<") || this.match(tt.jsxTagStart)) {
+ this.next();
+ } else {
+ this.unexpected();
+ }
+
+ do {
+ node.params.push(this.flowParseTypeParameter());
+ if (!this.isRelational(">")) {
+ this.expect(tt.comma);
+ }
+ } while (!this.isRelational(">"));
+ this.expectRelational(">");
+
+ this.state.inType = oldInType;
+
+ return this.finishNode(node, "TypeParameterDeclaration");
+ };
+
+ pp.flowParseTypeParameterInstantiation = function () {
+ const node = this.startNode();
+ const oldInType = this.state.inType;
+ node.params = [];
+
+ this.state.inType = true;
+
+ this.expectRelational("<");
+ while (!this.isRelational(">")) {
+ node.params.push(this.flowParseType());
+ if (!this.isRelational(">")) {
+ this.expect(tt.comma);
+ }
+ }
+ this.expectRelational(">");
+
+ this.state.inType = oldInType;
+
+ return this.finishNode(node, "TypeParameterInstantiation");
+ };
+
+ pp.flowParseObjectPropertyKey = function () {
+ return (this.match(tt.num) || this.match(tt.string)) ? this.parseExprAtom() : this.parseIdentifier(true);
+ };
+
+ pp.flowParseObjectTypeIndexer = function (node, isStatic, variance) {
+ node.static = isStatic;
+
+ this.expect(tt.bracketL);
+ if (this.lookahead().type === tt.colon) {
+ node.id = this.flowParseObjectPropertyKey();
+ node.key = this.flowParseTypeInitialiser();
+ } else {
+ node.id = null;
+ node.key = this.flowParseType();
+ }
+ this.expect(tt.bracketR);
+ node.value = this.flowParseTypeInitialiser();
+ node.variance = variance;
+
+ // Finish node first to not include a possible semicolon in the locations
+ const indexer = this.finishNode(node, "ObjectTypeIndexer");
+ this.flowObjectTypeSemicolon();
+
+ return indexer;
+ };
+
+ pp.flowParseObjectTypeMethodish = function (node) {
+ node.params = [];
+ node.rest = null;
+ node.typeParameters = null;
+
+ if (this.isRelational("<")) {
+ node.typeParameters = this.flowParseTypeParameterDeclaration();
+ }
+
+ this.expect(tt.parenL);
+ while (this.match(tt.name)) {
+ node.params.push(this.flowParseFunctionTypeParam());
+ if (!this.match(tt.parenR)) {
+ this.expect(tt.comma);
+ }
+ }
+
+ if (this.eat(tt.ellipsis)) {
+ node.rest = this.flowParseFunctionTypeParam();
+ }
+ this.expect(tt.parenR);
+ node.returnType = this.flowParseTypeInitialiser();
+
+ return this.finishNode(node, "FunctionTypeAnnotation");
+ };
+
+ pp.flowParseObjectTypeMethod = function (startPos, startLoc, isStatic, key) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(startPos, startLoc));
+ node.static = isStatic;
+ node.key = key;
+ node.optional = false;
+ this.flowObjectTypeSemicolon();
+ return this.finishNode(node, "ObjectTypeProperty");
+ };
+
+ pp.flowParseObjectTypeCallProperty = function (node, isStatic) {
+ const valueNode = this.startNode();
+ node.static = isStatic;
+ node.value = this.flowParseObjectTypeMethodish(valueNode);
+ this.flowObjectTypeSemicolon();
+ return this.finishNode(node, "ObjectTypeCallProperty");
+ };
+
+ pp.flowParseObjectType = function (allowStatic, allowExact) {
+ const oldInType = this.state.inType;
+ this.state.inType = true;
+
+ const nodeStart = this.startNode();
+ let node;
+ let propertyKey;
+ let isStatic = false;
+
+ nodeStart.callProperties = [];
+ nodeStart.properties = [];
+ nodeStart.indexers = [];
+
+ let endDelim;
+ let exact;
+ if (allowExact && this.match(tt.braceBarL)) {
+ this.expect(tt.braceBarL);
+ endDelim = tt.braceBarR;
+ exact = true;
+ } else {
+ this.expect(tt.braceL);
+ endDelim = tt.braceR;
+ exact = false;
+ }
+
+ nodeStart.exact = exact;
+
+ while (!this.match(endDelim)) {
+ let optional = false;
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ node = this.startNode();
+ if (allowStatic && this.isContextual("static") && this.lookahead().type !== tt.colon) {
+ this.next();
+ isStatic = true;
+ }
+
+ const variance = this.flowParseVariance();
+
+ if (this.match(tt.bracketL)) {
+ nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance));
+ } else if (this.match(tt.parenL) || this.isRelational("<")) {
+ if (variance) {
+ this.unexpected(variance.start);
+ }
+ nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic));
+ } else {
+ propertyKey = this.flowParseObjectPropertyKey();
+ if (this.isRelational("<") || this.match(tt.parenL)) {
+ // This is a method property
+ if (variance) {
+ this.unexpected(variance.start);
+ }
+ nodeStart.properties.push(this.flowParseObjectTypeMethod(startPos, startLoc, isStatic, propertyKey));
+ } else {
+ if (this.eat(tt.question)) {
+ optional = true;
+ }
+ node.key = propertyKey;
+ node.value = this.flowParseTypeInitialiser();
+ node.optional = optional;
+ node.static = isStatic;
+ node.variance = variance;
+ this.flowObjectTypeSemicolon();
+ nodeStart.properties.push(this.finishNode(node, "ObjectTypeProperty"));
+ }
+ }
+
+ isStatic = false;
+ }
+
+ this.expect(endDelim);
+
+ const out = this.finishNode(nodeStart, "ObjectTypeAnnotation");
+
+ this.state.inType = oldInType;
+
+ return out;
+ };
+
+ pp.flowObjectTypeSemicolon = function () {
+ if (!this.eat(tt.semi) && !this.eat(tt.comma) &&
+ !this.match(tt.braceR) && !this.match(tt.braceBarR)) {
+ this.unexpected();
+ }
+ };
+
+ pp.flowParseQualifiedTypeIdentifier = function (startPos, startLoc, id) {
+ startPos = startPos || this.state.start;
+ startLoc = startLoc || this.state.startLoc;
+ let node = id || this.parseIdentifier();
+
+ while (this.eat(tt.dot)) {
+ const node2 = this.startNodeAt(startPos, startLoc);
+ node2.qualification = node;
+ node2.id = this.parseIdentifier();
+ node = this.finishNode(node2, "QualifiedTypeIdentifier");
+ }
+
+ return node;
+ };
+
+ pp.flowParseGenericType = function (startPos, startLoc, id) {
+ const node = this.startNodeAt(startPos, startLoc);
+
+ node.typeParameters = null;
+ node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id);
+
+ if (this.isRelational("<")) {
+ node.typeParameters = this.flowParseTypeParameterInstantiation();
+ }
+
+ return this.finishNode(node, "GenericTypeAnnotation");
+ };
+
+ pp.flowParseTypeofType = function () {
+ const node = this.startNode();
+ this.expect(tt._typeof);
+ node.argument = this.flowParsePrimaryType();
+ return this.finishNode(node, "TypeofTypeAnnotation");
+ };
+
+ pp.flowParseTupleType = function () {
+ const node = this.startNode();
+ node.types = [];
+ this.expect(tt.bracketL);
+ // We allow trailing commas
+ while (this.state.pos < this.input.length && !this.match(tt.bracketR)) {
+ node.types.push(this.flowParseType());
+ if (this.match(tt.bracketR)) break;
+ this.expect(tt.comma);
+ }
+ this.expect(tt.bracketR);
+ return this.finishNode(node, "TupleTypeAnnotation");
+ };
+
+ pp.flowParseFunctionTypeParam = function () {
+ let name = null;
+ let optional = false;
+ let typeAnnotation = null;
+ const node = this.startNode();
+ const lh = this.lookahead();
+ if (lh.type === tt.colon ||
+ lh.type === tt.question) {
+ name = this.parseIdentifier();
+ if (this.eat(tt.question)) {
+ optional = true;
+ }
+ typeAnnotation = this.flowParseTypeInitialiser();
+ } else {
+ typeAnnotation = this.flowParseType();
+ }
+ node.name = name;
+ node.optional = optional;
+ node.typeAnnotation = typeAnnotation;
+ return this.finishNode(node, "FunctionTypeParam");
+ };
+
+ pp.reinterpretTypeAsFunctionTypeParam = function (type) {
+ const node = this.startNodeAt(type.start, type.loc);
+ node.name = null;
+ node.optional = false;
+ node.typeAnnotation = type;
+ return this.finishNode(node, "FunctionTypeParam");
+ };
+
+ pp.flowParseFunctionTypeParams = function (params = []) {
+ const ret = { params, rest: null };
+ while (!this.match(tt.parenR) && !this.match(tt.ellipsis)) {
+ ret.params.push(this.flowParseFunctionTypeParam());
+ if (!this.match(tt.parenR)) {
+ this.expect(tt.comma);
+ }
+ }
+ if (this.eat(tt.ellipsis)) {
+ ret.rest = this.flowParseFunctionTypeParam();
+ }
+ return ret;
+ };
+
+ pp.flowIdentToTypeAnnotation = function (startPos, startLoc, node, id) {
+ switch (id.name) {
+ case "any":
+ return this.finishNode(node, "AnyTypeAnnotation");
+
+ case "void":
+ return this.finishNode(node, "VoidTypeAnnotation");
+
+ case "bool":
+ case "boolean":
+ return this.finishNode(node, "BooleanTypeAnnotation");
+
+ case "mixed":
+ return this.finishNode(node, "MixedTypeAnnotation");
+
+ case "empty":
+ return this.finishNode(node, "EmptyTypeAnnotation");
+
+ case "number":
+ return this.finishNode(node, "NumberTypeAnnotation");
+
+ case "string":
+ return this.finishNode(node, "StringTypeAnnotation");
+
+ default:
+ return this.flowParseGenericType(startPos, startLoc, id);
+ }
+ };
+
+ // The parsing of types roughly parallels the parsing of expressions, and
+ // primary types are kind of like primary expressions...they're the
+ // primitives with which other types are constructed.
+ pp.flowParsePrimaryType = function () {
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ const node = this.startNode();
+ let tmp;
+ let type;
+ let isGroupedType = false;
+ const oldNoAnonFunctionType = this.state.noAnonFunctionType;
+
+ switch (this.state.type) {
+ case tt.name:
+ return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier());
+
+ case tt.braceL:
+ return this.flowParseObjectType(false, false);
+
+ case tt.braceBarL:
+ return this.flowParseObjectType(false, true);
+
+ case tt.bracketL:
+ return this.flowParseTupleType();
+
+ case tt.relational:
+ if (this.state.value === "<") {
+ node.typeParameters = this.flowParseTypeParameterDeclaration();
+ this.expect(tt.parenL);
+ tmp = this.flowParseFunctionTypeParams();
+ node.params = tmp.params;
+ node.rest = tmp.rest;
+ this.expect(tt.parenR);
+
+ this.expect(tt.arrow);
+
+ node.returnType = this.flowParseType();
+
+ return this.finishNode(node, "FunctionTypeAnnotation");
+ }
+ break;
+
+ case tt.parenL:
+ this.next();
+
+ // Check to see if this is actually a grouped type
+ if (!this.match(tt.parenR) && !this.match(tt.ellipsis)) {
+ if (this.match(tt.name)) {
+ const token = this.lookahead().type;
+ isGroupedType = token !== tt.question && token !== tt.colon;
+ } else {
+ isGroupedType = true;
+ }
+ }
+
+ if (isGroupedType) {
+ this.state.noAnonFunctionType = false;
+ type = this.flowParseType();
+ this.state.noAnonFunctionType = oldNoAnonFunctionType;
+
+ // A `,` or a `) =>` means this is an anonymous function type
+ if (this.state.noAnonFunctionType ||
+ !(this.match(tt.comma) ||
+ (this.match(tt.parenR) && this.lookahead().type === tt.arrow))) {
+ this.expect(tt.parenR);
+ return type;
+ } else {
+ // Eat a comma if there is one
+ this.eat(tt.comma);
+ }
+ }
+
+ if (type) {
+ tmp = this.flowParseFunctionTypeParams(
+ [this.reinterpretTypeAsFunctionTypeParam(type)],
+ );
+ } else {
+ tmp = this.flowParseFunctionTypeParams();
+ }
+
+ node.params = tmp.params;
+ node.rest = tmp.rest;
+
+ this.expect(tt.parenR);
+
+ this.expect(tt.arrow);
+
+ node.returnType = this.flowParseType();
+
+ node.typeParameters = null;
+
+ return this.finishNode(node, "FunctionTypeAnnotation");
+
+ case tt.string:
+ return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation");
+
+ case tt._true: case tt._false:
+ node.value = this.match(tt._true);
+ this.next();
+ return this.finishNode(node, "BooleanLiteralTypeAnnotation");
+
+ case tt.plusMin:
+ if (this.state.value === "-") {
+ this.next();
+ if (!this.match(tt.num)) this.unexpected(null, "Unexpected token, expected number");
+
+ return this.parseLiteral(-this.state.value, "NumberLiteralTypeAnnotation", node.start, node.loc.start);
+ }
+
+ this.unexpected();
+ case tt.num:
+ return this.parseLiteral(this.state.value, "NumberLiteralTypeAnnotation");
+
+ case tt._null:
+ node.value = this.match(tt._null);
+ this.next();
+ return this.finishNode(node, "NullLiteralTypeAnnotation");
+
+ case tt._this:
+ node.value = this.match(tt._this);
+ this.next();
+ return this.finishNode(node, "ThisTypeAnnotation");
+
+ case tt.star:
+ this.next();
+ return this.finishNode(node, "ExistsTypeAnnotation");
+
+ default:
+ if (this.state.type.keyword === "typeof") {
+ return this.flowParseTypeofType();
+ }
+ }
+
+ this.unexpected();
+ };
+
+ pp.flowParsePostfixType = function () {
+ const startPos = this.state.start, startLoc = this.state.startLoc;
+ let type = this.flowParsePrimaryType();
+ while (!this.canInsertSemicolon() && this.match(tt.bracketL)) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.elementType = type;
+ this.expect(tt.bracketL);
+ this.expect(tt.bracketR);
+ type = this.finishNode(node, "ArrayTypeAnnotation");
+ }
+ return type;
+ };
+
+ pp.flowParsePrefixType = function () {
+ const node = this.startNode();
+ if (this.eat(tt.question)) {
+ node.typeAnnotation = this.flowParsePrefixType();
+ return this.finishNode(node, "NullableTypeAnnotation");
+ } else {
+ return this.flowParsePostfixType();
+ }
+ };
+
+ pp.flowParseAnonFunctionWithoutParens = function () {
+ const param = this.flowParsePrefixType();
+ if (!this.state.noAnonFunctionType && this.eat(tt.arrow)) {
+ const node = this.startNodeAt(param.start, param.loc);
+ node.params = [this.reinterpretTypeAsFunctionTypeParam(param)];
+ node.rest = null;
+ node.returnType = this.flowParseType();
+ node.typeParameters = null;
+ return this.finishNode(node, "FunctionTypeAnnotation");
+ }
+ return param;
+ };
+
+ pp.flowParseIntersectionType = function () {
+ const node = this.startNode();
+ this.eat(tt.bitwiseAND);
+ const type = this.flowParseAnonFunctionWithoutParens();
+ node.types = [type];
+ while (this.eat(tt.bitwiseAND)) {
+ node.types.push(this.flowParseAnonFunctionWithoutParens());
+ }
+ return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation");
+ };
+
+ pp.flowParseUnionType = function () {
+ const node = this.startNode();
+ this.eat(tt.bitwiseOR);
+ const type = this.flowParseIntersectionType();
+ node.types = [type];
+ while (this.eat(tt.bitwiseOR)) {
+ node.types.push(this.flowParseIntersectionType());
+ }
+ return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation");
+ };
+
+ pp.flowParseType = function () {
+ const oldInType = this.state.inType;
+ this.state.inType = true;
+ const type = this.flowParseUnionType();
+ this.state.inType = oldInType;
+ return type;
+ };
+
+ pp.flowParseTypeAnnotation = function () {
+ const node = this.startNode();
+ node.typeAnnotation = this.flowParseTypeInitialiser();
+ return this.finishNode(node, "TypeAnnotation");
+ };
+
+ pp.flowParseTypeAndPredicateAnnotation = function () {
+ const node = this.startNode();
+ [node.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
+ return this.finishNode(node, "TypeAnnotation");
+ };
+
+ pp.flowParseTypeAnnotatableIdentifier = function () {
+ const ident = this.flowParseRestrictedIdentifier();
+ if (this.match(tt.colon)) {
+ ident.typeAnnotation = this.flowParseTypeAnnotation();
+ this.finishNode(ident, ident.type);
+ }
+ return ident;
+ };
+
+ pp.typeCastToParameter = function (node) {
+ node.expression.typeAnnotation = node.typeAnnotation;
+
+ return this.finishNodeAt(
+ node.expression,
+ node.expression.type,
+ node.typeAnnotation.end,
+ node.typeAnnotation.loc.end
+ );
+ };
+
+ pp.flowParseVariance = function() {
+ let variance = null;
+ if (this.match(tt.plusMin)) {
+ variance = this.startNode();
+ if (this.state.value === "+") {
+ variance.kind = "plus";
+ } else {
+ variance.kind = "minus";
+ }
+ this.next();
+ this.finishNode(variance, "Variance");
+ }
+ return variance;
+ };
+
+ //export default function (instance) {
+ pluginsFlowJS = function (instance) {
+ // plain function return types: function name(): string {}
+ instance.extend("parseFunctionBody", function (inner) {
+ return function (node, allowExpression) {
+ if (this.match(tt.colon) && !allowExpression) {
+ // if allowExpression is true then we're parsing an arrow function and if
+ // there's a return type then it's been handled elsewhere
+ node.returnType = this.flowParseTypeAndPredicateAnnotation();
+ }
+
+ return inner.call(this, node, allowExpression);
+ };
+ });
+
+ // interfaces
+ instance.extend("parseStatement", function (inner) {
+ return function (declaration, topLevel) {
+ // strict mode handling of `interface` since it's a reserved word
+ if (this.state.strict && this.match(tt.name) && this.state.value === "interface") {
+ const node = this.startNode();
+ this.next();
+ return this.flowParseInterface(node);
+ } else {
+ return inner.call(this, declaration, topLevel);
+ }
+ };
+ });
+
+ // declares, interfaces and type aliases
+ instance.extend("parseExpressionStatement", function (inner) {
+ return function (node, expr) {
+ if (expr.type === "Identifier") {
+ if (expr.name === "declare") {
+ if (this.match(tt._class) || this.match(tt.name) || this.match(tt._function) || this.match(tt._var)) {
+ return this.flowParseDeclare(node);
+ }
+ } else if (this.match(tt.name)) {
+ if (expr.name === "interface") {
+ return this.flowParseInterface(node);
+ } else if (expr.name === "type") {
+ return this.flowParseTypeAlias(node);
+ }
+ }
+ }
+
+ return inner.call(this, node, expr);
+ };
+ });
+
+ // export type
+ instance.extend("shouldParseExportDeclaration", function (inner) {
+ return function () {
+ return this.isContextual("type")
+ || this.isContextual("interface")
+ || inner.call(this);
+ };
+ });
+
+ instance.extend("parseConditional", function (inner) {
+ return function (expr, noIn, startPos, startLoc, refNeedsArrowPos) {
+ // only do the expensive clone if there is a question mark
+ // and if we come from inside parens
+ if (refNeedsArrowPos && this.match(tt.question)) {
+ const state = this.state.clone();
+ try {
+ return inner.call(this, expr, noIn, startPos, startLoc);
+ } catch (err) {
+ if (err instanceof SyntaxError) {
+ this.state = state;
+ refNeedsArrowPos.start = err.pos || this.state.start;
+ return expr;
+ } else {
+ // istanbul ignore next: no such error is expected
+ throw err;
+ }
+ }
+ }
+
+ return inner.call(this, expr, noIn, startPos, startLoc);
+ };
+ });
+
+ instance.extend("parseParenItem", function (inner) {
+ return function (node, startPos, startLoc) {
+ node = inner.call(this, node, startPos, startLoc);
+ if (this.eat(tt.question)) {
+ node.optional = true;
+ }
+
+ if (this.match(tt.colon)) {
+ const typeCastNode = this.startNodeAt(startPos, startLoc);
+ typeCastNode.expression = node;
+ typeCastNode.typeAnnotation = this.flowParseTypeAnnotation();
+
+ return this.finishNode(typeCastNode, "TypeCastExpression");
+ }
+
+ return node;
+ };
+ });
+
+ instance.extend("parseExport", function (inner) {
+ return function (node) {
+ node = inner.call(this, node);
+ if (node.type === "ExportNamedDeclaration") {
+ node.exportKind = node.exportKind || "value";
+ }
+ return node;
+ };
+ });
+
+ instance.extend("parseExportDeclaration", function (inner) {
+ return function (node) {
+ if (this.isContextual("type")) {
+ node.exportKind = "type";
+
+ const declarationNode = this.startNode();
+ this.next();
+
+ if (this.match(tt.braceL)) {
+ // export type { foo, bar };
+ node.specifiers = this.parseExportSpecifiers();
+ this.parseExportFrom(node);
+ return null;
+ } else {
+ // export type Foo = Bar;
+ return this.flowParseTypeAlias(declarationNode);
+ }
+ } else if (this.isContextual("interface")) {
+ node.exportKind = "type";
+ const declarationNode = this.startNode();
+ this.next();
+ return this.flowParseInterface(declarationNode);
+ } else {
+ return inner.call(this, node);
+ }
+ };
+ });
+
+ instance.extend("parseClassId", function (inner) {
+ return function (node) {
+ inner.apply(this, arguments);
+ if (this.isRelational("<")) {
+ node.typeParameters = this.flowParseTypeParameterDeclaration();
+ }
+ };
+ });
+
+ // don't consider `void` to be a keyword as then it'll use the void token type
+ // and set startExpr
+ instance.extend("isKeyword", function (inner) {
+ return function (name) {
+ if (this.state.inType && name === "void") {
+ return false;
+ } else {
+ return inner.call(this, name);
+ }
+ };
+ });
+
+ // ensure that inside flow types, we bypass the jsx parser plugin
+ instance.extend("readToken", function (inner) {
+ return function (code) {
+ if (this.state.inType && (code === 62 || code === 60)) {
+ return this.finishOp(tt.relational, 1);
+ } else {
+ return inner.call(this, code);
+ }
+ };
+ });
+
+ // don't lex any token as a jsx one inside a flow type
+ instance.extend("jsx_readToken", function (inner) {
+ return function () {
+ if (!this.state.inType) return inner.call(this);
+ };
+ });
+
+ instance.extend("toAssignable", function (inner) {
+ return function (node, isBinding, contextDescription) {
+ if (node.type === "TypeCastExpression") {
+ return inner.call(this, this.typeCastToParameter(node), isBinding, contextDescription);
+ } else {
+ return inner.call(this, node, isBinding, contextDescription);
+ }
+ };
+ });
+
+ // turn type casts that we found in function parameter head into type annotated params
+ instance.extend("toAssignableList", function (inner) {
+ return function (exprList, isBinding, contextDescription) {
+ for (let i = 0; i < exprList.length; i++) {
+ const expr = exprList[i];
+ if (expr && expr.type === "TypeCastExpression") {
+ exprList[i] = this.typeCastToParameter(expr);
+ }
+ }
+ return inner.call(this, exprList, isBinding, contextDescription);
+ };
+ });
+
+ // this is a list of nodes, from something like a call expression, we need to filter the
+ // type casts that we've found that are illegal in this context
+ instance.extend("toReferencedList", function () {
+ return function (exprList) {
+ for (let i = 0; i < exprList.length; i++) {
+ const expr = exprList[i];
+ if (expr && expr._exprListItem && expr.type === "TypeCastExpression") {
+ this.raise(expr.start, "Unexpected type cast");
+ }
+ }
+
+ return exprList;
+ };
+ });
+
+ // parse an item inside a expression list eg. `(NODE, NODE)` where NODE represents
+ // the position where this function is called
+ instance.extend("parseExprListItem", function (inner) {
+ return function (...args) {
+ const container = this.startNode();
+ const node = inner.call(this, ...args);
+ if (this.match(tt.colon)) {
+ container._exprListItem = true;
+ container.expression = node;
+ container.typeAnnotation = this.flowParseTypeAnnotation();
+ return this.finishNode(container, "TypeCastExpression");
+ } else {
+ return node;
+ }
+ };
+ });
+
+ instance.extend("checkLVal", function (inner) {
+ return function (node) {
+ if (node.type !== "TypeCastExpression") {
+ return inner.apply(this, arguments);
+ }
+ };
+ });
+
+ // parse class property type annotations
+ instance.extend("parseClassProperty", function (inner) {
+ return function (node) {
+ if (this.match(tt.colon)) {
+ node.typeAnnotation = this.flowParseTypeAnnotation();
+ }
+ return inner.call(this, node);
+ };
+ });
+
+ // determine whether or not we're currently in the position where a class method would appear
+ instance.extend("isClassMethod", function (inner) {
+ return function () {
+ return this.isRelational("<") || inner.call(this);
+ };
+ });
+
+ // determine whether or not we're currently in the position where a class property would appear
+ instance.extend("isClassProperty", function (inner) {
+ return function () {
+ return this.match(tt.colon) || inner.call(this);
+ };
+ });
+
+ // parse type parameters for class methods
+ instance.extend("parseClassMethod", function (inner) {
+ return function (classBody, method, ...args) {
+ if (method.variance) {
+ this.unexpected(method.variance.start);
+ }
+ delete method.variance;
+ if (this.isRelational("<")) {
+ method.typeParameters = this.flowParseTypeParameterDeclaration();
+ }
+
+ inner.call(this, classBody, method, ...args);
+ };
+ });
+
+ // parse a the super class type parameters and implements
+ instance.extend("parseClassSuper", function (inner) {
+ return function (node, isStatement) {
+ inner.call(this, node, isStatement);
+ if (node.superClass && this.isRelational("<")) {
+ node.superTypeParameters = this.flowParseTypeParameterInstantiation();
+ }
+ if (this.isContextual("implements")) {
+ this.next();
+ const implemented = node.implements = [];
+ do {
+ const node = this.startNode();
+ node.id = this.parseIdentifier();
+ if (this.isRelational("<")) {
+ node.typeParameters = this.flowParseTypeParameterInstantiation();
+ } else {
+ node.typeParameters = null;
+ }
+ implemented.push(this.finishNode(node, "ClassImplements"));
+ } while (this.eat(tt.comma));
+ }
+ };
+ });
+
+ instance.extend("parsePropertyName", function (inner) {
+ return function (node) {
+ const variance = this.flowParseVariance();
+ const key = inner.call(this, node);
+ node.variance = variance;
+ return key;
+ };
+ });
+
+ // parse type parameters for object method shorthand
+ instance.extend("parseObjPropValue", function (inner) {
+ return function (prop) {
+ if (prop.variance) {
+ this.unexpected(prop.variance.start);
+ }
+ delete prop.variance;
+
+ let typeParameters;
+
+ // method shorthand
+ if (this.isRelational("<")) {
+ typeParameters = this.flowParseTypeParameterDeclaration();
+ if (!this.match(tt.parenL)) this.unexpected();
+ }
+
+ inner.apply(this, arguments);
+
+ // add typeParameters if we found them
+ if (typeParameters) {
+ (prop.value || prop).typeParameters = typeParameters;
+ }
+ };
+ });
+
+ instance.extend("parseAssignableListItemTypes", function () {
+ return function (param) {
+ if (this.eat(tt.question)) {
+ param.optional = true;
+ }
+ if (this.match(tt.colon)) {
+ param.typeAnnotation = this.flowParseTypeAnnotation();
+ }
+ this.finishNode(param, param.type);
+ return param;
+ };
+ });
+
+ instance.extend("parseMaybeDefault", function (inner) {
+ return function (...args) {
+ const node = inner.apply(this, args);
+
+ if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) {
+ this.raise(node.typeAnnotation.start, "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`");
+ }
+
+ return node;
+ };
+ });
+
+
+ // parse typeof and type imports
+ instance.extend("parseImportSpecifiers", function (inner) {
+ return function (node) {
+ node.importKind = "value";
+
+ let kind = null;
+ if (this.match(tt._typeof)) {
+ kind = "typeof";
+ } else if (this.isContextual("type")) {
+ kind = "type";
+ }
+ if (kind) {
+ const lh = this.lookahead();
+ if ((lh.type === tt.name && lh.value !== "from") || lh.type === tt.braceL || lh.type === tt.star) {
+ this.next();
+ node.importKind = kind;
+ }
+ }
+
+ inner.call(this, node);
+ };
+ });
+
+ // parse import-type/typeof shorthand
+ instance.extend("parseImportSpecifier", function () {
+ return function (node) {
+ const specifier = this.startNode();
+ const firstIdentLoc = this.state.start;
+ const firstIdent = this.parseIdentifier(true);
+
+ let specifierTypeKind = null;
+ if (firstIdent.name === "type") {
+ specifierTypeKind = "type";
+ } else if (firstIdent.name === "typeof") {
+ specifierTypeKind = "typeof";
+ }
+
+ let isBinding = false;
+ if (this.isContextual("as")) {
+ const as_ident = this.parseIdentifier(true);
+ if (specifierTypeKind !== null && !this.match(tt.name) && !this.state.type.keyword) {
+ // `import {type as ,` or `import {type as }`
+ specifier.imported = as_ident;
+ specifier.importKind = specifierTypeKind;
+ specifier.local = as_ident.__clone();
+ } else {
+ // `import {type as foo`
+ specifier.imported = firstIdent;
+ specifier.importKind = null;
+ specifier.local = this.parseIdentifier();
+ }
+ } else if (specifierTypeKind !== null && (this.match(tt.name) || this.state.type.keyword)) {
+ // `import {type foo`
+ specifier.imported = this.parseIdentifier(true);
+ specifier.importKind = specifierTypeKind;
+ if (this.eatContextual("as")) {
+ specifier.local = this.parseIdentifier();
+ } else {
+ isBinding = true;
+ specifier.local = specifier.imported.__clone();
+ }
+ } else {
+ isBinding = true;
+ specifier.imported = firstIdent;
+ specifier.importKind = null;
+ specifier.local = specifier.imported.__clone();
+ }
+
+ if (
+ (node.importKind === "type" || node.importKind === "typeof") &&
+ (specifier.importKind === "type" || specifier.importKind === "typeof")
+ ) {
+ this.raise(firstIdentLoc, "`The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements`");
+ }
+
+ if (isBinding) this.checkReservedWord(specifier.local.name, specifier.start, true, true);
+
+ this.checkLVal(specifier.local, true, undefined, "import specifier");
+ node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
+ };
+ });
+
+ // parse function type parameters - function foo<T>() {}
+ instance.extend("parseFunctionParams", function (inner) {
+ return function (node) {
+ if (this.isRelational("<")) {
+ node.typeParameters = this.flowParseTypeParameterDeclaration();
+ }
+ inner.call(this, node);
+ };
+ });
+
+ // parse flow type annotations on variable declarator heads - let foo: string = bar
+ instance.extend("parseVarHead", function (inner) {
+ return function (decl) {
+ inner.call(this, decl);
+ if (this.match(tt.colon)) {
+ decl.id.typeAnnotation = this.flowParseTypeAnnotation();
+ this.finishNode(decl.id, decl.id.type);
+ }
+ };
+ });
+
+ // parse the return type of an async arrow function - let foo = (async (): number => {});
+ instance.extend("parseAsyncArrowFromCallExpression", function (inner) {
+ return function (node, call) {
+ if (this.match(tt.colon)) {
+ const oldNoAnonFunctionType = this.state.noAnonFunctionType;
+ this.state.noAnonFunctionType = true;
+ node.returnType = this.flowParseTypeAnnotation();
+ this.state.noAnonFunctionType = oldNoAnonFunctionType;
+ }
+
+ return inner.call(this, node, call);
+ };
+ });
+
+ // todo description
+ instance.extend("shouldParseAsyncArrow", function (inner) {
+ return function () {
+ return this.match(tt.colon) || inner.call(this);
+ };
+ });
+
+ // We need to support type parameter declarations for arrow functions. This
+ // is tricky. There are three situations we need to handle
+ //
+ // 1. This is either JSX or an arrow function. We'll try JSX first. If that
+ // fails, we'll try an arrow function. If that fails, we'll throw the JSX
+ // error.
+ // 2. This is an arrow function. We'll parse the type parameter declaration,
+ // parse the rest, make sure the rest is an arrow function, and go from
+ // there
+ // 3. This is neither. Just call the inner function
+ instance.extend("parseMaybeAssign", function (inner) {
+ return function (...args) {
+ let jsxError = null;
+ if (tt.jsxTagStart && this.match(tt.jsxTagStart)) {
+ const state = this.state.clone();
+ try {
+ return inner.apply(this, args);
+ } catch (err) {
+ if (err instanceof SyntaxError) {
+ this.state = state;
+ jsxError = err;
+ } else {
+ // istanbul ignore next: no such error is expected
+ throw err;
+ }
+ }
+ }
+
+ if (jsxError != null || this.isRelational("<")) {
+ // Need to push something onto the context to stop
+ // the JSX plugin from messing with the tokens
+ this.state.context.push(ct.parenExpression);
+ let arrowExpression;
+ let typeParameters;
+ try {
+ typeParameters = this.flowParseTypeParameterDeclaration();
+
+ arrowExpression = inner.apply(this, args);
+ arrowExpression.typeParameters = typeParameters;
+ this.resetStartLocationFromNode(arrowExpression, typeParameters);
+ } catch (err) {
+ this.state.context.pop();
+
+ throw jsxError || err;
+ }
+
+ this.state.context.pop();
+
+ if (arrowExpression.type === "ArrowFunctionExpression") {
+ return arrowExpression;
+ } else if (jsxError != null) {
+ throw jsxError;
+ } else {
+ this.raise(
+ typeParameters.start,
+ "Expected an arrow function after this type parameter declaration",
+ );
+ }
+ }
+
+ return inner.apply(this, args);
+ };
+ });
+
+ // handle return types for arrow functions
+ instance.extend("parseArrow", function (inner) {
+ return function (node) {
+ if (this.match(tt.colon)) {
+ const state = this.state.clone();
+ try {
+ const oldNoAnonFunctionType = this.state.noAnonFunctionType;
+ this.state.noAnonFunctionType = true;
+ const returnType = this.flowParseTypeAndPredicateAnnotation();
+ this.state.noAnonFunctionType = oldNoAnonFunctionType;
+
+ if (this.canInsertSemicolon()) this.unexpected();
+ if (!this.match(tt.arrow)) this.unexpected();
+ // assign after it is clear it is an arrow
+ node.returnType = returnType;
+ } catch (err) {
+ if (err instanceof SyntaxError) {
+ this.state = state;
+ } else {
+ // istanbul ignore next: no such error is expected
+ throw err;
+ }
+ }
+ }
+
+ return inner.call(this, node);
+ };
+ });
+
+ instance.extend("shouldParseArrow", function (inner) {
+ return function () {
+ return this.match(tt.colon) || inner.call(this);
+ };
+ });
+ }
+}
+
+// plugins/jsx/xhtml.js
+let pluginsJsxXhtmlJS = {};
+{
+ pluginsJsxXhtmlJS = {
+ quot: "\u0022",
+ amp: "&",
+ apos: "\u0027",
+ lt: "<",
+ gt: ">",
+ nbsp: "\u00A0",
+ iexcl: "\u00A1",
+ cent: "\u00A2",
+ pound: "\u00A3",
+ curren: "\u00A4",
+ yen: "\u00A5",
+ brvbar: "\u00A6",
+ sect: "\u00A7",
+ uml: "\u00A8",
+ copy: "\u00A9",
+ ordf: "\u00AA",
+ laquo: "\u00AB",
+ not: "\u00AC",
+ shy: "\u00AD",
+ reg: "\u00AE",
+ macr: "\u00AF",
+ deg: "\u00B0",
+ plusmn: "\u00B1",
+ sup2: "\u00B2",
+ sup3: "\u00B3",
+ acute: "\u00B4",
+ micro: "\u00B5",
+ para: "\u00B6",
+ middot: "\u00B7",
+ cedil: "\u00B8",
+ sup1: "\u00B9",
+ ordm: "\u00BA",
+ raquo: "\u00BB",
+ frac14: "\u00BC",
+ frac12: "\u00BD",
+ frac34: "\u00BE",
+ iquest: "\u00BF",
+ Agrave: "\u00C0",
+ Aacute: "\u00C1",
+ Acirc: "\u00C2",
+ Atilde: "\u00C3",
+ Auml: "\u00C4",
+ Aring: "\u00C5",
+ AElig: "\u00C6",
+ Ccedil: "\u00C7",
+ Egrave: "\u00C8",
+ Eacute: "\u00C9",
+ Ecirc: "\u00CA",
+ Euml: "\u00CB",
+ Igrave: "\u00CC",
+ Iacute: "\u00CD",
+ Icirc: "\u00CE",
+ Iuml: "\u00CF",
+ ETH: "\u00D0",
+ Ntilde: "\u00D1",
+ Ograve: "\u00D2",
+ Oacute: "\u00D3",
+ Ocirc: "\u00D4",
+ Otilde: "\u00D5",
+ Ouml: "\u00D6",
+ times: "\u00D7",
+ Oslash: "\u00D8",
+ Ugrave: "\u00D9",
+ Uacute: "\u00DA",
+ Ucirc: "\u00DB",
+ Uuml: "\u00DC",
+ Yacute: "\u00DD",
+ THORN: "\u00DE",
+ szlig: "\u00DF",
+ agrave: "\u00E0",
+ aacute: "\u00E1",
+ acirc: "\u00E2",
+ atilde: "\u00E3",
+ auml: "\u00E4",
+ aring: "\u00E5",
+ aelig: "\u00E6",
+ ccedil: "\u00E7",
+ egrave: "\u00E8",
+ eacute: "\u00E9",
+ ecirc: "\u00EA",
+ euml: "\u00EB",
+ igrave: "\u00EC",
+ iacute: "\u00ED",
+ icirc: "\u00EE",
+ iuml: "\u00EF",
+ eth: "\u00F0",
+ ntilde: "\u00F1",
+ ograve: "\u00F2",
+ oacute: "\u00F3",
+ ocirc: "\u00F4",
+ otilde: "\u00F5",
+ ouml: "\u00F6",
+ divide: "\u00F7",
+ oslash: "\u00F8",
+ ugrave: "\u00F9",
+ uacute: "\u00FA",
+ ucirc: "\u00FB",
+ uuml: "\u00FC",
+ yacute: "\u00FD",
+ thorn: "\u00FE",
+ yuml: "\u00FF",
+ OElig: "\u0152",
+ oelig: "\u0153",
+ Scaron: "\u0160",
+ scaron: "\u0161",
+ Yuml: "\u0178",
+ fnof: "\u0192",
+ circ: "\u02C6",
+ tilde: "\u02DC",
+ Alpha: "\u0391",
+ Beta: "\u0392",
+ Gamma: "\u0393",
+ Delta: "\u0394",
+ Epsilon: "\u0395",
+ Zeta: "\u0396",
+ Eta: "\u0397",
+ Theta: "\u0398",
+ Iota: "\u0399",
+ Kappa: "\u039A",
+ Lambda: "\u039B",
+ Mu: "\u039C",
+ Nu: "\u039D",
+ Xi: "\u039E",
+ Omicron: "\u039F",
+ Pi: "\u03A0",
+ Rho: "\u03A1",
+ Sigma: "\u03A3",
+ Tau: "\u03A4",
+ Upsilon: "\u03A5",
+ Phi: "\u03A6",
+ Chi: "\u03A7",
+ Psi: "\u03A8",
+ Omega: "\u03A9",
+ alpha: "\u03B1",
+ beta: "\u03B2",
+ gamma: "\u03B3",
+ delta: "\u03B4",
+ epsilon: "\u03B5",
+ zeta: "\u03B6",
+ eta: "\u03B7",
+ theta: "\u03B8",
+ iota: "\u03B9",
+ kappa: "\u03BA",
+ lambda: "\u03BB",
+ mu: "\u03BC",
+ nu: "\u03BD",
+ xi: "\u03BE",
+ omicron: "\u03BF",
+ pi: "\u03C0",
+ rho: "\u03C1",
+ sigmaf: "\u03C2",
+ sigma: "\u03C3",
+ tau: "\u03C4",
+ upsilon: "\u03C5",
+ phi: "\u03C6",
+ chi: "\u03C7",
+ psi: "\u03C8",
+ omega: "\u03C9",
+ thetasym: "\u03D1",
+ upsih: "\u03D2",
+ piv: "\u03D6",
+ ensp: "\u2002",
+ emsp: "\u2003",
+ thinsp: "\u2009",
+ zwnj: "\u200C",
+ zwj: "\u200D",
+ lrm: "\u200E",
+ rlm: "\u200F",
+ ndash: "\u2013",
+ mdash: "\u2014",
+ lsquo: "\u2018",
+ rsquo: "\u2019",
+ sbquo: "\u201A",
+ ldquo: "\u201C",
+ rdquo: "\u201D",
+ bdquo: "\u201E",
+ dagger: "\u2020",
+ Dagger: "\u2021",
+ bull: "\u2022",
+ hellip: "\u2026",
+ permil: "\u2030",
+ prime: "\u2032",
+ Prime: "\u2033",
+ lsaquo: "\u2039",
+ rsaquo: "\u203A",
+ oline: "\u203E",
+ frasl: "\u2044",
+ euro: "\u20AC",
+ image: "\u2111",
+ weierp: "\u2118",
+ real: "\u211C",
+ trade: "\u2122",
+ alefsym: "\u2135",
+ larr: "\u2190",
+ uarr: "\u2191",
+ rarr: "\u2192",
+ darr: "\u2193",
+ harr: "\u2194",
+ crarr: "\u21B5",
+ lArr: "\u21D0",
+ uArr: "\u21D1",
+ rArr: "\u21D2",
+ dArr: "\u21D3",
+ hArr: "\u21D4",
+ forall: "\u2200",
+ part: "\u2202",
+ exist: "\u2203",
+ empty: "\u2205",
+ nabla: "\u2207",
+ isin: "\u2208",
+ notin: "\u2209",
+ ni: "\u220B",
+ prod: "\u220F",
+ sum: "\u2211",
+ minus: "\u2212",
+ lowast: "\u2217",
+ radic: "\u221A",
+ prop: "\u221D",
+ infin: "\u221E",
+ ang: "\u2220",
+ and: "\u2227",
+ or: "\u2228",
+ cap: "\u2229",
+ cup: "\u222A",
+ "int": "\u222B",
+ there4: "\u2234",
+ sim: "\u223C",
+ cong: "\u2245",
+ asymp: "\u2248",
+ ne: "\u2260",
+ equiv: "\u2261",
+ le: "\u2264",
+ ge: "\u2265",
+ sub: "\u2282",
+ sup: "\u2283",
+ nsub: "\u2284",
+ sube: "\u2286",
+ supe: "\u2287",
+ oplus: "\u2295",
+ otimes: "\u2297",
+ perp: "\u22A5",
+ sdot: "\u22C5",
+ lceil: "\u2308",
+ rceil: "\u2309",
+ lfloor: "\u230A",
+ rfloor: "\u230B",
+ lang: "\u2329",
+ rang: "\u232A",
+ loz: "\u25CA",
+ spades: "\u2660",
+ clubs: "\u2663",
+ hearts: "\u2665",
+ diams: "\u2666"
+ };
+}
+
+// plugins/jsx/index.js
+let pluginsJsxIndexJS = {};
+{
+ const XHTMLEntities = pluginsJsxXhtmlJS;
+ const { TokenType, types : tt } = tokenizerTypesJS;
+ const { TokContext, types : tc } = tokenizerContextJS;
+ const Parser = parserIndexJS;
+ const { isIdentifierChar, isIdentifierStart } = utilIdentifierJS;
+ const { isNewLine } = utilWhitespaceJS;
+
+ const HEX_NUMBER = /^[\da-fA-F]+$/;
+ const DECIMAL_NUMBER = /^\d+$/;
+
+ tc.j_oTag = new TokContext("<tag", false);
+ tc.j_cTag = new TokContext("</tag", false);
+ tc.j_expr = new TokContext("<tag>...</tag>", true, true);
+
+ tt.jsxName = new TokenType("jsxName");
+ tt.jsxText = new TokenType("jsxText", { beforeExpr: true });
+ tt.jsxTagStart = new TokenType("jsxTagStart", { startsExpr: true });
+ tt.jsxTagEnd = new TokenType("jsxTagEnd");
+
+ tt.jsxTagStart.updateContext = function() {
+ this.state.context.push(tc.j_expr); // treat as beginning of JSX expression
+ this.state.context.push(tc.j_oTag); // start opening tag context
+ this.state.exprAllowed = false;
+ };
+
+ tt.jsxTagEnd.updateContext = function(prevType) {
+ const out = this.state.context.pop();
+ if (out === tc.j_oTag && prevType === tt.slash || out === tc.j_cTag) {
+ this.state.context.pop();
+ this.state.exprAllowed = this.curContext() === tc.j_expr;
+ } else {
+ this.state.exprAllowed = true;
+ }
+ };
+
+ const pp = Parser.prototype;
+
+ // Reads inline JSX contents token.
+
+ pp.jsxReadToken = function() {
+ let out = "";
+ let chunkStart = this.state.pos;
+ for (;;) {
+ if (this.state.pos >= this.input.length) {
+ this.raise(this.state.start, "Unterminated JSX contents");
+ }
+
+ const ch = this.input.charCodeAt(this.state.pos);
+
+ switch (ch) {
+ case 60: // "<"
+ case 123: // "{"
+ if (this.state.pos === this.state.start) {
+ if (ch === 60 && this.state.exprAllowed) {
+ ++this.state.pos;
+ return this.finishToken(tt.jsxTagStart);
+ }
+ return this.getTokenFromCode(ch);
+ }
+ out += this.input.slice(chunkStart, this.state.pos);
+ return this.finishToken(tt.jsxText, out);
+
+ case 38: // "&"
+ out += this.input.slice(chunkStart, this.state.pos);
+ out += this.jsxReadEntity();
+ chunkStart = this.state.pos;
+ break;
+
+ default:
+ if (isNewLine(ch)) {
+ out += this.input.slice(chunkStart, this.state.pos);
+ out += this.jsxReadNewLine(true);
+ chunkStart = this.state.pos;
+ } else {
+ ++this.state.pos;
+ }
+ }
+ }
+ };
+
+ pp.jsxReadNewLine = function(normalizeCRLF) {
+ const ch = this.input.charCodeAt(this.state.pos);
+ let out;
+ ++this.state.pos;
+ if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) {
+ ++this.state.pos;
+ out = normalizeCRLF ? "\n" : "\r\n";
+ } else {
+ out = String.fromCharCode(ch);
+ }
+ ++this.state.curLine;
+ this.state.lineStart = this.state.pos;
+
+ return out;
+ };
+
+ pp.jsxReadString = function(quote) {
+ let out = "";
+ let chunkStart = ++this.state.pos;
+ for (;;) {
+ if (this.state.pos >= this.input.length) {
+ this.raise(this.state.start, "Unterminated string constant");
+ }
+
+ const ch = this.input.charCodeAt(this.state.pos);
+ if (ch === quote) break;
+ if (ch === 38) { // "&"
+ out += this.input.slice(chunkStart, this.state.pos);
+ out += this.jsxReadEntity();
+ chunkStart = this.state.pos;
+ } else if (isNewLine(ch)) {
+ out += this.input.slice(chunkStart, this.state.pos);
+ out += this.jsxReadNewLine(false);
+ chunkStart = this.state.pos;
+ } else {
+ ++this.state.pos;
+ }
+ }
+ out += this.input.slice(chunkStart, this.state.pos++);
+ return this.finishToken(tt.string, out);
+ };
+
+ pp.jsxReadEntity = function() {
+ let str = "";
+ let count = 0;
+ let entity;
+ let ch = this.input[this.state.pos];
+
+ const startPos = ++this.state.pos;
+ while (this.state.pos < this.input.length && count++ < 10) {
+ ch = this.input[this.state.pos++];
+ if (ch === ";") {
+ if (str[0] === "#") {
+ if (str[1] === "x") {
+ str = str.substr(2);
+ if (HEX_NUMBER.test(str))
+ entity = String.fromCodePoint(parseInt(str, 16));
+ } else {
+ str = str.substr(1);
+ if (DECIMAL_NUMBER.test(str))
+ entity = String.fromCodePoint(parseInt(str, 10));
+ }
+ } else {
+ entity = XHTMLEntities[str];
+ }
+ break;
+ }
+ str += ch;
+ }
+ if (!entity) {
+ this.state.pos = startPos;
+ return "&";
+ }
+ return entity;
+ };
+
+
+ // Read a JSX identifier (valid tag or attribute name).
+ //
+ // Optimized version since JSX identifiers can"t contain
+ // escape characters and so can be read as single slice.
+ // Also assumes that first character was already checked
+ // by isIdentifierStart in readToken.
+
+ pp.jsxReadWord = function() {
+ let ch;
+ const start = this.state.pos;
+ do {
+ ch = this.input.charCodeAt(++this.state.pos);
+ } while (isIdentifierChar(ch) || ch === 45); // "-"
+ return this.finishToken(tt.jsxName, this.input.slice(start, this.state.pos));
+ };
+
+ // Transforms JSX element name to string.
+
+ function getQualifiedJSXName(object) {
+ if (object.type === "JSXIdentifier") {
+ return object.name;
+ }
+
+ if (object.type === "JSXNamespacedName") {
+ return object.namespace.name + ":" + object.name.name;
+ }
+
+ if (object.type === "JSXMemberExpression") {
+ return getQualifiedJSXName(object.object) + "." + getQualifiedJSXName(object.property);
+ }
+ }
+
+ // Parse next token as JSX identifier
+
+ pp.jsxParseIdentifier = function() {
+ const node = this.startNode();
+ if (this.match(tt.jsxName)) {
+ node.name = this.state.value;
+ } else if (this.state.type.keyword) {
+ node.name = this.state.type.keyword;
+ } else {
+ this.unexpected();
+ }
+ this.next();
+ return this.finishNode(node, "JSXIdentifier");
+ };
+
+ // Parse namespaced identifier.
+
+ pp.jsxParseNamespacedName = function() {
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ const name = this.jsxParseIdentifier();
+ if (!this.eat(tt.colon)) return name;
+
+ const node = this.startNodeAt(startPos, startLoc);
+ node.namespace = name;
+ node.name = this.jsxParseIdentifier();
+ return this.finishNode(node, "JSXNamespacedName");
+ };
+
+ // Parses element name in any form - namespaced, member
+ // or single identifier.
+
+ pp.jsxParseElementName = function() {
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ let node = this.jsxParseNamespacedName();
+ while (this.eat(tt.dot)) {
+ const newNode = this.startNodeAt(startPos, startLoc);
+ newNode.object = node;
+ newNode.property = this.jsxParseIdentifier();
+ node = this.finishNode(newNode, "JSXMemberExpression");
+ }
+ return node;
+ };
+
+ // Parses any type of JSX attribute value.
+
+ pp.jsxParseAttributeValue = function() {
+ let node;
+ switch (this.state.type) {
+ case tt.braceL:
+ node = this.jsxParseExpressionContainer();
+ if (node.expression.type === "JSXEmptyExpression") {
+ this.raise(node.start, "JSX attributes must only be assigned a non-empty expression");
+ } else {
+ return node;
+ }
+
+ case tt.jsxTagStart:
+ case tt.string:
+ node = this.parseExprAtom();
+ node.extra = null;
+ return node;
+
+ default:
+ this.raise(this.state.start, "JSX value should be either an expression or a quoted JSX text");
+ }
+ };
+
+ // JSXEmptyExpression is unique type since it doesn't actually parse anything,
+ // and so it should start at the end of last read token (left brace) and finish
+ // at the beginning of the next one (right brace).
+
+ pp.jsxParseEmptyExpression = function() {
+ const node = this.startNodeAt(this.state.lastTokEnd, this.state.lastTokEndLoc);
+ return this.finishNodeAt(node, "JSXEmptyExpression", this.state.start, this.state.startLoc);
+ };
+
+ // Parse JSX spread child
+
+ pp.jsxParseSpreadChild = function() {
+ const node = this.startNode();
+ this.expect(tt.braceL);
+ this.expect(tt.ellipsis);
+ node.expression = this.parseExpression();
+ this.expect(tt.braceR);
+
+ return this.finishNode(node, "JSXSpreadChild");
+ };
+
+ // Parses JSX expression enclosed into curly brackets.
+
+
+ pp.jsxParseExpressionContainer = function() {
+ const node = this.startNode();
+ this.next();
+ if (this.match(tt.braceR)) {
+ node.expression = this.jsxParseEmptyExpression();
+ } else {
+ node.expression = this.parseExpression();
+ }
+ this.expect(tt.braceR);
+ return this.finishNode(node, "JSXExpressionContainer");
+ };
+
+ // Parses following JSX attribute name-value pair.
+
+ pp.jsxParseAttribute = function() {
+ const node = this.startNode();
+ if (this.eat(tt.braceL)) {
+ this.expect(tt.ellipsis);
+ node.argument = this.parseMaybeAssign();
+ this.expect(tt.braceR);
+ return this.finishNode(node, "JSXSpreadAttribute");
+ }
+ node.name = this.jsxParseNamespacedName();
+ node.value = this.eat(tt.eq) ? this.jsxParseAttributeValue() : null;
+ return this.finishNode(node, "JSXAttribute");
+ };
+
+ // Parses JSX opening tag starting after "<".
+
+ pp.jsxParseOpeningElementAt = function(startPos, startLoc) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.attributes = [];
+ node.name = this.jsxParseElementName();
+ while (!this.match(tt.slash) && !this.match(tt.jsxTagEnd)) {
+ node.attributes.push(this.jsxParseAttribute());
+ }
+ node.selfClosing = this.eat(tt.slash);
+ this.expect(tt.jsxTagEnd);
+ return this.finishNode(node, "JSXOpeningElement");
+ };
+
+ // Parses JSX closing tag starting after "</".
+
+ pp.jsxParseClosingElementAt = function(startPos, startLoc) {
+ const node = this.startNodeAt(startPos, startLoc);
+ node.name = this.jsxParseElementName();
+ this.expect(tt.jsxTagEnd);
+ return this.finishNode(node, "JSXClosingElement");
+ };
+
+ // Parses entire JSX element, including it"s opening tag
+ // (starting after "<"), attributes, contents and closing tag.
+
+ pp.jsxParseElementAt = function(startPos, startLoc) {
+ const node = this.startNodeAt(startPos, startLoc);
+ const children = [];
+ const openingElement = this.jsxParseOpeningElementAt(startPos, startLoc);
+ let closingElement = null;
+
+ if (!openingElement.selfClosing) {
+ contents: for (;;) {
+ switch (this.state.type) {
+ case tt.jsxTagStart:
+ startPos = this.state.start; startLoc = this.state.startLoc;
+ this.next();
+ if (this.eat(tt.slash)) {
+ closingElement = this.jsxParseClosingElementAt(startPos, startLoc);
+ break contents;
+ }
+ children.push(this.jsxParseElementAt(startPos, startLoc));
+ break;
+
+ case tt.jsxText:
+ children.push(this.parseExprAtom());
+ break;
+
+ case tt.braceL:
+ if (this.lookahead().type === tt.ellipsis) {
+ children.push(this.jsxParseSpreadChild());
+ } else {
+ children.push(this.jsxParseExpressionContainer());
+ }
+
+ break;
+
+ // istanbul ignore next - should never happen
+ default:
+ this.unexpected();
+ }
+ }
+
+ if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) {
+ this.raise(
+ closingElement.start,
+ "Expected corresponding JSX closing tag for <" + getQualifiedJSXName(openingElement.name) + ">"
+ );
+ }
+ }
+
+ node.openingElement = openingElement;
+ node.closingElement = closingElement;
+ node.children = children;
+ if (this.match(tt.relational) && this.state.value === "<") {
+ this.raise(this.state.start, "Adjacent JSX elements must be wrapped in an enclosing tag");
+ }
+ return this.finishNode(node, "JSXElement");
+ };
+
+ // Parses entire JSX element from current position.
+
+ pp.jsxParseElement = function() {
+ const startPos = this.state.start;
+ const startLoc = this.state.startLoc;
+ this.next();
+ return this.jsxParseElementAt(startPos, startLoc);
+ };
+
+ //export default function(instance) {
+ pluginsJsxIndexJS = function(instance) {
+ instance.extend("parseExprAtom", function(inner) {
+ return function(refShortHandDefaultPos) {
+ if (this.match(tt.jsxText)) {
+ const node = this.parseLiteral(this.state.value, "JSXText");
+ // https://github.com/babel/babel/issues/2078
+ node.extra = null;
+ return node;
+ } else if (this.match(tt.jsxTagStart)) {
+ return this.jsxParseElement();
+ } else {
+ return inner.call(this, refShortHandDefaultPos);
+ }
+ };
+ });
+
+ instance.extend("readToken", function(inner) {
+ return function(code) {
+ if (this.state.inPropertyName) return inner.call(this, code);
+
+ const context = this.curContext();
+
+ if (context === tc.j_expr) {
+ return this.jsxReadToken();
+ }
+
+ if (context === tc.j_oTag || context === tc.j_cTag) {
+ if (isIdentifierStart(code)) {
+ return this.jsxReadWord();
+ }
+
+ if (code === 62) {
+ ++this.state.pos;
+ return this.finishToken(tt.jsxTagEnd);
+ }
+
+ if ((code === 34 || code === 39) && context === tc.j_oTag) {
+ return this.jsxReadString(code);
+ }
+ }
+
+ if (code === 60 && this.state.exprAllowed) {
+ ++this.state.pos;
+ return this.finishToken(tt.jsxTagStart);
+ }
+
+ return inner.call(this, code);
+ };
+ });
+
+ instance.extend("updateContext", function(inner) {
+ return function(prevType) {
+ if (this.match(tt.braceL)) {
+ const curContext = this.curContext();
+ if (curContext === tc.j_oTag) {
+ this.state.context.push(tc.braceExpression);
+ } else if (curContext === tc.j_expr) {
+ this.state.context.push(tc.templateQuasi);
+ } else {
+ inner.call(this, prevType);
+ }
+ this.state.exprAllowed = true;
+ } else if (this.match(tt.slash) && prevType === tt.jsxTagStart) {
+ this.state.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore
+ this.state.context.push(tc.j_cTag); // reconsider as closing tag context
+ this.state.exprAllowed = false;
+ } else {
+ return inner.call(this, prevType);
+ }
+ };
+ });
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Babylon/inspector-blob.js b/third_party/webkit/PerformanceTests/ARES-6/Babylon/inspector-blob.js
new file mode 100644
index 0000000000..7dcfbcf34c
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Babylon/inspector-blob.js
@@ -0,0 +1,1146 @@
+/*
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.ScriptSyntaxTree = class ScriptSyntaxTree extends WebInspector.Object
+{
+ constructor(sourceText, script)
+ {
+ super();
+
+ console.assert(script && script instanceof WebInspector.Script, script);
+
+ this._script = script;
+
+ try {
+ let sourceType = this._script.sourceType === WebInspector.Script.SourceType.Module ? "module" : "script";
+ let esprimaSyntaxTree = esprima.parse(sourceText, {range: true, sourceType});
+ this._syntaxTree = this._createInternalSyntaxTree(esprimaSyntaxTree);
+ this._parsedSuccessfully = true;
+ } catch (error) {
+ this._parsedSuccessfully = false;
+ this._syntaxTree = null;
+ console.error("Couldn't parse JavaScript File: " + script.url, error);
+ }
+ }
+
+ // Public
+
+ get parsedSuccessfully()
+ {
+ return this._parsedSuccessfully;
+ }
+
+ forEachNode(callback)
+ {
+ console.assert(this._parsedSuccessfully);
+ if (!this._parsedSuccessfully)
+ return;
+
+ this._recurse(this._syntaxTree, callback, this._defaultParserState());
+ }
+
+ filter(predicate, startNode)
+ {
+ console.assert(startNode && this._parsedSuccessfully);
+ if (!this._parsedSuccessfully)
+ return [];
+
+ var nodes = [];
+ function filter(node, state)
+ {
+ if (predicate(node))
+ nodes.push(node);
+ else
+ state.skipChildNodes = true;
+ }
+
+ this._recurse(startNode, filter, this._defaultParserState());
+
+ return nodes;
+ }
+
+ containersOfOffset(offset)
+ {
+ console.assert(this._parsedSuccessfully);
+ if (!this._parsedSuccessfully)
+ return [];
+
+ let allNodes = [];
+ const start = 0;
+ const end = 1;
+
+ this.forEachNode((node, state) => {
+ if (node.range[end] < offset)
+ state.skipChildNodes = true;
+ if (node.range[start] > offset)
+ state.shouldStopEarly = true;
+ if (node.range[start] <= offset && node.range[end] >= offset)
+ allNodes.push(node);
+ });
+
+ return allNodes;
+ }
+
+ filterByRange(startOffset, endOffset)
+ {
+ console.assert(this._parsedSuccessfully);
+ if (!this._parsedSuccessfully)
+ return [];
+
+ var allNodes = [];
+ var start = 0;
+ var end = 1;
+ function filterForNodesInRange(node, state)
+ {
+ // program start range program end
+ // [ [ ] ]
+ // [ ] [ [ ] ] [ ]
+
+ // If a node's range ends before the range we're interested in starts, we don't need to search any of its
+ // enclosing ranges, because, by definition, those enclosing ranges are contained within this node's range.
+ if (node.range[end] < startOffset)
+ state.skipChildNodes = true;
+
+ // We are only interested in nodes whose start position is within our range.
+ if (startOffset <= node.range[start] && node.range[start] <= endOffset)
+ allNodes.push(node);
+
+ // Once we see nodes that start beyond our range, we can quit traversing the AST. We can do this safely
+ // because we know the AST is traversed using depth first search, so it will traverse into enclosing ranges
+ // before it traverses into adjacent ranges.
+ if (node.range[start] > endOffset)
+ state.shouldStopEarly = true;
+ }
+
+ this.forEachNode(filterForNodesInRange);
+
+ return allNodes;
+ }
+
+ containsNonEmptyReturnStatement(startNode)
+ {
+ console.assert(startNode && this._parsedSuccessfully);
+ if (!this._parsedSuccessfully)
+ return false;
+
+ if (startNode.attachments._hasNonEmptyReturnStatement !== undefined)
+ return startNode.attachments._hasNonEmptyReturnStatement;
+
+ function removeFunctionsFilter(node)
+ {
+ return node.type !== WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression
+ && node.type !== WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration
+ && node.type !== WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression;
+ }
+
+ var nodes = this.filter(removeFunctionsFilter, startNode);
+ var hasNonEmptyReturnStatement = false;
+ var returnStatementType = WebInspector.ScriptSyntaxTree.NodeType.ReturnStatement;
+ for (var node of nodes) {
+ if (node.type === returnStatementType && node.argument) {
+ hasNonEmptyReturnStatement = true;
+ break;
+ }
+ }
+
+ startNode.attachments._hasNonEmptyReturnStatement = hasNonEmptyReturnStatement;
+
+ return hasNonEmptyReturnStatement;
+ }
+
+ static functionReturnDivot(node)
+ {
+ console.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration || node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression || node.type === WebInspector.ScriptSyntaxTree.NodeType.MethodDefinition || node.type === WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression);
+
+ // COMPATIBILITY (iOS 9): Legacy Backends view the return type as being the opening "{" of the function body.
+ // After iOS 9, this is to move to the start of the function statement/expression. See below:
+ // FIXME: Need a better way to determine backend versions. Using DOM.pseudoElement because that was added after iOS 9.
+ if (!DOMAgent.hasEvent("pseudoElementAdded"))
+ return node.body.range[0];
+
+ // "f" in "function". "s" in "set". "g" in "get". First letter in any method name for classes and object literals.
+ // The "[" for computed methods in classes and object literals.
+ return node.typeProfilingReturnDivot;
+ }
+
+ updateTypes(nodesToUpdate, callback)
+ {
+ console.assert(RuntimeAgent.getRuntimeTypesForVariablesAtOffsets);
+ console.assert(Array.isArray(nodesToUpdate) && this._parsedSuccessfully);
+
+ if (!this._parsedSuccessfully)
+ return;
+
+ var allRequests = [];
+ var allRequestNodes = [];
+ var sourceID = this._script.id;
+
+ for (var node of nodesToUpdate) {
+ switch (node.type) {
+ case WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration:
+ case WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression:
+ case WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression:
+ for (var param of node.params) {
+ for (var identifier of this._gatherIdentifiersInDeclaration(param)) {
+ allRequests.push({
+ typeInformationDescriptor: WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.NormalExpression,
+ sourceID,
+ divot: identifier.range[0]
+ });
+ allRequestNodes.push(identifier);
+ }
+ }
+
+ allRequests.push({
+ typeInformationDescriptor: WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.FunctionReturn,
+ sourceID,
+ divot: WebInspector.ScriptSyntaxTree.functionReturnDivot(node)
+ });
+ allRequestNodes.push(node);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator:
+ for (var identifier of this._gatherIdentifiersInDeclaration(node.id)) {
+ allRequests.push({
+ typeInformationDescriptor: WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.NormalExpression,
+ sourceID,
+ divot: identifier.range[0]
+ });
+ allRequestNodes.push(identifier);
+ }
+ break;
+ }
+ }
+
+ console.assert(allRequests.length === allRequestNodes.length);
+
+ function handleTypes(error, typeInformationArray)
+ {
+ if (error)
+ return;
+
+ console.assert(typeInformationArray.length === allRequests.length);
+
+ for (var i = 0; i < typeInformationArray.length; i++) {
+ var node = allRequestNodes[i];
+ var typeInformation = WebInspector.TypeDescription.fromPayload(typeInformationArray[i]);
+ if (allRequests[i].typeInformationDescriptor === WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.FunctionReturn)
+ node.attachments.returnTypes = typeInformation;
+ else
+ node.attachments.types = typeInformation;
+ }
+
+ callback(allRequestNodes);
+ }
+
+ this._script.target.RuntimeAgent.getRuntimeTypesForVariablesAtOffsets(allRequests, handleTypes);
+ }
+
+ // Private
+
+ _gatherIdentifiersInDeclaration(node)
+ {
+ function gatherIdentifiers(node)
+ {
+ switch (node.type) {
+ case WebInspector.ScriptSyntaxTree.NodeType.Identifier:
+ return [node];
+ case WebInspector.ScriptSyntaxTree.NodeType.Property:
+ return gatherIdentifiers(node.value);
+ case WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern:
+ var identifiers = [];
+ for (var property of node.properties) {
+ for (var identifier of gatherIdentifiers(property))
+ identifiers.push(identifier);
+ }
+ return identifiers;
+ case WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern:
+ var identifiers = [];
+ for (var element of node.elements) {
+ for (var identifier of gatherIdentifiers(element))
+ identifiers.push(identifier);
+ }
+ return identifiers;
+ case WebInspector.ScriptSyntaxTree.NodeType.AssignmentPattern:
+ return gatherIdentifiers(node.left);
+ case WebInspector.ScriptSyntaxTree.NodeType.RestElement:
+ case WebInspector.ScriptSyntaxTree.NodeType.RestProperty:
+ return gatherIdentifiers(node.argument);
+ default:
+ console.assert(false, "Unexpected node type in variable declarator: " + node.type);
+ return [];
+ }
+ }
+
+ console.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.Identifier || node.type === WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern || node.type === WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern || node.type === WebInspector.ScriptSyntaxTree.NodeType.RestElement || node.type === WebInspector.ScriptSyntaxTree.NodeType.RestProperty);
+
+ return gatherIdentifiers(node);
+ }
+
+ _defaultParserState()
+ {
+ return {
+ shouldStopEarly: false,
+ skipChildNodes: false
+ };
+ }
+
+ _recurse(node, callback, state)
+ {
+ if (!node)
+ return;
+
+ if (state.shouldStopEarly || state.skipChildNodes)
+ return;
+
+ callback(node, state);
+
+ switch (node.type) {
+ case WebInspector.ScriptSyntaxTree.NodeType.AssignmentExpression:
+ this._recurse(node.left, callback, state);
+ this._recurse(node.right, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ArrayExpression:
+ case WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern:
+ this._recurseArray(node.elements, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.AssignmentPattern:
+ this._recurse(node.left, callback, state);
+ this._recurse(node.right, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.AwaitExpression:
+ this._recurse(node.argument, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.BlockStatement:
+ this._recurseArray(node.body, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.BinaryExpression:
+ this._recurse(node.left, callback, state);
+ this._recurse(node.right, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.BreakStatement:
+ this._recurse(node.label, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.CatchClause:
+ this._recurse(node.param, callback, state);
+ this._recurse(node.body, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.CallExpression:
+ this._recurse(node.callee, callback, state);
+ this._recurseArray(node.arguments, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ClassBody:
+ this._recurseArray(node.body, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ClassDeclaration:
+ case WebInspector.ScriptSyntaxTree.NodeType.ClassExpression:
+ this._recurse(node.id, callback, state);
+ this._recurse(node.superClass, callback, state);
+ this._recurse(node.body, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ContinueStatement:
+ this._recurse(node.label, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.DoWhileStatement:
+ this._recurse(node.body, callback, state);
+ this._recurse(node.test, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ExpressionStatement:
+ this._recurse(node.expression, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ForStatement:
+ this._recurse(node.init, callback, state);
+ this._recurse(node.test, callback, state);
+ this._recurse(node.update, callback, state);
+ this._recurse(node.body, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ForInStatement:
+ case WebInspector.ScriptSyntaxTree.NodeType.ForOfStatement:
+ this._recurse(node.left, callback, state);
+ this._recurse(node.right, callback, state);
+ this._recurse(node.body, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration:
+ case WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression:
+ case WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression:
+ this._recurse(node.id, callback, state);
+ this._recurseArray(node.params, callback, state);
+ this._recurse(node.body, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.IfStatement:
+ this._recurse(node.test, callback, state);
+ this._recurse(node.consequent, callback, state);
+ this._recurse(node.alternate, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.LabeledStatement:
+ this._recurse(node.label, callback, state);
+ this._recurse(node.body, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.LogicalExpression:
+ this._recurse(node.left, callback, state);
+ this._recurse(node.right, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.MemberExpression:
+ this._recurse(node.object, callback, state);
+ this._recurse(node.property, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.MethodDefinition:
+ this._recurse(node.key, callback, state);
+ this._recurse(node.value, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.NewExpression:
+ this._recurse(node.callee, callback, state);
+ this._recurseArray(node.arguments, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ObjectExpression:
+ case WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern:
+ this._recurseArray(node.properties, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.Program:
+ this._recurseArray(node.body, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.Property:
+ this._recurse(node.key, callback, state);
+ this._recurse(node.value, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.RestElement:
+ this._recurse(node.argument, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.RestProperty:
+ this._recurse(node.argument, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ReturnStatement:
+ this._recurse(node.argument, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.SequenceExpression:
+ this._recurseArray(node.expressions, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.SpreadElement:
+ this._recurse(node.argument, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.SpreadProperty:
+ this._recurse(node.argument, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.SwitchStatement:
+ this._recurse(node.discriminant, callback, state);
+ this._recurseArray(node.cases, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.SwitchCase:
+ this._recurse(node.test, callback, state);
+ this._recurseArray(node.consequent, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ConditionalExpression:
+ this._recurse(node.test, callback, state);
+ this._recurse(node.consequent, callback, state);
+ this._recurse(node.alternate, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.TaggedTemplateExpression:
+ this._recurse(node.tag, callback, state);
+ this._recurse(node.quasi, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.TemplateLiteral:
+ this._recurseArray(node.quasis, callback, state);
+ this._recurseArray(node.expressions, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ThrowStatement:
+ this._recurse(node.argument, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.TryStatement:
+ this._recurse(node.block, callback, state);
+ this._recurse(node.handler, callback, state);
+ this._recurse(node.finalizer, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.UnaryExpression:
+ this._recurse(node.argument, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.UpdateExpression:
+ this._recurse(node.argument, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.VariableDeclaration:
+ this._recurseArray(node.declarations, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator:
+ this._recurse(node.id, callback, state);
+ this._recurse(node.init, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.WhileStatement:
+ this._recurse(node.test, callback, state);
+ this._recurse(node.body, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.WithStatement:
+ this._recurse(node.object, callback, state);
+ this._recurse(node.body, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.YieldExpression:
+ this._recurse(node.argument, callback, state);
+ break;
+
+ // Modules.
+
+ case WebInspector.ScriptSyntaxTree.NodeType.ExportAllDeclaration:
+ this._recurse(node.source, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ExportNamedDeclaration:
+ this._recurse(node.declaration, callback, state);
+ this._recurseArray(node.specifiers, callback, state);
+ this._recurse(node.source, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ExportDefaultDeclaration:
+ this._recurse(node.declaration, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ExportSpecifier:
+ this._recurse(node.local, callback, state);
+ this._recurse(node.exported, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ImportDeclaration:
+ this._recurseArray(node.specifiers, callback, state);
+ this._recurse(node.source, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ImportDefaultSpecifier:
+ this._recurse(node.local, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ImportNamespaceSpecifier:
+ this._recurse(node.local, callback, state);
+ break;
+ case WebInspector.ScriptSyntaxTree.NodeType.ImportSpecifier:
+ this._recurse(node.imported, callback, state);
+ this._recurse(node.local, callback, state);
+ break;
+
+ // All the leaf nodes go here.
+ case WebInspector.ScriptSyntaxTree.NodeType.DebuggerStatement:
+ case WebInspector.ScriptSyntaxTree.NodeType.EmptyStatement:
+ case WebInspector.ScriptSyntaxTree.NodeType.Identifier:
+ case WebInspector.ScriptSyntaxTree.NodeType.Import:
+ case WebInspector.ScriptSyntaxTree.NodeType.Literal:
+ case WebInspector.ScriptSyntaxTree.NodeType.MetaProperty:
+ case WebInspector.ScriptSyntaxTree.NodeType.Super:
+ case WebInspector.ScriptSyntaxTree.NodeType.ThisExpression:
+ case WebInspector.ScriptSyntaxTree.NodeType.TemplateElement:
+ break;
+ }
+
+ state.skipChildNodes = false;
+ }
+
+ _recurseArray(array, callback, state)
+ {
+ for (var node of array)
+ this._recurse(node, callback, state);
+ }
+
+ // This function translates from esprima's Abstract Syntax Tree to ours.
+ // Mostly, this is just the identity function. We've added an extra typeProfilingReturnDivot property for functions/methods.
+ // Our AST complies with the Mozilla parser API:
+ // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API
+ _createInternalSyntaxTree(node)
+ {
+ if (!node)
+ return null;
+
+ var result = null;
+ switch (node.type) {
+ case "ArrayExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ArrayExpression,
+ elements: node.elements.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "ArrayPattern":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern,
+ elements: node.elements.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "ArrowFunctionExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression,
+ id: this._createInternalSyntaxTree(node.id),
+ params: node.params.map(this._createInternalSyntaxTree, this),
+ body: this._createInternalSyntaxTree(node.body),
+ generator: node.generator,
+ expression: node.expression, // Boolean indicating if the body a single expression or a block statement.
+ async: node.async,
+ typeProfilingReturnDivot: node.range[0]
+ };
+ break;
+ case "AssignmentExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.AssignmentExpression,
+ operator: node.operator,
+ left: this._createInternalSyntaxTree(node.left),
+ right: this._createInternalSyntaxTree(node.right)
+ };
+ break;
+ case "AssignmentPattern":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.AssignmentPattern,
+ left: this._createInternalSyntaxTree(node.left),
+ right: this._createInternalSyntaxTree(node.right),
+ };
+ break;
+ case "AwaitExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.AwaitExpression,
+ argument: this._createInternalSyntaxTree(node.argument),
+ };
+ break;
+ case "BlockStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.BlockStatement,
+ body: node.body.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "BinaryExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.BinaryExpression,
+ operator: node.operator,
+ left: this._createInternalSyntaxTree(node.left),
+ right: this._createInternalSyntaxTree(node.right)
+ };
+ break;
+ case "BreakStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.BreakStatement,
+ label: this._createInternalSyntaxTree(node.label)
+ };
+ break;
+ case "CallExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.CallExpression,
+ callee: this._createInternalSyntaxTree(node.callee),
+ arguments: node.arguments.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "CatchClause":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.CatchClause,
+ param: this._createInternalSyntaxTree(node.param),
+ body: this._createInternalSyntaxTree(node.body)
+ };
+ break;
+ case "ClassBody":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ClassBody,
+ body: node.body.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "ClassDeclaration":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ClassDeclaration,
+ id: this._createInternalSyntaxTree(node.id),
+ superClass: this._createInternalSyntaxTree(node.superClass),
+ body: this._createInternalSyntaxTree(node.body),
+ };
+ break;
+ case "ClassExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ClassExpression,
+ id: this._createInternalSyntaxTree(node.id),
+ superClass: this._createInternalSyntaxTree(node.superClass),
+ body: this._createInternalSyntaxTree(node.body),
+ };
+ break;
+ case "ConditionalExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ConditionalExpression,
+ test: this._createInternalSyntaxTree(node.test),
+ consequent: this._createInternalSyntaxTree(node.consequent),
+ alternate: this._createInternalSyntaxTree(node.alternate)
+ };
+ break;
+ case "ContinueStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ContinueStatement,
+ label: this._createInternalSyntaxTree(node.label)
+ };
+ break;
+ case "DoWhileStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.DoWhileStatement,
+ body: this._createInternalSyntaxTree(node.body),
+ test: this._createInternalSyntaxTree(node.test)
+ };
+ break;
+ case "DebuggerStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.DebuggerStatement
+ };
+ break;
+ case "EmptyStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.EmptyStatement
+ };
+ break;
+ case "ExpressionStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ExpressionStatement,
+ expression: this._createInternalSyntaxTree(node.expression)
+ };
+ break;
+ case "ForStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ForStatement,
+ init: this._createInternalSyntaxTree(node.init),
+ test: this._createInternalSyntaxTree(node.test),
+ update: this._createInternalSyntaxTree(node.update),
+ body: this._createInternalSyntaxTree(node.body)
+ };
+ break;
+ case "ForInStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ForInStatement,
+ left: this._createInternalSyntaxTree(node.left),
+ right: this._createInternalSyntaxTree(node.right),
+ body: this._createInternalSyntaxTree(node.body)
+ };
+ break;
+ case "ForOfStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ForOfStatement,
+ left: this._createInternalSyntaxTree(node.left),
+ right: this._createInternalSyntaxTree(node.right),
+ body: this._createInternalSyntaxTree(node.body)
+ };
+ break;
+ case "FunctionDeclaration":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration,
+ id: this._createInternalSyntaxTree(node.id),
+ params: node.params.map(this._createInternalSyntaxTree, this),
+ body: this._createInternalSyntaxTree(node.body),
+ generator: node.generator,
+ async: node.async,
+ typeProfilingReturnDivot: node.range[0]
+ };
+ break;
+ case "FunctionExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression,
+ id: this._createInternalSyntaxTree(node.id),
+ params: node.params.map(this._createInternalSyntaxTree, this),
+ body: this._createInternalSyntaxTree(node.body),
+ generator: node.generator,
+ async: node.async,
+ typeProfilingReturnDivot: node.range[0] // This may be overridden in the Property AST node.
+ };
+ break;
+ case "Identifier":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.Identifier,
+ name: node.name
+ };
+ break;
+ case "IfStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.IfStatement,
+ test: this._createInternalSyntaxTree(node.test),
+ consequent: this._createInternalSyntaxTree(node.consequent),
+ alternate: this._createInternalSyntaxTree(node.alternate)
+ };
+ break;
+ case "Literal":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.Literal,
+ value: node.value,
+ raw: node.raw
+ };
+ break;
+ case "LabeledStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.LabeledStatement,
+ label: this._createInternalSyntaxTree(node.label),
+ body: this._createInternalSyntaxTree(node.body)
+ };
+ break;
+ case "LogicalExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.LogicalExpression,
+ left: this._createInternalSyntaxTree(node.left),
+ right: this._createInternalSyntaxTree(node.right),
+ operator: node.operator
+ };
+ break;
+ case "MemberExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.MemberExpression,
+ object: this._createInternalSyntaxTree(node.object),
+ property: this._createInternalSyntaxTree(node.property),
+ computed: node.computed
+ };
+ break;
+ case "MetaProperty":
+ // i.e: new.target produces {meta: "new", property: "target"}
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.MetaProperty,
+ meta: this._createInternalSyntaxTree(node.meta),
+ property: this._createInternalSyntaxTree(node.property),
+ };
+ break;
+ case "MethodDefinition":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.MethodDefinition,
+ key: this._createInternalSyntaxTree(node.key),
+ value: this._createInternalSyntaxTree(node.value),
+ computed: node.computed,
+ kind: node.kind,
+ static: node.static
+ };
+ result.value.typeProfilingReturnDivot = node.range[0]; // "g" in "get" or "s" in "set" or "[" in "['computed']" or "m" in "methodName".
+ break;
+ case "NewExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.NewExpression,
+ callee: this._createInternalSyntaxTree(node.callee),
+ arguments: node.arguments.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "ObjectExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ObjectExpression,
+ properties: node.properties.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "ObjectPattern":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern,
+ properties: node.properties.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "Program":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.Program,
+ sourceType: node.sourceType,
+ body: node.body.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "Property":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.Property,
+ key: this._createInternalSyntaxTree(node.key),
+ value: this._createInternalSyntaxTree(node.value),
+ kind: node.kind,
+ method: node.method,
+ computed: node.computed
+ };
+ if (result.kind === "get" || result.kind === "set" || result.method)
+ result.value.typeProfilingReturnDivot = node.range[0]; // "g" in "get" or "s" in "set" or "[" in "['computed']" method or "m" in "methodName".
+ break;
+ case "RestElement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.RestElement,
+ argument: this._createInternalSyntaxTree(node.argument)
+ };
+ break;
+ case "RestProperty":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.RestProperty,
+ argument: this._createInternalSyntaxTree(node.argument),
+ };
+ break;
+ case "ReturnStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ReturnStatement,
+ argument: this._createInternalSyntaxTree(node.argument)
+ };
+ break;
+ case "SequenceExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.SequenceExpression,
+ expressions: node.expressions.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "SpreadElement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.SpreadElement,
+ argument: this._createInternalSyntaxTree(node.argument),
+ };
+ break;
+ case "SpreadProperty":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.SpreadProperty,
+ argument: this._createInternalSyntaxTree(node.argument),
+ };
+ break;
+ case "Super":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.Super
+ };
+ break;
+ case "SwitchStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.SwitchStatement,
+ discriminant: this._createInternalSyntaxTree(node.discriminant),
+ cases: node.cases.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "SwitchCase":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.SwitchCase,
+ test: this._createInternalSyntaxTree(node.test),
+ consequent: node.consequent.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "TaggedTemplateExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.TaggedTemplateExpression,
+ tag: this._createInternalSyntaxTree(node.tag),
+ quasi: this._createInternalSyntaxTree(node.quasi)
+ };
+ break;
+ case "TemplateElement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.TemplateElement,
+ value: node.value,
+ tail: node.tail
+ };
+ break;
+ case "TemplateLiteral":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.TemplateLiteral,
+ quasis: node.quasis.map(this._createInternalSyntaxTree, this),
+ expressions: node.expressions.map(this._createInternalSyntaxTree, this)
+ };
+ break;
+ case "ThisExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ThisExpression
+ };
+ break;
+ case "ThrowStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ThrowStatement,
+ argument: this._createInternalSyntaxTree(node.argument)
+ };
+ break;
+ case "TryStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.TryStatement,
+ block: this._createInternalSyntaxTree(node.block),
+ handler: this._createInternalSyntaxTree(node.handler),
+ finalizer: this._createInternalSyntaxTree(node.finalizer)
+ };
+ break;
+ case "UnaryExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.UnaryExpression,
+ operator: node.operator,
+ argument: this._createInternalSyntaxTree(node.argument)
+ };
+ break;
+ case "UpdateExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.UpdateExpression,
+ operator: node.operator,
+ prefix: node.prefix,
+ argument: this._createInternalSyntaxTree(node.argument)
+ };
+ break;
+ case "VariableDeclaration":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.VariableDeclaration,
+ declarations: node.declarations.map(this._createInternalSyntaxTree, this),
+ kind: node.kind
+ };
+ break;
+ case "VariableDeclarator":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator,
+ id: this._createInternalSyntaxTree(node.id),
+ init: this._createInternalSyntaxTree(node.init)
+ };
+ break;
+ case "WhileStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.WhileStatement,
+ test: this._createInternalSyntaxTree(node.test),
+ body: this._createInternalSyntaxTree(node.body)
+ };
+ break;
+ case "WithStatement":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.WithStatement,
+ object: this._createInternalSyntaxTree(node.object),
+ body: this._createInternalSyntaxTree(node.body)
+ };
+ break;
+ case "YieldExpression":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.YieldExpression,
+ argument: this._createInternalSyntaxTree(node.argument),
+ delegate: node.delegate
+ };
+ break;
+
+ // Modules.
+
+ case "ExportAllDeclaration":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ExportAllDeclaration,
+ source: this._createInternalSyntaxTree(node.source),
+ };
+ break;
+ case "ExportNamedDeclaration":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ExportNamedDeclaration,
+ declaration: this._createInternalSyntaxTree(node.declaration),
+ specifiers: node.specifiers.map(this._createInternalSyntaxTree, this),
+ source: this._createInternalSyntaxTree(node.source),
+ };
+ break;
+ case "ExportDefaultDeclaration":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ExportDefaultDeclaration,
+ declaration: this._createInternalSyntaxTree(node.declaration),
+ };
+ break;
+ case "ExportSpecifier":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ExportSpecifier,
+ local: this._createInternalSyntaxTree(node.local),
+ exported: this._createInternalSyntaxTree(node.exported),
+ };
+ break;
+ case "Import":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.Import,
+ };
+ break;
+ case "ImportDeclaration":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ImportDeclaration,
+ specifiers: node.specifiers.map(this._createInternalSyntaxTree, this),
+ source: this._createInternalSyntaxTree(node.source),
+ };
+ break;
+ case "ImportDefaultSpecifier":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ImportDefaultSpecifier,
+ local: this._createInternalSyntaxTree(node.local),
+ };
+ break;
+ case "ImportNamespaceSpecifier":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ImportNamespaceSpecifier,
+ local: this._createInternalSyntaxTree(node.local),
+ };
+ break;
+ case "ImportSpecifier":
+ result = {
+ type: WebInspector.ScriptSyntaxTree.NodeType.ImportSpecifier,
+ imported: this._createInternalSyntaxTree(node.imported),
+ local: this._createInternalSyntaxTree(node.local),
+ };
+ break;
+
+ default:
+ console.error("Unsupported Syntax Tree Node: " + node.type, node);
+ return null;
+ }
+
+ result.range = node.range;
+ // This is an object for which you can add fields to an AST node without worrying about polluting the syntax-related fields of the node.
+ result.attachments = {};
+
+ return result;
+ }
+};
+
+// This should be kept in sync with an enum in JavaSciptCore/runtime/TypeProfiler.h
+WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor = {
+ NormalExpression: 1,
+ FunctionReturn: 2
+};
+
+WebInspector.ScriptSyntaxTree.NodeType = {
+ ArrayExpression: Symbol("array-expression"),
+ ArrayPattern: Symbol("array-pattern"),
+ ArrowFunctionExpression: Symbol("arrow-function-expression"),
+ AssignmentExpression: Symbol("assignment-expression"),
+ AssignmentPattern: Symbol("assignment-pattern"),
+ AwaitExpression: Symbol("await-expression"),
+ BinaryExpression: Symbol("binary-expression"),
+ BlockStatement: Symbol("block-statement"),
+ BreakStatement: Symbol("break-statement"),
+ CallExpression: Symbol("call-expression"),
+ CatchClause: Symbol("catch-clause"),
+ ClassBody: Symbol("class-body"),
+ ClassDeclaration: Symbol("class-declaration"),
+ ClassExpression: Symbol("class-expression"),
+ ConditionalExpression: Symbol("conditional-expression"),
+ ContinueStatement: Symbol("continue-statement"),
+ DebuggerStatement: Symbol("debugger-statement"),
+ DoWhileStatement: Symbol("do-while-statement"),
+ EmptyStatement: Symbol("empty-statement"),
+ ExportAllDeclaration: Symbol("export-all-declaration"),
+ ExportDefaultDeclaration: Symbol("export-default-declaration"),
+ ExportNamedDeclaration: Symbol("export-named-declaration"),
+ ExportSpecifier: Symbol("export-specifier"),
+ ExpressionStatement: Symbol("expression-statement"),
+ ForInStatement: Symbol("for-in-statement"),
+ ForOfStatement: Symbol("for-of-statement"),
+ ForStatement: Symbol("for-statement"),
+ FunctionDeclaration: Symbol("function-declaration"),
+ FunctionExpression: Symbol("function-expression"),
+ Identifier: Symbol("identifier"),
+ IfStatement: Symbol("if-statement"),
+ Import: Symbol("import"),
+ ImportDeclaration: Symbol("import-declaration"),
+ ImportDefaultSpecifier: Symbol("import-default-specifier"),
+ ImportNamespaceSpecifier: Symbol("import-namespace-specifier"),
+ ImportSpecifier: Symbol("import-specifier"),
+ LabeledStatement: Symbol("labeled-statement"),
+ Literal: Symbol("literal"),
+ LogicalExpression: Symbol("logical-expression"),
+ MemberExpression: Symbol("member-expression"),
+ MetaProperty: Symbol("meta-property"),
+ MethodDefinition: Symbol("method-definition"),
+ NewExpression: Symbol("new-expression"),
+ ObjectExpression: Symbol("object-expression"),
+ ObjectPattern: Symbol("object-pattern"),
+ Program: Symbol("program"),
+ Property: Symbol("property"),
+ RestElement: Symbol("rest-element"),
+ RestProperty: Symbol("rest-property"),
+ ReturnStatement: Symbol("return-statement"),
+ SequenceExpression: Symbol("sequence-expression"),
+ SpreadElement: Symbol("spread-element"),
+ SpreadProperty: Symbol("spread-property"),
+ Super: Symbol("super"),
+ SwitchCase: Symbol("switch-case"),
+ SwitchStatement: Symbol("switch-statement"),
+ TaggedTemplateExpression: Symbol("tagged-template-expression"),
+ TemplateElement: Symbol("template-element"),
+ TemplateLiteral: Symbol("template-literal"),
+ ThisExpression: Symbol("this-expression"),
+ ThrowStatement: Symbol("throw-statement"),
+ TryStatement: Symbol("try-statement"),
+ UnaryExpression: Symbol("unary-expression"),
+ UpdateExpression: Symbol("update-expression"),
+ VariableDeclaration: Symbol("variable-declaration"),
+ VariableDeclarator: Symbol("variable-declarator"),
+ WhileStatement: Symbol("while-statement"),
+ WithStatement: Symbol("with-statement"),
+ YieldExpression: Symbol("yield-expression"),
+};
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/ast.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/ast.js
new file mode 100644
index 0000000000..56558a70af
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/ast.js
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+const Basic = {};
+
+Basic.NumberApply = function(state)
+{
+ // I'd call this arguments but we're in strict mode.
+ let parameters = this.parameters.map(value => value.evaluate(state));
+
+ return state.getValue(this.name, parameters.length).apply(state, parameters);
+};
+
+Basic.Variable = function(state)
+{
+ let parameters = this.parameters.map(value => value.evaluate(state));
+
+ return state.getValue(this.name, parameters.length).leftApply(state, parameters);
+}
+
+Basic.Const = function(state)
+{
+ return this.value;
+}
+
+Basic.NumberPow = function(state)
+{
+ return Math.pow(this.left.evaluate(state), this.right.evaluate(state));
+}
+
+Basic.NumberMul = function(state)
+{
+ return this.left.evaluate(state) * this.right.evaluate(state);
+}
+
+Basic.NumberDiv = function(state)
+{
+ return this.left.evaluate(state) / this.right.evaluate(state);
+}
+
+Basic.NumberNeg = function(state)
+{
+ return -this.term.evaluate(state);
+}
+
+Basic.NumberAdd = function(state)
+{
+ return this.left.evaluate(state) + this.right.evaluate(state);
+}
+
+Basic.NumberSub = function(state)
+{
+ return this.left.evaluate(state) - this.right.evaluate(state);
+}
+
+Basic.StringVar = function(state)
+{
+ let value = state.stringValues.get(this.name);
+ if (value == null)
+ state.abort("Could not find string variable " + this.name);
+ return value;
+}
+
+Basic.Equals = function(state)
+{
+ return this.left.evaluate(state) == this.right.evaluate(state);
+}
+
+Basic.NotEquals = function(state)
+{
+ return this.left.evaluate(state) != this.right.evaluate(state);
+}
+
+Basic.LessThan = function(state)
+{
+ return this.left.evaluate(state) < this.right.evaluate(state);
+}
+
+Basic.GreaterThan = function(state)
+{
+ return this.left.evaluate(state) > this.right.evaluate(state);
+}
+
+Basic.LessEqual = function(state)
+{
+ return this.left.evaluate(state) <= this.right.evaluate(state);
+}
+
+Basic.GreaterEqual = function(state)
+{
+ return this.left.evaluate(state) >= this.right.evaluate(state);
+}
+
+Basic.GoTo = function*(state)
+{
+ state.nextLineNumber = this.target;
+}
+
+Basic.GoSub = function*(state)
+{
+ state.subStack.push(state.nextLineNumber);
+ state.nextLineNumber = this.target;
+}
+
+Basic.Def = function*(state)
+{
+ state.validate(!state.values.has(this.name), "Cannot redefine function");
+ state.values.set(this.name, new NumberFunction(this.parameters, this.expression));
+}
+
+Basic.Let = function*(state)
+{
+ this.variable.evaluate(state).assign(this.expression.evaluate(state));
+}
+
+Basic.If = function*(state)
+{
+ if (this.condition.evaluate(state))
+ state.nextLineNumber = this.target;
+}
+
+Basic.Return = function*(state)
+{
+ this.validate(state.subStack.length, "Not in a subroutine");
+ this.nextLineNumber = state.subStack.pop();
+}
+
+Basic.Stop = function*(state)
+{
+ state.nextLineNumber = null;
+}
+
+Basic.On = function*(state)
+{
+ let index = this.expression.evaluate(state);
+ if (!(index >= 1) || !(index <= this.targets.length))
+ state.abort("Index out of bounds: " + index);
+ this.nextLineNumber = this.targets[Math.floor(index)];
+}
+
+Basic.For = function*(state)
+{
+ let sideState = state.getSideState(this);
+ sideState.variable = state.getValue(this.variable, 0).leftApply(state, []);
+ sideState.initialValue = this.initial.evaluate(state);
+ sideState.limitValue = this.limit.evaluate(state);
+ sideState.stepValue = this.step.evaluate(state);
+ sideState.variable.assign(sideState.initialValue);
+ sideState.shouldStop = function() {
+ return (sideState.variable.value - sideState.limitValue) * Math.sign(sideState.stepValue) > 0;
+ };
+ if (sideState.shouldStop())
+ this.nextLineNumber = this.target.lineNumber + 1;
+}
+
+Basic.Next = function*(state)
+{
+ let sideState = state.getSideState(this.target);
+ sideState.variable.assign(sideState.variable.value + sideState.stepValue);
+ if (sideState.shouldStop())
+ return;
+ state.nextLineNumber = this.target.lineNumber + 1;
+}
+
+Basic.Next.isBlockEnd = true;
+
+Basic.Print = function*(state)
+{
+ let string = "";
+ for (let item of this.items) {
+ switch (item.kind) {
+ case "comma":
+ while (string.length % 14)
+ string += " ";
+ break;
+ case "tab": {
+ let value = item.value.evaluate(state);
+ value = Math.max(Math.round(value), 1);
+ while (string.length % value)
+ string += " ";
+ break;
+ }
+ case "string":
+ case "number":
+ string += item.value.evaluate(state);
+ break;
+ default:
+ throw new Error("Bad item kind: " + item.kind);
+ }
+ }
+
+ yield {kind: "output", string};
+}
+
+Basic.Input = function*(state)
+{
+ let results = yield {kind: "input", numItems: this.items.length};
+ state.validate(results != null && results.length == this.items.length, "Input did not get the right number of items");
+ for (let i = 0; i < results.length; ++i)
+ this.items[i].evaluate(state).assign(results[i]);
+}
+
+Basic.Read = function*(state)
+{
+ for (let item of this.items) {
+ state.validate(state.dataIndex < state.program.data.length, "Attempting to read past the end of data");
+ item.assign(state.program.data[state.dataIndex++]);
+ }
+}
+
+Basic.Restore = function*(state)
+{
+ state.dataIndex = 0;
+}
+
+Basic.Dim = function*(state)
+{
+ for (let item of this.items) {
+ state.validate(!state.values.has(item.name), "Variable " + item.name + " already exists");
+ state.validate(item.bounds.length, "Dim statement is for arrays");
+ state.values.set(item.name, new NumberArray(item.bounds.map(bound => bound + 1)));
+ }
+}
+
+Basic.Randomize = function*(state)
+{
+ state.rng = createRNGWithRandomSeed();
+}
+
+Basic.End = function*(state)
+{
+ state.nextLineNumber = null;
+}
+
+Basic.End.isBlockEnd = true;
+
+Basic.Program = function* programGenerator(state)
+{
+ state.validate(state.program == this, "State must match program");
+ let maxLineNumber = Math.max(...this.statements.keys());
+ while (state.nextLineNumber != null) {
+ state.validate(state.nextLineNumber <= maxLineNumber, "Went out of bounds of the program");
+ let statement = this.statements.get(state.nextLineNumber++);
+ if (statement == null || statement.process == null)
+ continue;
+ state.statement = statement;
+ yield* statement.process(state);
+ }
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/basic-tests.yaml b/third_party/webkit/PerformanceTests/ARES-6/Basic/basic-tests.yaml
new file mode 100644
index 0000000000..6d55fbe63a
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/basic-tests.yaml
@@ -0,0 +1,28 @@
+# Copyright (C) 2016 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+- path: .
+ tests:
+ - stress-test.js
+ cmd: defaultRunNoisyTest unless parseRunCommands
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/basic.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/basic.js
new file mode 100644
index 0000000000..88288d1176
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/basic.js
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+function prepare(string)
+{
+ let program = parse(lex(string)).program();
+ return program.process(new State(program));
+}
+
+function simulate(program, inputs = [])
+{
+ let result = "";
+ let args = [];
+ for (;;) {
+ let next = program.next(...args);
+ args = [];
+ if (next.done)
+ break;
+ if (next.value.kind == "output") {
+ result += next.value.string + "\n";
+ continue;
+ }
+ if (next.value.kind == "input") {
+ args = inputs.splice(0, next.value.numItems);
+ continue;
+ }
+ }
+ return result;
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/benchmark.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/benchmark.js
new file mode 100644
index 0000000000..7730411bab
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/benchmark.js
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class BasicBenchmark {
+ constructor(verbose = 0)
+ {
+ this._verbose = verbose;
+ }
+
+ runIteration()
+ {
+ function expect(program, expected, ...inputs)
+ {
+ let result = simulate(prepare(program, inputs));
+ if (result != expected)
+ throw new Error("Program " + JSON.stringify(program) + " with inputs " + JSON.stringify(inputs) + " produced " + JSON.stringify(result) + " but we expected " + JSON.stringify(expected));
+ }
+
+ expect("10 print \"hello, world!\"\n20 end", "hello, world!\n");
+ expect("10 let x = 0\n20 let x = x + 1\n30 print x\n40 if x < 10 then 20\n50 end", "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n");
+ expect("10 print int(rnd * 100)\n20 end\n", "98\n");
+ expect("10 let value = int(rnd * 2000)\n20 print value\n30 if value <> 100 then 10\n40 end", "1974\n697\n1126\n1998\n1658\n264\n1650\n1677\n226\n117\n492\n861\n877\n1969\n38\n1039\n197\n1261\n1102\n1522\n916\n1683\n1943\n1835\n476\n1898\n939\n176\n966\n908\n474\n614\n1326\n564\n1916\n728\n524\n162\n1303\n758\n832\n1279\n1856\n1876\n982\n6\n1613\n1781\n681\n1238\n494\n1583\n1953\n788\n1026\n347\n1116\n1465\n514\n583\n463\n1970\n1573\n412\n1256\n1453\n838\n1538\n1984\n1598\n209\n411\n1700\n546\n861\n91\n132\n884\n378\n693\n11\n433\n1719\n860\n164\n472\n231\n1786\n806\n811\n106\n1697\n118\n980\n890\n1199\n227\n1667\n1933\n1903\n1390\n1595\n923\n1746\n39\n1361\n117\n1297\n923\n901\n1180\n818\n1444\n269\n933\n327\n1744\n1082\n1527\n1260\n622\n528\n318\n856\n296\n1796\n1574\n585\n1871\n111\n827\n1725\n1320\n1868\n1695\n1914\n216\n63\n1847\n156\n671\n893\n127\n1867\n811\n279\n913\n310\n814\n907\n1363\n1624\n1670\n478\n714\n436\n355\n1484\n1628\n1208\n800\n611\n917\n829\n830\n273\n1791\n340\n214\n992\n1444\n442\n1555\n144\n1194\n282\n180\n1228\n1251\n1883\n678\n1555\n347\n72\n1661\n1828\n1090\n1183\n957\n1685\n930\n475\n103\n759\n1725\n1902\n1662\n1587\n61\n614\n863\n1418\n321\n1050\n505\n1622\n1425\n803\n589\n1511\n1098\n1051\n1554\n1898\n27\n747\n813\n1544\n332\n728\n1363\n771\n759\n1145\n1098\n1991\n385\n230\n520\n1369\n1840\n1285\n1562\n1845\n102\n760\n1874\n748\n361\n575\n277\n1661\n1764\n1117\n332\n757\n1766\n1722\n143\n474\n1507\n1294\n1180\n1578\n904\n845\n321\n496\n1911\n1784\n1116\n938\n1591\n1403\n1374\n533\n1085\n452\n708\n1096\n1634\n522\n564\n1397\n1357\n980\n978\n1760\n1088\n1361\n1184\n314\n1242\n217\n133\n1187\n1723\n646\n605\n591\n46\n135\n1420\n1821\n1147\n1211\n61\n244\n1307\n1551\n449\n1122\n1336\n140\n880\n22\n1155\n1326\n590\n1499\n1376\n112\n1771\n1897\n1071\n938\n1685\n1963\n1203\n1296\n804\n1275\n453\n1387\n482\n1262\n1883\n1381\n418\n1417\n1222\n1208\n1263\n632\n450\n1422\n1285\n1408\n644\n665\n275\n363\n1012\n165\n354\n80\n609\n291\n1661\n1724\n117\n407\n59\n906\n1224\n136\n855\n1275\n1468\n482\n1537\n1283\n1784\n1568\n1832\n452\n867\n1546\n1467\n800\n45\n1225\n1890\n465\n1372\n47\n1608\n193\n1345\n1847\n1059\n1788\n518\n52\n1052\n1003\n1210\n1135\n1433\n519\n1558\n39\n1249\n1017\n39\n1713\n1449\n1245\n1354\n82\n1140\n916\n1595\n838\n607\n389\n1270\n821\n247\n1692\n1305\n1211\n1960\n429\n1703\n1635\n575\n1618\n1490\n1495\n682\n1256\n964\n420\n1520\n1429\n1997\n396\n382\n856\n1182\n296\n1295\n298\n1892\n990\n711\n934\n1939\n1339\n682\n1631\n1533\n742\n1520\n1281\n1332\n1042\n656\n1576\n1253\n1608\n375\n169\n14\n414\n1586\n1562\n1508\n1245\n303\n715\n1053\n340\n915\n160\n1796\n111\n925\n1872\n735\n350\n107\n1913\n1653\n987\n825\n1893\n1601\n460\n1228\n1526\n1613\n1359\n1854\n1352\n542\n665\n109\n1874\n467\n533\n1188\n1629\n851\n630\n1060\n1530\n1853\n743\n765\n126\n1540\n1411\n858\n1741\n284\n299\n577\n1848\n1495\n283\n1886\n284\n129\n1077\n1245\n1364\n1505\n176\n1012\n1663\n1306\n1586\n410\n315\n660\n256\n1102\n1289\n1292\n939\n762\n601\n1140\n574\n1851\n44\n560\n1948\n1142\n1787\n947\n948\n280\n1210\n1139\n1072\n1033\n92\n1244\n1589\n1079\n22\n1514\n163\n157\n1742\n1058\n514\n196\n1858\n565\n354\n1413\n792\n183\n526\n1724\n1007\n158\n1229\n1802\n99\n1514\n708\n1276\n1802\n1564\n1387\n1235\n1132\n715\n1584\n617\n1664\n1559\n1625\n1037\n601\n1175\n1713\n107\n88\n384\n1634\n904\n1835\n1472\n212\n1145\n443\n1617\n866\n1963\n937\n1917\n855\n1215\n1867\n520\n892\n1483\n1898\n1747\n1441\n289\n1609\n328\n566\n271\n458\n1616\n843\n1107\n507\n1090\n854\n1094\n806\n166\n408\n661\n334\n230\n1917\n1323\n927\n1912\n673\n311\n952\n1783\n1549\n1714\n1500\n450\n1498\n530\n442\n607\n609\n1226\n370\n1769\n1815\n788\n536\n293\n115\n947\n290\n1764\n243\n1219\n1851\n289\n599\n1528\n150\n1859\n297\n279\n1542\n1719\n1910\n551\n401\n952\n1764\n946\n1835\n647\n1309\n271\n275\n70\n129\n1518\n972\n1164\n816\n1125\n575\n588\n1456\n1154\n290\n1681\n1133\n561\n343\n1360\n1035\n1158\n1365\n744\n781\n58\n531\n271\n1612\n1774\n28\n1480\n1312\n1855\n666\n1574\n613\n42\n456\n351\n727\n1503\n1115\n333\n1972\n822\n1575\n848\n1087\n1262\n1671\n710\n460\n1816\n287\n172\n492\n1079\n582\n1236\n1756\n1792\n1095\n1205\n1894\n22\n1930\n1529\n1547\n1383\n1768\n364\n1108\n1972\n287\n200\n230\n1335\n187\n486\n1722\n20\n963\n792\n1114\n633\n1862\n1433\n829\n737\n215\n1570\n378\n1677\n944\n1301\n1160\n500\n150\n886\n1337\n662\n1062\n290\n460\n592\n1867\n872\n155\n1613\n1913\n1548\n1847\n855\n1702\n952\n1894\n587\n1813\n1021\n21\n654\n254\n910\n1696\n1606\n679\n1222\n696\n1319\n368\n447\n549\n905\n1194\n189\n1766\n616\n278\n1418\n1965\n872\n998\n1268\n1673\n1647\n1163\n533\n1650\n1849\n1124\n1252\n1412\n703\n944\n468\n1485\n1352\n681\n864\n1432\n1771\n497\n956\n1794\n363\n1099\n1804\n457\n1227\n1487\n446\n1993\n1576\n272\n709\n1810\n330\n876\n1107\n1187\n122\n1625\n472\n676\n314\n1257\n1509\n350\n741\n366\n33\n536\n293\n1663\n1039\n1527\n126\n923\n1937\n1767\n1302\n1510\n1518\n1343\n91\n1551\n1614\n1687\n1748\n137\n75\n738\n1977\n751\n237\n313\n566\n24\n202\n889\n1716\n1460\n129\n1760\n1597\n96\n1057\n1323\n1188\n1373\n537\n955\n65\n1679\n1441\n1315\n398\n647\n1470\n1335\n617\n331\n796\n129\n1635\n1497\n836\n855\n1472\n1828\n568\n862\n690\n1370\n1657\n819\n45\n420\n258\n1980\n672\n615\n358\n852\n1148\n1897\n1306\n1092\n1405\n719\n1752\n1456\n1338\n332\n351\n479\n747\n249\n1977\n1671\n1061\n1685\n306\n254\n1060\n764\n420\n1139\n1452\n426\n835\n929\n1424\n1336\n697\n191\n1697\n1897\n644\n546\n982\n359\n1201\n1095\n1623\n1947\n215\n10\n855\n297\n551\n1037\n945\n396\n211\n1059\n423\n1521\n1770\n203\n1828\n879\n1179\n1912\n1028\n1416\n1845\n698\n715\n1857\n817\n50\n473\n1122\n126\n70\n1773\n40\n1970\n1311\n826\n355\n1921\n23\n526\n1717\n1397\n1932\n1075\n1652\n997\n1039\n1481\n779\n415\n49\n1330\n317\n1701\n690\n245\n1824\n639\n799\n1240\n422\n344\n1639\n20\n546\n912\n1930\n1368\n1541\n1109\n369\n66\n1564\n444\n1928\n1963\n1899\n744\n1593\n1702\n100\n");
+
+ expect("10 dim a(2000)\n20 for i = 2 to 2000\n30 let a(i) = 1\n40 next i\n50 for i = 2 to sqr(2000)\n60 if a(i) = 0 then 100\n70 for j = i ^ 2 to 2000 step i\n80 let a(j) = 0\n90 next j\n100 next i\n110 for i = 2 to 2000\n120 if a(i) = 0 then 140\n130 print i\n140 next i\n150 end\n", "2\n3\n5\n7\n11\n13\n17\n19\n23\n29\n31\n37\n41\n43\n47\n53\n59\n61\n67\n71\n73\n79\n83\n89\n97\n101\n103\n107\n109\n113\n127\n131\n137\n139\n149\n151\n157\n163\n167\n173\n179\n181\n191\n193\n197\n199\n211\n223\n227\n229\n233\n239\n241\n251\n257\n263\n269\n271\n277\n281\n283\n293\n307\n311\n313\n317\n331\n337\n347\n349\n353\n359\n367\n373\n379\n383\n389\n397\n401\n409\n419\n421\n431\n433\n439\n443\n449\n457\n461\n463\n467\n479\n487\n491\n499\n503\n509\n521\n523\n541\n547\n557\n563\n569\n571\n577\n587\n593\n599\n601\n607\n613\n617\n619\n631\n641\n643\n647\n653\n659\n661\n673\n677\n683\n691\n701\n709\n719\n727\n733\n739\n743\n751\n757\n761\n769\n773\n787\n797\n809\n811\n821\n823\n827\n829\n839\n853\n857\n859\n863\n877\n881\n883\n887\n907\n911\n919\n929\n937\n941\n947\n953\n967\n971\n977\n983\n991\n997\n1009\n1013\n1019\n1021\n1031\n1033\n1039\n1049\n1051\n1061\n1063\n1069\n1087\n1091\n1093\n1097\n1103\n1109\n1117\n1123\n1129\n1151\n1153\n1163\n1171\n1181\n1187\n1193\n1201\n1213\n1217\n1223\n1229\n1231\n1237\n1249\n1259\n1277\n1279\n1283\n1289\n1291\n1297\n1301\n1303\n1307\n1319\n1321\n1327\n1361\n1367\n1373\n1381\n1399\n1409\n1423\n1427\n1429\n1433\n1439\n1447\n1451\n1453\n1459\n1471\n1481\n1483\n1487\n1489\n1493\n1499\n1511\n1523\n1531\n1543\n1549\n1553\n1559\n1567\n1571\n1579\n1583\n1597\n1601\n1607\n1609\n1613\n1619\n1621\n1627\n1637\n1657\n1663\n1667\n1669\n1693\n1697\n1699\n1709\n1721\n1723\n1733\n1741\n1747\n1753\n1759\n1777\n1783\n1787\n1789\n1801\n1811\n1823\n1831\n1847\n1861\n1867\n1871\n1873\n1877\n1879\n1889\n1901\n1907\n1913\n1931\n1933\n1949\n1951\n1973\n1979\n1987\n1993\n1997\n1999\n");
+ }
+}
+
+function runBenchmark()
+{
+ const verbose = 0;
+ const numIterations = 150;
+
+ let before = currentTime();
+
+ let benchmark = new Benchmark(verbose);
+
+ for (let iteration = 0; iteration < numIterations; ++iteration)
+ benchmark.runIteration();
+
+ let after = currentTime();
+ return after - before;
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/caseless_map.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/caseless_map.js
new file mode 100644
index 0000000000..669913756b
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/caseless_map.js
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class CaselessMap {
+ constructor(otherMap)
+ {
+ if (otherMap == null)
+ this._map = new Map();
+ else
+ this._map = new Map(otherMap._map);
+ }
+
+ set(key, value)
+ {
+ this._map.set(key.toLowerCase(), value);
+ }
+
+ has(key)
+ {
+ return this._map.has(key.toLowerCase());
+ }
+
+ get(key)
+ {
+ return this._map.get(key.toLowerCase());
+ }
+
+ [Symbol.iterator]()
+ {
+ return this._map[Symbol.iterator]();
+ }
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/lexer.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/lexer.js
new file mode 100644
index 0000000000..5dfd831495
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/lexer.js
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+// Loosely based on ECMA 55 sections 4-8, but loosened to allow for modern conventions, like
+// multi-character variable names. But this doesn't go too far - in particular, this doesn't do
+// unicode, because that would require more thought.
+function* lex(string)
+{
+ let sourceLineNumber = 0;
+ for (let line of string.split("\n")) {
+ ++sourceLineNumber;
+
+ function consumeWhitespace()
+ {
+ if (/^\s+/.test(line))
+ line = RegExp.rightContext;
+ }
+
+ function consume(kind)
+ {
+ line = RegExp.rightContext;
+ return {kind, string: RegExp.lastMatch, sourceLineNumber, userLineNumber};
+ }
+
+ const isIdentifier = /^[a-z_]([a-z0-9_]*)/i;
+ const isNumber = /^(([0-9]+(\.([0-9]*))?)|(\.[0-9]+)(e([+-]?)([0-9]+))?)/i;
+ const isString = /^\"([^\"]|(\"\"))*\"/;
+ const isKeyword = /^((base)|(data)|(def)|(dim)|(end)|(for)|(go)|(gosub)|(goto)|(if)|(input)|(let)|(next)|(on)|(option)|(print)|(randomize)|(read)|(restore)|(return)|(step)|(stop)|(sub)|(then)|(to))/i;
+ const isOperator = /^(-|\+|\*|\/|\^|\(|\)|(<[>=]?)|(>=?)|=|,|\$|;)/;
+ const isRem = /^rem\s.*/;
+
+ consumeWhitespace();
+
+ if (!/^[0-9]+/.test(line))
+ throw new Error("At line " + sourceLineNumber + ": Expect line number: " + line);
+ let userLineNumber = +RegExp.lastMatch;
+ line = RegExp.rightContext;
+ yield {kind: "userLineNumber", string: RegExp.lastMatch, sourceLineNumber, userLineNumber};
+
+ consumeWhitespace();
+
+ while (line.length) {
+ if (isKeyword.test(line))
+ yield consume("keyword");
+ else if (isIdentifier.test(line))
+ yield consume("identifier");
+ else if (isNumber.test(line)) {
+ let token = consume("number");
+ token.value = +token.string;
+ yield token;
+ } else if (isString.test(line)) {
+ let token = consume("string");
+ token.value = "";
+ for (let i = 1; i < token.string.length - 1; ++i) {
+ let char = token.string.charAt(i);
+ if (char == "\"")
+ i++;
+ token.value += char;
+ }
+ yield token;
+ } else if (isOperator.test(line))
+ yield consume("operator");
+ else if (isRem.test(line))
+ yield consume("remark");
+ else
+ throw new Error("At line " + sourceLineNumber + ": Cannot lex token: " + line);
+ consumeWhitespace();
+ }
+
+ // Note: this is necessary for the parser, which may look-ahead without checking if we're
+ // done. Fortunately, it won't look-ahead past a newLine.
+ yield {kind: "newLine", string:"\n", sourceLineNumber, userLineNumber};
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/number.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/number.js
new file mode 100644
index 0000000000..e3f7a00231
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/number.js
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class NumberValue {
+ constructor(value = 0)
+ {
+ this._value = value;
+ }
+
+ get value() { return this._value; }
+
+ apply(state, parameters)
+ {
+ state.validate(parameters.length == 0, "Should not pass arguments to simple numeric variables");
+ return this._value;
+ }
+
+ leftApply(state, parameters)
+ {
+ state.validate(parameters.length == 0, "Should not pass arguments to simple numeric variables");
+ return this;
+ }
+
+ assign(value)
+ {
+ this._value = value;
+ }
+}
+
+class NumberArray {
+ constructor(dim = [11])
+ {
+ function allocateDim(index)
+ {
+ let result = new Array(dim[index]);
+ if (index + 1 < dim.length) {
+ for (let i = 0; i < dim[index]; ++i)
+ result[i] = allocateDim(index + 1);
+ } else {
+ for (let i = 0; i < dim[index]; ++i)
+ result[i] = new NumberValue();
+ }
+ return result;
+ }
+
+ this._array = allocateDim(0);
+ this._dim = dim;
+ }
+
+ apply(state, parameters)
+ {
+ return this.leftApply(state, parameters).apply(state, []);
+ }
+
+ leftApply(state, parameters)
+ {
+ if (this._dim.length != parameters.length)
+ state.abort("Expected " + this._dim.length + " arguments but " + parameters.length + " were passed.");
+ let result = this._array;
+ for (var i = 0; i < parameters.length; ++i) {
+ let index = Math.floor(parameters[i]);
+ if (!(index >= state.program.base) || !(index < result.length))
+ state.abort("Index out of bounds: " + index);
+ result = result[index];
+ }
+ return result;
+ }
+}
+
+class NumberFunction {
+ constructor(parameters, code)
+ {
+ this._parameters = parameters;
+ this._code = code;
+ }
+
+ apply(state, parameters)
+ {
+ if (this._parameters.length != parameters.length)
+ state.abort("Expected " + this._parameters.length + " arguments but " + parameters.length + " were passed");
+ let oldValues = state.values;
+ state.values = new Map(oldValues);
+ for (let i = 0; i < parameters.length; ++i)
+ state.values.set(this._parameters[i], parameters[i]);
+ let result = this.code.evaluate(state);
+ state.values = oldValues;
+ return result;
+ }
+
+ leftApply(state, parameters)
+ {
+ state.abort("Cannot use a function as an lvalue");
+ }
+}
+
+class NativeFunction {
+ constructor(callback)
+ {
+ this._callback = callback;
+ }
+
+ apply(state, parameters)
+ {
+ if (this._callback.length != parameters.length)
+ state.abort("Expected " + this._callback.length + " arguments but " + parameters.length + " were passed");
+ return this._callback(...parameters);
+ }
+
+ leftApply(state, parameters)
+ {
+ state.abort("Cannot use a native function as an lvalue");
+ }
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/parser.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/parser.js
new file mode 100644
index 0000000000..562e157595
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/parser.js
@@ -0,0 +1,558 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+function parse(tokenizer)
+{
+ let program;
+
+ let pushBackBuffer = [];
+
+ function nextToken()
+ {
+ if (pushBackBuffer.length)
+ return pushBackBuffer.pop();
+ let result = tokenizer.next();
+ if (result.done)
+ return {kind: "endOfFile", string: "<end of file>"};
+ return result.value;
+ }
+
+ function pushToken(token)
+ {
+ pushBackBuffer.push(token);
+ }
+
+ function peekToken()
+ {
+ let result = nextToken();
+ pushToken(result);
+ return result;
+ }
+
+ function consumeKind(kind)
+ {
+ let token = nextToken();
+ if (token.kind != kind) {
+ throw new Error("At " + token.sourceLineNumber + ": expected " + kind + " but got: " + token.string);
+ }
+ return token;
+ }
+
+ function consumeToken(string)
+ {
+ let token = nextToken();
+ if (token.string.toLowerCase() != string.toLowerCase())
+ throw new Error("At " + token.sourceLineNumber + ": expected " + string + " but got: " + token.string);
+ return token;
+ }
+
+ function parseVariable()
+ {
+ let name = consumeKind("identifier").string;
+ let result = {evaluate: Basic.Variable, name, parameters: []};
+ if (peekToken().string == "(") {
+ do {
+ nextToken();
+ result.parameters.push(parseNumericExpression());
+ } while (peekToken().string == ",");
+ consumeToken(")");
+ }
+ return result;
+ }
+
+ function parseNumericExpression()
+ {
+ function parsePrimary()
+ {
+ let token = nextToken();
+ switch (token.kind) {
+ case "identifier": {
+ let result = {evaluate: Basic.NumberApply, name: token.string, parameters: []};
+ if (peekToken().string == "(") {
+ do {
+ nextToken();
+ result.parameters.push(parseNumericExpression());
+ } while (peekToken().string == ",");
+ consumeToken(")");
+ }
+ return result;
+ }
+
+ case "number":
+ return {evaluate: Basic.Const, value: token.value};
+
+ case "operator":
+ switch (token.string) {
+ case "(": {
+ let result = parseNumericExpression();
+ consumeToken(")");
+ return result;
+ } }
+ break;
+ }
+ throw new Error("At " + token.sourceLineNumber + ": expected identifier, number, or (, but got: " + token.string);
+ }
+
+ function parseFactor()
+ {
+ let primary = parsePrimary();
+
+ let ok = true;
+ while (ok) {
+ switch (peekToken().string) {
+ case "^":
+ nextToken();
+ primary = {evaluate: Basic.NumberPow, left: primary, right: parsePrimary()};
+ break;
+ default:
+ ok = false;
+ break;
+ }
+ }
+
+ return primary;
+ }
+
+ function parseTerm()
+ {
+ let factor = parseFactor();
+
+ let ok = true;
+ while (ok) {
+ switch (peekToken().string) {
+ case "*":
+ nextToken();
+ factor = {evaluate: Basic.NumberMul, left: factor, right: parseFactor()};
+ break;
+ case "/":
+ nextToken();
+ factor = {evaluate: Basic.NumberDiv, left: factor, right: parseFactor()};
+ break;
+ default:
+ ok = false;
+ break;
+ }
+ }
+
+ return factor;
+ }
+
+ // Only the leading term in Basic can have a sign.
+ let negate = false;
+ switch (peekToken().string) {
+ case "+":
+ nextToken();
+ break;
+ case "-":
+ negate = true;
+ nextToken()
+ break;
+ }
+
+ let term = parseTerm();
+ if (negate)
+ term = {evaluate: Basic.NumberNeg, term: term};
+
+ let ok = true;
+ while (ok) {
+ switch (peekToken().string) {
+ case "+":
+ nextToken();
+ term = {evaluate: Basic.NumberAdd, left: term, right: parseTerm()};
+ break;
+ case "-":
+ nextToken();
+ term = {evaluate: Basic.NumberSub, left: term, right: parseTerm()};
+ break;
+ default:
+ ok = false;
+ break;
+ }
+ }
+
+ return term;
+ }
+
+ function parseConstant()
+ {
+ switch (peekToken().string) {
+ case "+":
+ nextToken();
+ return consumeKind("number").value;
+ case "-":
+ nextToken();
+ return -consumeKind("number").value;
+ default:
+ if (isStringExpression())
+ return consumeKind("string").value;
+ return consumeKind("number").value;
+ }
+ }
+
+ function parseStringExpression()
+ {
+ let token = nextToken();
+ switch (token.kind) {
+ case "string":
+ return {evaluate: Basic.Const, value: token.value};
+ case "identifier":
+ consumeToken("$");
+ return {evaluate: Basic.StringVar, name: token.string};
+ default:
+ throw new Error("At " + token.sourceLineNumber + ": expected string expression but got " + token.string);
+ }
+ }
+
+ function isStringExpression()
+ {
+ // A string expression must start with a string variable or a string constant.
+ let token = nextToken();
+ if (token.kind == "string") {
+ pushToken(token);
+ return true;
+ }
+ if (token.kind == "identifier") {
+ let result = peekToken().string == "$";
+ pushToken(token);
+ return result;
+ }
+ pushToken(token);
+ return false;
+ }
+
+ function parseRelationalExpression()
+ {
+ if (isStringExpression()) {
+ let left = parseStringExpression();
+ let operator = nextToken();
+ let evaluate;
+ switch (operator.string) {
+ case "=":
+ evaluate = Basic.Equals;
+ break;
+ case "<>":
+ evaluate = Basic.NotEquals;
+ break;
+ default:
+ throw new Error("At " + operator.sourceLineNumber + ": expected a string comparison operator but got: " + operator.string);
+ }
+ return {evaluate, left, right: parseStringExpression()};
+ }
+
+ let left = parseNumericExpression();
+ let operator = nextToken();
+ let evaluate;
+ switch (operator.string) {
+ case "=":
+ evaluate = Basic.Equals;
+ break;
+ case "<>":
+ evaluate = Basic.NotEquals;
+ break;
+ case "<":
+ evaluate = Basic.LessThan;
+ break;
+ case ">":
+ evaluate = Basic.GreaterThan;
+ break;
+ case "<=":
+ evaluate = Basic.LessEqual;
+ break;
+ case ">=":
+ evaluate = Basic.GreaterEqual;
+ break;
+ default:
+ throw new Error("At " + operator.sourceLineNumber + ": expected a numeric comparison operator but got: " + operator.string);
+ }
+ return {evaluate, left, right: parseNumericExpression()};
+ }
+
+ function parseNonNegativeInteger()
+ {
+ let token = nextToken();
+ if (!/^[0-9]+$/.test(token.string))
+ throw new Error("At ", token.sourceLineNumber + ": expected a line number but got: " + token.string);
+ return token.value;
+ }
+
+ function parseGoToStatement()
+ {
+ statement.kind = Basic.GoTo;
+ statement.target = parseNonNegativeInteger();
+ }
+
+ function parseGoSubStatement()
+ {
+ statement.kind = Basic.GoSub;
+ statement.target = parseNonNegativeInteger();
+ }
+
+ function parseStatement()
+ {
+ let statement = {};
+ statement.lineNumber = consumeKind("userLineNumber").userLineNumber;
+ program.statements.set(statement.lineNumber, statement);
+
+ let command = nextToken();
+ statement.sourceLineNumber = command.sourceLineNumber;
+ switch (command.kind) {
+ case "keyword":
+ switch (command.string.toLowerCase()) {
+ case "def":
+ statement.process = Basic.Def;
+ statement.name = consumeKind("identifier");
+ statement.parameters = [];
+ if (peekToken().string == "(") {
+ do {
+ nextToken();
+ statement.parameters.push(consumeKind("identifier"));
+ } while (peekToken().string == ",");
+ }
+ statement.expression = parseNumericExpression();
+ break;
+ case "let":
+ statement.process = Basic.Let;
+ statement.variable = parseVariable();
+ consumeToken("=");
+ if (statement.process == Basic.Let)
+ statement.expression = parseNumericExpression();
+ else
+ statement.expression = parseStringExpression();
+ break;
+ case "go": {
+ let next = nextToken();
+ if (next.string == "to")
+ parseGoToStatement();
+ else if (next.string == "sub")
+ parseGoSubStatement();
+ else
+ throw new Error("At " + next.sourceLineNumber + ": expected to or sub but got: " + next.string);
+ break;
+ }
+ case "goto":
+ parseGoToStatement();
+ break;
+ case "gosub":
+ parseGoSubStatement();
+ break;
+ case "if":
+ statement.process = Basic.If;
+ statement.condition = parseRelationalExpression();
+ consumeToken("then");
+ statement.target = parseNonNegativeInteger();
+ break;
+ case "return":
+ statement.process = Basic.Return;
+ break;
+ case "stop":
+ statement.process = Basic.Stop;
+ break;
+ case "on":
+ statement.process = Basic.On;
+ statement.expression = parseNumericExpression();
+ if (peekToken().string == "go") {
+ consumeToken("go");
+ consumeToken("to");
+ } else
+ consumeToken("goto");
+ statement.targets = [];
+ for (;;) {
+ statement.targets.push(parseNonNegativeInteger());
+ if (peekToken().string != ",")
+ break;
+ nextToken();
+ }
+ break;
+ case "for":
+ statement.process = Basic.For;
+ statement.variable = consumeKind("identifier").string;
+ consumeToken("=");
+ statement.initial = parseNumericExpression();
+ consumeToken("to");
+ statement.limit = parseNumericExpression();
+ if (peekToken().string == "step") {
+ nextToken();
+ statement.step = parseNumericExpression();
+ } else
+ statement.step = {evaluate: Basic.Const, value: 1};
+ consumeKind("newLine");
+ let lastStatement = parseStatements();
+ if (lastStatement.process != Basic.Next)
+ throw new Error("At " + lastStatement.sourceLineNumber + ": expected next statement");
+ if (lastStatement.variable != statement.variable)
+ throw new Error("At " + lastStatement.sourceLineNumber + ": expected next for " + statement.variable + " but got " + lastStatement.variable);
+ lastStatement.target = statement;
+ statement.target = lastStatement;
+ return statement;
+ case "next":
+ statement.process = Basic.Next;
+ statement.variable = consumeKind("identifier").string;
+ break;
+ case "print": {
+ statement.process = Basic.Print;
+ statement.items = [];
+ let ok = true;
+ while (ok) {
+ switch (peekToken().string) {
+ case ",":
+ nextToken();
+ statement.items.push({kind: "comma"});
+ break;
+ case ";":
+ nextToken();
+ break;
+ case "tab":
+ nextToken();
+ consumeToken("(");
+ statement.items.push({kind: "tab", value: parseNumericExpression()});
+ break;
+ case "\n":
+ ok = false;
+ break;
+ default:
+ if (isStringExpression()) {
+ statement.items.push({kind: "string", value: parseStringExpression()});
+ break;
+ }
+ statement.items.push({kind: "number", value: parseNumericExpression()});
+ break;
+ }
+ }
+ break;
+ }
+ case "input":
+ statement.process = Basic.Input;
+ statement.items = [];
+ for (;;) {
+ stament.items.push(parseVariable());
+ if (peekToken().string != ",")
+ break;
+ nextToken();
+ }
+ break;
+ case "read":
+ statement.process = Basic.Read;
+ statement.items = [];
+ for (;;) {
+ stament.items.push(parseVariable());
+ if (peekToken().string != ",")
+ break;
+ nextToken();
+ }
+ break;
+ case "restore":
+ statement.process = Basic.Restore;
+ break;
+ case "data":
+ for (;;) {
+ program.data.push(parseConstant());
+ if (peekToken().string != ",")
+ break;
+ nextToken();
+ }
+ break;
+ case "dim":
+ statement.process = Basic.Dim;
+ statement.items = [];
+ for (;;) {
+ let name = consumeKind("identifier").string;
+ consumeToken("(");
+ let bounds = [];
+ bounds.push(parseNonNegativeInteger());
+ if (peekToken().string == ",") {
+ nextToken();
+ bounds.push(parseNonNegativeInteger());
+ }
+ consumeToken(")");
+ statement.items.push({name, bounds});
+
+ if (peekToken().string != ",")
+ break;
+ consumeToken(",");
+ }
+ break;
+ case "option": {
+ consumeToken("base");
+ let base = parseNonNegativeInteger();
+ if (base != 0 && base != 1)
+ throw new Error("At " + command.sourceLineNumber + ": unexpected base: " + base);
+ program.base = base;
+ break;
+ }
+ case "randomize":
+ statement.process = Basic.Randomize;
+ break;
+ case "end":
+ statement.process = Basic.End;
+ break;
+ default:
+ throw new Error("At " + command.sourceLineNumber + ": unexpected command but got: " + command.string);
+ }
+ break;
+ case "remark":
+ // Just ignore it.
+ break;
+ default:
+ throw new Error("At " + command.sourceLineNumber + ": expected command but got: " + command.string + " (of kind " + command.kind + ")");
+ }
+
+ consumeKind("newLine");
+ return statement;
+ }
+
+ function parseStatements()
+ {
+ let statement;
+ do {
+ statement = parseStatement();
+ } while (!statement.process || !statement.process.isBlockEnd);
+ return statement;
+ }
+
+ return {
+ program()
+ {
+ program = {
+ process: Basic.Program,
+ statements: new Map(),
+ data: [],
+ base: 0
+ };
+ let lastStatement = parseStatements(program.statements);
+ if (lastStatement.process != Basic.End)
+ throw new Error("At " + lastStatement.sourceLineNumber + ": expected end");
+
+ return program;
+ },
+
+ statement(program_)
+ {
+ program = program_;
+ return parseStatement();
+ }
+ };
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/random.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/random.js
new file mode 100644
index 0000000000..d940c0e381
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/random.js
@@ -0,0 +1,54 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"use strict";
+
+// This is based on Octane's RNG.
+function createRNG(seed)
+{
+ return function() {
+ // Robert Jenkins' 32 bit integer hash function.
+ seed = ((seed + 0x7ed55d16) + (seed << 12)) & 0xffffffff;
+ seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff;
+ seed = ((seed + 0x165667b1) + (seed << 5)) & 0xffffffff;
+ seed = ((seed + 0xd3a2646c) ^ (seed << 9)) & 0xffffffff;
+ seed = ((seed + 0xfd7046c5) + (seed << 3)) & 0xffffffff;
+ seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff;
+ return (seed & 0xfffffff) / 0x10000000;
+ };
+}
+
+function createRNGWithFixedSeed()
+{
+ // This uses Octane's initial seed.
+ return createRNG(49734321);
+}
+
+function createRNGWithRandomSeed()
+{
+ return createRNG((Math.random() * 4294967296) | 0);
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/state.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/state.js
new file mode 100644
index 0000000000..2c45971ea4
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/state.js
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class State {
+ constructor(program)
+ {
+ this.values = new CaselessMap();
+ this.stringValues = new CaselessMap();
+ this.sideState = new WeakMap();
+ this.statement = null;
+ this.nextLineNumber = 0;
+ this.subStack = [];
+ this.dataIndex = 0;
+ this.program = program;
+ this.rng = createRNGWithFixedSeed();
+
+ let addNative = (name, callback) => {
+ this.values.set(name, new NativeFunction(callback));
+ };
+
+ addNative("abs", x => Math.abs(x));
+ addNative("atn", x => Math.atan(x));
+ addNative("cos", x => Math.cos(x));
+ addNative("exp", x => Math.exp(x));
+ addNative("int", x => Math.floor(x));
+ addNative("log", x => Math.log(x));
+ addNative("rnd", () => this.rng());
+ addNative("sgn", x => Math.sign(x));
+ addNative("sin", x => Math.sin(x));
+ addNative("sqr", x => Math.sqrt(x));
+ addNative("tan", x => Math.tan(x));
+ }
+
+ getValue(name, numParameters)
+ {
+ if (this.values.has(name))
+ return this.values.get(name);
+
+ let result;
+ if (numParameters == 0)
+ result = new NumberValue();
+ else {
+ let dim = [];
+ while (numParameters--)
+ dim.push(11);
+ result = new NumberArray(dim);
+ }
+ this.values.set(name, result);
+ return result;
+ }
+
+ getSideState(key)
+ {
+ if (!this.sideState.has(key)) {
+ let result = {};
+ this.sideState.set(key, result);
+ return result;
+ }
+ return this.sideState.get(key);
+ }
+
+ abort(text)
+ {
+ if (!this.statement)
+ throw new Error("At beginning of execution: " + text);
+ throw new Error("At " + this.statement.sourceLineNumber + ": " + text);
+ }
+
+ validate(predicate, text)
+ {
+ if (!predicate)
+ this.abort(text);
+ }
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/stress-test.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/stress-test.js
new file mode 100644
index 0000000000..c169c07748
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/stress-test.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+load("ast.js");
+load("basic.js");
+load("caseless_map.js");
+load("lexer.js");
+load("number.js");
+load("parser.js");
+load("random.js");
+load("state.js");
+load("util.js");
+load("benchmark.js");
+
+let benchmark = new BasicBenchmark();
+let before = preciseTime();
+
+// Run for at least 10 iterations.
+for (let i = 0; i < 10; ++i) {
+ print("Running mandatory iteration #" + (i + 1) + ":");
+ benchmark.runIteration();
+}
+
+// Run until we have been running for two seconds.
+while (preciseTime() < before + 2) {
+ print("Running bonus iteration:");
+ benchmark.runIteration();
+}
+
+print("Success!");
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/test.html b/third_party/webkit/PerformanceTests/ARES-6/Basic/test.html
new file mode 100644
index 0000000000..10c7cadd77
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/test.html
@@ -0,0 +1,34 @@
+<html>
+<head>
+<title>Basic</title>
+<script src="ast.js"></script>
+<script src="basic.js"></script>
+<script src="caseless_map.js"></script>
+<script src="lexer.js"></script>
+<script src="number.js"></script>
+<script src="parser.js"></script>
+<script src="random.js"></script>
+<script src="state.js"></script>
+<script src="util.js"></script>
+<script src="benchmark.js"></script>
+<script>
+ function runTest() {
+ try {
+ var result = runBenchmark();
+ document.getElementById("result-summary").innerHTML = "That took " + result + " ms.";
+ } catch (e) {
+ document.getElementById("result-summary").innerHTML = "Failed: " + e;
+ }
+ }
+</script>
+</head>
+<body>
+<h1>Basic</h1>
+<p>
+ <div id="result-summary"></div>
+ <div><a href="javascript:runTest()">Start Test</a></div>
+</p>
+</body>
+</html>
+
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/test.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/test.js
new file mode 100644
index 0000000000..3c4b339566
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/test.js
@@ -0,0 +1,16 @@
+"use strict";
+
+load("ast.js");
+load("basic.js");
+load("caseless_map.js");
+load("lexer.js");
+load("number.js");
+load("parser.js");
+load("random.js");
+load("state.js");
+load("util.js");
+
+load("benchmark.js");
+
+let result = runBenchmark();
+print("That took " + result + " ms.");
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Basic/util.js b/third_party/webkit/PerformanceTests/ARES-6/Basic/util.js
new file mode 100644
index 0000000000..b6120502cd
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/Basic/util.js
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+let currentTime;
+if (this.performance && performance.now)
+ currentTime = function() { return performance.now() };
+else if (this.preciseTime)
+ currentTime = function() { return preciseTime() * 1000; };
+else
+ currentTime = function() { return +new Date(); };
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/about.html b/third_party/webkit/PerformanceTests/ARES-6/about.html
new file mode 100644
index 0000000000..9e5472f851
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/about.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="stylesheet" href="styles.css">
+ <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
+</head>
+<body>
+
+ <div class="swoop">&nbsp;</div>
+
+ <header>
+ <h1 class="logo"><img src="ARES-6.svg" title="ARES-6" alt="ARES-6"></h1>
+ </header>
+
+ <main class="about">
+
+ <h2>About the Tests</h2>
+
+ <p>ARES-6 measures the execution time of JavaScript&#8217;s newest features, including symbols, for-of, arrow functions, Map/Set/WeakMap, let/const, classes, proxies, string interpolation, destructuring, default arguments, spread, tail calls, and generators. ARES-6 is comprised of four sub-tests: Air, Basic, Babylon, and ML.</p>
+
+ <p>Air is an ES2015 port of the <a href="https://webkit.org/blog/5852/introducing-the-b3-jit-compiler/">WebKit B3 JIT</a>&#8217;s <a href="https://trac.webkit.org/changeset/201783"><code>Air::allocateStack</code> phase</a>. This code is a heavy user of Map, Set, classes, spread, and for-of. The benchmark runs <code>allocateStack</code> on hot function bodies from other popular JavaScript benchmarks: <code>executeIteration</code> from <a href="https://developers.google.com/octane/">Octane</a>/Gameboy, <code>gaussianBlur</code> from <a href="http://krakenbenchmark.mozilla.org">Kraken</a>, and <code>scanIdentifier</code> from Octane/Typescript. Air also runs <code>allocateStack</code> on a hot function from Air itself. <a href="https://trac.webkit.org/browser/trunk/PerformanceTests/ARES-6/Air?rev=211697">Browse the source.</a></p>
+
+ <p>Basic is an <a href="https://trac.webkit.org/changeset/202446">ES2015 implementation</a> of the <a href="http://www.ecma-international.org/publications/files/ECMA-ST-WITHDRAWN/ECMA-55,%201st%20Edition,%20January%201978.pdf">ECMA-55 BASIC standard</a>. BASIC was an interactive language from the start, so our implementation uses generator functions for the entire interpreter. When the BASIC program says <code>INPUT</code>, our interpreter says <code>yield</code>. This allows users of the interpreter to easily integrate it into a runloop. Basic also uses classes, Map, and WeakMap. The benchmark runs a handful of simple programs, the most complex of which finds prime numbers. <a href="https://trac.webkit.org/browser/trunk/PerformanceTests/ARES-6/Basic?rev=211697&order=name">Browse the source.</a></p>
+
+ <p>
+ <a href="https://github.com/babel/babylon">Babylon</a> is an implementation of a parser for the JavaScript language.
+ Babylon is the parser used in the <a href="https://babeljs.io">Babel</a> JavaScript transpiler.
+ The benchmark runs the Babylon parser on four different JavaScript sources. Babylon makes heavy use of classes,
+ does non trivial string processing, and creates non-trivial object graphs.
+ </p>
+
+ <p>
+ <a href="https://github.com/mljs/feedforward-neural-networks">ML</a> is an implementation of a <a href="https://en.wikipedia.org/wiki/Feedforward_neural_network"> feedforward neural network</a>.
+ The benchmark trains several networks using different <a href="https://en.wikipedia.org/wiki/Activation_function">activation functions</a>
+ and several sample data sets. ML makes heavy use of classes. It relies on the <a href="https://github.com/mljs/matrix">ml-matrix</a> library
+ and does non-trivial matrix math.
+ </p>
+
+ <p>ARES-6 rewards browsers that start up quickly and run smoothly. It's not enough to just measure the total running time of a workload. Browsers may perform differently for the same workload depending on how many times it has run. Garbage collection runs periodically, making some iterations take longer than others. Code that runs repeatedly gets optimized by the browser, so the first iteration of any workload is more expensive than the rest. ARES-6 runs Air, Basic, and Babylon for 200 iterations, and ML for 60 iterations. For each benchmark, ARES-6 reports the time of the first iteration, the average of the 4 worst iterations, and the average of all but the first iteration. ARES-6 also reports an overall score which is the geometric mean of all twelve of these numbers. ARES-6 equally rewards fast start-up, low jank, and sophisticated adaptive optimizations for long-running code.</p>
+
+ <p>Each ARES-6 sample has 200 iterations of Air, Basic, and Babylon, and 60 iterations of ML. ARES-6 runs 6 samples, and reports the average with 95% confidence intervals. Each sample runs in a fresh <code>iframe</code> to simulate some of the effects of page navigation.</p>
+
+ <p><a href="index.html" class="button return">Return to Testing</a></p>
+
+ </main>
+
+</body>
+</html>
diff --git a/third_party/webkit/PerformanceTests/ARES-6/air_benchmark.js b/third_party/webkit/PerformanceTests/ARES-6/air_benchmark.js
new file mode 100644
index 0000000000..6397c4fcea
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/air_benchmark.js
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+const AirBenchmarkCode = String.raw`
+<script src="Air/symbols.js"></script>
+<script src="Air/tmp_base.js"></script>
+<script src="Air/arg.js"></script>
+<script src="Air/basic_block.js"></script>
+<script src="Air/code.js"></script>
+<script src="Air/frequented_block.js"></script>
+<script src="Air/inst.js"></script>
+<script src="Air/opcode.js"></script>
+<script src="Air/reg.js"></script>
+<script src="Air/stack_slot.js"></script>
+<script src="Air/tmp.js"></script>
+<script src="Air/util.js"></script>
+<script src="Air/custom.js"></script>
+<script src="Air/liveness.js"></script>
+<script src="Air/insertion_set.js"></script>
+<script src="Air/allocate_stack.js"></script>
+<script src="Air/payload-gbemu-executeIteration.js"></script>
+<script src="Air/payload-imaging-gaussian-blur-gaussianBlur.js"></script>
+<script src="Air/payload-airjs-ACLj8C.js"></script>
+<script src="Air/payload-typescript-scanIdentifier.js"></script>
+<script src="Air/benchmark.js"></script>
+<script>
+var results = [];
+var benchmark = new AirBenchmark();
+var numIterations = 200;
+for (var i = 0; i < numIterations; ++i) {
+ var before = currentTime();
+ benchmark.runIteration();
+ var after = currentTime();
+ results.push(after - before);
+}
+reportResult(results);
+</script>`;
+
+let runAirBenchmark = null;
+if (!isInBrowser) {
+ let sources = [
+ "Air/symbols.js"
+ , "Air/tmp_base.js"
+ , "Air/arg.js"
+ , "Air/basic_block.js"
+ , "Air/code.js"
+ , "Air/frequented_block.js"
+ , "Air/inst.js"
+ , "Air/opcode.js"
+ , "Air/reg.js"
+ , "Air/stack_slot.js"
+ , "Air/tmp.js"
+ , "Air/util.js"
+ , "Air/custom.js"
+ , "Air/liveness.js"
+ , "Air/insertion_set.js"
+ , "Air/allocate_stack.js"
+ , "Air/payload-gbemu-executeIteration.js"
+ , "Air/payload-imaging-gaussian-blur-gaussianBlur.js"
+ , "Air/payload-airjs-ACLj8C.js"
+ , "Air/payload-typescript-scanIdentifier.js"
+ , "Air/benchmark.js"
+ ];
+
+ runAirBenchmark = makeBenchmarkRunner(sources, "AirBenchmark");
+}
+
+const AirBenchmarkRunner = {
+ code: AirBenchmarkCode,
+ run: runAirBenchmark,
+ cells: { },
+ name: "Air"
+};
+
+if (isInBrowser) {
+ AirBenchmarkRunner.cells = {
+ firstIteration: document.getElementById("AirFirstIteration"),
+ averageWorstCase: document.getElementById("AirAverageWorstCase"),
+ steadyState: document.getElementById("AirSteadyState"),
+ message: document.getElementById("AirMessage")
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/babylon_benchmark.js b/third_party/webkit/PerformanceTests/ARES-6/babylon_benchmark.js
new file mode 100644
index 0000000000..0b5e163c78
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/babylon_benchmark.js
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+const BabylonBenchmarkCode = String.raw`
+<script src="Babylon/index.js"></script>
+<script src="Babylon/benchmark.js"></script>
+<script>
+var results = [];
+var benchmark = new BabylonBenchmark();
+var numIterations = 200;
+for (var i = 0; i < numIterations; ++i) {
+ var before = currentTime();
+ benchmark.runIteration();
+ var after = currentTime();
+ results.push(after - before);
+}
+reportResult(results);
+</script>`;
+
+
+let runBabylonBenchmark = null;
+if (!isInBrowser) {
+ let sources = [
+ "Babylon/index.js"
+ , "Babylon/benchmark.js"
+ ];
+
+ runBabylonBenchmark = makeBenchmarkRunner(sources, "BabylonBenchmark");
+}
+
+const BabylonBenchmarkRunner = {
+ name: "Babylon",
+ code: BabylonBenchmarkCode,
+ run: runBabylonBenchmark,
+ cells: {}
+};
+
+if (isInBrowser) {
+ BabylonBenchmarkRunner.cells = {
+ firstIteration: document.getElementById("BabylonFirstIteration"),
+ averageWorstCase: document.getElementById("BabylonAverageWorstCase"),
+ steadyState: document.getElementById("BabylonSteadyState"),
+ message: document.getElementById("BabylonMessage")
+ };
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/basic_benchmark.js b/third_party/webkit/PerformanceTests/ARES-6/basic_benchmark.js
new file mode 100644
index 0000000000..8e7df844f4
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/basic_benchmark.js
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+const BasicBenchmarkCode = String.raw`
+<script src="Basic/ast.js"></script>
+<script src="Basic/basic.js"></script>
+<script src="Basic/caseless_map.js"></script>
+<script src="Basic/lexer.js"></script>
+<script src="Basic/number.js"></script>
+<script src="Basic/parser.js"></script>
+<script src="Basic/random.js"></script>
+<script src="Basic/state.js"></script>
+<script src="Basic/util.js"></script>
+<script src="Basic/benchmark.js"></script>
+<script>
+var results = [];
+var benchmark = new BasicBenchmark();
+var numIterations = 200;
+for (var i = 0; i < numIterations; ++i) {
+ var before = currentTime();
+ benchmark.runIteration();
+ var after = currentTime();
+ results.push(after - before);
+}
+reportResult(results);
+</script>`;
+
+
+let runBasicBenchmark = null;
+if (!isInBrowser) {
+ let sources = [
+ "Basic/ast.js"
+ , "Basic/basic.js"
+ , "Basic/caseless_map.js"
+ , "Basic/lexer.js"
+ , "Basic/number.js"
+ , "Basic/parser.js"
+ , "Basic/random.js"
+ , "Basic/state.js"
+ , "Basic/util.js"
+ , "Basic/benchmark.js"
+ ];
+
+ runBasicBenchmark = makeBenchmarkRunner(sources, "BasicBenchmark");
+}
+
+const BasicBenchmarkRunner = {
+ name: "Basic",
+ code: BasicBenchmarkCode,
+ run: runBasicBenchmark,
+ cells: {}
+};
+
+if (isInBrowser) {
+ BasicBenchmarkRunner.cells = {
+ firstIteration: document.getElementById("BasicFirstIteration"),
+ averageWorstCase: document.getElementById("BasicAverageWorstCase"),
+ steadyState: document.getElementById("BasicSteadyState"),
+ message: document.getElementById("BasicMessage")
+ };
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/cli.js b/third_party/webkit/PerformanceTests/ARES-6/cli.js
new file mode 100644
index 0000000000..69cfad4f6b
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/cli.js
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+const isInBrowser = false;
+
+var readFile = readFile || read;
+
+function makeDoRun(source) {
+ // jsc shim
+ if (typeof runString === 'function') {
+ return function() {
+ let globalObjectOfScript = runString(source);
+ let results = globalObjectOfScript.results;
+ reportResult(results);
+ };
+ }
+
+ // spidermonkey shim
+ if (typeof newGlobal === 'function') {
+ return function() {
+ var globalObjectOfScript = newGlobal();
+ globalObjectOfScript.eval(source);
+ let results = globalObjectOfScript.results;
+ reportResult(results);
+ }
+ }
+
+ // v8 shim
+ return function() {
+ const realm = Realm.create();
+ Realm.eval(realm, source);
+ reportResult(Realm.eval(realm, "results"));
+ Realm.dispose(realm);
+ }
+}
+
+function makeBenchmarkRunner(sources, benchmarkConstructor, numIterations = 200) {
+ let source = "'use strict';"
+ for (let file of sources) {
+ source += readFile(file);
+ }
+ source += `
+ this.results = [];
+ var benchmark = new ${benchmarkConstructor}();
+ var numIterations = ${numIterations};
+ for (var i = 0; i < numIterations; ++i) {
+ var before = currentTime();
+ benchmark.runIteration();
+ var after = currentTime();
+ results.push(after - before);
+ }
+ `;
+ return makeDoRun(source);
+}
+
+load("driver.js");
+load("results.js");
+load("stats.js");
+load("air_benchmark.js");
+load("basic_benchmark.js");
+load("babylon_benchmark.js");
+load("ml_benchmark.js");
+load("glue.js");
+
+driver.start(6);
diff --git a/third_party/webkit/PerformanceTests/ARES-6/driver.js b/third_party/webkit/PerformanceTests/ARES-6/driver.js
new file mode 100644
index 0000000000..b8a561d884
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/driver.js
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class Driver {
+ constructor(statusCell, triggerCell, triggerLink, magicCell, summaryCell, key)
+ {
+ this._benchmarks = new Map();
+ this._statusCell = statusCell;
+ this._triggerCell = triggerCell;
+ this._triggerLink = triggerLink;
+ this._magicCell = magicCell;
+ this._summary = new Stats(summaryCell, "summary");
+ this._key = key;
+ this._values = [];
+ this._names = [];
+ if (isInBrowser)
+ window[key] = this;
+ }
+
+ addBenchmark(benchmark)
+ {
+ this._benchmarks.set(benchmark, new Results(benchmark));
+ }
+
+ readyTrigger()
+ {
+ if (isInBrowser) {
+ this._triggerCell.addEventListener('click', this._triggerLink);
+ this._triggerCell.classList.add('ready');
+ }
+ }
+
+ disableTrigger()
+ {
+ if (isInBrowser) {
+ this._triggerCell.removeEventListener('click', this._triggerLink);
+ this._triggerCell.classList.remove('ready');
+ }
+ }
+
+ start(numIterations)
+ {
+ this.disableTrigger();
+ this._updateIterations();
+
+ this._summary.reset();
+ for (let [benchmark, results] of this._benchmarks)
+ results.reset();
+ this._isRunning = true;
+ this._startIterations = this._numIterations = numIterations;
+ this._iterator = null;
+ this._iterate();
+ }
+
+ reportResult(...args)
+ {
+ this._benchmarks.get(this._benchmark).reportResult(...args);
+ this._recomputeSummary();
+ this._iterate();
+ }
+
+ reportError(...args)
+ {
+ if (isInBrowser)
+ console.log("Error encountered: ", ...args);
+
+ this._benchmarks.get(this._benchmark).reportError(...args);
+
+ if (isInBrowser) {
+ this._statusCell.innerHTML = "Test failure \u2014 error in console";
+ this._statusCell.classList.add("failed");
+ } else
+ print("Test failure");
+ }
+
+ _recomputeSummary()
+ {
+ class Geomean {
+ constructor()
+ {
+ this._count = 0;
+ this._sum = 0;
+ }
+
+ add(value)
+ {
+ this._count++;
+ this._sum += Math.log(value);
+ }
+
+ get result()
+ {
+ return Math.exp(this._sum * (1 / this._count));
+ }
+ }
+
+ let statses = [];
+ for (let [benchmark, results] of this._benchmarks) {
+ for (let subResult of Results.subResults) {
+ statses.push(results[subResult]);
+ let val = results[subResult].valueForIteration(results[subResult].numIterations - 1);
+ if (val > 0 && benchmark.name == this._benchmark.name) {
+ this._values.push(val);
+ this._names.push(benchmark.name + "_" + subResult);
+ }
+ }
+ }
+
+ let numIterations = Math.min(...statses.map(stats => stats.numIterations));
+ let data = new Array(numIterations);
+ for (let i = 0; i < data.length; ++i)
+ data[i] = new Geomean();
+
+ for (let stats of statses) {
+ for (let i = 0; i < data.length; ++i)
+ data[i].add(stats.valueForIteration(i));
+ }
+
+ let geomeans = data.map(geomean => geomean.result);
+ if (geomeans.length == this._startIterations) {
+ for (let iter = 0; iter < geomeans.length; iter++) {
+ this._values.push(geomeans[iter]);
+ this._names.push("geomean");
+ }
+ }
+ this._summary.reset(...geomeans);
+ }
+
+ _iterate()
+ {
+ this._benchmark = this._iterator ? this._iterator.next().value : null;
+ if (!this._benchmark) {
+ if (!this._numIterations) {
+ if (isInBrowser) {
+ this._statusCell.innerHTML = "Restart";
+ this.readyTrigger();
+ if (typeof tpRecordTime !== "undefined")
+ tpRecordTime(this._values.join(','), 0, this._names.join(','));
+
+ this.sendResultsToRaptor();
+ } else
+ print("Success! Benchmark is now finished.");
+ return;
+ }
+ this._numIterations--;
+ this._updateIterations();
+ this._iterator = this._benchmarks.keys();
+ this._benchmark = this._iterator.next().value;
+ }
+
+ this._benchmarks.get(this._benchmark).reportRunning();
+
+ let benchmark = this._benchmark;
+ if (isInBrowser) {
+ window.setTimeout(() => {
+ if (!this._isRunning)
+ return;
+
+ this._magicCell.contentDocument.body.textContent = "";
+ this._magicCell.contentDocument.body.innerHTML = "<iframe id=\"magicFrame\" frameborder=\"0\">";
+
+ let magicFrame = this._magicCell.contentDocument.getElementById("magicFrame");
+ magicFrame.contentDocument.open();
+ magicFrame.contentDocument.write(
+ `<!DOCTYPE html><head><title>benchmark payload</title></head><body><script>` +
+ `window.onerror = top.${this._key}.reportError.bind(top.${this._key});\n` +
+ `function reportResult()\n` +
+ `{\n` +
+ ` var driver = top.${this._key};\n` +
+ ` driver.reportResult.apply(driver, arguments);\n` +
+ `}\n` +
+ `</script>\n` +
+ `${this._benchmark.code}</body></html>`);
+ }, 100);
+ } else {
+ Promise.resolve(20).then(() => {
+ if (!this._isRunning)
+ return;
+
+ try {
+ print(`Running... ${this._benchmark.name} ( ${this._numIterations + 1} to go)`);
+ benchmark.run();
+ print("\n");
+ } catch(e) {
+ print(e);
+ print(e.stack);
+ }
+ });
+ }
+ }
+
+ _updateIterations()
+ {
+ if (isInBrowser) {
+ this._statusCell.innerHTML = "Running Tests... " + ( this._startIterations - this._numIterations ) + "/" + this._startIterations;
+ }
+
+ }
+
+ sendResultsToRaptor()
+ {
+ // this contains all test names = [ "Air_firstIteration", "Air_averageWorstCase", ...]
+ var allNames = this._names;
+ // this contains all test metrics = [ 111, 83.5, 21.78894472361809, ...]
+ var allValues = this._values;
+ // this object will store name:[value1, value2, ...] pairs for the arrays above
+ var measuredValuesByFullName = {};
+ for (var i = 0, len = allNames.length; i < len; i++) {
+ if (measuredValuesByFullName[allNames[i]] === undefined) {
+ measuredValuesByFullName[allNames[i]] = [];
+ }
+ }
+
+ allNames.map(function(name, index) {
+ // now we save all the values for each test
+ // ex.: measuredValuesByFullName['Air_firstIteration'].push(111);
+ // measuredValuesByFullName['Air_firstIteration'].push(107);
+ measuredValuesByFullName[name].push(allValues[index]);
+ });
+
+ // delete the geomean array - this will be calculated by raptor
+ delete measuredValuesByFullName.geomean;
+
+ if (location.search === '?raptor') {
+ var _data = ['raptor-benchmark', 'ares6', measuredValuesByFullName];
+ console.log('ares6 source is about to post results to the raptor webext');
+ window.postMessage(_data, '*');
+ window.sessionStorage.setItem('benchmark_results', JSON.stringify(_data));
+ }
+
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/glue.js b/third_party/webkit/PerformanceTests/ARES-6/glue.js
new file mode 100644
index 0000000000..91871036ba
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/glue.js
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+const driver = new Driver(
+ isInBrowser ? document.getElementById("status") : null,
+ isInBrowser ? document.getElementById("trigger") : null,
+ function() {
+ driver.start(6)
+ },
+ isInBrowser ? document.getElementById("magic") : null,
+ isInBrowser ? document.getElementById("Geomean") : null,
+ "sampleBench");
+
+function reportResult(...args) {
+ driver.reportResult(...args);
+}
+
+{
+ const title = "ARES-6 1.0.1";
+ if (isInBrowser) {
+ document.title = title;
+ } else {
+ print(title);
+ }
+}
+
+driver.addBenchmark(AirBenchmarkRunner);
+driver.addBenchmark(BasicBenchmarkRunner);
+driver.addBenchmark(BabylonBenchmarkRunner);
+driver.addBenchmark(MLBenchmarkRunner);
+driver.readyTrigger();
+
+if (typeof location !== 'undefined' && (location.search === '?gecko' || location.search === '?raptor')) {
+ driver.start(5);
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/index.html b/third_party/webkit/PerformanceTests/ARES-6/index.html
new file mode 100644
index 0000000000..92fe3cb43c
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/index.html
@@ -0,0 +1,155 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="stylesheet" href="styles.css">
+ <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
+</head>
+<body>
+ <script>
+ window.onerror = function(message, url, lineNumber)
+ {
+ document.getElementById("error").innerHTML = "ERROR: " + url + ":" + lineNumber + ": " + message;
+ }
+
+ const isInBrowser = true;
+ </script>
+ <script src="driver.js"></script>
+ <script src="results.js"></script>
+ <script src="stats.js"></script>
+ <div class="swoop">&nbsp;</div>
+
+ <header>
+ <h1 class="logo"><img src="ARES-6.svg" title="ARES-6" alt="ARES-6"></h1>
+ <button id="trigger" class="start">
+ <span id="status">Start</span>
+ </button>
+ <div id="error" class="error"></div>
+ </header>
+
+ <main>
+
+ <p>ARES-6 measures the execution time of JavaScript's newest features. <a href="about.html">Read more details&hellip;</a></p>
+
+ <div class="overall">
+ <h2>Overall</h2>
+ <div class="score">
+ <span id="Geomean">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+ </div>
+
+ <div class="tests">
+
+ <div class="air test">
+ <h2 id="AirMessage">Air</h2>
+
+ <div class="score">
+ <label>First Iteration</label>
+ <span id="AirFirstIteration">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+
+ <div class="score">
+ <label>Worst 4 Iterations</label>
+ <span id="AirAverageWorstCase">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+
+ <div class="score">
+ <label>Average</label>
+ <span id="AirSteadyState">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+ </div>
+
+ <div class="basic test">
+ <h2 id="BasicMessage">Basic</h2>
+
+ <div class="score">
+ <label>First Iteration</label>
+ <span id="BasicFirstIteration">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+
+ <div class="score">
+ <label>Worst 4 Iteratons</label>
+ <span id="BasicAverageWorstCase">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+
+ <div class="score">
+ <label>Average</label>
+ <span id="BasicSteadyState">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+ </div>
+
+ <div class="babylon test">
+ <h2 id="BabylonMessage">Babylon</h2>
+
+ <div class="score">
+ <label>First Iteration</label>
+ <span id="BabylonFirstIteration">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+
+ <div class="score">
+ <label>Worst 4 Iterations</label>
+ <span id="BabylonAverageWorstCase">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+
+ <div class="score">
+ <label>Average</label>
+ <span id="BabylonSteadyState">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+ </div>
+
+ <div class="ML test">
+ <h2 id="MLMessage">ML</h2>
+
+ <div class="score">
+ <label>First Iteration</label>
+ <span id="MLFirstIteration">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+
+ <div class="score">
+ <label>Worst 4 Iterations</label>
+ <span id="MLAverageWorstCase">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+
+ <div class="score">
+ <label>Average</label>
+ <span id="MLSteadyState">
+ <span class="value">&#8709;</span><span class="units">ms</span>
+ </span>
+ </div>
+ </div>
+
+ </div>
+ </main>
+
+ <iframe id="magic" frameBorder=0></iframe>
+ <script src="air_benchmark.js"></script>
+ <script src="basic_benchmark.js"></script>
+ <script src="babylon_benchmark.js"></script>
+ <script src="ml_benchmark.js"></script>
+ <script src="glue.js"></script>
+
+</body>
+</html>
diff --git a/third_party/webkit/PerformanceTests/ARES-6/ml/benchmark.js b/third_party/webkit/PerformanceTests/ARES-6/ml/benchmark.js
new file mode 100644
index 0000000000..bd6ccd3e3a
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/ml/benchmark.js
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+let currentTime;
+if (this.performance && performance.now)
+ currentTime = function() { return performance.now() };
+else if (this.preciseTime)
+ currentTime = function() { return preciseTime() * 1000; };
+else
+ currentTime = function() { return +new Date(); };
+
+class MLBenchmark {
+ constructor() { }
+
+ runIteration()
+ {
+ let Matrix = MLMatrix;
+ let ACTIVATION_FUNCTIONS = FeedforwardNeuralNetworksActivationFunctions;
+
+ function run() {
+
+ let it = (name, f) => {
+ f();
+ };
+
+ function assert(b) {
+ if (!b)
+ throw new Error("Bad");
+ }
+
+ var functions = Object.keys(ACTIVATION_FUNCTIONS);
+
+ it('Training the neural network with XOR operator', function () {
+ var trainingSet = new Matrix([[0, 0], [0, 1], [1, 0], [1, 1]]);
+ var predictions = [false, true, true, false];
+
+ for (var i = 0; i < functions.length; ++i) {
+ var options = {
+ hiddenLayers: [4],
+ iterations: 40,
+ learningRate: 0.3,
+ activation: functions[i]
+ };
+ var xorNN = new FeedforwardNeuralNetwork(options);
+
+ xorNN.train(trainingSet, predictions);
+ var results = xorNN.predict(trainingSet);
+ }
+ });
+
+ it('Training the neural network with AND operator', function () {
+ var trainingSet = [[0, 0], [0, 1], [1, 0], [1, 1]];
+ var predictions = [[1, 0], [1, 0], [1, 0], [0, 1]];
+
+ for (var i = 0; i < functions.length; ++i) {
+ var options = {
+ hiddenLayers: [3],
+ iterations: 75,
+ learningRate: 0.3,
+ activation: functions[i]
+ };
+ var andNN = new FeedforwardNeuralNetwork(options);
+ andNN.train(trainingSet, predictions);
+
+ var results = andNN.predict(trainingSet);
+ }
+ });
+
+ it('Export and import', function () {
+ var trainingSet = [[0, 0], [0, 1], [1, 0], [1, 1]];
+ var predictions = [0, 1, 1, 1];
+
+ for (var i = 0; i < functions.length; ++i) {
+ var options = {
+ hiddenLayers: [4],
+ iterations: 40,
+ learningRate: 0.3,
+ activation: functions[i]
+ };
+ var orNN = new FeedforwardNeuralNetwork(options);
+ orNN.train(trainingSet, predictions);
+
+ var model = JSON.parse(JSON.stringify(orNN));
+ var networkNN = FeedforwardNeuralNetwork.load(model);
+
+ var results = networkNN.predict(trainingSet);
+ }
+ });
+
+ it('Multiclass clasification', function () {
+ var trainingSet = [[0, 0], [0, 1], [1, 0], [1, 1]];
+ var predictions = [2, 0, 1, 0];
+
+ for (var i = 0; i < functions.length; ++i) {
+ var options = {
+ hiddenLayers: [4],
+ iterations: 40,
+ learningRate: 0.5,
+ activation: functions[i]
+ };
+ var nn = new FeedforwardNeuralNetwork(options);
+ nn.train(trainingSet, predictions);
+
+ var result = nn.predict(trainingSet);
+ }
+ });
+
+ it('Big case', function () {
+ var trainingSet = [[1, 1], [1, 2], [2, 1], [2, 2], [3, 1], [1, 3], [1, 4], [4, 1],
+ [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [5, 5], [4, 5], [3, 5]];
+ var predictions = [[1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [1, 0],
+ [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]];
+ for (var i = 0; i < functions.length; ++i) {
+ var options = {
+ hiddenLayers: [20],
+ iterations: 60,
+ learningRate: 0.01,
+ activation: functions[i]
+ };
+ var nn = new FeedforwardNeuralNetwork(options);
+ nn.train(trainingSet, predictions);
+
+ var result = nn.predict([[5, 4]]);
+
+ assert(result[0][0] < result[0][1]);
+ }
+ });
+ }
+
+ run();
+ }
+}
+
+function runBenchmark()
+{
+ const numIterations = 60;
+
+ let before = currentTime();
+
+ let benchmark = new Benchmark();
+
+ for (let iteration = 0; iteration < numIterations; ++iteration)
+ benchmark.runIteration();
+
+ let after = currentTime();
+ return after - before;
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/ml/index.js b/third_party/webkit/PerformanceTests/ARES-6/ml/index.js
new file mode 100644
index 0000000000..03871ba081
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/ml/index.js
@@ -0,0 +1,6330 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 ml.js
+ *
+ * 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.
+*/
+'use strict';
+
+// ml-stat array.js
+const MLStatArray = {};
+{
+ function compareNumbers(a, b) {
+ return a - b;
+ }
+
+ /**
+ * Computes the sum of the given values
+ * @param {Array} values
+ * @returns {number}
+ */
+ MLStatArray.sum = function sum(values) {
+ var sum = 0;
+ for (var i = 0; i < values.length; i++) {
+ sum += values[i];
+ }
+ return sum;
+ };
+
+ /**
+ * Computes the maximum of the given values
+ * @param {Array} values
+ * @returns {number}
+ */
+ MLStatArray.max = function max(values) {
+ var max = values[0];
+ var l = values.length;
+ for (var i = 1; i < l; i++) {
+ if (values[i] > max) max = values[i];
+ }
+ return max;
+ };
+
+ /**
+ * Computes the minimum of the given values
+ * @param {Array} values
+ * @returns {number}
+ */
+ MLStatArray.min = function min(values) {
+ var min = values[0];
+ var l = values.length;
+ for (var i = 1; i < l; i++) {
+ if (values[i] < min) min = values[i];
+ }
+ return min;
+ };
+
+ /**
+ * Computes the min and max of the given values
+ * @param {Array} values
+ * @returns {{min: number, max: number}}
+ */
+ MLStatArray.minMax = function minMax(values) {
+ var min = values[0];
+ var max = values[0];
+ var l = values.length;
+ for (var i = 1; i < l; i++) {
+ if (values[i] < min) min = values[i];
+ if (values[i] > max) max = values[i];
+ }
+ return {
+ min: min,
+ max: max
+ };
+ };
+
+ /**
+ * Computes the arithmetic mean of the given values
+ * @param {Array} values
+ * @returns {number}
+ */
+ MLStatArray.arithmeticMean = function arithmeticMean(values) {
+ var sum = 0;
+ var l = values.length;
+ for (var i = 0; i < l; i++) {
+ sum += values[i];
+ }
+ return sum / l;
+ };
+
+ /**
+ * {@link arithmeticMean}
+ */
+ MLStatArray.mean = MLStatArray.arithmeticMean;
+
+ /**
+ * Computes the geometric mean of the given values
+ * @param {Array} values
+ * @returns {number}
+ */
+ MLStatArray.geometricMean = function geometricMean(values) {
+ var mul = 1;
+ var l = values.length;
+ for (var i = 0; i < l; i++) {
+ mul *= values[i];
+ }
+ return Math.pow(mul, 1 / l);
+ };
+
+ /**
+ * Computes the mean of the log of the given values
+ * If the return value is exponentiated, it gives the same result as the
+ * geometric mean.
+ * @param {Array} values
+ * @returns {number}
+ */
+ MLStatArray.logMean = function logMean(values) {
+ var lnsum = 0;
+ var l = values.length;
+ for (var i = 0; i < l; i++) {
+ lnsum += Math.log(values[i]);
+ }
+ return lnsum / l;
+ };
+
+ /**
+ * Computes the weighted grand mean for a list of means and sample sizes
+ * @param {Array} means - Mean values for each set of samples
+ * @param {Array} samples - Number of original values for each set of samples
+ * @returns {number}
+ */
+ MLStatArray.grandMean = function grandMean(means, samples) {
+ var sum = 0;
+ var n = 0;
+ var l = means.length;
+ for (var i = 0; i < l; i++) {
+ sum += samples[i] * means[i];
+ n += samples[i];
+ }
+ return sum / n;
+ };
+
+ /**
+ * Computes the truncated mean of the given values using a given percentage
+ * @param {Array} values
+ * @param {number} percent - The percentage of values to keep (range: [0,1])
+ * @param {boolean} [alreadySorted=false]
+ * @returns {number}
+ */
+ MLStatArray.truncatedMean = function truncatedMean(values, percent, alreadySorted) {
+ if (alreadySorted === undefined) alreadySorted = false;
+ if (!alreadySorted) {
+ values = [].concat(values).sort(compareNumbers);
+ }
+ var l = values.length;
+ var k = Math.floor(l * percent);
+ var sum = 0;
+ for (var i = k; i < (l - k); i++) {
+ sum += values[i];
+ }
+ return sum / (l - 2 * k);
+ };
+
+ /**
+ * Computes the harmonic mean of the given values
+ * @param {Array} values
+ * @returns {number}
+ */
+ MLStatArray.harmonicMean = function harmonicMean(values) {
+ var sum = 0;
+ var l = values.length;
+ for (var i = 0; i < l; i++) {
+ if (values[i] === 0) {
+ throw new RangeError('value at index ' + i + 'is zero');
+ }
+ sum += 1 / values[i];
+ }
+ return l / sum;
+ };
+
+ /**
+ * Computes the contraharmonic mean of the given values
+ * @param {Array} values
+ * @returns {number}
+ */
+ MLStatArray.contraHarmonicMean = function contraHarmonicMean(values) {
+ var r1 = 0;
+ var r2 = 0;
+ var l = values.length;
+ for (var i = 0; i < l; i++) {
+ r1 += values[i] * values[i];
+ r2 += values[i];
+ }
+ if (r2 < 0) {
+ throw new RangeError('sum of values is negative');
+ }
+ return r1 / r2;
+ };
+
+ /**
+ * Computes the median of the given values
+ * @param {Array} values
+ * @param {boolean} [alreadySorted=false]
+ * @returns {number}
+ */
+ MLStatArray.median = function median(values, alreadySorted) {
+ if (alreadySorted === undefined) alreadySorted = false;
+ if (!alreadySorted) {
+ values = [].concat(values).sort(compareNumbers);
+ }
+ var l = values.length;
+ var half = Math.floor(l / 2);
+ if (l % 2 === 0) {
+ return (values[half - 1] + values[half]) * 0.5;
+ } else {
+ return values[half];
+ }
+ };
+
+ /**
+ * Computes the variance of the given values
+ * @param {Array} values
+ * @param {boolean} [unbiased=true] - if true, divide by (n-1); if false, divide by n.
+ * @returns {number}
+ */
+ MLStatArray.variance = function variance(values, unbiased) {
+ if (unbiased === undefined) unbiased = true;
+ var theMean = MLStatArray.mean(values);
+ var theVariance = 0;
+ var l = values.length;
+
+ for (var i = 0; i < l; i++) {
+ var x = values[i] - theMean;
+ theVariance += x * x;
+ }
+
+ if (unbiased) {
+ return theVariance / (l - 1);
+ } else {
+ return theVariance / l;
+ }
+ };
+
+ /**
+ * Computes the standard deviation of the given values
+ * @param {Array} values
+ * @param {boolean} [unbiased=true] - if true, divide by (n-1); if false, divide by n.
+ * @returns {number}
+ */
+ MLStatArray.standardDeviation = function standardDeviation(values, unbiased) {
+ return Math.sqrt(MLStatArray.variance(values, unbiased));
+ };
+
+ MLStatArray.standardError = function standardError(values) {
+ return MLStatArray.standardDeviation(values) / Math.sqrt(values.length);
+ };
+
+ /**
+ * IEEE Transactions on biomedical engineering, vol. 52, no. 1, january 2005, p. 76-
+ * Calculate the standard deviation via the Median of the absolute deviation
+ * The formula for the standard deviation only holds for Gaussian random variables.
+ * @returns {{mean: number, stdev: number}}
+ */
+ MLStatArray.robustMeanAndStdev = function robustMeanAndStdev(y) {
+ var mean = 0, stdev = 0;
+ var length = y.length, i = 0;
+ for (i = 0; i < length; i++) {
+ mean += y[i];
+ }
+ mean /= length;
+ var averageDeviations = new Array(length);
+ for (i = 0; i < length; i++)
+ averageDeviations[i] = Math.abs(y[i] - mean);
+ averageDeviations.sort(compareNumbers);
+ if (length % 2 === 1) {
+ stdev = averageDeviations[(length - 1) / 2] / 0.6745;
+ } else {
+ stdev = 0.5 * (averageDeviations[length / 2] + averageDeviations[length / 2 - 1]) / 0.6745;
+ }
+
+ return {
+ mean: mean,
+ stdev: stdev
+ };
+ };
+
+ MLStatArray.quartiles = function quartiles(values, alreadySorted) {
+ if (typeof (alreadySorted) === 'undefined') alreadySorted = false;
+ if (!alreadySorted) {
+ values = [].concat(values).sort(compareNumbers);
+ }
+
+ var quart = values.length / 4;
+ var q1 = values[Math.ceil(quart) - 1];
+ var q2 = MLStatArray.median(values, true);
+ var q3 = values[Math.ceil(quart * 3) - 1];
+
+ return {q1: q1, q2: q2, q3: q3};
+ };
+
+ MLStatArray.pooledStandardDeviation = function pooledStandardDeviation(samples, unbiased) {
+ return Math.sqrt(MLStatArray.pooledVariance(samples, unbiased));
+ };
+
+ MLStatArray.pooledVariance = function pooledVariance(samples, unbiased) {
+ if (typeof (unbiased) === 'undefined') unbiased = true;
+ var sum = 0;
+ var length = 0, l = samples.length;
+ for (var i = 0; i < l; i++) {
+ var values = samples[i];
+ var vari = MLStatArray.variance(values);
+
+ sum += (values.length - 1) * vari;
+
+ if (unbiased)
+ length += values.length - 1;
+ else
+ length += values.length;
+ }
+ return sum / length;
+ };
+
+ MLStatArray.mode = function mode(values) {
+ var l = values.length,
+ itemCount = new Array(l),
+ i;
+ for (i = 0; i < l; i++) {
+ itemCount[i] = 0;
+ }
+ var itemArray = new Array(l);
+ var count = 0;
+
+ for (i = 0; i < l; i++) {
+ var index = itemArray.indexOf(values[i]);
+ if (index >= 0)
+ itemCount[index]++;
+ else {
+ itemArray[count] = values[i];
+ itemCount[count] = 1;
+ count++;
+ }
+ }
+
+ var maxValue = 0, maxIndex = 0;
+ for (i = 0; i < count; i++) {
+ if (itemCount[i] > maxValue) {
+ maxValue = itemCount[i];
+ maxIndex = i;
+ }
+ }
+
+ return itemArray[maxIndex];
+ };
+
+ MLStatArray.covariance = function covariance(vector1, vector2, unbiased) {
+ if (typeof (unbiased) === 'undefined') unbiased = true;
+ var mean1 = MLStatArray.mean(vector1);
+ var mean2 = MLStatArray.mean(vector2);
+
+ if (vector1.length !== vector2.length)
+ throw 'Vectors do not have the same dimensions';
+
+ var cov = 0, l = vector1.length;
+ for (var i = 0; i < l; i++) {
+ var x = vector1[i] - mean1;
+ var y = vector2[i] - mean2;
+ cov += x * y;
+ }
+
+ if (unbiased)
+ return cov / (l - 1);
+ else
+ return cov / l;
+ };
+
+ MLStatArray.skewness = function skewness(values, unbiased) {
+ if (typeof (unbiased) === 'undefined') unbiased = true;
+ var theMean = MLStatArray.mean(values);
+
+ var s2 = 0, s3 = 0, l = values.length;
+ for (var i = 0; i < l; i++) {
+ var dev = values[i] - theMean;
+ s2 += dev * dev;
+ s3 += dev * dev * dev;
+ }
+ var m2 = s2 / l;
+ var m3 = s3 / l;
+
+ var g = m3 / (Math.pow(m2, 3 / 2.0));
+ if (unbiased) {
+ var a = Math.sqrt(l * (l - 1));
+ var b = l - 2;
+ return (a / b) * g;
+ } else {
+ return g;
+ }
+ };
+
+ MLStatArray.kurtosis = function kurtosis(values, unbiased) {
+ if (typeof (unbiased) === 'undefined') unbiased = true;
+ var theMean = MLStatArray.mean(values);
+ var n = values.length, s2 = 0, s4 = 0;
+
+ for (var i = 0; i < n; i++) {
+ var dev = values[i] - theMean;
+ s2 += dev * dev;
+ s4 += dev * dev * dev * dev;
+ }
+ var m2 = s2 / n;
+ var m4 = s4 / n;
+
+ if (unbiased) {
+ var v = s2 / (n - 1);
+ var a = (n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3));
+ var b = s4 / (v * v);
+ var c = ((n - 1) * (n - 1)) / ((n - 2) * (n - 3));
+
+ return a * b - 3 * c;
+ } else {
+ return m4 / (m2 * m2) - 3;
+ }
+ };
+
+ MLStatArray.entropy = function entropy(values, eps) {
+ if (typeof (eps) === 'undefined') eps = 0;
+ var sum = 0, l = values.length;
+ for (var i = 0; i < l; i++)
+ sum += values[i] * Math.log(values[i] + eps);
+ return -sum;
+ };
+
+ MLStatArray.weightedMean = function weightedMean(values, weights) {
+ var sum = 0, l = values.length;
+ for (var i = 0; i < l; i++)
+ sum += values[i] * weights[i];
+ return sum;
+ };
+
+ MLStatArray.weightedStandardDeviation = function weightedStandardDeviation(values, weights) {
+ return Math.sqrt(MLStatArray.weightedVariance(values, weights));
+ };
+
+ MLStatArray.weightedVariance = function weightedVariance(values, weights) {
+ var theMean = MLStatArray.weightedMean(values, weights);
+ var vari = 0, l = values.length;
+ var a = 0, b = 0;
+
+ for (var i = 0; i < l; i++) {
+ var z = values[i] - theMean;
+ var w = weights[i];
+
+ vari += w * (z * z);
+ b += w;
+ a += w * w;
+ }
+
+ return vari * (b / (b * b - a));
+ };
+
+ MLStatArray.center = function center(values, inPlace) {
+ if (typeof (inPlace) === 'undefined') inPlace = false;
+
+ var result = values;
+ if (!inPlace)
+ result = [].concat(values);
+
+ var theMean = MLStatArray.mean(result), l = result.length;
+ for (var i = 0; i < l; i++)
+ result[i] -= theMean;
+ };
+
+ MLStatArray.standardize = function standardize(values, standardDev, inPlace) {
+ if (typeof (standardDev) === 'undefined') standardDev = MLStatArray.standardDeviation(values);
+ if (typeof (inPlace) === 'undefined') inPlace = false;
+ var l = values.length;
+ var result = inPlace ? values : new Array(l);
+ for (var i = 0; i < l; i++)
+ result[i] = values[i] / standardDev;
+ return result;
+ };
+
+ MLStatArray.cumulativeSum = function cumulativeSum(array) {
+ var l = array.length;
+ var result = new Array(l);
+ result[0] = array[0];
+ for (var i = 1; i < l; i++)
+ result[i] = result[i - 1] + array[i];
+ return result;
+ };
+}
+
+
+// ml-stat matrix.js
+const MLStatMatrix = {};
+{
+ let arrayStat = MLStatArray;
+
+ function compareNumbers(a, b) {
+ return a - b;
+ }
+
+ MLStatMatrix.max = function max(matrix) {
+ var max = -Infinity;
+ for (var i = 0; i < matrix.length; i++) {
+ for (var j = 0; j < matrix[i].length; j++) {
+ if (matrix[i][j] > max) max = matrix[i][j];
+ }
+ }
+ return max;
+ };
+
+ MLStatMatrix.min = function min(matrix) {
+ var min = Infinity;
+ for (var i = 0; i < matrix.length; i++) {
+ for (var j = 0; j < matrix[i].length; j++) {
+ if (matrix[i][j] < min) min = matrix[i][j];
+ }
+ }
+ return min;
+ };
+
+ MLStatMatrix.minMax = function minMax(matrix) {
+ var min = Infinity;
+ var max = -Infinity;
+ for (var i = 0; i < matrix.length; i++) {
+ for (var j = 0; j < matrix[i].length; j++) {
+ if (matrix[i][j] < min) min = matrix[i][j];
+ if (matrix[i][j] > max) max = matrix[i][j];
+ }
+ }
+ return {
+ min:min,
+ max:max
+ };
+ };
+
+ MLStatMatrix.entropy = function entropy(matrix, eps) {
+ if (typeof (eps) === 'undefined') {
+ eps = 0;
+ }
+ var sum = 0,
+ l1 = matrix.length,
+ l2 = matrix[0].length;
+ for (var i = 0; i < l1; i++) {
+ for (var j = 0; j < l2; j++) {
+ sum += matrix[i][j] * Math.log(matrix[i][j] + eps);
+ }
+ }
+ return -sum;
+ };
+
+ MLStatMatrix.mean = function mean(matrix, dimension) {
+ if (typeof (dimension) === 'undefined') {
+ dimension = 0;
+ }
+ var rows = matrix.length,
+ cols = matrix[0].length,
+ theMean, N, i, j;
+
+ if (dimension === -1) {
+ theMean = [0];
+ N = rows * cols;
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < cols; j++) {
+ theMean[0] += matrix[i][j];
+ }
+ }
+ theMean[0] /= N;
+ } else if (dimension === 0) {
+ theMean = new Array(cols);
+ N = rows;
+ for (j = 0; j < cols; j++) {
+ theMean[j] = 0;
+ for (i = 0; i < rows; i++) {
+ theMean[j] += matrix[i][j];
+ }
+ theMean[j] /= N;
+ }
+ } else if (dimension === 1) {
+ theMean = new Array(rows);
+ N = cols;
+ for (j = 0; j < rows; j++) {
+ theMean[j] = 0;
+ for (i = 0; i < cols; i++) {
+ theMean[j] += matrix[j][i];
+ }
+ theMean[j] /= N;
+ }
+ } else {
+ throw new Error('Invalid dimension');
+ }
+ return theMean;
+ };
+
+ MLStatMatrix.sum = function sum(matrix, dimension) {
+ if (typeof (dimension) === 'undefined') {
+ dimension = 0;
+ }
+ var rows = matrix.length,
+ cols = matrix[0].length,
+ theSum, i, j;
+
+ if (dimension === -1) {
+ theSum = [0];
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < cols; j++) {
+ theSum[0] += matrix[i][j];
+ }
+ }
+ } else if (dimension === 0) {
+ theSum = new Array(cols);
+ for (j = 0; j < cols; j++) {
+ theSum[j] = 0;
+ for (i = 0; i < rows; i++) {
+ theSum[j] += matrix[i][j];
+ }
+ }
+ } else if (dimension === 1) {
+ theSum = new Array(rows);
+ for (j = 0; j < rows; j++) {
+ theSum[j] = 0;
+ for (i = 0; i < cols; i++) {
+ theSum[j] += matrix[j][i];
+ }
+ }
+ } else {
+ throw new Error('Invalid dimension');
+ }
+ return theSum;
+ };
+
+ MLStatMatrix.product = function product(matrix, dimension) {
+ if (typeof (dimension) === 'undefined') {
+ dimension = 0;
+ }
+ var rows = matrix.length,
+ cols = matrix[0].length,
+ theProduct, i, j;
+
+ if (dimension === -1) {
+ theProduct = [1];
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < cols; j++) {
+ theProduct[0] *= matrix[i][j];
+ }
+ }
+ } else if (dimension === 0) {
+ theProduct = new Array(cols);
+ for (j = 0; j < cols; j++) {
+ theProduct[j] = 1;
+ for (i = 0; i < rows; i++) {
+ theProduct[j] *= matrix[i][j];
+ }
+ }
+ } else if (dimension === 1) {
+ theProduct = new Array(rows);
+ for (j = 0; j < rows; j++) {
+ theProduct[j] = 1;
+ for (i = 0; i < cols; i++) {
+ theProduct[j] *= matrix[j][i];
+ }
+ }
+ } else {
+ throw new Error('Invalid dimension');
+ }
+ return theProduct;
+ };
+
+ MLStatMatrix.standardDeviation = function standardDeviation(matrix, means, unbiased) {
+ var vari = MLStatMatrix.variance(matrix, means, unbiased), l = vari.length;
+ for (var i = 0; i < l; i++) {
+ vari[i] = Math.sqrt(vari[i]);
+ }
+ return vari;
+ };
+
+ MLStatMatrix.variance = function variance(matrix, means, unbiased) {
+ if (typeof (unbiased) === 'undefined') {
+ unbiased = true;
+ }
+ means = means || MLStatMatrix.mean(matrix);
+ var rows = matrix.length;
+ if (rows === 0) return [];
+ var cols = matrix[0].length;
+ var vari = new Array(cols);
+
+ for (var j = 0; j < cols; j++) {
+ var sum1 = 0, sum2 = 0, x = 0;
+ for (var i = 0; i < rows; i++) {
+ x = matrix[i][j] - means[j];
+ sum1 += x;
+ sum2 += x * x;
+ }
+ if (unbiased) {
+ vari[j] = (sum2 - ((sum1 * sum1) / rows)) / (rows - 1);
+ } else {
+ vari[j] = (sum2 - ((sum1 * sum1) / rows)) / rows;
+ }
+ }
+ return vari;
+ };
+
+ MLStatMatrix.median = function median(matrix) {
+ var rows = matrix.length, cols = matrix[0].length;
+ var medians = new Array(cols);
+
+ for (var i = 0; i < cols; i++) {
+ var data = new Array(rows);
+ for (var j = 0; j < rows; j++) {
+ data[j] = matrix[j][i];
+ }
+ data.sort(compareNumbers);
+ var N = data.length;
+ if (N % 2 === 0) {
+ medians[i] = (data[N / 2] + data[(N / 2) - 1]) * 0.5;
+ } else {
+ medians[i] = data[Math.floor(N / 2)];
+ }
+ }
+ return medians;
+ };
+
+ MLStatMatrix.mode = function mode(matrix) {
+ var rows = matrix.length,
+ cols = matrix[0].length,
+ modes = new Array(cols),
+ i, j;
+ for (i = 0; i < cols; i++) {
+ var itemCount = new Array(rows);
+ for (var k = 0; k < rows; k++) {
+ itemCount[k] = 0;
+ }
+ var itemArray = new Array(rows);
+ var count = 0;
+
+ for (j = 0; j < rows; j++) {
+ var index = itemArray.indexOf(matrix[j][i]);
+ if (index >= 0) {
+ itemCount[index]++;
+ } else {
+ itemArray[count] = matrix[j][i];
+ itemCount[count] = 1;
+ count++;
+ }
+ }
+
+ var maxValue = 0, maxIndex = 0;
+ for (j = 0; j < count; j++) {
+ if (itemCount[j] > maxValue) {
+ maxValue = itemCount[j];
+ maxIndex = j;
+ }
+ }
+
+ modes[i] = itemArray[maxIndex];
+ }
+ return modes;
+ };
+
+ MLStatMatrix.skewness = function skewness(matrix, unbiased) {
+ if (typeof (unbiased) === 'undefined') unbiased = true;
+ var means = MLStatMatrix.mean(matrix);
+ var n = matrix.length, l = means.length;
+ var skew = new Array(l);
+
+ for (var j = 0; j < l; j++) {
+ var s2 = 0, s3 = 0;
+ for (var i = 0; i < n; i++) {
+ var dev = matrix[i][j] - means[j];
+ s2 += dev * dev;
+ s3 += dev * dev * dev;
+ }
+
+ var m2 = s2 / n;
+ var m3 = s3 / n;
+ var g = m3 / Math.pow(m2, 3 / 2);
+
+ if (unbiased) {
+ var a = Math.sqrt(n * (n - 1));
+ var b = n - 2;
+ skew[j] = (a / b) * g;
+ } else {
+ skew[j] = g;
+ }
+ }
+ return skew;
+ };
+
+ MLStatMatrix.kurtosis = function kurtosis(matrix, unbiased) {
+ if (typeof (unbiased) === 'undefined') unbiased = true;
+ var means = MLStatMatrix.mean(matrix);
+ var n = matrix.length, m = matrix[0].length;
+ var kurt = new Array(m);
+
+ for (var j = 0; j < m; j++) {
+ var s2 = 0, s4 = 0;
+ for (var i = 0; i < n; i++) {
+ var dev = matrix[i][j] - means[j];
+ s2 += dev * dev;
+ s4 += dev * dev * dev * dev;
+ }
+ var m2 = s2 / n;
+ var m4 = s4 / n;
+
+ if (unbiased) {
+ var v = s2 / (n - 1);
+ var a = (n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3));
+ var b = s4 / (v * v);
+ var c = ((n - 1) * (n - 1)) / ((n - 2) * (n - 3));
+ kurt[j] = a * b - 3 * c;
+ } else {
+ kurt[j] = m4 / (m2 * m2) - 3;
+ }
+ }
+ return kurt;
+ };
+
+ MLStatMatrix.standardError = function standardError(matrix) {
+ var samples = matrix.length;
+ var standardDeviations = MLStatMatrix.standardDeviation(matrix);
+ var l = standardDeviations.length;
+ var standardErrors = new Array(l);
+ var sqrtN = Math.sqrt(samples);
+
+ for (var i = 0; i < l; i++) {
+ standardErrors[i] = standardDeviations[i] / sqrtN;
+ }
+ return standardErrors;
+ };
+
+ MLStatMatrix.covariance = function covariance(matrix, dimension) {
+ return MLStatMatrix.scatter(matrix, undefined, dimension);
+ };
+
+ MLStatMatrix.scatter = function scatter(matrix, divisor, dimension) {
+ if (typeof (dimension) === 'undefined') {
+ dimension = 0;
+ }
+ if (typeof (divisor) === 'undefined') {
+ if (dimension === 0) {
+ divisor = matrix.length - 1;
+ } else if (dimension === 1) {
+ divisor = matrix[0].length - 1;
+ }
+ }
+ var means = MLStatMatrix.mean(matrix, dimension);
+ var rows = matrix.length;
+ if (rows === 0) {
+ return [[]];
+ }
+ var cols = matrix[0].length,
+ cov, i, j, s, k;
+
+ if (dimension === 0) {
+ cov = new Array(cols);
+ for (i = 0; i < cols; i++) {
+ cov[i] = new Array(cols);
+ }
+ for (i = 0; i < cols; i++) {
+ for (j = i; j < cols; j++) {
+ s = 0;
+ for (k = 0; k < rows; k++) {
+ s += (matrix[k][j] - means[j]) * (matrix[k][i] - means[i]);
+ }
+ s /= divisor;
+ cov[i][j] = s;
+ cov[j][i] = s;
+ }
+ }
+ } else if (dimension === 1) {
+ cov = new Array(rows);
+ for (i = 0; i < rows; i++) {
+ cov[i] = new Array(rows);
+ }
+ for (i = 0; i < rows; i++) {
+ for (j = i; j < rows; j++) {
+ s = 0;
+ for (k = 0; k < cols; k++) {
+ s += (matrix[j][k] - means[j]) * (matrix[i][k] - means[i]);
+ }
+ s /= divisor;
+ cov[i][j] = s;
+ cov[j][i] = s;
+ }
+ }
+ } else {
+ throw new Error('Invalid dimension');
+ }
+
+ return cov;
+ };
+
+ MLStatMatrix.correlation = function correlation(matrix) {
+ var means = MLStatMatrix.mean(matrix),
+ standardDeviations = MLStatMatrix.standardDeviation(matrix, true, means),
+ scores = MLStatMatrix.zScores(matrix, means, standardDeviations),
+ rows = matrix.length,
+ cols = matrix[0].length,
+ i, j;
+
+ var cor = new Array(cols);
+ for (i = 0; i < cols; i++) {
+ cor[i] = new Array(cols);
+ }
+ for (i = 0; i < cols; i++) {
+ for (j = i; j < cols; j++) {
+ var c = 0;
+ for (var k = 0, l = scores.length; k < l; k++) {
+ c += scores[k][j] * scores[k][i];
+ }
+ c /= rows - 1;
+ cor[i][j] = c;
+ cor[j][i] = c;
+ }
+ }
+ return cor;
+ };
+
+ MLStatMatrix.zScores = function zScores(matrix, means, standardDeviations) {
+ means = means || MLStatMatrix.mean(matrix);
+ if (typeof (standardDeviations) === 'undefined') standardDeviations = MLStatMatrix.standardDeviation(matrix, true, means);
+ return MLStatMatrix.standardize(MLStatMatrix.center(matrix, means, false), standardDeviations, true);
+ };
+
+ MLStatMatrix.center = function center(matrix, means, inPlace) {
+ means = means || MLStatMatrix.mean(matrix);
+ var result = matrix,
+ l = matrix.length,
+ i, j, jj;
+
+ if (!inPlace) {
+ result = new Array(l);
+ for (i = 0; i < l; i++) {
+ result[i] = new Array(matrix[i].length);
+ }
+ }
+
+ for (i = 0; i < l; i++) {
+ var row = result[i];
+ for (j = 0, jj = row.length; j < jj; j++) {
+ row[j] = matrix[i][j] - means[j];
+ }
+ }
+ return result;
+ };
+
+ MLStatMatrix.standardize = function standardize(matrix, standardDeviations, inPlace) {
+ if (typeof (standardDeviations) === 'undefined') standardDeviations = MLStatMatrix.standardDeviation(matrix);
+ var result = matrix,
+ l = matrix.length,
+ i, j, jj;
+
+ if (!inPlace) {
+ result = new Array(l);
+ for (i = 0; i < l; i++) {
+ result[i] = new Array(matrix[i].length);
+ }
+ }
+
+ for (i = 0; i < l; i++) {
+ var resultRow = result[i];
+ var sourceRow = matrix[i];
+ for (j = 0, jj = resultRow.length; j < jj; j++) {
+ if (standardDeviations[j] !== 0 && !isNaN(standardDeviations[j])) {
+ resultRow[j] = sourceRow[j] / standardDeviations[j];
+ }
+ }
+ }
+ return result;
+ };
+
+ MLStatMatrix.weightedVariance = function weightedVariance(matrix, weights) {
+ var means = MLStatMatrix.mean(matrix);
+ var rows = matrix.length;
+ if (rows === 0) return [];
+ var cols = matrix[0].length;
+ var vari = new Array(cols);
+
+ for (var j = 0; j < cols; j++) {
+ var sum = 0;
+ var a = 0, b = 0;
+
+ for (var i = 0; i < rows; i++) {
+ var z = matrix[i][j] - means[j];
+ var w = weights[i];
+
+ sum += w * (z * z);
+ b += w;
+ a += w * w;
+ }
+
+ vari[j] = sum * (b / (b * b - a));
+ }
+
+ return vari;
+ };
+
+ MLStatMatrix.weightedMean = function weightedMean(matrix, weights, dimension) {
+ if (typeof (dimension) === 'undefined') {
+ dimension = 0;
+ }
+ var rows = matrix.length;
+ if (rows === 0) return [];
+ var cols = matrix[0].length,
+ means, i, ii, j, w, row;
+
+ if (dimension === 0) {
+ means = new Array(cols);
+ for (i = 0; i < cols; i++) {
+ means[i] = 0;
+ }
+ for (i = 0; i < rows; i++) {
+ row = matrix[i];
+ w = weights[i];
+ for (j = 0; j < cols; j++) {
+ means[j] += row[j] * w;
+ }
+ }
+ } else if (dimension === 1) {
+ means = new Array(rows);
+ for (i = 0; i < rows; i++) {
+ means[i] = 0;
+ }
+ for (j = 0; j < rows; j++) {
+ row = matrix[j];
+ w = weights[j];
+ for (i = 0; i < cols; i++) {
+ means[j] += row[i] * w;
+ }
+ }
+ } else {
+ throw new Error('Invalid dimension');
+ }
+
+ var weightSum = arrayStat.sum(weights);
+ if (weightSum !== 0) {
+ for (i = 0, ii = means.length; i < ii; i++) {
+ means[i] /= weightSum;
+ }
+ }
+ return means;
+ };
+
+ MLStatMatrix.weightedCovariance = function weightedCovariance(matrix, weights, means, dimension) {
+ dimension = dimension || 0;
+ means = means || MLStatMatrix.weightedMean(matrix, weights, dimension);
+ var s1 = 0, s2 = 0;
+ for (var i = 0, ii = weights.length; i < ii; i++) {
+ s1 += weights[i];
+ s2 += weights[i] * weights[i];
+ }
+ var factor = s1 / (s1 * s1 - s2);
+ return MLStatMatrix.weightedScatter(matrix, weights, means, factor, dimension);
+ };
+
+ MLStatMatrix.weightedScatter = function weightedScatter(matrix, weights, means, factor, dimension) {
+ dimension = dimension || 0;
+ means = means || MLStatMatrix.weightedMean(matrix, weights, dimension);
+ if (typeof (factor) === 'undefined') {
+ factor = 1;
+ }
+ var rows = matrix.length;
+ if (rows === 0) {
+ return [[]];
+ }
+ var cols = matrix[0].length,
+ cov, i, j, k, s;
+
+ if (dimension === 0) {
+ cov = new Array(cols);
+ for (i = 0; i < cols; i++) {
+ cov[i] = new Array(cols);
+ }
+ for (i = 0; i < cols; i++) {
+ for (j = i; j < cols; j++) {
+ s = 0;
+ for (k = 0; k < rows; k++) {
+ s += weights[k] * (matrix[k][j] - means[j]) * (matrix[k][i] - means[i]);
+ }
+ cov[i][j] = s * factor;
+ cov[j][i] = s * factor;
+ }
+ }
+ } else if (dimension === 1) {
+ cov = new Array(rows);
+ for (i = 0; i < rows; i++) {
+ cov[i] = new Array(rows);
+ }
+ for (i = 0; i < rows; i++) {
+ for (j = i; j < rows; j++) {
+ s = 0;
+ for (k = 0; k < cols; k++) {
+ s += weights[k] * (matrix[j][k] - means[j]) * (matrix[i][k] - means[i]);
+ }
+ cov[i][j] = s * factor;
+ cov[j][i] = s * factor;
+ }
+ }
+ } else {
+ throw new Error('Invalid dimension');
+ }
+
+ return cov;
+ };
+}
+
+// ml-stat index.js
+const MLStat = {};
+{
+ MLStat.array = MLStatArray;
+ MLStat.matrix = MLStatMatrix;
+}
+
+
+// ml-array-utils ArrayUtils.js
+const MLArrayUtilsArrayUtils = {};
+{
+ const Stat = MLStat.array;
+ /**
+ * Function that returns an array of points given 1D array as follows:
+ *
+ * [x1, y1, .. , x2, y2, ..]
+ *
+ * And receive the number of dimensions of each point.
+ * @param array
+ * @param dimensions
+ * @returns {Array} - Array of points.
+ */
+ function coordArrayToPoints(array, dimensions) {
+ if(array.length % dimensions !== 0) {
+ throw new RangeError('Dimensions number must be accordance with the size of the array.');
+ }
+
+ var length = array.length / dimensions;
+ var pointsArr = new Array(length);
+
+ var k = 0;
+ for(var i = 0; i < array.length; i += dimensions) {
+ var point = new Array(dimensions);
+ for(var j = 0; j < dimensions; ++j) {
+ point[j] = array[i + j];
+ }
+
+ pointsArr[k] = point;
+ k++;
+ }
+
+ return pointsArr;
+ }
+
+
+ /**
+ * Function that given an array as follows:
+ * [x1, y1, .. , x2, y2, ..]
+ *
+ * Returns an array as follows:
+ * [[x1, x2, ..], [y1, y2, ..], [ .. ]]
+ *
+ * And receives the number of dimensions of each coordinate.
+ * @param array
+ * @param dimensions
+ * @returns {Array} - Matrix of coordinates
+ */
+ function coordArrayToCoordMatrix(array, dimensions) {
+ if(array.length % dimensions !== 0) {
+ throw new RangeError('Dimensions number must be accordance with the size of the array.');
+ }
+
+ var coordinatesArray = new Array(dimensions);
+ var points = array.length / dimensions;
+ for (var i = 0; i < coordinatesArray.length; i++) {
+ coordinatesArray[i] = new Array(points);
+ }
+
+ for(i = 0; i < array.length; i += dimensions) {
+ for(var j = 0; j < dimensions; ++j) {
+ var currentPoint = Math.floor(i / dimensions);
+ coordinatesArray[j][currentPoint] = array[i + j];
+ }
+ }
+
+ return coordinatesArray;
+ }
+
+ /**
+ * Function that receives a coordinate matrix as follows:
+ * [[x1, x2, ..], [y1, y2, ..], [ .. ]]
+ *
+ * Returns an array of coordinates as follows:
+ * [x1, y1, .. , x2, y2, ..]
+ *
+ * @param coordMatrix
+ * @returns {Array}
+ */
+ function coordMatrixToCoordArray(coordMatrix) {
+ var coodinatesArray = new Array(coordMatrix.length * coordMatrix[0].length);
+ var k = 0;
+ for(var i = 0; i < coordMatrix[0].length; ++i) {
+ for(var j = 0; j < coordMatrix.length; ++j) {
+ coodinatesArray[k] = coordMatrix[j][i];
+ ++k;
+ }
+ }
+
+ return coodinatesArray;
+ }
+
+ /**
+ * Tranpose a matrix, this method is for coordMatrixToPoints and
+ * pointsToCoordMatrix, that because only transposing the matrix
+ * you can change your representation.
+ *
+ * @param matrix
+ * @returns {Array}
+ */
+ function transpose(matrix) {
+ var resultMatrix = new Array(matrix[0].length);
+ for(var i = 0; i < resultMatrix.length; ++i) {
+ resultMatrix[i] = new Array(matrix.length);
+ }
+
+ for (i = 0; i < matrix.length; ++i) {
+ for(var j = 0; j < matrix[0].length; ++j) {
+ resultMatrix[j][i] = matrix[i][j];
+ }
+ }
+
+ return resultMatrix;
+ }
+
+ /**
+ * Function that transform an array of points into a coordinates array
+ * as follows:
+ * [x1, y1, .. , x2, y2, ..]
+ *
+ * @param points
+ * @returns {Array}
+ */
+ function pointsToCoordArray(points) {
+ var coodinatesArray = new Array(points.length * points[0].length);
+ var k = 0;
+ for(var i = 0; i < points.length; ++i) {
+ for(var j = 0; j < points[0].length; ++j) {
+ coodinatesArray[k] = points[i][j];
+ ++k;
+ }
+ }
+
+ return coodinatesArray;
+ }
+
+ /**
+ * Apply the dot product between the smaller vector and a subsets of the
+ * largest one.
+ *
+ * @param firstVector
+ * @param secondVector
+ * @returns {Array} each dot product of size of the difference between the
+ * larger and the smallest one.
+ */
+ function applyDotProduct(firstVector, secondVector) {
+ var largestVector, smallestVector;
+ if(firstVector.length <= secondVector.length) {
+ smallestVector = firstVector;
+ largestVector = secondVector;
+ } else {
+ smallestVector = secondVector;
+ largestVector = firstVector;
+ }
+
+ var difference = largestVector.length - smallestVector.length + 1;
+ var dotProductApplied = new Array(difference);
+
+ for (var i = 0; i < difference; ++i) {
+ var sum = 0;
+ for (var j = 0; j < smallestVector.length; ++j) {
+ sum += smallestVector[j] * largestVector[i + j];
+ }
+ dotProductApplied[i] = sum;
+ }
+
+ return dotProductApplied;
+ }
+ /**
+ * To scale the input array between the specified min and max values. The operation is performed inplace
+ * if the options.inplace is specified. If only one of the min or max parameters is specified, then the scaling
+ * will multiply the input array by min/min(input) or max/max(input)
+ * @param input
+ * @param options
+ * @returns {*}
+ */
+ function scale(input, options){
+ var y;
+ if(options.inPlace){
+ y = input;
+ }
+ else{
+ y = new Array(input.length);
+ }
+ const max = options.max;
+ const min = options.min;
+ if(typeof max === "number"){
+ if(typeof min === "number"){
+ var minMax = Stat.minMax(input);
+ var factor = (max - min)/(minMax.max-minMax.min);
+ for(var i=0;i< y.length;i++){
+ y[i]=(input[i]-minMax.min)*factor+min;
+ }
+ }
+ else{
+ var currentMin = Stat.max(input);
+ var factor = max/currentMin;
+ for(var i=0;i< y.length;i++){
+ y[i] = input[i]*factor;
+ }
+ }
+ }
+ else{
+ if(typeof min === "number"){
+ var currentMin = Stat.min(input);
+ var factor = min/currentMin;
+ for(var i=0;i< y.length;i++){
+ y[i] = input[i]*factor;
+ }
+ }
+ }
+ return y;
+ }
+
+ MLArrayUtilsArrayUtils.coordArrayToPoints = coordArrayToPoints;
+ MLArrayUtilsArrayUtils.coordArrayToCoordMatrix = coordArrayToCoordMatrix;
+ MLArrayUtilsArrayUtils.coordMatrixToCoordArray = coordMatrixToCoordArray;
+ MLArrayUtilsArrayUtils.coordMatrixToPoints = transpose;
+ MLArrayUtilsArrayUtils.pointsToCoordArray = pointsToCoordArray;
+ MLArrayUtilsArrayUtils.pointsToCoordMatrix = transpose;
+ MLArrayUtilsArrayUtils.applyDotProduct = applyDotProduct;
+ MLArrayUtilsArrayUtils.scale = scale;
+}
+
+
+// ml-array-utils getEquallySpaced.js
+const MLArrayUtilsGetEquallySpaced = {};
+{
+ /**
+ *
+ * Function that returns a Number array of equally spaced numberOfPoints
+ * containing a representation of intensities of the spectra arguments x
+ * and y.
+ *
+ * The options parameter contains an object in the following form:
+ * from: starting point
+ * to: last point
+ * numberOfPoints: number of points between from and to
+ * variant: "slot" or "smooth" - smooth is the default option
+ *
+ * The slot variant consist that each point in the new array is calculated
+ * averaging the existing points between the slot that belongs to the current
+ * value. The smooth variant is the same but takes the integral of the range
+ * of the slot and divide by the step size between two points in the new array.
+ *
+ * @param x - sorted increasing x values
+ * @param y
+ * @param options
+ * @returns {Array} new array with the equally spaced data.
+ *
+ */
+ function getEquallySpacedData(x, y, options) {
+ if (x.length>1 && x[0]>x[1]) {
+ x=x.slice().reverse();
+ y=y.slice().reverse();
+ }
+
+ var xLength = x.length;
+ if(xLength !== y.length)
+ throw new RangeError("the x and y vector doesn't have the same size.");
+
+ if (options === undefined) options = {};
+
+ var from = options.from === undefined ? x[0] : options.from
+ if (isNaN(from) || !isFinite(from)) {
+ throw new RangeError("'From' value must be a number");
+ }
+ var to = options.to === undefined ? x[x.length - 1] : options.to;
+ if (isNaN(to) || !isFinite(to)) {
+ throw new RangeError("'To' value must be a number");
+ }
+
+ var reverse = from > to;
+ if(reverse) {
+ var temp = from;
+ from = to;
+ to = temp;
+ }
+
+ var numberOfPoints = options.numberOfPoints === undefined ? 100 : options.numberOfPoints;
+ if (isNaN(numberOfPoints) || !isFinite(numberOfPoints)) {
+ throw new RangeError("'Number of points' value must be a number");
+ }
+ if(numberOfPoints < 1)
+ throw new RangeError("the number of point must be higher than 1");
+
+ var algorithm = options.variant === "slot" ? "slot" : "smooth"; // default value: smooth
+
+ var output = algorithm === "slot" ? getEquallySpacedSlot(x, y, from, to, numberOfPoints) : getEquallySpacedSmooth(x, y, from, to, numberOfPoints);
+
+ return reverse ? output.reverse() : output;
+ }
+
+ /**
+ * function that retrieves the getEquallySpacedData with the variant "smooth"
+ *
+ * @param x
+ * @param y
+ * @param from - Initial point
+ * @param to - Final point
+ * @param numberOfPoints
+ * @returns {Array} - Array of y's equally spaced with the variant "smooth"
+ */
+ function getEquallySpacedSmooth(x, y, from, to, numberOfPoints) {
+ var xLength = x.length;
+
+ var step = (to - from) / (numberOfPoints - 1);
+ var halfStep = step / 2;
+
+ var start = from - halfStep;
+ var output = new Array(numberOfPoints);
+
+ var initialOriginalStep = x[1] - x[0];
+ var lastOriginalStep = x[x.length - 1] - x[x.length - 2];
+
+ // Init main variables
+ var min = start;
+ var max = start + step;
+
+ var previousX = Number.MIN_VALUE;
+ var previousY = 0;
+ var nextX = x[0] - initialOriginalStep;
+ var nextY = 0;
+
+ var currentValue = 0;
+ var slope = 0;
+ var intercept = 0;
+ var sumAtMin = 0;
+ var sumAtMax = 0;
+
+ var i = 0; // index of input
+ var j = 0; // index of output
+
+ function getSlope(x0, y0, x1, y1) {
+ return (y1 - y0) / (x1 - x0);
+ }
+
+ main: while(true) {
+ while (nextX - max >= 0) {
+ // no overlap with original point, just consume current value
+ var add = integral(0, max - previousX, slope, previousY);
+ sumAtMax = currentValue + add;
+
+ output[j] = (sumAtMax - sumAtMin) / step;
+ j++;
+
+ if (j === numberOfPoints)
+ break main;
+
+ min = max;
+ max += step;
+ sumAtMin = sumAtMax;
+ }
+
+ if(previousX <= min && min <= nextX) {
+ add = integral(0, min - previousX, slope, previousY);
+ sumAtMin = currentValue + add;
+ }
+
+ currentValue += integral(previousX, nextX, slope, intercept);
+
+ previousX = nextX;
+ previousY = nextY;
+
+ if (i < xLength) {
+ nextX = x[i];
+ nextY = y[i];
+ i++;
+ } else if (i === xLength) {
+ nextX += lastOriginalStep;
+ nextY = 0;
+ }
+ // updating parameters
+ slope = getSlope(previousX, previousY, nextX, nextY);
+ intercept = -slope*previousX + previousY;
+ }
+
+ return output;
+ }
+
+ /**
+ * function that retrieves the getEquallySpacedData with the variant "slot"
+ *
+ * @param x
+ * @param y
+ * @param from - Initial point
+ * @param to - Final point
+ * @param numberOfPoints
+ * @returns {Array} - Array of y's equally spaced with the variant "slot"
+ */
+ function getEquallySpacedSlot(x, y, from, to, numberOfPoints) {
+ var xLength = x.length;
+
+ var step = (to - from) / (numberOfPoints - 1);
+ var halfStep = step / 2;
+ var lastStep = x[x.length - 1] - x[x.length - 2];
+
+ var start = from - halfStep;
+ var output = new Array(numberOfPoints);
+
+ // Init main variables
+ var min = start;
+ var max = start + step;
+
+ var previousX = -Number.MAX_VALUE;
+ var previousY = 0;
+ var nextX = x[0];
+ var nextY = y[0];
+ var frontOutsideSpectra = 0;
+ var backOutsideSpectra = true;
+
+ var currentValue = 0;
+
+ // for slot algorithm
+ var currentPoints = 0;
+
+ var i = 1; // index of input
+ var j = 0; // index of output
+
+ main: while(true) {
+ if (previousX>=nextX) throw (new Error('x must be an increasing serie'));
+ while (previousX - max > 0) {
+ // no overlap with original point, just consume current value
+ if(backOutsideSpectra) {
+ currentPoints++;
+ backOutsideSpectra = false;
+ }
+
+ output[j] = currentPoints <= 0 ? 0 : currentValue / currentPoints;
+ j++;
+
+ if (j === numberOfPoints)
+ break main;
+
+ min = max;
+ max += step;
+ currentValue = 0;
+ currentPoints = 0;
+ }
+
+ if(previousX > min) {
+ currentValue += previousY;
+ currentPoints++;
+ }
+
+ if(previousX === -Number.MAX_VALUE || frontOutsideSpectra > 1)
+ currentPoints--;
+
+ previousX = nextX;
+ previousY = nextY;
+
+ if (i < xLength) {
+ nextX = x[i];
+ nextY = y[i];
+ i++;
+ } else {
+ nextX += lastStep;
+ nextY = 0;
+ frontOutsideSpectra++;
+ }
+ }
+
+ return output;
+ }
+ /**
+ * Function that calculates the integral of the line between two
+ * x-coordinates, given the slope and intercept of the line.
+ *
+ * @param x0
+ * @param x1
+ * @param slope
+ * @param intercept
+ * @returns {number} integral value.
+ */
+ function integral(x0, x1, slope, intercept) {
+ return (0.5 * slope * x1 * x1 + intercept * x1) - (0.5 * slope * x0 * x0 + intercept * x0);
+ }
+
+ MLArrayUtilsGetEquallySpaced.getEquallySpacedData = getEquallySpacedData;
+ MLArrayUtilsGetEquallySpaced.integral = integral;
+}
+
+
+// ml-array-utils snv.js
+const MLArrayUtilsSNV = {};
+{
+ MLArrayUtilsSNV.SNV = SNV;
+ let Stat = MLStat.array;
+
+ /**
+ * Function that applies the standard normal variate (SNV) to an array of values.
+ *
+ * @param data - Array of values.
+ * @returns {Array} - applied the SNV.
+ */
+ function SNV(data) {
+ var mean = Stat.mean(data);
+ var std = Stat.standardDeviation(data);
+ var result = data.slice();
+ for (var i = 0; i < data.length; i++) {
+ result[i] = (result[i] - mean) / std;
+ }
+ return result;
+ }
+}
+
+// ml-array-utils index.js
+const MLArrayUtils = {};
+{
+ MLArrayUtils.getEquallySpacedData = MLArrayUtilsGetEquallySpaced.getEquallySpacedData;
+ MLArrayUtils.SNV = MLArrayUtilsSNV.SNV;
+}
+
+
+
+// do this early so things can use it. This is from ml-matrix src/matrix.js
+const MLMatrixMatrix = {};
+
+// ml-matrix src/util.js
+const MLMatrixUtil = {};
+{
+ let exports = MLMatrixUtil;
+ let Matrix = MLMatrixMatrix;
+
+ /**
+ * @private
+ * Check that a row index is not out of bounds
+ * @param {Matrix} matrix
+ * @param {number} index
+ * @param {boolean} [outer]
+ */
+ exports.checkRowIndex = function checkRowIndex(matrix, index, outer) {
+ var max = outer ? matrix.rows : matrix.rows - 1;
+ if (index < 0 || index > max) {
+ throw new RangeError('Row index out of range');
+ }
+ };
+
+ /**
+ * @private
+ * Check that a column index is not out of bounds
+ * @param {Matrix} matrix
+ * @param {number} index
+ * @param {boolean} [outer]
+ */
+ exports.checkColumnIndex = function checkColumnIndex(matrix, index, outer) {
+ var max = outer ? matrix.columns : matrix.columns - 1;
+ if (index < 0 || index > max) {
+ throw new RangeError('Column index out of range');
+ }
+ };
+
+ /**
+ * @private
+ * Check that the provided vector is an array with the right length
+ * @param {Matrix} matrix
+ * @param {Array|Matrix} vector
+ * @return {Array}
+ * @throws {RangeError}
+ */
+ exports.checkRowVector = function checkRowVector(matrix, vector) {
+ if (vector.to1DArray) {
+ vector = vector.to1DArray();
+ }
+ if (vector.length !== matrix.columns) {
+ throw new RangeError('vector size must be the same as the number of columns');
+ }
+ return vector;
+ };
+
+ /**
+ * @private
+ * Check that the provided vector is an array with the right length
+ * @param {Matrix} matrix
+ * @param {Array|Matrix} vector
+ * @return {Array}
+ * @throws {RangeError}
+ */
+ exports.checkColumnVector = function checkColumnVector(matrix, vector) {
+ if (vector.to1DArray) {
+ vector = vector.to1DArray();
+ }
+ if (vector.length !== matrix.rows) {
+ throw new RangeError('vector size must be the same as the number of rows');
+ }
+ return vector;
+ };
+
+ exports.checkIndices = function checkIndices(matrix, rowIndices, columnIndices) {
+ var rowOut = rowIndices.some(r => {
+ return r < 0 || r >= matrix.rows;
+
+ });
+
+ var columnOut = columnIndices.some(c => {
+ return c < 0 || c >= matrix.columns;
+ });
+
+ if (rowOut || columnOut) {
+ throw new RangeError('Indices are out of range');
+ }
+
+ if (typeof rowIndices !== 'object' || typeof columnIndices !== 'object') {
+ throw new TypeError('Unexpected type for row/column indices');
+ }
+ if (!Array.isArray(rowIndices)) rowIndices = Array.from(rowIndices);
+ if (!Array.isArray(columnIndices)) rowIndices = Array.from(columnIndices);
+
+ return {
+ row: rowIndices,
+ column: columnIndices
+ };
+ };
+
+ exports.checkRange = function checkRange(matrix, startRow, endRow, startColumn, endColumn) {
+ if (arguments.length !== 5) throw new TypeError('Invalid argument type');
+ var notAllNumbers = Array.from(arguments).slice(1).some(function (arg) {
+ return typeof arg !== 'number';
+ });
+ if (notAllNumbers) throw new TypeError('Invalid argument type');
+ if (startRow > endRow || startColumn > endColumn || startRow < 0 || startRow >= matrix.rows || endRow < 0 || endRow >= matrix.rows || startColumn < 0 || startColumn >= matrix.columns || endColumn < 0 || endColumn >= matrix.columns) {
+ throw new RangeError('Submatrix indices are out of range');
+ }
+ };
+
+ exports.getRange = function getRange(from, to) {
+ var arr = new Array(to - from + 1);
+ for (var i = 0; i < arr.length; i++) {
+ arr[i] = from + i;
+ }
+ return arr;
+ };
+
+ exports.sumByRow = function sumByRow(matrix) {
+ var sum = Matrix.Matrix.zeros(matrix.rows, 1);
+ for (var i = 0; i < matrix.rows; ++i) {
+ for (var j = 0; j < matrix.columns; ++j) {
+ sum.set(i, 0, sum.get(i, 0) + matrix.get(i, j));
+ }
+ }
+ return sum;
+ };
+
+ exports.sumByColumn = function sumByColumn(matrix) {
+ var sum = Matrix.Matrix.zeros(1, matrix.columns);
+ for (var i = 0; i < matrix.rows; ++i) {
+ for (var j = 0; j < matrix.columns; ++j) {
+ sum.set(0, j, sum.get(0, j) + matrix.get(i, j));
+ }
+ }
+ return sum;
+ };
+
+ exports.sumAll = function sumAll(matrix) {
+ var v = 0;
+ for (var i = 0; i < matrix.rows; i++) {
+ for (var j = 0; j < matrix.columns; j++) {
+ v += matrix.get(i, j);
+ }
+ }
+ return v;
+ };
+}
+
+// ml-matrix symbolsspecies.js
+if (!Symbol.species) {
+ Symbol.species = Symbol.for('@@species');
+}
+
+
+// ml-matrix src/dc/util.js
+const MLMatrixDCUtil = {};
+{
+ let exports = MLMatrixDCUtil;
+ exports.hypotenuse = function hypotenuse(a, b) {
+ var r;
+ if (Math.abs(a) > Math.abs(b)) {
+ r = b / a;
+ return Math.abs(a) * Math.sqrt(1 + r * r);
+ }
+ if (b !== 0) {
+ r = a / b;
+ return Math.abs(b) * Math.sqrt(1 + r * r);
+ }
+ return 0;
+ };
+
+ // For use in the decomposition algorithms. With big matrices, access time is
+ // too long on elements from array subclass
+ // todo check when it is fixed in v8
+ // http://jsperf.com/access-and-write-array-subclass
+ exports.getEmpty2DArray = function (rows, columns) {
+ var array = new Array(rows);
+ for (var i = 0; i < rows; i++) {
+ array[i] = new Array(columns);
+ }
+ return array;
+ };
+
+ exports.getFilled2DArray = function (rows, columns, value) {
+ var array = new Array(rows);
+ for (var i = 0; i < rows; i++) {
+ array[i] = new Array(columns);
+ for (var j = 0; j < columns; j++) {
+ array[i][j] = value;
+ }
+ }
+ return array;
+ };
+}
+
+// ml-matrix src/dc/lu.js
+let MLMatrixDCLU = {};
+{
+ let Matrix = MLMatrixMatrix;
+
+ // https://github.com/lutzroeder/Mapack/blob/master/Source/LuDecomposition.cs
+ function LuDecomposition(matrix) {
+ if (!(this instanceof LuDecomposition)) {
+ return new LuDecomposition(matrix);
+ }
+
+ matrix = Matrix.Matrix.checkMatrix(matrix);
+
+ var lu = matrix.clone(),
+ rows = lu.rows,
+ columns = lu.columns,
+ pivotVector = new Array(rows),
+ pivotSign = 1,
+ i, j, k, p, s, t, v,
+ LUrowi, LUcolj, kmax;
+
+ for (i = 0; i < rows; i++) {
+ pivotVector[i] = i;
+ }
+
+ LUcolj = new Array(rows);
+
+ for (j = 0; j < columns; j++) {
+
+ for (i = 0; i < rows; i++) {
+ LUcolj[i] = lu[i][j];
+ }
+
+ for (i = 0; i < rows; i++) {
+ LUrowi = lu[i];
+ kmax = Math.min(i, j);
+ s = 0;
+ for (k = 0; k < kmax; k++) {
+ s += LUrowi[k] * LUcolj[k];
+ }
+ LUrowi[j] = LUcolj[i] -= s;
+ }
+
+ p = j;
+ for (i = j + 1; i < rows; i++) {
+ if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) {
+ p = i;
+ }
+ }
+
+ if (p !== j) {
+ for (k = 0; k < columns; k++) {
+ t = lu[p][k];
+ lu[p][k] = lu[j][k];
+ lu[j][k] = t;
+ }
+
+ v = pivotVector[p];
+ pivotVector[p] = pivotVector[j];
+ pivotVector[j] = v;
+
+ pivotSign = -pivotSign;
+ }
+
+ if (j < rows && lu[j][j] !== 0) {
+ for (i = j + 1; i < rows; i++) {
+ lu[i][j] /= lu[j][j];
+ }
+ }
+ }
+
+ this.LU = lu;
+ this.pivotVector = pivotVector;
+ this.pivotSign = pivotSign;
+ }
+
+ LuDecomposition.prototype = {
+ isSingular: function () {
+ var data = this.LU,
+ col = data.columns;
+ for (var j = 0; j < col; j++) {
+ if (data[j][j] === 0) {
+ return true;
+ }
+ }
+ return false;
+ },
+ get determinant() {
+ var data = this.LU;
+ if (!data.isSquare()) {
+ throw new Error('Matrix must be square');
+ }
+ var determinant = this.pivotSign, col = data.columns;
+ for (var j = 0; j < col; j++) {
+ determinant *= data[j][j];
+ }
+ return determinant;
+ },
+ get lowerTriangularMatrix() {
+ var data = this.LU,
+ rows = data.rows,
+ columns = data.columns,
+ X = new Matrix.Matrix(rows, columns);
+ for (var i = 0; i < rows; i++) {
+ for (var j = 0; j < columns; j++) {
+ if (i > j) {
+ X[i][j] = data[i][j];
+ } else if (i === j) {
+ X[i][j] = 1;
+ } else {
+ X[i][j] = 0;
+ }
+ }
+ }
+ return X;
+ },
+ get upperTriangularMatrix() {
+ var data = this.LU,
+ rows = data.rows,
+ columns = data.columns,
+ X = new Matrix.Matrix(rows, columns);
+ for (var i = 0; i < rows; i++) {
+ for (var j = 0; j < columns; j++) {
+ if (i <= j) {
+ X[i][j] = data[i][j];
+ } else {
+ X[i][j] = 0;
+ }
+ }
+ }
+ return X;
+ },
+ get pivotPermutationVector() {
+ return this.pivotVector.slice();
+ },
+ solve: function (value) {
+ value = Matrix.Matrix.checkMatrix(value);
+
+ var lu = this.LU,
+ rows = lu.rows;
+
+ if (rows !== value.rows) {
+ throw new Error('Invalid matrix dimensions');
+ }
+ if (this.isSingular()) {
+ throw new Error('LU matrix is singular');
+ }
+
+ var count = value.columns;
+ var X = value.subMatrixRow(this.pivotVector, 0, count - 1);
+ var columns = lu.columns;
+ var i, j, k;
+
+ for (k = 0; k < columns; k++) {
+ for (i = k + 1; i < columns; i++) {
+ for (j = 0; j < count; j++) {
+ X[i][j] -= X[k][j] * lu[i][k];
+ }
+ }
+ }
+ for (k = columns - 1; k >= 0; k--) {
+ for (j = 0; j < count; j++) {
+ X[k][j] /= lu[k][k];
+ }
+ for (i = 0; i < k; i++) {
+ for (j = 0; j < count; j++) {
+ X[i][j] -= X[k][j] * lu[i][k];
+ }
+ }
+ }
+ return X;
+ }
+ };
+
+ MLMatrixDCLU = LuDecomposition;
+}
+
+
+// ml-matrix src/dc/svd.js
+let MLMatrixDCSVD = {};
+{
+ let Matrix = MLMatrixMatrix;
+ let util = MLMatrixDCUtil;
+ let hypotenuse = util.hypotenuse;
+ let getFilled2DArray = util.getFilled2DArray;
+
+ // https://github.com/lutzroeder/Mapack/blob/master/Source/SingularValueDecomposition.cs
+ function SingularValueDecomposition(value, options) {
+ if (!(this instanceof SingularValueDecomposition)) {
+ return new SingularValueDecomposition(value, options);
+ }
+ value = Matrix.Matrix.checkMatrix(value);
+
+ options = options || {};
+
+ var m = value.rows,
+ n = value.columns,
+ nu = Math.min(m, n);
+
+ var wantu = true, wantv = true;
+ if (options.computeLeftSingularVectors === false) wantu = false;
+ if (options.computeRightSingularVectors === false) wantv = false;
+ var autoTranspose = options.autoTranspose === true;
+
+ var swapped = false;
+ var a;
+ if (m < n) {
+ if (!autoTranspose) {
+ a = value.clone();
+ // eslint-disable-next-line no-console
+ console.warn('Computing SVD on a matrix with more columns than rows. Consider enabling autoTranspose');
+ } else {
+ a = value.transpose();
+ m = a.rows;
+ n = a.columns;
+ swapped = true;
+ var aux = wantu;
+ wantu = wantv;
+ wantv = aux;
+ }
+ } else {
+ a = value.clone();
+ }
+
+ var s = new Array(Math.min(m + 1, n)),
+ U = getFilled2DArray(m, nu, 0),
+ V = getFilled2DArray(n, n, 0),
+ e = new Array(n),
+ work = new Array(m);
+
+ var nct = Math.min(m - 1, n);
+ var nrt = Math.max(0, Math.min(n - 2, m));
+
+ var i, j, k, p, t, ks, f, cs, sn, max, kase,
+ scale, sp, spm1, epm1, sk, ek, b, c, shift, g;
+
+ for (k = 0, max = Math.max(nct, nrt); k < max; k++) {
+ if (k < nct) {
+ s[k] = 0;
+ for (i = k; i < m; i++) {
+ s[k] = hypotenuse(s[k], a[i][k]);
+ }
+ if (s[k] !== 0) {
+ if (a[k][k] < 0) {
+ s[k] = -s[k];
+ }
+ for (i = k; i < m; i++) {
+ a[i][k] /= s[k];
+ }
+ a[k][k] += 1;
+ }
+ s[k] = -s[k];
+ }
+
+ for (j = k + 1; j < n; j++) {
+ if ((k < nct) && (s[k] !== 0)) {
+ t = 0;
+ for (i = k; i < m; i++) {
+ t += a[i][k] * a[i][j];
+ }
+ t = -t / a[k][k];
+ for (i = k; i < m; i++) {
+ a[i][j] += t * a[i][k];
+ }
+ }
+ e[j] = a[k][j];
+ }
+
+ if (wantu && (k < nct)) {
+ for (i = k; i < m; i++) {
+ U[i][k] = a[i][k];
+ }
+ }
+
+ if (k < nrt) {
+ e[k] = 0;
+ for (i = k + 1; i < n; i++) {
+ e[k] = hypotenuse(e[k], e[i]);
+ }
+ if (e[k] !== 0) {
+ if (e[k + 1] < 0) {
+ e[k] = 0 - e[k];
+ }
+ for (i = k + 1; i < n; i++) {
+ e[i] /= e[k];
+ }
+ e[k + 1] += 1;
+ }
+ e[k] = -e[k];
+ if ((k + 1 < m) && (e[k] !== 0)) {
+ for (i = k + 1; i < m; i++) {
+ work[i] = 0;
+ }
+ for (j = k + 1; j < n; j++) {
+ for (i = k + 1; i < m; i++) {
+ work[i] += e[j] * a[i][j];
+ }
+ }
+ for (j = k + 1; j < n; j++) {
+ t = -e[j] / e[k + 1];
+ for (i = k + 1; i < m; i++) {
+ a[i][j] += t * work[i];
+ }
+ }
+ }
+ if (wantv) {
+ for (i = k + 1; i < n; i++) {
+ V[i][k] = e[i];
+ }
+ }
+ }
+ }
+
+ p = Math.min(n, m + 1);
+ if (nct < n) {
+ s[nct] = a[nct][nct];
+ }
+ if (m < p) {
+ s[p - 1] = 0;
+ }
+ if (nrt + 1 < p) {
+ e[nrt] = a[nrt][p - 1];
+ }
+ e[p - 1] = 0;
+
+ if (wantu) {
+ for (j = nct; j < nu; j++) {
+ for (i = 0; i < m; i++) {
+ U[i][j] = 0;
+ }
+ U[j][j] = 1;
+ }
+ for (k = nct - 1; k >= 0; k--) {
+ if (s[k] !== 0) {
+ for (j = k + 1; j < nu; j++) {
+ t = 0;
+ for (i = k; i < m; i++) {
+ t += U[i][k] * U[i][j];
+ }
+ t = -t / U[k][k];
+ for (i = k; i < m; i++) {
+ U[i][j] += t * U[i][k];
+ }
+ }
+ for (i = k; i < m; i++) {
+ U[i][k] = -U[i][k];
+ }
+ U[k][k] = 1 + U[k][k];
+ for (i = 0; i < k - 1; i++) {
+ U[i][k] = 0;
+ }
+ } else {
+ for (i = 0; i < m; i++) {
+ U[i][k] = 0;
+ }
+ U[k][k] = 1;
+ }
+ }
+ }
+
+ if (wantv) {
+ for (k = n - 1; k >= 0; k--) {
+ if ((k < nrt) && (e[k] !== 0)) {
+ for (j = k + 1; j < n; j++) {
+ t = 0;
+ for (i = k + 1; i < n; i++) {
+ t += V[i][k] * V[i][j];
+ }
+ t = -t / V[k + 1][k];
+ for (i = k + 1; i < n; i++) {
+ V[i][j] += t * V[i][k];
+ }
+ }
+ }
+ for (i = 0; i < n; i++) {
+ V[i][k] = 0;
+ }
+ V[k][k] = 1;
+ }
+ }
+
+ var pp = p - 1,
+ iter = 0,
+ eps = Math.pow(2, -52);
+ while (p > 0) {
+ for (k = p - 2; k >= -1; k--) {
+ if (k === -1) {
+ break;
+ }
+ if (Math.abs(e[k]) <= eps * (Math.abs(s[k]) + Math.abs(s[k + 1]))) {
+ e[k] = 0;
+ break;
+ }
+ }
+ if (k === p - 2) {
+ kase = 4;
+ } else {
+ for (ks = p - 1; ks >= k; ks--) {
+ if (ks === k) {
+ break;
+ }
+ t = (ks !== p ? Math.abs(e[ks]) : 0) + (ks !== k + 1 ? Math.abs(e[ks - 1]) : 0);
+ if (Math.abs(s[ks]) <= eps * t) {
+ s[ks] = 0;
+ break;
+ }
+ }
+ if (ks === k) {
+ kase = 3;
+ } else if (ks === p - 1) {
+ kase = 1;
+ } else {
+ kase = 2;
+ k = ks;
+ }
+ }
+
+ k++;
+
+ switch (kase) {
+ case 1: {
+ f = e[p - 2];
+ e[p - 2] = 0;
+ for (j = p - 2; j >= k; j--) {
+ t = hypotenuse(s[j], f);
+ cs = s[j] / t;
+ sn = f / t;
+ s[j] = t;
+ if (j !== k) {
+ f = -sn * e[j - 1];
+ e[j - 1] = cs * e[j - 1];
+ }
+ if (wantv) {
+ for (i = 0; i < n; i++) {
+ t = cs * V[i][j] + sn * V[i][p - 1];
+ V[i][p - 1] = -sn * V[i][j] + cs * V[i][p - 1];
+ V[i][j] = t;
+ }
+ }
+ }
+ break;
+ }
+ case 2 : {
+ f = e[k - 1];
+ e[k - 1] = 0;
+ for (j = k; j < p; j++) {
+ t = hypotenuse(s[j], f);
+ cs = s[j] / t;
+ sn = f / t;
+ s[j] = t;
+ f = -sn * e[j];
+ e[j] = cs * e[j];
+ if (wantu) {
+ for (i = 0; i < m; i++) {
+ t = cs * U[i][j] + sn * U[i][k - 1];
+ U[i][k - 1] = -sn * U[i][j] + cs * U[i][k - 1];
+ U[i][j] = t;
+ }
+ }
+ }
+ break;
+ }
+ case 3 : {
+ scale = Math.max(Math.max(Math.max(Math.max(Math.abs(s[p - 1]), Math.abs(s[p - 2])), Math.abs(e[p - 2])), Math.abs(s[k])), Math.abs(e[k]));
+ sp = s[p - 1] / scale;
+ spm1 = s[p - 2] / scale;
+ epm1 = e[p - 2] / scale;
+ sk = s[k] / scale;
+ ek = e[k] / scale;
+ b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2;
+ c = (sp * epm1) * (sp * epm1);
+ shift = 0;
+ if ((b !== 0) || (c !== 0)) {
+ shift = Math.sqrt(b * b + c);
+ if (b < 0) {
+ shift = -shift;
+ }
+ shift = c / (b + shift);
+ }
+ f = (sk + sp) * (sk - sp) + shift;
+ g = sk * ek;
+ for (j = k; j < p - 1; j++) {
+ t = hypotenuse(f, g);
+ cs = f / t;
+ sn = g / t;
+ if (j !== k) {
+ e[j - 1] = t;
+ }
+ f = cs * s[j] + sn * e[j];
+ e[j] = cs * e[j] - sn * s[j];
+ g = sn * s[j + 1];
+ s[j + 1] = cs * s[j + 1];
+ if (wantv) {
+ for (i = 0; i < n; i++) {
+ t = cs * V[i][j] + sn * V[i][j + 1];
+ V[i][j + 1] = -sn * V[i][j] + cs * V[i][j + 1];
+ V[i][j] = t;
+ }
+ }
+ t = hypotenuse(f, g);
+ cs = f / t;
+ sn = g / t;
+ s[j] = t;
+ f = cs * e[j] + sn * s[j + 1];
+ s[j + 1] = -sn * e[j] + cs * s[j + 1];
+ g = sn * e[j + 1];
+ e[j + 1] = cs * e[j + 1];
+ if (wantu && (j < m - 1)) {
+ for (i = 0; i < m; i++) {
+ t = cs * U[i][j] + sn * U[i][j + 1];
+ U[i][j + 1] = -sn * U[i][j] + cs * U[i][j + 1];
+ U[i][j] = t;
+ }
+ }
+ }
+ e[p - 2] = f;
+ iter = iter + 1;
+ break;
+ }
+ case 4: {
+ if (s[k] <= 0) {
+ s[k] = (s[k] < 0 ? -s[k] : 0);
+ if (wantv) {
+ for (i = 0; i <= pp; i++) {
+ V[i][k] = -V[i][k];
+ }
+ }
+ }
+ while (k < pp) {
+ if (s[k] >= s[k + 1]) {
+ break;
+ }
+ t = s[k];
+ s[k] = s[k + 1];
+ s[k + 1] = t;
+ if (wantv && (k < n - 1)) {
+ for (i = 0; i < n; i++) {
+ t = V[i][k + 1];
+ V[i][k + 1] = V[i][k];
+ V[i][k] = t;
+ }
+ }
+ if (wantu && (k < m - 1)) {
+ for (i = 0; i < m; i++) {
+ t = U[i][k + 1];
+ U[i][k + 1] = U[i][k];
+ U[i][k] = t;
+ }
+ }
+ k++;
+ }
+ iter = 0;
+ p--;
+ break;
+ }
+ // no default
+ }
+ }
+
+ if (swapped) {
+ var tmp = V;
+ V = U;
+ U = tmp;
+ }
+
+ this.m = m;
+ this.n = n;
+ this.s = s;
+ this.U = U;
+ this.V = V;
+ }
+
+ SingularValueDecomposition.prototype = {
+ get condition() {
+ return this.s[0] / this.s[Math.min(this.m, this.n) - 1];
+ },
+ get norm2() {
+ return this.s[0];
+ },
+ get rank() {
+ var eps = Math.pow(2, -52),
+ tol = Math.max(this.m, this.n) * this.s[0] * eps,
+ r = 0,
+ s = this.s;
+ for (var i = 0, ii = s.length; i < ii; i++) {
+ if (s[i] > tol) {
+ r++;
+ }
+ }
+ return r;
+ },
+ get diagonal() {
+ return this.s;
+ },
+ // https://github.com/accord-net/framework/blob/development/Sources/Accord.Math/Decompositions/SingularValueDecomposition.cs
+ get threshold() {
+ return (Math.pow(2, -52) / 2) * Math.max(this.m, this.n) * this.s[0];
+ },
+ get leftSingularVectors() {
+ if (!Matrix.Matrix.isMatrix(this.U)) {
+ this.U = new Matrix.Matrix(this.U);
+ }
+ return this.U;
+ },
+ get rightSingularVectors() {
+ if (!Matrix.Matrix.isMatrix(this.V)) {
+ this.V = new Matrix.Matrix(this.V);
+ }
+ return this.V;
+ },
+ get diagonalMatrix() {
+ return Matrix.Matrix.diag(this.s);
+ },
+ solve: function (value) {
+
+ var Y = value,
+ e = this.threshold,
+ scols = this.s.length,
+ Ls = Matrix.Matrix.zeros(scols, scols),
+ i;
+
+ for (i = 0; i < scols; i++) {
+ if (Math.abs(this.s[i]) <= e) {
+ Ls[i][i] = 0;
+ } else {
+ Ls[i][i] = 1 / this.s[i];
+ }
+ }
+
+ var U = this.U;
+ var V = this.rightSingularVectors;
+
+ var VL = V.mmul(Ls),
+ vrows = V.rows,
+ urows = U.length,
+ VLU = Matrix.Matrix.zeros(vrows, urows),
+ j, k, sum;
+
+ for (i = 0; i < vrows; i++) {
+ for (j = 0; j < urows; j++) {
+ sum = 0;
+ for (k = 0; k < scols; k++) {
+ sum += VL[i][k] * U[j][k];
+ }
+ VLU[i][j] = sum;
+ }
+ }
+
+ return VLU.mmul(Y);
+ },
+ solveForDiagonal: function (value) {
+ return this.solve(Matrix.Matrix.diag(value));
+ },
+ inverse: function () {
+ var V = this.V;
+ var e = this.threshold,
+ vrows = V.length,
+ vcols = V[0].length,
+ X = new Matrix.Matrix(vrows, this.s.length),
+ i, j;
+
+ for (i = 0; i < vrows; i++) {
+ for (j = 0; j < vcols; j++) {
+ if (Math.abs(this.s[j]) > e) {
+ X[i][j] = V[i][j] / this.s[j];
+ } else {
+ X[i][j] = 0;
+ }
+ }
+ }
+
+ var U = this.U;
+
+ var urows = U.length,
+ ucols = U[0].length,
+ Y = new Matrix.Matrix(vrows, urows),
+ k, sum;
+
+ for (i = 0; i < vrows; i++) {
+ for (j = 0; j < urows; j++) {
+ sum = 0;
+ for (k = 0; k < ucols; k++) {
+ sum += X[i][k] * U[j][k];
+ }
+ Y[i][j] = sum;
+ }
+ }
+
+ return Y;
+ }
+ };
+
+ MLMatrixDCSVD = SingularValueDecomposition;
+}
+
+// ml-matrix src/abstractMatrix.js
+let MLMatrixAbstractMatrix;
+{
+ let LuDecomposition = MLMatrixDCLU;
+ let SvDecomposition = MLMatrixDCSVD;
+ let arrayUtils = MLArrayUtils;
+ let util = MLMatrixUtil;
+
+ MLMatrixAbstractMatrix = function abstractMatrix(superCtor) {
+ if (superCtor === undefined) superCtor = Object;
+
+ /**
+ * Real matrix
+ * @class Matrix
+ * @param {number|Array|Matrix} nRows - Number of rows of the new matrix,
+ * 2D array containing the data or Matrix instance to clone
+ * @param {number} [nColumns] - Number of columns of the new matrix
+ */
+ class Matrix extends superCtor {
+ static get [Symbol.species]() {
+ return this;
+ }
+
+ /**
+ * Constructs a Matrix with the chosen dimensions from a 1D array
+ * @param {number} newRows - Number of rows
+ * @param {number} newColumns - Number of columns
+ * @param {Array} newData - A 1D array containing data for the matrix
+ * @return {Matrix} - The new matrix
+ */
+ static from1DArray(newRows, newColumns, newData) {
+ var length = newRows * newColumns;
+ if (length !== newData.length) {
+ throw new RangeError('Data length does not match given dimensions');
+ }
+ var newMatrix = new this(newRows, newColumns);
+ for (var row = 0; row < newRows; row++) {
+ for (var column = 0; column < newColumns; column++) {
+ newMatrix.set(row, column, newData[row * newColumns + column]);
+ }
+ }
+ return newMatrix;
+ }
+
+ /**
+ * Creates a row vector, a matrix with only one row.
+ * @param {Array} newData - A 1D array containing data for the vector
+ * @return {Matrix} - The new matrix
+ */
+ static rowVector(newData) {
+ var vector = new this(1, newData.length);
+ for (var i = 0; i < newData.length; i++) {
+ vector.set(0, i, newData[i]);
+ }
+ return vector;
+ }
+
+ /**
+ * Creates a column vector, a matrix with only one column.
+ * @param {Array} newData - A 1D array containing data for the vector
+ * @return {Matrix} - The new matrix
+ */
+ static columnVector(newData) {
+ var vector = new this(newData.length, 1);
+ for (var i = 0; i < newData.length; i++) {
+ vector.set(i, 0, newData[i]);
+ }
+ return vector;
+ }
+
+ /**
+ * Creates an empty matrix with the given dimensions. Values will be undefined. Same as using new Matrix(rows, columns).
+ * @param {number} rows - Number of rows
+ * @param {number} columns - Number of columns
+ * @return {Matrix} - The new matrix
+ */
+ static empty(rows, columns) {
+ return new this(rows, columns);
+ }
+
+ /**
+ * Creates a matrix with the given dimensions. Values will be set to zero.
+ * @param {number} rows - Number of rows
+ * @param {number} columns - Number of columns
+ * @return {Matrix} - The new matrix
+ */
+ static zeros(rows, columns) {
+ return this.empty(rows, columns).fill(0);
+ }
+
+ /**
+ * Creates a matrix with the given dimensions. Values will be set to one.
+ * @param {number} rows - Number of rows
+ * @param {number} columns - Number of columns
+ * @return {Matrix} - The new matrix
+ */
+ static ones(rows, columns) {
+ return this.empty(rows, columns).fill(1);
+ }
+
+ /**
+ * Creates a matrix with the given dimensions. Values will be randomly set.
+ * @param {number} rows - Number of rows
+ * @param {number} columns - Number of columns
+ * @param {function} [rng=Math.random] - Random number generator
+ * @return {Matrix} The new matrix
+ */
+ static rand(rows, columns, rng) {
+ if (rng === undefined) rng = Math.random;
+ var matrix = this.empty(rows, columns);
+ for (var i = 0; i < rows; i++) {
+ for (var j = 0; j < columns; j++) {
+ matrix.set(i, j, rng());
+ }
+ }
+ return matrix;
+ }
+
+ /**
+ * Creates a matrix with the given dimensions. Values will be random integers.
+ * @param {number} rows - Number of rows
+ * @param {number} columns - Number of columns
+ * @param {number} [maxValue=1000] - Maximum value
+ * @param {function} [rng=Math.random] - Random number generator
+ * @return {Matrix} The new matrix
+ */
+ static randInt(rows, columns, maxValue, rng) {
+ if (maxValue === undefined) maxValue = 1000;
+ if (rng === undefined) rng = Math.random;
+ var matrix = this.empty(rows, columns);
+ for (var i = 0; i < rows; i++) {
+ for (var j = 0; j < columns; j++) {
+ var value = Math.floor(rng() * maxValue);
+ matrix.set(i, j, value);
+ }
+ }
+ return matrix;
+ }
+
+ /**
+ * Creates an identity matrix with the given dimension. Values of the diagonal will be 1 and others will be 0.
+ * @param {number} rows - Number of rows
+ * @param {number} [columns=rows] - Number of columns
+ * @param {number} [value=1] - Value to fill the diagonal with
+ * @return {Matrix} - The new identity matrix
+ */
+ static eye(rows, columns, value) {
+ if (columns === undefined) columns = rows;
+ if (value === undefined) value = 1;
+ var min = Math.min(rows, columns);
+ var matrix = this.zeros(rows, columns);
+ for (var i = 0; i < min; i++) {
+ matrix.set(i, i, value);
+ }
+ return matrix;
+ }
+
+ /**
+ * Creates a diagonal matrix based on the given array.
+ * @param {Array} data - Array containing the data for the diagonal
+ * @param {number} [rows] - Number of rows (Default: data.length)
+ * @param {number} [columns] - Number of columns (Default: rows)
+ * @return {Matrix} - The new diagonal matrix
+ */
+ static diag(data, rows, columns) {
+ var l = data.length;
+ if (rows === undefined) rows = l;
+ if (columns === undefined) columns = rows;
+ var min = Math.min(l, rows, columns);
+ var matrix = this.zeros(rows, columns);
+ for (var i = 0; i < min; i++) {
+ matrix.set(i, i, data[i]);
+ }
+ return matrix;
+ }
+
+ /**
+ * Returns a matrix whose elements are the minimum between matrix1 and matrix2
+ * @param {Matrix} matrix1
+ * @param {Matrix} matrix2
+ * @return {Matrix}
+ */
+ static min(matrix1, matrix2) {
+ matrix1 = this.checkMatrix(matrix1);
+ matrix2 = this.checkMatrix(matrix2);
+ var rows = matrix1.rows;
+ var columns = matrix1.columns;
+ var result = new this(rows, columns);
+ for (var i = 0; i < rows; i++) {
+ for (var j = 0; j < columns; j++) {
+ result.set(i, j, Math.min(matrix1.get(i, j), matrix2.get(i, j)));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns a matrix whose elements are the maximum between matrix1 and matrix2
+ * @param {Matrix} matrix1
+ * @param {Matrix} matrix2
+ * @return {Matrix}
+ */
+ static max(matrix1, matrix2) {
+ matrix1 = this.checkMatrix(matrix1);
+ matrix2 = this.checkMatrix(matrix2);
+ var rows = matrix1.rows;
+ var columns = matrix1.columns;
+ var result = new this(rows, columns);
+ for (var i = 0; i < rows; i++) {
+ for (var j = 0; j < columns; j++) {
+ result.set(i, j, Math.max(matrix1.get(i, j), matrix2.get(i, j)));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Check that the provided value is a Matrix and tries to instantiate one if not
+ * @param {*} value - The value to check
+ * @return {Matrix}
+ */
+ static checkMatrix(value) {
+ return Matrix.isMatrix(value) ? value : new this(value);
+ }
+
+ /**
+ * Returns true if the argument is a Matrix, false otherwise
+ * @param {*} value - The value to check
+ * @return {boolean}
+ */
+ static isMatrix(value) {
+ return (value != null) && (value.klass === 'Matrix');
+ }
+
+ /**
+ * @prop {number} size - The number of elements in the matrix.
+ */
+ get size() {
+ return this.rows * this.columns;
+ }
+
+ /**
+ * Applies a callback for each element of the matrix. The function is called in the matrix (this) context.
+ * @param {function} callback - Function that will be called with two parameters : i (row) and j (column)
+ * @return {Matrix} this
+ */
+ apply(callback) {
+ if (typeof callback !== 'function') {
+ throw new TypeError('callback must be a function');
+ }
+ var ii = this.rows;
+ var jj = this.columns;
+ for (var i = 0; i < ii; i++) {
+ for (var j = 0; j < jj; j++) {
+ callback.call(this, i, j);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Returns a new 1D array filled row by row with the matrix values
+ * @return {Array}
+ */
+ to1DArray() {
+ var array = new Array(this.size);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ array[i * this.columns + j] = this.get(i, j);
+ }
+ }
+ return array;
+ }
+
+ /**
+ * Returns a 2D array containing a copy of the data
+ * @return {Array}
+ */
+ to2DArray() {
+ var copy = new Array(this.rows);
+ for (var i = 0; i < this.rows; i++) {
+ copy[i] = new Array(this.columns);
+ for (var j = 0; j < this.columns; j++) {
+ copy[i][j] = this.get(i, j);
+ }
+ }
+ return copy;
+ }
+
+ /**
+ * @return {boolean} true if the matrix has one row
+ */
+ isRowVector() {
+ return this.rows === 1;
+ }
+
+ /**
+ * @return {boolean} true if the matrix has one column
+ */
+ isColumnVector() {
+ return this.columns === 1;
+ }
+
+ /**
+ * @return {boolean} true if the matrix has one row or one column
+ */
+ isVector() {
+ return (this.rows === 1) || (this.columns === 1);
+ }
+
+ /**
+ * @return {boolean} true if the matrix has the same number of rows and columns
+ */
+ isSquare() {
+ return this.rows === this.columns;
+ }
+
+ /**
+ * @return {boolean} true if the matrix is square and has the same values on both sides of the diagonal
+ */
+ isSymmetric() {
+ if (this.isSquare()) {
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j <= i; j++) {
+ if (this.get(i, j) !== this.get(j, i)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Sets a given element of the matrix. mat.set(3,4,1) is equivalent to mat[3][4]=1
+ * @abstract
+ * @param {number} rowIndex - Index of the row
+ * @param {number} columnIndex - Index of the column
+ * @param {number} value - The new value for the element
+ * @return {Matrix} this
+ */
+ set(rowIndex, columnIndex, value) { // eslint-disable-line no-unused-vars
+ throw new Error('set method is unimplemented');
+ }
+
+ /**
+ * Returns the given element of the matrix. mat.get(3,4) is equivalent to matrix[3][4]
+ * @abstract
+ * @param {number} rowIndex - Index of the row
+ * @param {number} columnIndex - Index of the column
+ * @return {number}
+ */
+ get(rowIndex, columnIndex) { // eslint-disable-line no-unused-vars
+ throw new Error('get method is unimplemented');
+ }
+
+ /**
+ * Creates a new matrix that is a repetition of the current matrix. New matrix has rowRep times the number of
+ * rows of the matrix, and colRep times the number of columns of the matrix
+ * @param {number} rowRep - Number of times the rows should be repeated
+ * @param {number} colRep - Number of times the columns should be re
+ * @return {Matrix}
+ * @example
+ * var matrix = new Matrix([[1,2]]);
+ * matrix.repeat(2); // [[1,2],[1,2]]
+ */
+ repeat(rowRep, colRep) {
+ rowRep = rowRep || 1;
+ colRep = colRep || 1;
+ var matrix = new this.constructor[Symbol.species](this.rows * rowRep, this.columns * colRep);
+ for (var i = 0; i < rowRep; i++) {
+ for (var j = 0; j < colRep; j++) {
+ matrix.setSubMatrix(this, this.rows * i, this.columns * j);
+ }
+ }
+ return matrix;
+ }
+
+ /**
+ * Fills the matrix with a given value. All elements will be set to this value.
+ * @param {number} value - New value
+ * @return {Matrix} this
+ */
+ fill(value) {
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, value);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Negates the matrix. All elements will be multiplied by (-1)
+ * @return {Matrix} this
+ */
+ neg() {
+ return this.mulS(-1);
+ }
+
+ /**
+ * Returns a new array from the given row index
+ * @param {number} index - Row index
+ * @return {Array}
+ */
+ getRow(index) {
+ util.checkRowIndex(this, index);
+ var row = new Array(this.columns);
+ for (var i = 0; i < this.columns; i++) {
+ row[i] = this.get(index, i);
+ }
+ return row;
+ }
+
+ /**
+ * Returns a new row vector from the given row index
+ * @param {number} index - Row index
+ * @return {Matrix}
+ */
+ getRowVector(index) {
+ return this.constructor.rowVector(this.getRow(index));
+ }
+
+ /**
+ * Sets a row at the given index
+ * @param {number} index - Row index
+ * @param {Array|Matrix} array - Array or vector
+ * @return {Matrix} this
+ */
+ setRow(index, array) {
+ util.checkRowIndex(this, index);
+ array = util.checkRowVector(this, array);
+ for (var i = 0; i < this.columns; i++) {
+ this.set(index, i, array[i]);
+ }
+ return this;
+ }
+
+ /**
+ * Swaps two rows
+ * @param {number} row1 - First row index
+ * @param {number} row2 - Second row index
+ * @return {Matrix} this
+ */
+ swapRows(row1, row2) {
+ util.checkRowIndex(this, row1);
+ util.checkRowIndex(this, row2);
+ for (var i = 0; i < this.columns; i++) {
+ var temp = this.get(row1, i);
+ this.set(row1, i, this.get(row2, i));
+ this.set(row2, i, temp);
+ }
+ return this;
+ }
+
+ /**
+ * Returns a new array from the given column index
+ * @param {number} index - Column index
+ * @return {Array}
+ */
+ getColumn(index) {
+ util.checkColumnIndex(this, index);
+ var column = new Array(this.rows);
+ for (var i = 0; i < this.rows; i++) {
+ column[i] = this.get(i, index);
+ }
+ return column;
+ }
+
+ /**
+ * Returns a new column vector from the given column index
+ * @param {number} index - Column index
+ * @return {Matrix}
+ */
+ getColumnVector(index) {
+ return this.constructor.columnVector(this.getColumn(index));
+ }
+
+ /**
+ * Sets a column at the given index
+ * @param {number} index - Column index
+ * @param {Array|Matrix} array - Array or vector
+ * @return {Matrix} this
+ */
+ setColumn(index, array) {
+ util.checkColumnIndex(this, index);
+ array = util.checkColumnVector(this, array);
+ for (var i = 0; i < this.rows; i++) {
+ this.set(i, index, array[i]);
+ }
+ return this;
+ }
+
+ /**
+ * Swaps two columns
+ * @param {number} column1 - First column index
+ * @param {number} column2 - Second column index
+ * @return {Matrix} this
+ */
+ swapColumns(column1, column2) {
+ util.checkColumnIndex(this, column1);
+ util.checkColumnIndex(this, column2);
+ for (var i = 0; i < this.rows; i++) {
+ var temp = this.get(i, column1);
+ this.set(i, column1, this.get(i, column2));
+ this.set(i, column2, temp);
+ }
+ return this;
+ }
+
+ /**
+ * Adds the values of a vector to each row
+ * @param {Array|Matrix} vector - Array or vector
+ * @return {Matrix} this
+ */
+ addRowVector(vector) {
+ vector = util.checkRowVector(this, vector);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, this.get(i, j) + vector[j]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Subtracts the values of a vector from each row
+ * @param {Array|Matrix} vector - Array or vector
+ * @return {Matrix} this
+ */
+ subRowVector(vector) {
+ vector = util.checkRowVector(this, vector);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, this.get(i, j) - vector[j]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Multiplies the values of a vector with each row
+ * @param {Array|Matrix} vector - Array or vector
+ * @return {Matrix} this
+ */
+ mulRowVector(vector) {
+ vector = util.checkRowVector(this, vector);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, this.get(i, j) * vector[j]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Divides the values of each row by those of a vector
+ * @param {Array|Matrix} vector - Array or vector
+ * @return {Matrix} this
+ */
+ divRowVector(vector) {
+ vector = util.checkRowVector(this, vector);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, this.get(i, j) / vector[j]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Adds the values of a vector to each column
+ * @param {Array|Matrix} vector - Array or vector
+ * @return {Matrix} this
+ */
+ addColumnVector(vector) {
+ vector = util.checkColumnVector(this, vector);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, this.get(i, j) + vector[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Subtracts the values of a vector from each column
+ * @param {Array|Matrix} vector - Array or vector
+ * @return {Matrix} this
+ */
+ subColumnVector(vector) {
+ vector = util.checkColumnVector(this, vector);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, this.get(i, j) - vector[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Multiplies the values of a vector with each column
+ * @param {Array|Matrix} vector - Array or vector
+ * @return {Matrix} this
+ */
+ mulColumnVector(vector) {
+ vector = util.checkColumnVector(this, vector);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, this.get(i, j) * vector[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Divides the values of each column by those of a vector
+ * @param {Array|Matrix} vector - Array or vector
+ * @return {Matrix} this
+ */
+ divColumnVector(vector) {
+ vector = util.checkColumnVector(this, vector);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, this.get(i, j) / vector[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Multiplies the values of a row with a scalar
+ * @param {number} index - Row index
+ * @param {number} value
+ * @return {Matrix} this
+ */
+ mulRow(index, value) {
+ util.checkRowIndex(this, index);
+ for (var i = 0; i < this.columns; i++) {
+ this.set(index, i, this.get(index, i) * value);
+ }
+ return this;
+ }
+
+ /**
+ * Multiplies the values of a column with a scalar
+ * @param {number} index - Column index
+ * @param {number} value
+ * @return {Matrix} this
+ */
+ mulColumn(index, value) {
+ util.checkColumnIndex(this, index);
+ for (var i = 0; i < this.rows; i++) {
+ this.set(i, index, this.get(i, index) * value);
+ }
+ return this;
+ }
+
+ /**
+ * Returns the maximum value of the matrix
+ * @return {number}
+ */
+ max() {
+ var v = this.get(0, 0);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ if (this.get(i, j) > v) {
+ v = this.get(i, j);
+ }
+ }
+ }
+ return v;
+ }
+
+ /**
+ * Returns the index of the maximum value
+ * @return {Array}
+ */
+ maxIndex() {
+ var v = this.get(0, 0);
+ var idx = [0, 0];
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ if (this.get(i, j) > v) {
+ v = this.get(i, j);
+ idx[0] = i;
+ idx[1] = j;
+ }
+ }
+ }
+ return idx;
+ }
+
+ /**
+ * Returns the minimum value of the matrix
+ * @return {number}
+ */
+ min() {
+ var v = this.get(0, 0);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ if (this.get(i, j) < v) {
+ v = this.get(i, j);
+ }
+ }
+ }
+ return v;
+ }
+
+ /**
+ * Returns the index of the minimum value
+ * @return {Array}
+ */
+ minIndex() {
+ var v = this.get(0, 0);
+ var idx = [0, 0];
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ if (this.get(i, j) < v) {
+ v = this.get(i, j);
+ idx[0] = i;
+ idx[1] = j;
+ }
+ }
+ }
+ return idx;
+ }
+
+ /**
+ * Returns the maximum value of one row
+ * @param {number} row - Row index
+ * @return {number}
+ */
+ maxRow(row) {
+ util.checkRowIndex(this, row);
+ var v = this.get(row, 0);
+ for (var i = 1; i < this.columns; i++) {
+ if (this.get(row, i) > v) {
+ v = this.get(row, i);
+ }
+ }
+ return v;
+ }
+
+ /**
+ * Returns the index of the maximum value of one row
+ * @param {number} row - Row index
+ * @return {Array}
+ */
+ maxRowIndex(row) {
+ util.checkRowIndex(this, row);
+ var v = this.get(row, 0);
+ var idx = [row, 0];
+ for (var i = 1; i < this.columns; i++) {
+ if (this.get(row, i) > v) {
+ v = this.get(row, i);
+ idx[1] = i;
+ }
+ }
+ return idx;
+ }
+
+ /**
+ * Returns the minimum value of one row
+ * @param {number} row - Row index
+ * @return {number}
+ */
+ minRow(row) {
+ util.checkRowIndex(this, row);
+ var v = this.get(row, 0);
+ for (var i = 1; i < this.columns; i++) {
+ if (this.get(row, i) < v) {
+ v = this.get(row, i);
+ }
+ }
+ return v;
+ }
+
+ /**
+ * Returns the index of the maximum value of one row
+ * @param {number} row - Row index
+ * @return {Array}
+ */
+ minRowIndex(row) {
+ util.checkRowIndex(this, row);
+ var v = this.get(row, 0);
+ var idx = [row, 0];
+ for (var i = 1; i < this.columns; i++) {
+ if (this.get(row, i) < v) {
+ v = this.get(row, i);
+ idx[1] = i;
+ }
+ }
+ return idx;
+ }
+
+ /**
+ * Returns the maximum value of one column
+ * @param {number} column - Column index
+ * @return {number}
+ */
+ maxColumn(column) {
+ util.checkColumnIndex(this, column);
+ var v = this.get(0, column);
+ for (var i = 1; i < this.rows; i++) {
+ if (this.get(i, column) > v) {
+ v = this.get(i, column);
+ }
+ }
+ return v;
+ }
+
+ /**
+ * Returns the index of the maximum value of one column
+ * @param {number} column - Column index
+ * @return {Array}
+ */
+ maxColumnIndex(column) {
+ util.checkColumnIndex(this, column);
+ var v = this.get(0, column);
+ var idx = [0, column];
+ for (var i = 1; i < this.rows; i++) {
+ if (this.get(i, column) > v) {
+ v = this.get(i, column);
+ idx[0] = i;
+ }
+ }
+ return idx;
+ }
+
+ /**
+ * Returns the minimum value of one column
+ * @param {number} column - Column index
+ * @return {number}
+ */
+ minColumn(column) {
+ util.checkColumnIndex(this, column);
+ var v = this.get(0, column);
+ for (var i = 1; i < this.rows; i++) {
+ if (this.get(i, column) < v) {
+ v = this.get(i, column);
+ }
+ }
+ return v;
+ }
+
+ /**
+ * Returns the index of the minimum value of one column
+ * @param {number} column - Column index
+ * @return {Array}
+ */
+ minColumnIndex(column) {
+ util.checkColumnIndex(this, column);
+ var v = this.get(0, column);
+ var idx = [0, column];
+ for (var i = 1; i < this.rows; i++) {
+ if (this.get(i, column) < v) {
+ v = this.get(i, column);
+ idx[0] = i;
+ }
+ }
+ return idx;
+ }
+
+ /**
+ * Returns an array containing the diagonal values of the matrix
+ * @return {Array}
+ */
+ diag() {
+ var min = Math.min(this.rows, this.columns);
+ var diag = new Array(min);
+ for (var i = 0; i < min; i++) {
+ diag[i] = this.get(i, i);
+ }
+ return diag;
+ }
+
+ /**
+ * Returns the sum by the argument given, if no argument given,
+ * it returns the sum of all elements of the matrix.
+ * @param {string} by - sum by 'row' or 'column'.
+ * @return {Matrix|number}
+ */
+ sum(by) {
+ switch (by) {
+ case 'row':
+ return util.sumByRow(this);
+ case 'column':
+ return util.sumByColumn(this);
+ default:
+ return util.sumAll(this);
+ }
+ }
+
+ /**
+ * Returns the mean of all elements of the matrix
+ * @return {number}
+ */
+ mean() {
+ return this.sum() / this.size;
+ }
+
+ /**
+ * Returns the product of all elements of the matrix
+ * @return {number}
+ */
+ prod() {
+ var prod = 1;
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ prod *= this.get(i, j);
+ }
+ }
+ return prod;
+ }
+
+ /**
+ * Computes the cumulative sum of the matrix elements (in place, row by row)
+ * @return {Matrix} this
+ */
+ cumulativeSum() {
+ var sum = 0;
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ sum += this.get(i, j);
+ this.set(i, j, sum);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Computes the dot (scalar) product between the matrix and another
+ * @param {Matrix} vector2 vector
+ * @return {number}
+ */
+ dot(vector2) {
+ if (Matrix.isMatrix(vector2)) vector2 = vector2.to1DArray();
+ var vector1 = this.to1DArray();
+ if (vector1.length !== vector2.length) {
+ throw new RangeError('vectors do not have the same size');
+ }
+ var dot = 0;
+ for (var i = 0; i < vector1.length; i++) {
+ dot += vector1[i] * vector2[i];
+ }
+ return dot;
+ }
+
+ /**
+ * Returns the matrix product between this and other
+ * @param {Matrix} other
+ * @return {Matrix}
+ */
+ mmul(other) {
+ other = this.constructor.checkMatrix(other);
+ if (this.columns !== other.rows) {
+ // eslint-disable-next-line no-console
+ console.warn('Number of columns of left matrix are not equal to number of rows of right matrix.');
+ }
+
+ var m = this.rows;
+ var n = this.columns;
+ var p = other.columns;
+
+ var result = new this.constructor[Symbol.species](m, p);
+
+ var Bcolj = new Array(n);
+ for (var j = 0; j < p; j++) {
+ for (var k = 0; k < n; k++) {
+ Bcolj[k] = other.get(k, j);
+ }
+
+ for (var i = 0; i < m; i++) {
+ var s = 0;
+ for (k = 0; k < n; k++) {
+ s += this.get(i, k) * Bcolj[k];
+ }
+
+ result.set(i, j, s);
+ }
+ }
+ return result;
+ }
+
+ strassen2x2(other) {
+ var result = new this.constructor[Symbol.species](2, 2);
+ const a11 = this.get(0, 0);
+ const b11 = other.get(0, 0);
+ const a12 = this.get(0, 1);
+ const b12 = other.get(0, 1);
+ const a21 = this.get(1, 0);
+ const b21 = other.get(1, 0);
+ const a22 = this.get(1, 1);
+ const b22 = other.get(1, 1);
+
+ // Compute intermediate values.
+ const m1 = (a11 + a22) * (b11 + b22);
+ const m2 = (a21 + a22) * b11;
+ const m3 = a11 * (b12 - b22);
+ const m4 = a22 * (b21 - b11);
+ const m5 = (a11 + a12) * b22;
+ const m6 = (a21 - a11) * (b11 + b12);
+ const m7 = (a12 - a22) * (b21 + b22);
+
+ // Combine intermediate values into the output.
+ const c00 = m1 + m4 - m5 + m7;
+ const c01 = m3 + m5;
+ const c10 = m2 + m4;
+ const c11 = m1 - m2 + m3 + m6;
+
+ result.set(0, 0, c00);
+ result.set(0, 1, c01);
+ result.set(1, 0, c10);
+ result.set(1, 1, c11);
+ return result;
+ }
+
+ strassen3x3(other) {
+ var result = new this.constructor[Symbol.species](3, 3);
+
+ const a00 = this.get(0, 0);
+ const a01 = this.get(0, 1);
+ const a02 = this.get(0, 2);
+ const a10 = this.get(1, 0);
+ const a11 = this.get(1, 1);
+ const a12 = this.get(1, 2);
+ const a20 = this.get(2, 0);
+ const a21 = this.get(2, 1);
+ const a22 = this.get(2, 2);
+
+ const b00 = other.get(0, 0);
+ const b01 = other.get(0, 1);
+ const b02 = other.get(0, 2);
+ const b10 = other.get(1, 0);
+ const b11 = other.get(1, 1);
+ const b12 = other.get(1, 2);
+ const b20 = other.get(2, 0);
+ const b21 = other.get(2, 1);
+ const b22 = other.get(2, 2);
+
+ const m1 = (a00 + a01 + a02 - a10 - a11 - a21 - a22) * b11;
+ const m2 = (a00 - a10) * (-b01 + b11);
+ const m3 = a11 * (-b00 + b01 + b10 - b11 - b12 - b20 + b22);
+ const m4 = (-a00 + a10 + a11) * (b00 - b01 + b11);
+ const m5 = (a10 + a11) * (-b00 + b01);
+ const m6 = a00 * b00;
+ const m7 = (-a00 + a20 + a21) * (b00 - b02 + b12);
+ const m8 = (-a00 + a20) * (b02 - b12);
+ const m9 = (a20 + a21) * (-b00 + b02);
+ const m10 = (a00 + a01 + a02 - a11 - a12 - a20 - a21) * b12;
+ const m11 = a21 * (-b00 + b02 + b10 - b11 - b12 - b20 + b21);
+ const m12 = (-a02 + a21 + a22) * (b11 + b20 - b21);
+ const m13 = (a02 - a22) * (b11 - b21);
+ const m14 = a02 * b20;
+ const m15 = (a21 + a22) * (-b20 + b21);
+ const m16 = (-a02 + a11 + a12) * (b12 + b20 - b22);
+ const m17 = (a02 - a12) * (b12 - b22);
+ const m18 = (a11 + a12) * (-b20 + b22);
+ const m19 = a01 * b10;
+ const m20 = a12 * b21;
+ const m21 = a10 * b02;
+ const m22 = a20 * b01;
+ const m23 = a22 * b22;
+
+ const c00 = m6 + m14 + m19;
+ const c01 = m1 + m4 + m5 + m6 + m12 + m14 + m15;
+ const c02 = m6 + m7 + m9 + m10 + m14 + m16 + m18;
+ const c10 = m2 + m3 + m4 + m6 + m14 + m16 + m17;
+ const c11 = m2 + m4 + m5 + m6 + m20;
+ const c12 = m14 + m16 + m17 + m18 + m21;
+ const c20 = m6 + m7 + m8 + m11 + m12 + m13 + m14;
+ const c21 = m12 + m13 + m14 + m15 + m22;
+ const c22 = m6 + m7 + m8 + m9 + m23;
+
+ result.set(0, 0, c00);
+ result.set(0, 1, c01);
+ result.set(0, 2, c02);
+ result.set(1, 0, c10);
+ result.set(1, 1, c11);
+ result.set(1, 2, c12);
+ result.set(2, 0, c20);
+ result.set(2, 1, c21);
+ result.set(2, 2, c22);
+ return result;
+ }
+
+ /**
+ * Returns the matrix product between x and y. More efficient than mmul(other) only when we multiply squared matrix and when the size of the matrix is > 1000.
+ * @param {Matrix} y
+ * @return {Matrix}
+ */
+ mmulStrassen(y) {
+ var x = this.clone();
+ var r1 = x.rows;
+ var c1 = x.columns;
+ var r2 = y.rows;
+ var c2 = y.columns;
+ if (c1 !== r2) {
+ // eslint-disable-next-line no-console
+ console.warn(`Multiplying ${r1} x ${c1} and ${r2} x ${c2} matrix: dimensions do not match.`);
+ }
+
+ // Put a matrix into the top left of a matrix of zeros.
+ // `rows` and `cols` are the dimensions of the output matrix.
+ function embed(mat, rows, cols) {
+ var r = mat.rows;
+ var c = mat.columns;
+ if ((r === rows) && (c === cols)) {
+ return mat;
+ } else {
+ var resultat = Matrix.zeros(rows, cols);
+ resultat = resultat.setSubMatrix(mat, 0, 0);
+ return resultat;
+ }
+ }
+
+
+ // Make sure both matrices are the same size.
+ // This is exclusively for simplicity:
+ // this algorithm can be implemented with matrices of different sizes.
+
+ var r = Math.max(r1, r2);
+ var c = Math.max(c1, c2);
+ x = embed(x, r, c);
+ y = embed(y, r, c);
+
+ // Our recursive multiplication function.
+ function blockMult(a, b, rows, cols) {
+ // For small matrices, resort to naive multiplication.
+ if (rows <= 512 || cols <= 512) {
+ return a.mmul(b); // a is equivalent to this
+ }
+
+ // Apply dynamic padding.
+ if ((rows % 2 === 1) && (cols % 2 === 1)) {
+ a = embed(a, rows + 1, cols + 1);
+ b = embed(b, rows + 1, cols + 1);
+ } else if (rows % 2 === 1) {
+ a = embed(a, rows + 1, cols);
+ b = embed(b, rows + 1, cols);
+ } else if (cols % 2 === 1) {
+ a = embed(a, rows, cols + 1);
+ b = embed(b, rows, cols + 1);
+ }
+
+ var halfRows = parseInt(a.rows / 2);
+ var halfCols = parseInt(a.columns / 2);
+ // Subdivide input matrices.
+ var a11 = a.subMatrix(0, halfRows - 1, 0, halfCols - 1);
+ var b11 = b.subMatrix(0, halfRows - 1, 0, halfCols - 1);
+
+ var a12 = a.subMatrix(0, halfRows - 1, halfCols, a.columns - 1);
+ var b12 = b.subMatrix(0, halfRows - 1, halfCols, b.columns - 1);
+
+ var a21 = a.subMatrix(halfRows, a.rows - 1, 0, halfCols - 1);
+ var b21 = b.subMatrix(halfRows, b.rows - 1, 0, halfCols - 1);
+
+ var a22 = a.subMatrix(halfRows, a.rows - 1, halfCols, a.columns - 1);
+ var b22 = b.subMatrix(halfRows, b.rows - 1, halfCols, b.columns - 1);
+
+ // Compute intermediate values.
+ var m1 = blockMult(Matrix.add(a11, a22), Matrix.add(b11, b22), halfRows, halfCols);
+ var m2 = blockMult(Matrix.add(a21, a22), b11, halfRows, halfCols);
+ var m3 = blockMult(a11, Matrix.sub(b12, b22), halfRows, halfCols);
+ var m4 = blockMult(a22, Matrix.sub(b21, b11), halfRows, halfCols);
+ var m5 = blockMult(Matrix.add(a11, a12), b22, halfRows, halfCols);
+ var m6 = blockMult(Matrix.sub(a21, a11), Matrix.add(b11, b12), halfRows, halfCols);
+ var m7 = blockMult(Matrix.sub(a12, a22), Matrix.add(b21, b22), halfRows, halfCols);
+
+ // Combine intermediate values into the output.
+ var c11 = Matrix.add(m1, m4);
+ c11.sub(m5);
+ c11.add(m7);
+ var c12 = Matrix.add(m3, m5);
+ var c21 = Matrix.add(m2, m4);
+ var c22 = Matrix.sub(m1, m2);
+ c22.add(m3);
+ c22.add(m6);
+
+ //Crop output to the desired size (undo dynamic padding).
+ var resultat = Matrix.zeros(2 * c11.rows, 2 * c11.columns);
+ resultat = resultat.setSubMatrix(c11, 0, 0);
+ resultat = resultat.setSubMatrix(c12, c11.rows, 0);
+ resultat = resultat.setSubMatrix(c21, 0, c11.columns);
+ resultat = resultat.setSubMatrix(c22, c11.rows, c11.columns);
+ return resultat.subMatrix(0, rows - 1, 0, cols - 1);
+ }
+ return blockMult(x, y, r, c);
+ }
+
+ /**
+ * Returns a row-by-row scaled matrix
+ * @param {number} [min=0] - Minimum scaled value
+ * @param {number} [max=1] - Maximum scaled value
+ * @return {Matrix} - The scaled matrix
+ */
+ scaleRows(min, max) {
+ min = min === undefined ? 0 : min;
+ max = max === undefined ? 1 : max;
+ if (min >= max) {
+ throw new RangeError('min should be strictly smaller than max');
+ }
+ var newMatrix = this.constructor.empty(this.rows, this.columns);
+ for (var i = 0; i < this.rows; i++) {
+ var scaled = arrayUtils.scale(this.getRow(i), {min, max});
+ newMatrix.setRow(i, scaled);
+ }
+ return newMatrix;
+ }
+
+ /**
+ * Returns a new column-by-column scaled matrix
+ * @param {number} [min=0] - Minimum scaled value
+ * @param {number} [max=1] - Maximum scaled value
+ * @return {Matrix} - The new scaled matrix
+ * @example
+ * var matrix = new Matrix([[1,2],[-1,0]]);
+ * var scaledMatrix = matrix.scaleColumns(); // [[1,1],[0,0]]
+ */
+ scaleColumns(min, max) {
+ min = min === undefined ? 0 : min;
+ max = max === undefined ? 1 : max;
+ if (min >= max) {
+ throw new RangeError('min should be strictly smaller than max');
+ }
+ var newMatrix = this.constructor.empty(this.rows, this.columns);
+ for (var i = 0; i < this.columns; i++) {
+ var scaled = arrayUtils.scale(this.getColumn(i), {
+ min: min,
+ max: max
+ });
+ newMatrix.setColumn(i, scaled);
+ }
+ return newMatrix;
+ }
+
+
+ /**
+ * Returns the Kronecker product (also known as tensor product) between this and other
+ * See https://en.wikipedia.org/wiki/Kronecker_product
+ * @param {Matrix} other
+ * @return {Matrix}
+ */
+ kroneckerProduct(other) {
+ other = this.constructor.checkMatrix(other);
+
+ var m = this.rows;
+ var n = this.columns;
+ var p = other.rows;
+ var q = other.columns;
+
+ var result = new this.constructor[Symbol.species](m * p, n * q);
+ for (var i = 0; i < m; i++) {
+ for (var j = 0; j < n; j++) {
+ for (var k = 0; k < p; k++) {
+ for (var l = 0; l < q; l++) {
+ result[p * i + k][q * j + l] = this.get(i, j) * other.get(k, l);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Transposes the matrix and returns a new one containing the result
+ * @return {Matrix}
+ */
+ transpose() {
+ var result = new this.constructor[Symbol.species](this.columns, this.rows);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ result.set(j, i, this.get(i, j));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Sorts the rows (in place)
+ * @param {function} compareFunction - usual Array.prototype.sort comparison function
+ * @return {Matrix} this
+ */
+ sortRows(compareFunction) {
+ if (compareFunction === undefined) compareFunction = compareNumbers;
+ for (var i = 0; i < this.rows; i++) {
+ this.setRow(i, this.getRow(i).sort(compareFunction));
+ }
+ return this;
+ }
+
+ /**
+ * Sorts the columns (in place)
+ * @param {function} compareFunction - usual Array.prototype.sort comparison function
+ * @return {Matrix} this
+ */
+ sortColumns(compareFunction) {
+ if (compareFunction === undefined) compareFunction = compareNumbers;
+ for (var i = 0; i < this.columns; i++) {
+ this.setColumn(i, this.getColumn(i).sort(compareFunction));
+ }
+ return this;
+ }
+
+ /**
+ * Returns a subset of the matrix
+ * @param {number} startRow - First row index
+ * @param {number} endRow - Last row index
+ * @param {number} startColumn - First column index
+ * @param {number} endColumn - Last column index
+ * @return {Matrix}
+ */
+ subMatrix(startRow, endRow, startColumn, endColumn) {
+ util.checkRange(this, startRow, endRow, startColumn, endColumn);
+ var newMatrix = new this.constructor[Symbol.species](endRow - startRow + 1, endColumn - startColumn + 1);
+ for (var i = startRow; i <= endRow; i++) {
+ for (var j = startColumn; j <= endColumn; j++) {
+ newMatrix[i - startRow][j - startColumn] = this.get(i, j);
+ }
+ }
+ return newMatrix;
+ }
+
+ /**
+ * Returns a subset of the matrix based on an array of row indices
+ * @param {Array} indices - Array containing the row indices
+ * @param {number} [startColumn = 0] - First column index
+ * @param {number} [endColumn = this.columns-1] - Last column index
+ * @return {Matrix}
+ */
+ subMatrixRow(indices, startColumn, endColumn) {
+ if (startColumn === undefined) startColumn = 0;
+ if (endColumn === undefined) endColumn = this.columns - 1;
+ if ((startColumn > endColumn) || (startColumn < 0) || (startColumn >= this.columns) || (endColumn < 0) || (endColumn >= this.columns)) {
+ throw new RangeError('Argument out of range');
+ }
+
+ var newMatrix = new this.constructor[Symbol.species](indices.length, endColumn - startColumn + 1);
+ for (var i = 0; i < indices.length; i++) {
+ for (var j = startColumn; j <= endColumn; j++) {
+ if (indices[i] < 0 || indices[i] >= this.rows) {
+ throw new RangeError('Row index out of range: ' + indices[i]);
+ }
+ newMatrix.set(i, j - startColumn, this.get(indices[i], j));
+ }
+ }
+ return newMatrix;
+ }
+
+ /**
+ * Returns a subset of the matrix based on an array of column indices
+ * @param {Array} indices - Array containing the column indices
+ * @param {number} [startRow = 0] - First row index
+ * @param {number} [endRow = this.rows-1] - Last row index
+ * @return {Matrix}
+ */
+ subMatrixColumn(indices, startRow, endRow) {
+ if (startRow === undefined) startRow = 0;
+ if (endRow === undefined) endRow = this.rows - 1;
+ if ((startRow > endRow) || (startRow < 0) || (startRow >= this.rows) || (endRow < 0) || (endRow >= this.rows)) {
+ throw new RangeError('Argument out of range');
+ }
+
+ var newMatrix = new this.constructor[Symbol.species](endRow - startRow + 1, indices.length);
+ for (var i = 0; i < indices.length; i++) {
+ for (var j = startRow; j <= endRow; j++) {
+ if (indices[i] < 0 || indices[i] >= this.columns) {
+ throw new RangeError('Column index out of range: ' + indices[i]);
+ }
+ newMatrix.set(j - startRow, i, this.get(j, indices[i]));
+ }
+ }
+ return newMatrix;
+ }
+
+ /**
+ * Set a part of the matrix to the given sub-matrix
+ * @param {Matrix|Array< Array >} matrix - The source matrix from which to extract values.
+ * @param {number} startRow - The index of the first row to set
+ * @param {number} startColumn - The index of the first column to set
+ * @return {Matrix}
+ */
+ setSubMatrix(matrix, startRow, startColumn) {
+ matrix = this.constructor.checkMatrix(matrix);
+ var endRow = startRow + matrix.rows - 1;
+ var endColumn = startColumn + matrix.columns - 1;
+ util.checkRange(this, startRow, endRow, startColumn, endColumn);
+ for (var i = 0; i < matrix.rows; i++) {
+ for (var j = 0; j < matrix.columns; j++) {
+ this[startRow + i][startColumn + j] = matrix.get(i, j);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Return a new matrix based on a selection of rows and columns
+ * @param {Array<number>} rowIndices - The row indices to select. Order matters and an index can be more than once.
+ * @param {Array<number>} columnIndices - The column indices to select. Order matters and an index can be use more than once.
+ * @return {Matrix} The new matrix
+ */
+ selection(rowIndices, columnIndices) {
+ var indices = util.checkIndices(this, rowIndices, columnIndices);
+ var newMatrix = new this.constructor[Symbol.species](rowIndices.length, columnIndices.length);
+ for (var i = 0; i < indices.row.length; i++) {
+ var rowIndex = indices.row[i];
+ for (var j = 0; j < indices.column.length; j++) {
+ var columnIndex = indices.column[j];
+ newMatrix[i][j] = this.get(rowIndex, columnIndex);
+ }
+ }
+ return newMatrix;
+ }
+
+ /**
+ * Returns the trace of the matrix (sum of the diagonal elements)
+ * @return {number}
+ */
+ trace() {
+ var min = Math.min(this.rows, this.columns);
+ var trace = 0;
+ for (var i = 0; i < min; i++) {
+ trace += this.get(i, i);
+ }
+ return trace;
+ }
+
+ /*
+ Matrix views
+ */
+
+ /**
+ * Returns a view of the transposition of the matrix
+ * @return {MatrixTransposeView}
+ */
+ transposeView() {
+ return new MLMatrixTransposeView(this);
+ }
+
+ /**
+ * Returns a view of the row vector with the given index
+ * @param {number} row - row index of the vector
+ * @return {MatrixRowView}
+ */
+ rowView(row) {
+ util.checkRowIndex(this, row);
+ return new MLMatrixRowView(this, row);
+ }
+
+ /**
+ * Returns a view of the column vector with the given index
+ * @param {number} column - column index of the vector
+ * @return {MatrixColumnView}
+ */
+ columnView(column) {
+ util.checkColumnIndex(this, column);
+ return new MLMatrixColumnView(this, column);
+ }
+
+ /**
+ * Returns a view of the matrix flipped in the row axis
+ * @return {MatrixFlipRowView}
+ */
+ flipRowView() {
+ return new MLMatrixFlipRowView(this);
+ }
+
+ /**
+ * Returns a view of the matrix flipped in the column axis
+ * @return {MatrixFlipColumnView}
+ */
+ flipColumnView() {
+ return new MLMatrixFlipColumnView(this);
+ }
+
+ /**
+ * Returns a view of a submatrix giving the index boundaries
+ * @param {number} startRow - first row index of the submatrix
+ * @param {number} endRow - last row index of the submatrix
+ * @param {number} startColumn - first column index of the submatrix
+ * @param {number} endColumn - last column index of the submatrix
+ * @return {MatrixSubView}
+ */
+ subMatrixView(startRow, endRow, startColumn, endColumn) {
+ return new MLMatrixSubView(this, startRow, endRow, startColumn, endColumn);
+ }
+
+ /**
+ * Returns a view of the cross of the row indices and the column indices
+ * @example
+ * // resulting vector is [[2], [2]]
+ * var matrix = new Matrix([[1,2,3], [4,5,6]]).selectionView([0, 0], [1])
+ * @param {Array<number>} rowIndices
+ * @param {Array<number>} columnIndices
+ * @return {MatrixSelectionView}
+ */
+ selectionView(rowIndices, columnIndices) {
+ return new MLMatrixSelectionView(this, rowIndices, columnIndices);
+ }
+
+
+ /**
+ * Calculates and returns the determinant of a matrix as a Number
+ * @example
+ * new Matrix([[1,2,3], [4,5,6]]).det()
+ * @return {number}
+ */
+ det() {
+ if (this.isSquare()) {
+ var a, b, c, d;
+ if (this.columns === 2) {
+ // 2 x 2 matrix
+ a = this.get(0, 0);
+ b = this.get(0, 1);
+ c = this.get(1, 0);
+ d = this.get(1, 1);
+
+ return a * d - (b * c);
+ } else if (this.columns === 3) {
+ // 3 x 3 matrix
+ var subMatrix0, subMatrix1, subMatrix2;
+ subMatrix0 = this.selectionView([1, 2], [1, 2]);
+ subMatrix1 = this.selectionView([1, 2], [0, 2]);
+ subMatrix2 = this.selectionView([1, 2], [0, 1]);
+ a = this.get(0, 0);
+ b = this.get(0, 1);
+ c = this.get(0, 2);
+
+ return a * subMatrix0.det() - b * subMatrix1.det() + c * subMatrix2.det();
+ } else {
+ // general purpose determinant using the LU decomposition
+ return new LuDecomposition(this).determinant;
+ }
+
+ } else {
+ throw Error('Determinant can only be calculated for a square matrix.');
+ }
+ }
+
+ /**
+ * Returns inverse of a matrix if it exists or the pseudoinverse
+ * @param {number} threshold - threshold for taking inverse of singular values (default = 1e-15)
+ * @return {Matrix} the (pseudo)inverted matrix.
+ */
+ pseudoInverse(threshold) {
+ if (threshold === undefined) threshold = Number.EPSILON;
+ var svdSolution = new SvDecomposition(this, {autoTranspose: true});
+
+ var U = svdSolution.leftSingularVectors;
+ var V = svdSolution.rightSingularVectors;
+ var s = svdSolution.diagonal;
+
+ for (var i = 0; i < s.length; i++) {
+ if (Math.abs(s[i]) > threshold) {
+ s[i] = 1.0 / s[i];
+ } else {
+ s[i] = 0.0;
+ }
+ }
+
+ // convert list to diagonal
+ s = this.constructor[Symbol.species].diag(s);
+ return V.mmul(s.mmul(U.transposeView()));
+ }
+ }
+
+ Matrix.prototype.klass = 'Matrix';
+
+ /**
+ * @private
+ * Check that two matrices have the same dimensions
+ * @param {Matrix} matrix
+ * @param {Matrix} otherMatrix
+ */
+ function checkDimensions(matrix, otherMatrix) { // eslint-disable-line no-unused-vars
+ if (matrix.rows !== otherMatrix.rows ||
+ matrix.columns !== otherMatrix.columns) {
+ throw new RangeError('Matrices dimensions must be equal');
+ }
+ }
+
+ function compareNumbers(a, b) {
+ return a - b;
+ }
+
+ /*
+ Synonyms
+ */
+
+ Matrix.random = Matrix.rand;
+ Matrix.diagonal = Matrix.diag;
+ Matrix.prototype.diagonal = Matrix.prototype.diag;
+ Matrix.identity = Matrix.eye;
+ Matrix.prototype.negate = Matrix.prototype.neg;
+ Matrix.prototype.tensorProduct = Matrix.prototype.kroneckerProduct;
+ Matrix.prototype.determinant = Matrix.prototype.det;
+
+ /*
+ Add dynamically instance and static methods for mathematical operations
+ */
+
+ var inplaceOperator = `
+ (function %name%(value) {
+ if (typeof value === 'number') return this.%name%S(value);
+ return this.%name%M(value);
+ })
+ `;
+
+ var inplaceOperatorScalar = `
+ (function %name%S(value) {
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, this.get(i, j) %op% value);
+ }
+ }
+ return this;
+ })
+ `;
+
+ var inplaceOperatorMatrix = `
+ (function %name%M(matrix) {
+ matrix = this.constructor.checkMatrix(matrix);
+ checkDimensions(this, matrix);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, this.get(i, j) %op% matrix.get(i, j));
+ }
+ }
+ return this;
+ })
+ `;
+
+ var staticOperator = `
+ (function %name%(matrix, value) {
+ var newMatrix = new this[Symbol.species](matrix);
+ return newMatrix.%name%(value);
+ })
+ `;
+
+ var inplaceMethod = `
+ (function %name%() {
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, %method%(this.get(i, j)));
+ }
+ }
+ return this;
+ })
+ `;
+
+ var staticMethod = `
+ (function %name%(matrix) {
+ var newMatrix = new this[Symbol.species](matrix);
+ return newMatrix.%name%();
+ })
+ `;
+
+ var inplaceMethodWithArgs = `
+ (function %name%(%args%) {
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, %method%(this.get(i, j), %args%));
+ }
+ }
+ return this;
+ })
+ `;
+
+ var staticMethodWithArgs = `
+ (function %name%(matrix, %args%) {
+ var newMatrix = new this[Symbol.species](matrix);
+ return newMatrix.%name%(%args%);
+ })
+ `;
+
+
+ var inplaceMethodWithOneArgScalar = `
+ (function %name%S(value) {
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, %method%(this.get(i, j), value));
+ }
+ }
+ return this;
+ })
+ `;
+ var inplaceMethodWithOneArgMatrix = `
+ (function %name%M(matrix) {
+ matrix = this.constructor.checkMatrix(matrix);
+ checkDimensions(this, matrix);
+ for (var i = 0; i < this.rows; i++) {
+ for (var j = 0; j < this.columns; j++) {
+ this.set(i, j, %method%(this.get(i, j), matrix.get(i, j)));
+ }
+ }
+ return this;
+ })
+ `;
+
+ var inplaceMethodWithOneArg = `
+ (function %name%(value) {
+ if (typeof value === 'number') return this.%name%S(value);
+ return this.%name%M(value);
+ })
+ `;
+
+ var staticMethodWithOneArg = staticMethodWithArgs;
+
+ var operators = [
+ // Arithmetic operators
+ ['+', 'add'],
+ ['-', 'sub', 'subtract'],
+ ['*', 'mul', 'multiply'],
+ ['/', 'div', 'divide'],
+ ['%', 'mod', 'modulus'],
+ // Bitwise operators
+ ['&', 'and'],
+ ['|', 'or'],
+ ['^', 'xor'],
+ ['<<', 'leftShift'],
+ ['>>', 'signPropagatingRightShift'],
+ ['>>>', 'rightShift', 'zeroFillRightShift']
+ ];
+
+ var i;
+
+ for (var operator of operators) {
+ var inplaceOp = eval(fillTemplateFunction(inplaceOperator, {name: operator[1], op: operator[0]}));
+ var inplaceOpS = eval(fillTemplateFunction(inplaceOperatorScalar, {name: operator[1] + 'S', op: operator[0]}));
+ var inplaceOpM = eval(fillTemplateFunction(inplaceOperatorMatrix, {name: operator[1] + 'M', op: operator[0]}));
+ var staticOp = eval(fillTemplateFunction(staticOperator, {name: operator[1]}));
+ for (i = 1; i < operator.length; i++) {
+ Matrix.prototype[operator[i]] = inplaceOp;
+ Matrix.prototype[operator[i] + 'S'] = inplaceOpS;
+ Matrix.prototype[operator[i] + 'M'] = inplaceOpM;
+ Matrix[operator[i]] = staticOp;
+ }
+ }
+
+ var methods = [
+ ['~', 'not']
+ ];
+
+ [
+ 'abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cbrt', 'ceil',
+ 'clz32', 'cos', 'cosh', 'exp', 'expm1', 'floor', 'fround', 'log', 'log1p',
+ 'log10', 'log2', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc'
+ ].forEach(function (mathMethod) {
+ methods.push(['Math.' + mathMethod, mathMethod]);
+ });
+
+ for (var method of methods) {
+ var inplaceMeth = eval(fillTemplateFunction(inplaceMethod, {name: method[1], method: method[0]}));
+ var staticMeth = eval(fillTemplateFunction(staticMethod, {name: method[1]}));
+ for (i = 1; i < method.length; i++) {
+ Matrix.prototype[method[i]] = inplaceMeth;
+ Matrix[method[i]] = staticMeth;
+ }
+ }
+
+ var methodsWithArgs = [
+ ['Math.pow', 1, 'pow']
+ ];
+
+ for (var methodWithArg of methodsWithArgs) {
+ var args = 'arg0';
+ for (i = 1; i < methodWithArg[1]; i++) {
+ args += `, arg${i}`;
+ }
+ if (methodWithArg[1] !== 1) {
+ var inplaceMethWithArgs = eval(fillTemplateFunction(inplaceMethodWithArgs, {
+ name: methodWithArg[2],
+ method: methodWithArg[0],
+ args: args
+ }));
+ var staticMethWithArgs = eval(fillTemplateFunction(staticMethodWithArgs, {name: methodWithArg[2], args: args}));
+ for (i = 2; i < methodWithArg.length; i++) {
+ Matrix.prototype[methodWithArg[i]] = inplaceMethWithArgs;
+ Matrix[methodWithArg[i]] = staticMethWithArgs;
+ }
+ } else {
+ var tmplVar = {
+ name: methodWithArg[2],
+ args: args,
+ method: methodWithArg[0]
+ };
+ var inplaceMethod2 = eval(fillTemplateFunction(inplaceMethodWithOneArg, tmplVar));
+ var inplaceMethodS = eval(fillTemplateFunction(inplaceMethodWithOneArgScalar, tmplVar));
+ var inplaceMethodM = eval(fillTemplateFunction(inplaceMethodWithOneArgMatrix, tmplVar));
+ var staticMethod2 = eval(fillTemplateFunction(staticMethodWithOneArg, tmplVar));
+ for (i = 2; i < methodWithArg.length; i++) {
+ Matrix.prototype[methodWithArg[i]] = inplaceMethod2;
+ Matrix.prototype[methodWithArg[i] + 'M'] = inplaceMethodM;
+ Matrix.prototype[methodWithArg[i] + 'S'] = inplaceMethodS;
+ Matrix[methodWithArg[i]] = staticMethod2;
+ }
+ }
+ }
+
+ function fillTemplateFunction(template, values) {
+ for (var value in values) {
+ template = template.replace(new RegExp('%' + value + '%', 'g'), values[value]);
+ }
+ return template;
+ }
+
+ return Matrix;
+ }
+}
+
+
+// ml-matrix src/views/base
+let MLMatrixBaseView;
+{
+ let abstractMatrix = MLMatrixAbstractMatrix;
+ let Matrix = MLMatrixMatrix;
+
+ class BaseView extends abstractMatrix() {
+ constructor(matrix, rows, columns) {
+ super();
+ this.matrix = matrix;
+ this.rows = rows;
+ this.columns = columns;
+ }
+
+ static get [Symbol.species]() {
+ return Matrix.Matrix;
+ }
+ }
+
+ MLMatrixBaseView = BaseView;
+}
+
+
+// ml-matrix src/views/column.js
+let MLMatrixColumnView;
+{
+ let BaseView = MLMatrixBaseView;
+
+ class MatrixColumnView extends BaseView {
+ constructor(matrix, column) {
+ super(matrix, matrix.rows, 1);
+ this.column = column;
+ }
+
+ set(rowIndex, columnIndex, value) {
+ this.matrix.set(rowIndex, this.column, value);
+ return this;
+ }
+
+ get(rowIndex) {
+ return this.matrix.get(rowIndex, this.column);
+ }
+ }
+
+ MLMatrixColumnView = MatrixColumnView;
+}
+
+
+// ml-matrix src/views/flipColumn.js
+let MLMatrixFlipColumnView;
+{
+ let BaseView = MLMatrixBaseView
+
+ class MatrixFlipColumnView extends BaseView {
+ constructor(matrix) {
+ super(matrix, matrix.rows, matrix.columns);
+ }
+
+ set(rowIndex, columnIndex, value) {
+ this.matrix.set(rowIndex, this.columns - columnIndex - 1, value);
+ return this;
+ }
+
+ get(rowIndex, columnIndex) {
+ return this.matrix.get(rowIndex, this.columns - columnIndex - 1);
+ }
+ }
+
+ MLMatrixFlipColumnView = MatrixFlipColumnView;
+}
+
+
+// ml-matrix src/views/flipRow.js
+let MLMatrixFlipRowView;
+{
+ let BaseView = MLMatrixBaseView
+
+ class MatrixFlipRowView extends BaseView {
+ constructor(matrix) {
+ super(matrix, matrix.rows, matrix.columns);
+ }
+
+ set(rowIndex, columnIndex, value) {
+ this.matrix.set(this.rows - rowIndex - 1, columnIndex, value);
+ return this;
+ }
+
+ get(rowIndex, columnIndex) {
+ return this.matrix.get(this.rows - rowIndex - 1, columnIndex);
+ }
+ }
+
+ MLMatrixFlipRowView = MatrixFlipRowView;
+}
+
+// ml-matrix src/views/row.js
+let MLMatrixRowView;
+{
+ let BaseView = MLMatrixBaseView;
+
+ class MatrixRowView extends BaseView {
+ constructor(matrix, row) {
+ super(matrix, 1, matrix.columns);
+ this.row = row;
+ }
+
+ set(rowIndex, columnIndex, value) {
+ this.matrix.set(this.row, columnIndex, value);
+ return this;
+ }
+
+ get(rowIndex, columnIndex) {
+ return this.matrix.get(this.row, columnIndex);
+ }
+ }
+
+ MLMatrixRowView = MatrixRowView;
+}
+
+
+// ml-matrix src/views/selection.js
+let MLMatrixSelectionView;
+{
+ let BaseView = MLMatrixBaseView;
+ let util = MLMatrixUtil;
+
+ class MatrixSelectionView extends BaseView {
+ constructor(matrix, rowIndices, columnIndices) {
+ var indices = util.checkIndices(matrix, rowIndices, columnIndices);
+ super(matrix, indices.row.length, indices.column.length);
+ this.rowIndices = indices.row;
+ this.columnIndices = indices.column;
+ }
+
+ set(rowIndex, columnIndex, value) {
+ this.matrix.set(this.rowIndices[rowIndex], this.columnIndices[columnIndex], value);
+ return this;
+ }
+
+ get(rowIndex, columnIndex) {
+ return this.matrix.get(this.rowIndices[rowIndex], this.columnIndices[columnIndex]);
+ }
+ }
+
+ MLMatrixSelectionView = MatrixSelectionView;
+}
+
+// ml-matrix src/views/sub.js
+let MLMatrixSubView;
+{
+ let BaseView = MLMatrixBaseView;
+ let util = MLMatrixUtil;
+
+ class MatrixSubView extends BaseView {
+ constructor(matrix, startRow, endRow, startColumn, endColumn) {
+ util.checkRange(matrix, startRow, endRow, startColumn, endColumn);
+ super(matrix, endRow - startRow + 1, endColumn - startColumn + 1);
+ this.startRow = startRow;
+ this.startColumn = startColumn;
+ }
+
+ set(rowIndex, columnIndex, value) {
+ this.matrix.set(this.startRow + rowIndex, this.startColumn + columnIndex, value);
+ return this;
+ }
+
+ get(rowIndex, columnIndex) {
+ return this.matrix.get(this.startRow + rowIndex, this.startColumn + columnIndex);
+ }
+ }
+
+ MLMatrixSubView = MatrixSubView;
+}
+
+// ml-matrix src/views/transpose.js
+let MLMatrixTransposeView;
+{
+ let BaseView = MLMatrixBaseView;
+
+ class MatrixTransposeView extends BaseView {
+ constructor(matrix) {
+ super(matrix, matrix.columns, matrix.rows);
+ }
+
+ set(rowIndex, columnIndex, value) {
+ this.matrix.set(columnIndex, rowIndex, value);
+ return this;
+ }
+
+ get(rowIndex, columnIndex) {
+ return this.matrix.get(columnIndex, rowIndex);
+ }
+ }
+
+ MLMatrixTransposeView = MatrixTransposeView;
+}
+
+// mlmatrix src/matrix.js
+{
+ let abstractMatrix = MLMatrixAbstractMatrix;
+ let util = MLMatrixUtil;
+
+ class Matrix extends abstractMatrix(Array) {
+ constructor(nRows, nColumns) {
+ var i;
+ if (arguments.length === 1 && typeof nRows === 'number') {
+ return new Array(nRows);
+ }
+ if (Matrix.isMatrix(nRows)) {
+ return nRows.clone();
+ } else if (Number.isInteger(nRows) && nRows > 0) { // Create an empty matrix
+ super(nRows);
+ if (Number.isInteger(nColumns) && nColumns > 0) {
+ for (i = 0; i < nRows; i++) {
+ this[i] = new Array(nColumns);
+ }
+ } else {
+ throw new TypeError('nColumns must be a positive integer');
+ }
+ } else if (Array.isArray(nRows)) { // Copy the values from the 2D array
+ const matrix = nRows;
+ nRows = matrix.length;
+ nColumns = matrix[0].length;
+ if (typeof nColumns !== 'number' || nColumns === 0) {
+ throw new TypeError('Data must be a 2D array with at least one element');
+ }
+ super(nRows);
+ for (i = 0; i < nRows; i++) {
+ if (matrix[i].length !== nColumns) {
+ throw new RangeError('Inconsistent array dimensions');
+ }
+ this[i] = [].concat(matrix[i]);
+ }
+ } else {
+ throw new TypeError('First argument must be a positive number or an array');
+ }
+ this.rows = nRows;
+ this.columns = nColumns;
+ return this;
+ }
+
+ set(rowIndex, columnIndex, value) {
+ this[rowIndex][columnIndex] = value;
+ return this;
+ }
+
+ get(rowIndex, columnIndex) {
+ return this[rowIndex][columnIndex];
+ }
+
+ /**
+ * Creates an exact and independent copy of the matrix
+ * @return {Matrix}
+ */
+ clone() {
+ var newMatrix = new this.constructor[Symbol.species](this.rows, this.columns);
+ for (var row = 0; row < this.rows; row++) {
+ for (var column = 0; column < this.columns; column++) {
+ newMatrix.set(row, column, this.get(row, column));
+ }
+ }
+ return newMatrix;
+ }
+
+ /**
+ * Removes a row from the given index
+ * @param {number} index - Row index
+ * @return {Matrix} this
+ */
+ removeRow(index) {
+ util.checkRowIndex(this, index);
+ if (this.rows === 1) {
+ throw new RangeError('A matrix cannot have less than one row');
+ }
+ this.splice(index, 1);
+ this.rows -= 1;
+ return this;
+ }
+
+ /**
+ * Adds a row at the given index
+ * @param {number} [index = this.rows] - Row index
+ * @param {Array|Matrix} array - Array or vector
+ * @return {Matrix} this
+ */
+ addRow(index, array) {
+ if (array === undefined) {
+ array = index;
+ index = this.rows;
+ }
+ util.checkRowIndex(this, index, true);
+ array = util.checkRowVector(this, array, true);
+ this.splice(index, 0, array);
+ this.rows += 1;
+ return this;
+ }
+
+ /**
+ * Removes a column from the given index
+ * @param {number} index - Column index
+ * @return {Matrix} this
+ */
+ removeColumn(index) {
+ util.checkColumnIndex(this, index);
+ if (this.columns === 1) {
+ throw new RangeError('A matrix cannot have less than one column');
+ }
+ for (var i = 0; i < this.rows; i++) {
+ this[i].splice(index, 1);
+ }
+ this.columns -= 1;
+ return this;
+ }
+
+ /**
+ * Adds a column at the given index
+ * @param {number} [index = this.columns] - Column index
+ * @param {Array|Matrix} array - Array or vector
+ * @return {Matrix} this
+ */
+ addColumn(index, array) {
+ if (typeof array === 'undefined') {
+ array = index;
+ index = this.columns;
+ }
+ util.checkColumnIndex(this, index, true);
+ array = util.checkColumnVector(this, array);
+ for (var i = 0; i < this.rows; i++) {
+ this[i].splice(index, 0, array[i]);
+ }
+ this.columns += 1;
+ return this;
+ }
+ }
+
+ MLMatrixMatrix.Matrix = Matrix;
+ Matrix.abstractMatrix = abstractMatrix;
+}
+
+
+// ml-matrix src/dc/cholesky.js
+let MLMatrixDCCholesky = {};
+{
+ let Matrix = MLMatrixMatrix.Matrix;
+
+ // https://github.com/lutzroeder/Mapack/blob/master/Source/CholeskyDecomposition.cs
+ function CholeskyDecomposition(value) {
+ if (!(this instanceof CholeskyDecomposition)) {
+ return new CholeskyDecomposition(value);
+ }
+ value = Matrix.checkMatrix(value);
+ if (!value.isSymmetric()) {
+ throw new Error('Matrix is not symmetric');
+ }
+
+ var a = value,
+ dimension = a.rows,
+ l = new Matrix(dimension, dimension),
+ positiveDefinite = true,
+ i, j, k;
+
+ for (j = 0; j < dimension; j++) {
+ var Lrowj = l[j];
+ var d = 0;
+ for (k = 0; k < j; k++) {
+ var Lrowk = l[k];
+ var s = 0;
+ for (i = 0; i < k; i++) {
+ s += Lrowk[i] * Lrowj[i];
+ }
+ Lrowj[k] = s = (a[j][k] - s) / l[k][k];
+ d = d + s * s;
+ }
+
+ d = a[j][j] - d;
+
+ positiveDefinite &= (d > 0);
+ l[j][j] = Math.sqrt(Math.max(d, 0));
+ for (k = j + 1; k < dimension; k++) {
+ l[j][k] = 0;
+ }
+ }
+
+ if (!positiveDefinite) {
+ throw new Error('Matrix is not positive definite');
+ }
+
+ this.L = l;
+ }
+
+ CholeskyDecomposition.prototype = {
+ get lowerTriangularMatrix() {
+ return this.L;
+ },
+ solve: function (value) {
+ value = Matrix.checkMatrix(value);
+
+ var l = this.L,
+ dimension = l.rows;
+
+ if (value.rows !== dimension) {
+ throw new Error('Matrix dimensions do not match');
+ }
+
+ var count = value.columns,
+ B = value.clone(),
+ i, j, k;
+
+ for (k = 0; k < dimension; k++) {
+ for (j = 0; j < count; j++) {
+ for (i = 0; i < k; i++) {
+ B[k][j] -= B[i][j] * l[k][i];
+ }
+ B[k][j] /= l[k][k];
+ }
+ }
+
+ for (k = dimension - 1; k >= 0; k--) {
+ for (j = 0; j < count; j++) {
+ for (i = k + 1; i < dimension; i++) {
+ B[k][j] -= B[i][j] * l[i][k];
+ }
+ B[k][j] /= l[k][k];
+ }
+ }
+
+ return B;
+ }
+ };
+
+ MLMatrixDCCholesky = CholeskyDecomposition;
+}
+
+
+// ml-matrix src/dc/evd.js
+let MLMatrixDCEVD;
+{
+ const Matrix = MLMatrixMatrix.Matrix;
+ const util = MLMatrixDCUtil;
+ const hypotenuse = util.hypotenuse;
+ const getFilled2DArray = util.getFilled2DArray;
+
+ const defaultOptions = {
+ assumeSymmetric: false
+ };
+
+ // https://github.com/lutzroeder/Mapack/blob/master/Source/EigenvalueDecomposition.cs
+ function EigenvalueDecomposition(matrix, options) {
+ options = Object.assign({}, defaultOptions, options);
+ if (!(this instanceof EigenvalueDecomposition)) {
+ return new EigenvalueDecomposition(matrix, options);
+ }
+ matrix = Matrix.checkMatrix(matrix);
+ if (!matrix.isSquare()) {
+ throw new Error('Matrix is not a square matrix');
+ }
+
+ var n = matrix.columns,
+ V = getFilled2DArray(n, n, 0),
+ d = new Array(n),
+ e = new Array(n),
+ value = matrix,
+ i, j;
+
+ var isSymmetric = false;
+ if (options.assumeSymmetric) {
+ isSymmetric = true;
+ } else {
+ isSymmetric = matrix.isSymmetric();
+ }
+
+ if (isSymmetric) {
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < n; j++) {
+ V[i][j] = value.get(i, j);
+ }
+ }
+ tred2(n, e, d, V);
+ tql2(n, e, d, V);
+ } else {
+ var H = getFilled2DArray(n, n, 0),
+ ort = new Array(n);
+ for (j = 0; j < n; j++) {
+ for (i = 0; i < n; i++) {
+ H[i][j] = value.get(i, j);
+ }
+ }
+ orthes(n, H, ort, V);
+ hqr2(n, e, d, V, H);
+ }
+
+ this.n = n;
+ this.e = e;
+ this.d = d;
+ this.V = V;
+ }
+
+ EigenvalueDecomposition.prototype = {
+ get realEigenvalues() {
+ return this.d;
+ },
+ get imaginaryEigenvalues() {
+ return this.e;
+ },
+ get eigenvectorMatrix() {
+ if (!Matrix.isMatrix(this.V)) {
+ this.V = new Matrix(this.V);
+ }
+ return this.V;
+ },
+ get diagonalMatrix() {
+ var n = this.n,
+ e = this.e,
+ d = this.d,
+ X = new Matrix(n, n),
+ i, j;
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < n; j++) {
+ X[i][j] = 0;
+ }
+ X[i][i] = d[i];
+ if (e[i] > 0) {
+ X[i][i + 1] = e[i];
+ } else if (e[i] < 0) {
+ X[i][i - 1] = e[i];
+ }
+ }
+ return X;
+ }
+ };
+
+ function tred2(n, e, d, V) {
+
+ var f, g, h, i, j, k,
+ hh, scale;
+
+ for (j = 0; j < n; j++) {
+ d[j] = V[n - 1][j];
+ }
+
+ for (i = n - 1; i > 0; i--) {
+ scale = 0;
+ h = 0;
+ for (k = 0; k < i; k++) {
+ scale = scale + Math.abs(d[k]);
+ }
+
+ if (scale === 0) {
+ e[i] = d[i - 1];
+ for (j = 0; j < i; j++) {
+ d[j] = V[i - 1][j];
+ V[i][j] = 0;
+ V[j][i] = 0;
+ }
+ } else {
+ for (k = 0; k < i; k++) {
+ d[k] /= scale;
+ h += d[k] * d[k];
+ }
+
+ f = d[i - 1];
+ g = Math.sqrt(h);
+ if (f > 0) {
+ g = -g;
+ }
+
+ e[i] = scale * g;
+ h = h - f * g;
+ d[i - 1] = f - g;
+ for (j = 0; j < i; j++) {
+ e[j] = 0;
+ }
+
+ for (j = 0; j < i; j++) {
+ f = d[j];
+ V[j][i] = f;
+ g = e[j] + V[j][j] * f;
+ for (k = j + 1; k <= i - 1; k++) {
+ g += V[k][j] * d[k];
+ e[k] += V[k][j] * f;
+ }
+ e[j] = g;
+ }
+
+ f = 0;
+ for (j = 0; j < i; j++) {
+ e[j] /= h;
+ f += e[j] * d[j];
+ }
+
+ hh = f / (h + h);
+ for (j = 0; j < i; j++) {
+ e[j] -= hh * d[j];
+ }
+
+ for (j = 0; j < i; j++) {
+ f = d[j];
+ g = e[j];
+ for (k = j; k <= i - 1; k++) {
+ V[k][j] -= (f * e[k] + g * d[k]);
+ }
+ d[j] = V[i - 1][j];
+ V[i][j] = 0;
+ }
+ }
+ d[i] = h;
+ }
+
+ for (i = 0; i < n - 1; i++) {
+ V[n - 1][i] = V[i][i];
+ V[i][i] = 1;
+ h = d[i + 1];
+ if (h !== 0) {
+ for (k = 0; k <= i; k++) {
+ d[k] = V[k][i + 1] / h;
+ }
+
+ for (j = 0; j <= i; j++) {
+ g = 0;
+ for (k = 0; k <= i; k++) {
+ g += V[k][i + 1] * V[k][j];
+ }
+ for (k = 0; k <= i; k++) {
+ V[k][j] -= g * d[k];
+ }
+ }
+ }
+
+ for (k = 0; k <= i; k++) {
+ V[k][i + 1] = 0;
+ }
+ }
+
+ for (j = 0; j < n; j++) {
+ d[j] = V[n - 1][j];
+ V[n - 1][j] = 0;
+ }
+
+ V[n - 1][n - 1] = 1;
+ e[0] = 0;
+ }
+
+ function tql2(n, e, d, V) {
+
+ var g, h, i, j, k, l, m, p, r,
+ dl1, c, c2, c3, el1, s, s2,
+ iter;
+
+ for (i = 1; i < n; i++) {
+ e[i - 1] = e[i];
+ }
+
+ e[n - 1] = 0;
+
+ var f = 0,
+ tst1 = 0,
+ eps = Math.pow(2, -52);
+
+ for (l = 0; l < n; l++) {
+ tst1 = Math.max(tst1, Math.abs(d[l]) + Math.abs(e[l]));
+ m = l;
+ while (m < n) {
+ if (Math.abs(e[m]) <= eps * tst1) {
+ break;
+ }
+ m++;
+ }
+
+ if (m > l) {
+ iter = 0;
+ do {
+ iter = iter + 1;
+
+ g = d[l];
+ p = (d[l + 1] - g) / (2 * e[l]);
+ r = hypotenuse(p, 1);
+ if (p < 0) {
+ r = -r;
+ }
+
+ d[l] = e[l] / (p + r);
+ d[l + 1] = e[l] * (p + r);
+ dl1 = d[l + 1];
+ h = g - d[l];
+ for (i = l + 2; i < n; i++) {
+ d[i] -= h;
+ }
+
+ f = f + h;
+
+ p = d[m];
+ c = 1;
+ c2 = c;
+ c3 = c;
+ el1 = e[l + 1];
+ s = 0;
+ s2 = 0;
+ for (i = m - 1; i >= l; i--) {
+ c3 = c2;
+ c2 = c;
+ s2 = s;
+ g = c * e[i];
+ h = c * p;
+ r = hypotenuse(p, e[i]);
+ e[i + 1] = s * r;
+ s = e[i] / r;
+ c = p / r;
+ p = c * d[i] - s * g;
+ d[i + 1] = h + s * (c * g + s * d[i]);
+
+ for (k = 0; k < n; k++) {
+ h = V[k][i + 1];
+ V[k][i + 1] = s * V[k][i] + c * h;
+ V[k][i] = c * V[k][i] - s * h;
+ }
+ }
+
+ p = -s * s2 * c3 * el1 * e[l] / dl1;
+ e[l] = s * p;
+ d[l] = c * p;
+
+ }
+ while (Math.abs(e[l]) > eps * tst1);
+ }
+ d[l] = d[l] + f;
+ e[l] = 0;
+ }
+
+ for (i = 0; i < n - 1; i++) {
+ k = i;
+ p = d[i];
+ for (j = i + 1; j < n; j++) {
+ if (d[j] < p) {
+ k = j;
+ p = d[j];
+ }
+ }
+
+ if (k !== i) {
+ d[k] = d[i];
+ d[i] = p;
+ for (j = 0; j < n; j++) {
+ p = V[j][i];
+ V[j][i] = V[j][k];
+ V[j][k] = p;
+ }
+ }
+ }
+ }
+
+ function orthes(n, H, ort, V) {
+
+ var low = 0,
+ high = n - 1,
+ f, g, h, i, j, m,
+ scale;
+
+ for (m = low + 1; m <= high - 1; m++) {
+ scale = 0;
+ for (i = m; i <= high; i++) {
+ scale = scale + Math.abs(H[i][m - 1]);
+ }
+
+ if (scale !== 0) {
+ h = 0;
+ for (i = high; i >= m; i--) {
+ ort[i] = H[i][m - 1] / scale;
+ h += ort[i] * ort[i];
+ }
+
+ g = Math.sqrt(h);
+ if (ort[m] > 0) {
+ g = -g;
+ }
+
+ h = h - ort[m] * g;
+ ort[m] = ort[m] - g;
+
+ for (j = m; j < n; j++) {
+ f = 0;
+ for (i = high; i >= m; i--) {
+ f += ort[i] * H[i][j];
+ }
+
+ f = f / h;
+ for (i = m; i <= high; i++) {
+ H[i][j] -= f * ort[i];
+ }
+ }
+
+ for (i = 0; i <= high; i++) {
+ f = 0;
+ for (j = high; j >= m; j--) {
+ f += ort[j] * H[i][j];
+ }
+
+ f = f / h;
+ for (j = m; j <= high; j++) {
+ H[i][j] -= f * ort[j];
+ }
+ }
+
+ ort[m] = scale * ort[m];
+ H[m][m - 1] = scale * g;
+ }
+ }
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < n; j++) {
+ V[i][j] = (i === j ? 1 : 0);
+ }
+ }
+
+ for (m = high - 1; m >= low + 1; m--) {
+ if (H[m][m - 1] !== 0) {
+ for (i = m + 1; i <= high; i++) {
+ ort[i] = H[i][m - 1];
+ }
+
+ for (j = m; j <= high; j++) {
+ g = 0;
+ for (i = m; i <= high; i++) {
+ g += ort[i] * V[i][j];
+ }
+
+ g = (g / ort[m]) / H[m][m - 1];
+ for (i = m; i <= high; i++) {
+ V[i][j] += g * ort[i];
+ }
+ }
+ }
+ }
+ }
+
+ function hqr2(nn, e, d, V, H) {
+ var n = nn - 1,
+ low = 0,
+ high = nn - 1,
+ eps = Math.pow(2, -52),
+ exshift = 0,
+ norm = 0,
+ p = 0,
+ q = 0,
+ r = 0,
+ s = 0,
+ z = 0,
+ iter = 0,
+ i, j, k, l, m, t, w, x, y,
+ ra, sa, vr, vi,
+ notlast, cdivres;
+
+ for (i = 0; i < nn; i++) {
+ if (i < low || i > high) {
+ d[i] = H[i][i];
+ e[i] = 0;
+ }
+
+ for (j = Math.max(i - 1, 0); j < nn; j++) {
+ norm = norm + Math.abs(H[i][j]);
+ }
+ }
+
+ while (n >= low) {
+ l = n;
+ while (l > low) {
+ s = Math.abs(H[l - 1][l - 1]) + Math.abs(H[l][l]);
+ if (s === 0) {
+ s = norm;
+ }
+ if (Math.abs(H[l][l - 1]) < eps * s) {
+ break;
+ }
+ l--;
+ }
+
+ if (l === n) {
+ H[n][n] = H[n][n] + exshift;
+ d[n] = H[n][n];
+ e[n] = 0;
+ n--;
+ iter = 0;
+ } else if (l === n - 1) {
+ w = H[n][n - 1] * H[n - 1][n];
+ p = (H[n - 1][n - 1] - H[n][n]) / 2;
+ q = p * p + w;
+ z = Math.sqrt(Math.abs(q));
+ H[n][n] = H[n][n] + exshift;
+ H[n - 1][n - 1] = H[n - 1][n - 1] + exshift;
+ x = H[n][n];
+
+ if (q >= 0) {
+ z = (p >= 0) ? (p + z) : (p - z);
+ d[n - 1] = x + z;
+ d[n] = d[n - 1];
+ if (z !== 0) {
+ d[n] = x - w / z;
+ }
+ e[n - 1] = 0;
+ e[n] = 0;
+ x = H[n][n - 1];
+ s = Math.abs(x) + Math.abs(z);
+ p = x / s;
+ q = z / s;
+ r = Math.sqrt(p * p + q * q);
+ p = p / r;
+ q = q / r;
+
+ for (j = n - 1; j < nn; j++) {
+ z = H[n - 1][j];
+ H[n - 1][j] = q * z + p * H[n][j];
+ H[n][j] = q * H[n][j] - p * z;
+ }
+
+ for (i = 0; i <= n; i++) {
+ z = H[i][n - 1];
+ H[i][n - 1] = q * z + p * H[i][n];
+ H[i][n] = q * H[i][n] - p * z;
+ }
+
+ for (i = low; i <= high; i++) {
+ z = V[i][n - 1];
+ V[i][n - 1] = q * z + p * V[i][n];
+ V[i][n] = q * V[i][n] - p * z;
+ }
+ } else {
+ d[n - 1] = x + p;
+ d[n] = x + p;
+ e[n - 1] = z;
+ e[n] = -z;
+ }
+
+ n = n - 2;
+ iter = 0;
+ } else {
+ x = H[n][n];
+ y = 0;
+ w = 0;
+ if (l < n) {
+ y = H[n - 1][n - 1];
+ w = H[n][n - 1] * H[n - 1][n];
+ }
+
+ if (iter === 10) {
+ exshift += x;
+ for (i = low; i <= n; i++) {
+ H[i][i] -= x;
+ }
+ s = Math.abs(H[n][n - 1]) + Math.abs(H[n - 1][n - 2]);
+ x = y = 0.75 * s;
+ w = -0.4375 * s * s;
+ }
+
+ if (iter === 30) {
+ s = (y - x) / 2;
+ s = s * s + w;
+ if (s > 0) {
+ s = Math.sqrt(s);
+ if (y < x) {
+ s = -s;
+ }
+ s = x - w / ((y - x) / 2 + s);
+ for (i = low; i <= n; i++) {
+ H[i][i] -= s;
+ }
+ exshift += s;
+ x = y = w = 0.964;
+ }
+ }
+
+ iter = iter + 1;
+
+ m = n - 2;
+ while (m >= l) {
+ z = H[m][m];
+ r = x - z;
+ s = y - z;
+ p = (r * s - w) / H[m + 1][m] + H[m][m + 1];
+ q = H[m + 1][m + 1] - z - r - s;
+ r = H[m + 2][m + 1];
+ s = Math.abs(p) + Math.abs(q) + Math.abs(r);
+ p = p / s;
+ q = q / s;
+ r = r / s;
+ if (m === l) {
+ break;
+ }
+ if (Math.abs(H[m][m - 1]) * (Math.abs(q) + Math.abs(r)) < eps * (Math.abs(p) * (Math.abs(H[m - 1][m - 1]) + Math.abs(z) + Math.abs(H[m + 1][m + 1])))) {
+ break;
+ }
+ m--;
+ }
+
+ for (i = m + 2; i <= n; i++) {
+ H[i][i - 2] = 0;
+ if (i > m + 2) {
+ H[i][i - 3] = 0;
+ }
+ }
+
+ for (k = m; k <= n - 1; k++) {
+ notlast = (k !== n - 1);
+ if (k !== m) {
+ p = H[k][k - 1];
+ q = H[k + 1][k - 1];
+ r = (notlast ? H[k + 2][k - 1] : 0);
+ x = Math.abs(p) + Math.abs(q) + Math.abs(r);
+ if (x !== 0) {
+ p = p / x;
+ q = q / x;
+ r = r / x;
+ }
+ }
+
+ if (x === 0) {
+ break;
+ }
+
+ s = Math.sqrt(p * p + q * q + r * r);
+ if (p < 0) {
+ s = -s;
+ }
+
+ if (s !== 0) {
+ if (k !== m) {
+ H[k][k - 1] = -s * x;
+ } else if (l !== m) {
+ H[k][k - 1] = -H[k][k - 1];
+ }
+
+ p = p + s;
+ x = p / s;
+ y = q / s;
+ z = r / s;
+ q = q / p;
+ r = r / p;
+
+ for (j = k; j < nn; j++) {
+ p = H[k][j] + q * H[k + 1][j];
+ if (notlast) {
+ p = p + r * H[k + 2][j];
+ H[k + 2][j] = H[k + 2][j] - p * z;
+ }
+
+ H[k][j] = H[k][j] - p * x;
+ H[k + 1][j] = H[k + 1][j] - p * y;
+ }
+
+ for (i = 0; i <= Math.min(n, k + 3); i++) {
+ p = x * H[i][k] + y * H[i][k + 1];
+ if (notlast) {
+ p = p + z * H[i][k + 2];
+ H[i][k + 2] = H[i][k + 2] - p * r;
+ }
+
+ H[i][k] = H[i][k] - p;
+ H[i][k + 1] = H[i][k + 1] - p * q;
+ }
+
+ for (i = low; i <= high; i++) {
+ p = x * V[i][k] + y * V[i][k + 1];
+ if (notlast) {
+ p = p + z * V[i][k + 2];
+ V[i][k + 2] = V[i][k + 2] - p * r;
+ }
+
+ V[i][k] = V[i][k] - p;
+ V[i][k + 1] = V[i][k + 1] - p * q;
+ }
+ }
+ }
+ }
+ }
+
+ if (norm === 0) {
+ return;
+ }
+
+ for (n = nn - 1; n >= 0; n--) {
+ p = d[n];
+ q = e[n];
+
+ if (q === 0) {
+ l = n;
+ H[n][n] = 1;
+ for (i = n - 1; i >= 0; i--) {
+ w = H[i][i] - p;
+ r = 0;
+ for (j = l; j <= n; j++) {
+ r = r + H[i][j] * H[j][n];
+ }
+
+ if (e[i] < 0) {
+ z = w;
+ s = r;
+ } else {
+ l = i;
+ if (e[i] === 0) {
+ H[i][n] = (w !== 0) ? (-r / w) : (-r / (eps * norm));
+ } else {
+ x = H[i][i + 1];
+ y = H[i + 1][i];
+ q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
+ t = (x * s - z * r) / q;
+ H[i][n] = t;
+ H[i + 1][n] = (Math.abs(x) > Math.abs(z)) ? ((-r - w * t) / x) : ((-s - y * t) / z);
+ }
+
+ t = Math.abs(H[i][n]);
+ if ((eps * t) * t > 1) {
+ for (j = i; j <= n; j++) {
+ H[j][n] = H[j][n] / t;
+ }
+ }
+ }
+ }
+ } else if (q < 0) {
+ l = n - 1;
+
+ if (Math.abs(H[n][n - 1]) > Math.abs(H[n - 1][n])) {
+ H[n - 1][n - 1] = q / H[n][n - 1];
+ H[n - 1][n] = -(H[n][n] - p) / H[n][n - 1];
+ } else {
+ cdivres = cdiv(0, -H[n - 1][n], H[n - 1][n - 1] - p, q);
+ H[n - 1][n - 1] = cdivres[0];
+ H[n - 1][n] = cdivres[1];
+ }
+
+ H[n][n - 1] = 0;
+ H[n][n] = 1;
+ for (i = n - 2; i >= 0; i--) {
+ ra = 0;
+ sa = 0;
+ for (j = l; j <= n; j++) {
+ ra = ra + H[i][j] * H[j][n - 1];
+ sa = sa + H[i][j] * H[j][n];
+ }
+
+ w = H[i][i] - p;
+
+ if (e[i] < 0) {
+ z = w;
+ r = ra;
+ s = sa;
+ } else {
+ l = i;
+ if (e[i] === 0) {
+ cdivres = cdiv(-ra, -sa, w, q);
+ H[i][n - 1] = cdivres[0];
+ H[i][n] = cdivres[1];
+ } else {
+ x = H[i][i + 1];
+ y = H[i + 1][i];
+ vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
+ vi = (d[i] - p) * 2 * q;
+ if (vr === 0 && vi === 0) {
+ vr = eps * norm * (Math.abs(w) + Math.abs(q) + Math.abs(x) + Math.abs(y) + Math.abs(z));
+ }
+ cdivres = cdiv(x * r - z * ra + q * sa, x * s - z * sa - q * ra, vr, vi);
+ H[i][n - 1] = cdivres[0];
+ H[i][n] = cdivres[1];
+ if (Math.abs(x) > (Math.abs(z) + Math.abs(q))) {
+ H[i + 1][n - 1] = (-ra - w * H[i][n - 1] + q * H[i][n]) / x;
+ H[i + 1][n] = (-sa - w * H[i][n] - q * H[i][n - 1]) / x;
+ } else {
+ cdivres = cdiv(-r - y * H[i][n - 1], -s - y * H[i][n], z, q);
+ H[i + 1][n - 1] = cdivres[0];
+ H[i + 1][n] = cdivres[1];
+ }
+ }
+
+ t = Math.max(Math.abs(H[i][n - 1]), Math.abs(H[i][n]));
+ if ((eps * t) * t > 1) {
+ for (j = i; j <= n; j++) {
+ H[j][n - 1] = H[j][n - 1] / t;
+ H[j][n] = H[j][n] / t;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < nn; i++) {
+ if (i < low || i > high) {
+ for (j = i; j < nn; j++) {
+ V[i][j] = H[i][j];
+ }
+ }
+ }
+
+ for (j = nn - 1; j >= low; j--) {
+ for (i = low; i <= high; i++) {
+ z = 0;
+ for (k = low; k <= Math.min(j, high); k++) {
+ z = z + V[i][k] * H[k][j];
+ }
+ V[i][j] = z;
+ }
+ }
+ }
+
+ function cdiv(xr, xi, yr, yi) {
+ var r, d;
+ if (Math.abs(yr) > Math.abs(yi)) {
+ r = yi / yr;
+ d = yr + r * yi;
+ return [(xr + r * xi) / d, (xi - r * xr) / d];
+ } else {
+ r = yr / yi;
+ d = yi + r * yr;
+ return [(r * xr + xi) / d, (r * xi - xr) / d];
+ }
+ }
+
+ MLMatrixDCEVD = EigenvalueDecomposition;
+}
+
+
+// ml-matrix src/dc/qr.js
+let MLMatrixDCQR;
+{
+ let Matrix = MLMatrixMatrix.Matrix;
+ let hypotenuse = MLMatrixDCUtil.hypotenuse;
+
+ //https://github.com/lutzroeder/Mapack/blob/master/Source/QrDecomposition.cs
+ function QrDecomposition(value) {
+ if (!(this instanceof QrDecomposition)) {
+ return new QrDecomposition(value);
+ }
+ value = Matrix.checkMatrix(value);
+
+ var qr = value.clone(),
+ m = value.rows,
+ n = value.columns,
+ rdiag = new Array(n),
+ i, j, k, s;
+
+ for (k = 0; k < n; k++) {
+ var nrm = 0;
+ for (i = k; i < m; i++) {
+ nrm = hypotenuse(nrm, qr[i][k]);
+ }
+ if (nrm !== 0) {
+ if (qr[k][k] < 0) {
+ nrm = -nrm;
+ }
+ for (i = k; i < m; i++) {
+ qr[i][k] /= nrm;
+ }
+ qr[k][k] += 1;
+ for (j = k + 1; j < n; j++) {
+ s = 0;
+ for (i = k; i < m; i++) {
+ s += qr[i][k] * qr[i][j];
+ }
+ s = -s / qr[k][k];
+ for (i = k; i < m; i++) {
+ qr[i][j] += s * qr[i][k];
+ }
+ }
+ }
+ rdiag[k] = -nrm;
+ }
+
+ this.QR = qr;
+ this.Rdiag = rdiag;
+ }
+
+ QrDecomposition.prototype = {
+ solve: function (value) {
+ value = Matrix.checkMatrix(value);
+
+ var qr = this.QR,
+ m = qr.rows;
+
+ if (value.rows !== m) {
+ throw new Error('Matrix row dimensions must agree');
+ }
+ if (!this.isFullRank()) {
+ throw new Error('Matrix is rank deficient');
+ }
+
+ var count = value.columns;
+ var X = value.clone();
+ var n = qr.columns;
+ var i, j, k, s;
+
+ for (k = 0; k < n; k++) {
+ for (j = 0; j < count; j++) {
+ s = 0;
+ for (i = k; i < m; i++) {
+ s += qr[i][k] * X[i][j];
+ }
+ s = -s / qr[k][k];
+ for (i = k; i < m; i++) {
+ X[i][j] += s * qr[i][k];
+ }
+ }
+ }
+ for (k = n - 1; k >= 0; k--) {
+ for (j = 0; j < count; j++) {
+ X[k][j] /= this.Rdiag[k];
+ }
+ for (i = 0; i < k; i++) {
+ for (j = 0; j < count; j++) {
+ X[i][j] -= X[k][j] * qr[i][k];
+ }
+ }
+ }
+
+ return X.subMatrix(0, n - 1, 0, count - 1);
+ },
+ isFullRank: function () {
+ var columns = this.QR.columns;
+ for (var i = 0; i < columns; i++) {
+ if (this.Rdiag[i] === 0) {
+ return false;
+ }
+ }
+ return true;
+ },
+ get upperTriangularMatrix() {
+ var qr = this.QR,
+ n = qr.columns,
+ X = new Matrix(n, n),
+ i, j;
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < n; j++) {
+ if (i < j) {
+ X[i][j] = qr[i][j];
+ } else if (i === j) {
+ X[i][j] = this.Rdiag[i];
+ } else {
+ X[i][j] = 0;
+ }
+ }
+ }
+ return X;
+ },
+ get orthogonalMatrix() {
+ var qr = this.QR,
+ rows = qr.rows,
+ columns = qr.columns,
+ X = new Matrix(rows, columns),
+ i, j, k, s;
+
+ for (k = columns - 1; k >= 0; k--) {
+ for (i = 0; i < rows; i++) {
+ X[i][k] = 0;
+ }
+ X[k][k] = 1;
+ for (j = k; j < columns; j++) {
+ if (qr[k][k] !== 0) {
+ s = 0;
+ for (i = k; i < rows; i++) {
+ s += qr[i][k] * X[i][j];
+ }
+
+ s = -s / qr[k][k];
+
+ for (i = k; i < rows; i++) {
+ X[i][j] += s * qr[i][k];
+ }
+ }
+ }
+ }
+ return X;
+ }
+ };
+
+ MLMatrixDCQR = QrDecomposition;
+}
+
+// ml-matric src/decompositions.js
+let MLMatrixDecompositions = {};
+{
+ let Matrix = MLMatrixMatrix.Matrix;
+
+ let SingularValueDecomposition = MLMatrixDCSVD;
+ let EigenvalueDecomposition = MLMatrixDCEVD;
+ let LuDecomposition = MLMatrixDCLU;
+ let QrDecomposition = MLMatrixDCQR
+ let CholeskyDecomposition = MLMatrixDCCholesky;
+
+ function inverse(matrix) {
+ matrix = Matrix.checkMatrix(matrix);
+ return solve(matrix, Matrix.eye(matrix.rows));
+ }
+
+ /**
+ * Returns the inverse
+ * @memberOf Matrix
+ * @static
+ * @param {Matrix} matrix
+ * @return {Matrix} matrix
+ * @alias inv
+ */
+ Matrix.inverse = Matrix.inv = inverse;
+
+ /**
+ * Returns the inverse
+ * @memberOf Matrix
+ * @static
+ * @param {Matrix} matrix
+ * @return {Matrix} matrix
+ * @alias inv
+ */
+ Matrix.prototype.inverse = Matrix.prototype.inv = function () {
+ return inverse(this);
+ };
+
+ function solve(leftHandSide, rightHandSide) {
+ leftHandSide = Matrix.checkMatrix(leftHandSide);
+ rightHandSide = Matrix.checkMatrix(rightHandSide);
+ return leftHandSide.isSquare() ? new LuDecomposition(leftHandSide).solve(rightHandSide) : new QrDecomposition(leftHandSide).solve(rightHandSide);
+ }
+
+ Matrix.solve = solve;
+ Matrix.prototype.solve = function (other) {
+ return solve(this, other);
+ };
+
+ MLMatrixDecompositions = {
+ SingularValueDecomposition: SingularValueDecomposition,
+ SVD: SingularValueDecomposition,
+ EigenvalueDecomposition: EigenvalueDecomposition,
+ EVD: EigenvalueDecomposition,
+ LuDecomposition: LuDecomposition,
+ LU: LuDecomposition,
+ QrDecomposition: QrDecomposition,
+ QR: QrDecomposition,
+ CholeskyDecomposition: CholeskyDecomposition,
+ CHO: CholeskyDecomposition,
+ inverse: inverse,
+ solve: solve
+ };
+}
+
+// ml-matrix src/index.js
+let MLMatrix = {};
+{
+ MLMatrix = MLMatrixMatrix.Matrix;
+ MLMatrix.Decompositions = MLMatrix.DC = MLMatrixDecompositions;
+}
+
+// feedforward-neural-networks utils.js
+let FeedforwardNeuralNetworksUtils;
+{
+ let Matrix = MLMatrix;
+
+ /**
+ * @private
+ * Retrieves the sum at each row of the given matrix.
+ * @param {Matrix} matrix
+ * @return {Matrix}
+ */
+ function sumRow(matrix) {
+ var sum = Matrix.zeros(matrix.rows, 1);
+ for (var i = 0; i < matrix.rows; ++i) {
+ for (var j = 0; j < matrix.columns; ++j) {
+ sum[i][0] += matrix[i][j];
+ }
+ }
+ return sum;
+ }
+
+ /**
+ * @private
+ * Retrieves the sum at each column of the given matrix.
+ * @param {Matrix} matrix
+ * @return {Matrix}
+ */
+ function sumCol(matrix) {
+ var sum = Matrix.zeros(1, matrix.columns);
+ for (var i = 0; i < matrix.rows; ++i) {
+ for (var j = 0; j < matrix.columns; ++j) {
+ sum[0][j] += matrix[i][j];
+ }
+ }
+ return sum;
+ }
+
+ /**
+ * @private
+ * Method that given an array of labels(predictions), returns two dictionaries, one to transform from labels to
+ * numbers and other in the reverse way
+ * @param {Array} array
+ * @return {object}
+ */
+ function dictOutputs(array) {
+ var inputs = {}, outputs = {}, l = array.length, index = 0;
+ for (var i = 0; i < l; i += 1) {
+ if (inputs[array[i]] === undefined) {
+ inputs[array[i]] = index;
+ outputs[index] = array[i];
+ index++;
+ }
+ }
+
+ return {
+ inputs: inputs,
+ outputs: outputs
+ };
+ }
+
+ FeedforwardNeuralNetworksUtils = {
+ dictOutputs: dictOutputs,
+ sumCol: sumCol,
+ sumRow: sumRow
+ };
+}
+
+// feedforward-neural-networks activationFunctions.js
+let FeedforwardNeuralNetworksActivationFunctions;
+{
+ function logistic(val) {
+ return 1 / (1 + Math.exp(-val));
+ }
+
+ function expELU(val, param) {
+ return val < 0 ? param * (Math.exp(val) - 1) : val;
+ }
+
+ function softExponential(val, param) {
+ if (param < 0) {
+ return -Math.log(1 - param * (val + param)) / param;
+ }
+ if (param > 0) {
+ return ((Math.exp(param * val) - 1) / param) + param;
+ }
+ return val;
+ }
+
+ function softExponentialPrime(val, param) {
+ if (param < 0) {
+ return 1 / (1 - param * (param + val));
+ } else {
+ return Math.exp(param * val);
+ }
+ }
+
+ const ACTIVATION_FUNCTIONS = {
+ 'tanh': {
+ activation: Math.tanh,
+ derivate: val => 1 - (val * val)
+ },
+ 'identity': {
+ activation: val => val,
+ derivate: () => 1
+ },
+ 'logistic': {
+ activation: logistic,
+ derivate: val => logistic(val) * (1 - logistic(val))
+ },
+ 'arctan': {
+ activation: Math.atan,
+ derivate: val => 1 / (val * val + 1)
+ },
+ 'softsign': {
+ activation: val => val / (1 + Math.abs(val)),
+ derivate: val => 1 / ((1 + Math.abs(val)) * (1 + Math.abs(val)))
+ },
+ 'relu': {
+ activation: val => val < 0 ? 0 : val,
+ derivate: val => val < 0 ? 0 : 1
+ },
+ 'softplus': {
+ activation: val => Math.log(1 + Math.exp(val)),
+ derivate: val => 1 / (1 + Math.exp(-val))
+ },
+ 'bent': {
+ activation: val => ((Math.sqrt(val * val + 1) - 1) / 2) + val,
+ derivate: val => (val / (2 * Math.sqrt(val * val + 1))) + 1
+ },
+ 'sinusoid': {
+ activation: Math.sin,
+ derivate: Math.cos
+ },
+ 'sinc': {
+ activation: val => val === 0 ? 1 : Math.sin(val) / val,
+ derivate: val => val === 0 ? 0 : (Math.cos(val) / val) - (Math.sin(val) / (val * val))
+ },
+ 'gaussian': {
+ activation: val => Math.exp(-(val * val)),
+ derivate: val => -2 * val * Math.exp(-(val * val))
+ },
+ 'parametric-relu': {
+ activation: (val, param) => val < 0 ? param * val : val,
+ derivate: (val, param) => val < 0 ? param : 1
+ },
+ 'exponential-elu': {
+ activation: expELU,
+ derivate: (val, param) => val < 0 ? expELU(val, param) + param : 1
+ },
+ 'soft-exponential': {
+ activation: softExponential,
+ derivate: softExponentialPrime
+ }
+ };
+
+ FeedforwardNeuralNetworksActivationFunctions = ACTIVATION_FUNCTIONS;
+}
+
+// feedforward-neural-networks Layer.js
+let FeedforwardNeuralNetworksLayer;
+{
+ let Matrix = MLMatrix;
+
+ let Utils = FeedforwardNeuralNetworksUtils;
+ const ACTIVATION_FUNCTIONS = FeedforwardNeuralNetworksActivationFunctions;
+
+ class Layer {
+ /**
+ * @private
+ * Create a new layer with the given options
+ * @param {object} options
+ * @param {number} [options.inputSize] - Number of conections that enter the neurons.
+ * @param {number} [options.outputSize] - Number of conections that leave the neurons.
+ * @param {number} [options.regularization] - Regularization parameter.
+ * @param {number} [options.epsilon] - Learning rate parameter.
+ * @param {string} [options.activation] - Activation function parameter from the FeedForwardNeuralNetwork class.
+ * @param {number} [options.activationParam] - Activation parameter if needed.
+ */
+ constructor(options) {
+ this.inputSize = options.inputSize;
+ this.outputSize = options.outputSize;
+ this.regularization = options.regularization;
+ this.epsilon = options.epsilon;
+ this.activation = options.activation;
+ this.activationParam = options.activationParam;
+
+ var selectedFunction = ACTIVATION_FUNCTIONS[options.activation];
+ var params = selectedFunction.activation.length;
+
+ var actFunction = params > 1 ? val => selectedFunction.activation(val, options.activationParam) : selectedFunction.activation;
+ var derFunction = params > 1 ? val => selectedFunction.derivate(val, options.activationParam) : selectedFunction.derivate;
+
+ this.activationFunction = function (i, j) {
+ this[i][j] = actFunction(this[i][j]);
+ };
+ this.derivate = function (i, j) {
+ this[i][j] = derFunction(this[i][j]);
+ };
+
+ if (options.model) {
+ // load model
+ this.W = Matrix.checkMatrix(options.W);
+ this.b = Matrix.checkMatrix(options.b);
+
+ } else {
+ // default constructor
+
+ this.W = Matrix.rand(this.inputSize, this.outputSize);
+ this.b = Matrix.zeros(1, this.outputSize);
+
+ this.W.apply(function (i, j) {
+ this[i][j] /= Math.sqrt(options.inputSize);
+ });
+ }
+ }
+
+ /**
+ * @private
+ * propagate the given input through the current layer.
+ * @param {Matrix} X - input.
+ * @return {Matrix} output at the current layer.
+ */
+ forward(X) {
+ var z = X.mmul(this.W).addRowVector(this.b);
+ z.apply(this.activationFunction);
+ this.a = z.clone();
+ return z;
+ }
+
+ /**
+ * @private
+ * apply backpropagation algorithm at the current layer
+ * @param {Matrix} delta - delta values estimated at the following layer.
+ * @param {Matrix} a - 'a' values from the following layer.
+ * @return {Matrix} the new delta values for the next layer.
+ */
+ backpropagation(delta, a) {
+ this.dW = a.transposeView().mmul(delta);
+ this.db = Utils.sumCol(delta);
+
+ var aCopy = a.clone();
+ return delta.mmul(this.W.transposeView()).mul(aCopy.apply(this.derivate));
+ }
+
+ /**
+ * @private
+ * Function that updates the weights at the current layer with the derivatives.
+ */
+ update() {
+ this.dW.add(this.W.clone().mul(this.regularization));
+ this.W.add(this.dW.mul(-this.epsilon));
+ this.b.add(this.db.mul(-this.epsilon));
+ }
+
+ /**
+ * @private
+ * Export the current layer to JSON.
+ * @return {object} model
+ */
+ toJSON() {
+ return {
+ model: 'Layer',
+ inputSize: this.inputSize,
+ outputSize: this.outputSize,
+ regularization: this.regularization,
+ epsilon: this.epsilon,
+ activation: this.activation,
+ W: this.W,
+ b: this.b
+ };
+ }
+
+ /**
+ * @private
+ * Creates a new Layer with the given model.
+ * @param {object} model
+ * @return {Layer}
+ */
+ static load(model) {
+ if (model.model !== 'Layer') {
+ throw new RangeError('the current model is not a Layer model');
+ }
+ return new Layer(model);
+ }
+
+ }
+
+ FeedforwardNeuralNetworksLayer = Layer;
+}
+
+// feedforward-neural-networks OutputLayer.js
+let FeedforwardNeuralNetworksOutputLayer;
+{
+ let Layer = FeedforwardNeuralNetworksLayer;
+
+ class OutputLayer extends Layer {
+ constructor(options) {
+ super(options);
+
+ this.activationFunction = function (i, j) {
+ this[i][j] = Math.exp(this[i][j]);
+ };
+ }
+
+ static load(model) {
+ if (model.model !== 'Layer') {
+ throw new RangeError('the current model is not a Layer model');
+ }
+
+ return new OutputLayer(model);
+ }
+ }
+
+ FeedforwardNeuralNetworksOutputLayer = OutputLayer;
+}
+
+// feedforward-neural-networks FeedForwardNeuralNetwork.js
+let FeedforwardNeuralNetwork;
+{
+ const Matrix = MLMatrix;
+
+ const Layer = FeedforwardNeuralNetworksLayer;
+ const OutputLayer = FeedforwardNeuralNetworksOutputLayer;
+ const Utils = FeedforwardNeuralNetworksUtils;
+ const ACTIVATION_FUNCTIONS = FeedforwardNeuralNetworksActivationFunctions;
+
+ class FeedForwardNeuralNetworks {
+
+ /**
+ * Create a new Feedforword neural network model.
+ * @param {object} options
+ * @param {Array} [options.hiddenLayers=[10]] - Array that contains the sizes of the hidden layers.
+ * @oaram {number} [options.iterations=50] - Number of iterations at the training step.
+ * @param {number} [options.learningRate=0.01] - Learning rate of the neural net (also known as epsilon).
+ * @poram {number} [options.regularization=0.01] - Regularization parameter af the neural net.
+ * @poram {string} [options.activation='tanh'] - activation function to be used. (options: 'tanh'(default),
+ * 'identity', 'logistic', 'arctan', 'softsign', 'relu', 'softplus', 'bent', 'sinusoid', 'sinc', 'gaussian').
+ * (single-parametric options: 'parametric-relu', 'exponential-relu', 'soft-exponential').
+ * @param {number} [options.activationParam=1] - if the selected activation function needs a parameter.
+ */
+ constructor(options) {
+ options = options || {};
+ if (options.model) {
+ // load network
+ this.hiddenLayers = options.hiddenLayers;
+ this.iterations = options.iterations;
+ this.learningRate = options.learningRate;
+ this.regularization = options.regularization;
+ this.dicts = options.dicts;
+ this.activation = options.activation;
+ this.activationParam = options.activationParam;
+ this.model = new Array(options.layers.length);
+
+ for (var i = 0; i < this.model.length - 1; ++i) {
+ this.model[i] = Layer.load(options.layers[i]);
+ }
+ this.model[this.model.length - 1] = OutputLayer.load(options.layers[this.model.length - 1]);
+ } else {
+ // default constructor
+ this.hiddenLayers = options.hiddenLayers === undefined ? [10] : options.hiddenLayers;
+ this.iterations = options.iterations === undefined ? 50 : options.iterations;
+
+ this.learningRate = options.learningRate === undefined ? 0.01 : options.learningRate;
+ //this.momentum = options.momentum === undefined ? 0.1 : options.momentum;
+ this.regularization = options.regularization === undefined ? 0.01 : options.regularization;
+
+ this.activation = options.activation === undefined ? 'tanh' : options.activation;
+ this.activationParam = options.activationParam === undefined ? 1 : options.activationParam;
+ if (!(this.activation in Object.keys(ACTIVATION_FUNCTIONS))) {
+ this.activation = 'tanh';
+ }
+ }
+ }
+
+ /**
+ * @private
+ * Function that build and initialize the neural net.
+ * @param {number} inputSize - total of features to fit.
+ * @param {number} outputSize - total of labels of the prediction set.
+ */
+ buildNetwork(inputSize, outputSize) {
+ var size = 2 + (this.hiddenLayers.length - 1);
+ this.model = new Array(size);
+
+ // input layer
+ this.model[0] = new Layer({
+ inputSize: inputSize,
+ outputSize: this.hiddenLayers[0],
+ activation: this.activation,
+ activationParam: this.activationParam,
+ regularization: this.regularization,
+ epsilon: this.learningRate
+ });
+
+ // hidden layers
+ for (var i = 1; i < this.hiddenLayers.length; ++i) {
+ this.model[i] = new Layer({
+ inputSize: this.hiddenLayers[i - 1],
+ outputSize: this.hiddenLayers[i],
+ activation: this.activation,
+ activationParam: this.activationParam,
+ regularization: this.regularization,
+ epsilon: this.learningRate
+ });
+ }
+
+ // output layer
+ this.model[size - 1] = new OutputLayer({
+ inputSize: this.hiddenLayers[this.hiddenLayers.length - 1],
+ outputSize: outputSize,
+ activation: this.activation,
+ activationParam: this.activationParam,
+ regularization: this.regularization,
+ epsilon: this.learningRate
+ });
+ }
+
+ /**
+ * Train the neural net with the given features and labels.
+ * @param {Matrix|Array} features
+ * @param {Matrix|Array} labels
+ */
+ train(features, labels) {
+ features = Matrix.checkMatrix(features);
+ this.dicts = Utils.dictOutputs(labels);
+
+ var inputSize = features.columns;
+ var outputSize = Object.keys(this.dicts.inputs).length;
+
+ this.buildNetwork(inputSize, outputSize);
+
+ for (var i = 0; i < this.iterations; ++i) {
+ var probabilities = this.propagate(features);
+ this.backpropagation(features, labels, probabilities);
+ }
+ }
+
+ /**
+ * @private
+ * Propagate the input(training set) and retrives the probabilities of each class.
+ * @param {Matrix} X
+ * @return {Matrix} probabilities of each class.
+ */
+ propagate(X) {
+ var input = X;
+ for (var i = 0; i < this.model.length; ++i) {
+ //console.log(i);
+ input = this.model[i].forward(input);
+ }
+
+ // get probabilities
+ return input.divColumnVector(Utils.sumRow(input));
+ }
+
+ /**
+ * @private
+ * Function that applies the backpropagation algorithm on each layer of the network
+ * in order to fit the features and labels.
+ * @param {Matrix} features
+ * @param {Array} labels
+ * @param {Matrix} probabilities - probabilities of each class of the feature set.
+ */
+ backpropagation(features, labels, probabilities) {
+ for (var i = 0; i < probabilities.length; ++i) {
+ probabilities[i][this.dicts.inputs[labels[i]]] -= 1;
+ }
+
+ // remember, the last delta doesn't matter
+ var delta = probabilities;
+ for (i = this.model.length - 1; i >= 0; --i) {
+ var a = i > 0 ? this.model[i - 1].a : features;
+ delta = this.model[i].backpropagation(delta, a);
+ }
+
+ for (i = 0; i < this.model.length; ++i) {
+ this.model[i].update();
+ }
+ }
+
+ /**
+ * Predict the output given the feature set.
+ * @param {Array|Matrix} features
+ * @return {Array}
+ */
+ predict(features) {
+ features = Matrix.checkMatrix(features);
+ var outputs = new Array(features.rows);
+ var probabilities = this.propagate(features);
+ for (var i = 0; i < features.rows; ++i) {
+ outputs[i] = this.dicts.outputs[probabilities.maxRowIndex(i)[1]];
+ }
+
+ return outputs;
+ }
+
+ /**
+ * Export the current model to JSOM.
+ * @return {object} model
+ */
+ toJSON() {
+ var model = {
+ model: 'FNN',
+ hiddenLayers: this.hiddenLayers,
+ iterations: this.iterations,
+ learningRate: this.learningRate,
+ regularization: this.regularization,
+ activation: this.activation,
+ activationParam: this.activationParam,
+ dicts: this.dicts,
+ layers: new Array(this.model.length)
+ };
+
+ for (var i = 0; i < this.model.length; ++i) {
+ model.layers[i] = this.model[i].toJSON();
+ }
+
+ return model;
+ }
+
+ /**
+ * Load a Feedforward Neural Network with the current model.
+ * @param {object} model
+ * @return {FeedForwardNeuralNetworks}
+ */
+ static load(model) {
+ if (model.model !== 'FNN') {
+ throw new RangeError('the current model is not a feed forward network');
+ }
+
+ return new FeedForwardNeuralNetworks(model);
+ }
+ }
+
+ FeedforwardNeuralNetwork = FeedForwardNeuralNetworks;
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/ml_benchmark.js b/third_party/webkit/PerformanceTests/ARES-6/ml_benchmark.js
new file mode 100644
index 0000000000..fa4ee17fe7
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/ml_benchmark.js
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+const MLBenchmarkCode = String.raw`
+<script src="ml/index.js"></script>
+<script src="ml/benchmark.js"></script>
+<script>
+var results = [];
+var benchmark = new MLBenchmark();
+var numIterations = 60;
+for (var i = 0; i < numIterations; ++i) {
+ var before = currentTime();
+ benchmark.runIteration();
+ var after = currentTime();
+ results.push(after - before);
+}
+reportResult(results);
+</script>`;
+
+
+let runMLBenchmark = null;
+if (!isInBrowser) {
+ let sources = [
+ "ml/index.js"
+ , "ml/benchmark.js"
+ ];
+
+ runMLBenchmark = makeBenchmarkRunner(sources, "MLBenchmark", 60);
+}
+
+const MLBenchmarkRunner = {
+ name: "ML",
+ code: MLBenchmarkCode,
+ run: runMLBenchmark,
+ cells: {}
+};
+
+if (isInBrowser) {
+ MLBenchmarkRunner.cells = {
+ firstIteration: document.getElementById("MLFirstIteration"),
+ averageWorstCase: document.getElementById("MLAverageWorstCase"),
+ steadyState: document.getElementById("MLSteadyState"),
+ message: document.getElementById("MLMessage")
+ };
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/results.js b/third_party/webkit/PerformanceTests/ARES-6/results.js
new file mode 100644
index 0000000000..f148d09a64
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/results.js
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class Results {
+ constructor(benchmark)
+ {
+ this._benchmark = benchmark;
+ for (let subResult of Results.subResults)
+ this[subResult] = new Stats(benchmark.cells[subResult], subResult);
+ }
+
+ get benchmark() { return this._benchmark; }
+
+ reset()
+ {
+ for (let subResult of Results.subResults)
+ this[subResult].reset();
+ }
+
+ reportRunning()
+ {
+ if (isInBrowser)
+ this._benchmark.cells.message.classList.add('running');
+ }
+
+ reportDone()
+ {
+ if (isInBrowser)
+ this._benchmark.cells.message.classList.remove('running');
+ }
+
+ reportResult(times)
+ {
+ if (times.length < 5)
+ throw new Error("We expect >= 5 iterations");
+
+ this.firstIteration.add(times[0]);
+ let steadyTimes = times.slice(1).sort((a, b) => b - a); // Sort in reverse order.
+ this.averageWorstCase.add((steadyTimes[0] + steadyTimes[1] + steadyTimes[2] + steadyTimes[3]) / 4);
+ this.steadyState.add(steadyTimes.reduce((previous, current) => previous + current) / steadyTimes.length);
+ this.reportDone();
+ }
+
+ reportError(message, url, lineNumber)
+ {
+ if (isInBrowser) {
+ this._benchmark.cells.message.classList.remove('running');
+ this._benchmark.cells.message.classList.add('failed');
+ } else
+ print("Failed running benchmark");
+ }
+}
+
+Results.subResults = ["firstIteration", "averageWorstCase", "steadyState"];
diff --git a/third_party/webkit/PerformanceTests/ARES-6/stats.js b/third_party/webkit/PerformanceTests/ARES-6/stats.js
new file mode 100644
index 0000000000..28272af6d1
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/stats.js
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class Stats {
+ constructor(cell, prefix)
+ {
+ this._cell = cell;
+ this._data = [];
+ this._prefix = "";
+ if (!isInBrowser && prefix) {
+ this._prefix = prefix + ": ";
+ if (this._prefix.length < 20)
+ this._prefix += " ".repeat(20 - this._prefix.length);
+ }
+ }
+
+ reset(...data)
+ {
+ this._data = data;
+ this._update();
+ }
+
+ add(...data)
+ {
+ this._data.push(...data);
+ this._update();
+ }
+
+ get numIterations() { return this._data.length; }
+ valueForIteration(index) { return this._data[index]; }
+
+ get result()
+ {
+ var tDistribution = [NaN, NaN, 12.71, 4.30, 3.18, 2.78, 2.57, 2.45, 2.36, 2.31, 2.26, 2.23, 2.20, 2.18, 2.16, 2.14, 2.13, 2.12, 2.11, 2.10, 2.09, 2.09, 2.08, 2.07, 2.07, 2.06, 2.06, 2.06, 2.05, 2.05, 2.05, 2.04, 2.04, 2.04, 2.03, 2.03, 2.03, 2.03, 2.03, 2.02, 2.02, 2.02, 2.02, 2.02, 2.02, 2.02, 2.01, 2.01, 2.01, 2.01, 2.01, 2.01, 2.01, 2.01, 2.01, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.96];
+ var tMax = tDistribution.length;
+ var tLimit = 1.96;
+
+ function tDist(n)
+ {
+ if (n > tMax)
+ return tLimit;
+ return tDistribution[n];
+ }
+
+ let sum = 0;
+ let n = 0;
+ for (let datum of this._data) {
+ sum += datum;
+ n++;
+ }
+
+ let mean = sum / n;
+
+ if (n <= 2)
+ return {n, mean};
+
+ let sumForStdDev = 0;
+ for (let datum of this._data)
+ sumForStdDev += Math.pow(datum - mean, 2);
+ let standardDeviation = Math.sqrt(sumForStdDev / (n - 1));
+ let standardError = standardDeviation / Math.sqrt(n);
+ let interval = tDist(n) * standardError;
+ return {n, mean, interval};
+ }
+
+ toString()
+ {
+ let result = this.result;
+
+ if (!result.n) {
+ if (isInBrowser)
+ return `<span class="value">\&#8709;</span><span class="units">ms</span>`;
+ return `${this._prefix}\&#x2b14;ms`;
+ }
+
+ if (result.mean != result.mean)
+ return "ERROR";
+
+ if ("interval" in result) {
+ if (isInBrowser)
+ return `<span class="value">${this._prefix}${result.mean.toFixed(2)}</span><span class="margin"> &plusmn;${result.interval.toFixed(2)}</span><span class="units">ms</span>`;
+ return `${this._prefix}${result.mean.toFixed(2)} +- ${result.interval.toFixed(2)} ms`;
+ }
+
+ if (isInBrowser)
+ return `<span class="value">${this._prefix}${result.mean.toFixed(2)}</span><span class="units">ms</span>`;
+ return `${this._prefix}${result.mean.toFixed(2)} ms`;
+ }
+
+ _update()
+ {
+ if (isInBrowser) {
+ if (this._cell)
+ this._cell.innerHTML = this.toString();
+ } else
+ print(this.toString());
+ }
+}
+
diff --git a/third_party/webkit/PerformanceTests/ARES-6/styles.css b/third_party/webkit/PerformanceTests/ARES-6/styles.css
new file mode 100644
index 0000000000..2c9910f479
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/styles.css
@@ -0,0 +1,337 @@
+html {
+ font-family: "Helvetica Neue","Helvetica",sans-serif;
+ font-size: 62.5%;
+ font-synthesis: none;
+}
+
+body {
+ margin: 0;
+ background-color: #2C2C3C;
+ width: 100%;
+ font-size: 1.6rem;
+ font-weight: 400;
+ line-height: 1.4;
+ color: #9B9B9B;
+ box-sizing: border-box;
+ padding: 6vw 9vw;
+}
+
+.swoop {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ background-image: url('swoop.svg');
+ background-repeat: no-repeat;
+ background-size: 50vw;
+ width: 0;
+ animation: wipe-in 1s ease-in 0ms forwards;
+}
+
+header,
+main,
+footer {
+ box-sizing: border-box;
+ max-width: 780px;
+ margin: 0 auto;
+}
+
+p a {
+ color: #E7B135;
+ text-decoration: none;
+}
+
+p a:hover {
+ text-decoration: underline;
+}
+
+header {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+h2,
+.indicator {
+ font-size: 5rem;
+ color: #9B9B9B;
+ font-weight: 500;
+ line-height: 1.25;
+ margin: 0;
+}
+
+p {
+ color: #ffffff;
+ font-size: 1.8rem;
+ margin-bottom: 3rem;
+ opacity: 0;
+ animation: fade-in 1s ease-in 200ms forwards;
+}
+
+.about h2 {
+ margin-top: 3rem;
+}
+
+.logo {
+ width: 33rem;
+ height: auto;
+ white-space: nowrap;
+ overflow: hidden;
+ margin: 1px 1rem 1px 0;
+ font-size: 0;
+
+ opacity: 0;
+ animation: scale-in 1100ms ease-out 0ms forwards;
+}
+
+.start {
+ flex: 1;
+ display: block;
+ position: relative;
+ background-color: transparent;
+ border: 5px solid #E7B135;
+ font-size: 2.4rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ color: #E7B135;
+
+ opacity: 0;
+ animation: flicker-in 500ms ease-out 1s forwards;
+
+}
+
+.start.ready {
+ transition: background 0.2s ease-out, color 0.2s ease-out;
+ cursor: pointer;
+}
+
+.start.ready:hover {
+ background-color: #E7B135;
+ color: #2C2C3C;
+}
+
+.start:after {
+ content: '';
+ display: block;
+ position: absolute;
+ right: 0;
+ top: 0;
+ width: 0;
+ height: 0;
+ border-top: 3rem solid #E7B135;
+ border-right: 0 solid transparent;
+ border-bottom: 0 solid transparent;
+ border-left: 3rem solid transparent;
+}
+
+.start.ready .testrun {
+ opacity: 0;
+}
+
+.tests {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-around;
+}
+
+.test {
+ position: relative;
+ flex: 1;
+ border-bottom: 1px solid #979797;
+ margin-right: 1rem;
+ margin-bottom: 3rem;
+ opacity: 0;
+ animation: fade-in 1s ease-out 700ms forwards;
+ min-width: 40%;
+}
+
+.test:nth-child(odd) {
+ animation-delay: 900ms;
+}
+
+.overall h2,
+.test h2 {
+ border-bottom: 1px solid #979797;
+}
+
+.test .running {
+ color: #ffffff;
+}
+
+#status {
+ line-height: 5.4rem;
+}
+
+.failed {
+ color: #ff5744;
+}
+
+#status.failed {
+ font-size: 1.5rem;
+}
+
+.test .failed:before {
+ content: '\2716';
+}
+
+.test .running:before {
+ content: '\25b8';
+}
+
+.score {
+ color: #E7B135;
+ margin: 1rem 0;
+ position: relative;
+}
+
+.score label {
+ text-transform: uppercase;
+ letter-spacing: 0.02rem;
+ font-weight: 500;
+ display: block;
+ line-height: 1;
+}
+
+.score .value {
+ font-size: 6.4rem;
+ font-weight: 600;
+
+ line-height: 1;
+ white-space: nowrap;
+}
+
+.score .units {
+ font-size: 4rem;
+ font-weight: 600;
+
+}
+
+.score .margin {
+ color: #9B9B9B;
+ position: absolute;
+ font-size: 2rem;
+ top: 2rem;
+ margin-left: 0.2rem;
+}
+
+.overall {
+ margin-bottom: 3rem;
+ opacity: 0;
+ animation: fade-in 1s ease-out 500ms forwards;
+}
+
+.overall .score {
+ color: #ffffff;
+}
+
+.overall .margin {
+ top: 0.5rem;
+}
+
+.about h2 {
+ margin-top: 3rem;
+ opacity: 0;
+ animation: fade-in 1s ease-out 500ms forwards;
+}
+
+.button {
+ display: inline-block;
+ position: relative;
+ border: 5px solid #E7B135;
+ padding: 1rem 3rem;
+ text-transform: uppercase;
+ font-weight: bold;
+ transition: background 0.2s ease-out, color 0.2s ease-out;
+}
+
+.button:hover {
+ background-color: #E7B135;
+ color: #2C2C3C;
+ text-decoration: none;
+}
+
+.button.return:before {
+ content: '';
+ display: block;
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 0;
+ height: 0;
+ border-top: 2rem solid #E7B135;
+ border-right: 2rem solid transparent;
+ border-bottom: 0 solid transparent;
+ border-left: 0 solid transparent;
+}
+
+#magic {
+ opacity: 0;
+}
+
+@keyframes fade-in {
+ 0% { opacity: 0; }
+ 100% { opacity: 1; }
+}
+
+@keyframes scale-in {
+ 0% { opacity: 0; transform: scale(0.8); }
+ 100% { opacity: 1; transform: scale(1); }
+}
+
+@keyframes flicker-in {
+ 0% { opacity: 0; }
+ 30% { opacity: 0.3; }
+ 40% { opacity: 0; }
+ 50% { opacity: 0.1; }
+ 60% { opacity: 0; }
+ 70% { opacity: 0.4; }
+ 80% { opacity: 0; }
+ 100% { opacity: 1; }
+}
+
+@keyframes wipe-in {
+ 0% { width: 0; }
+ 100% { width: 100vw; }
+}
+
+@media only screen and (max-width: 784px) {
+ .logo {
+ width: 100%;
+ margin-bottom: 1rem;
+ margin: 0 0 1rem 0;
+ }
+ .start {
+ width: 100%;
+ }
+ .test {
+ flex: none;
+ width: 100%;
+ }
+ #status {
+ line-height: 4.3rem;
+ }
+ .start {
+ font-size: 2.1rem;
+ }
+ #status.failed {
+ font-size: 1.4rem;
+ }
+ p {
+ font-size: 1.6rem;
+ }
+}
+
+@media only screen and (max-width: 320px) {
+ #status {
+ line-height: 3.8rem;
+ }
+ .start {
+ font-size: 1.9rem;
+ }
+ #status.failed {
+ font-size: 1.1rem;
+ }
+ p {
+ font-size: 1.4rem;
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/ARES-6/swoop.svg b/third_party/webkit/PerformanceTests/ARES-6/swoop.svg
new file mode 100644
index 0000000000..3ad8ada4fe
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/ARES-6/swoop.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="614" height="612" viewBox="0 0 614 612">
+ <polygon fill="#9B9B9B" points="101.822 54.713 0 611.475 0 249.855 97.38 43.051 558.229 0 613.901 0"/><polygon fill="#E7B135" points="90.252 25.088 0 65.877 0 36.104 0 0 90.252 0 432.078 0"/>
+</svg>