Merge jdk8-b93

Mon, 03 Jun 2013 23:24:36 -0700

author
lana
date
Mon, 03 Jun 2013 23:24:36 -0700
changeset 304
ddbf41575a2b
parent 261
1c7481ac7fe0
parent 303
4463e94d9b0d
child 305
e857ab684db0
child 307
d2bd881976b5

Merge

src/jdk/nashorn/internal/runtime/options/ValueOption.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompiler.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompilerSupport.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/CaptureTreeNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/NameEntry.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/NativeMachine.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/UnsetAddrList.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/ast/CTypeNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/ast/CallNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/bench/AbstractBench.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchGreedyBacktrack.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchRailsRegs.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchSeveralRegexps.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/constants/Reduce.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/encoding/AsciiTables.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/encoding/PosixBracket.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/regexp/joni/encoding/Ptr.java file | annotate | diff | comparison | revisions
src/netscape/javascript/JSObject.java file | annotate | diff | comparison | revisions
     1.1 --- a/.hgignore	Thu May 30 10:58:35 2013 -0700
     1.2 +++ b/.hgignore	Mon Jun 03 23:24:36 2013 -0700
     1.3 @@ -24,3 +24,4 @@
     1.4  .idea/*
     1.5  test/lib/testng.jar
     1.6  test/script/external/*
     1.7 +.project
     2.1 --- a/docs/JavaScriptingProgrammersGuide.html	Thu May 30 10:58:35 2013 -0700
     2.2 +++ b/docs/JavaScriptingProgrammersGuide.html	Mon Jun 03 23:24:36 2013 -0700
     2.3 @@ -71,9 +71,20 @@
     2.4  Arrays</a></span></li>
     2.5  <li><span><a href="#jsimplement">Implementing Java
     2.6  Interfaces</a></span></li>
     2.7 -<li><span><a href="#jsextend">Extending Java classes
     2.8 +<li><span><a href="#jsextendabstract">Extending Abstract Java Classes
     2.9 +</a></span></li>
    2.10 +<li><span><a href="#jsextendconcrete">Extending Concrete Java Classes
    2.11 +</a></span></li>
    2.12 +<li><span><a href="#jsimplementmultiple">Implementing Multiple Java Interfaces
    2.13 +</a></span></li>
    2.14 +<li><span><a href="#classBoundImplementations">Class-Bound Implementations
    2.15  </a></span></li>
    2.16  <li><span><a href="#jsoverload">Overload Resolution</a></span></li>
    2.17 +<li><span><a href="#dataTypeMapping">Mapping of Data Types Between Java
    2.18 +and JavaScript</a></span></li>
    2.19 +
    2.20 +
    2.21 +
    2.22  </ul>
    2.23  </li>
    2.24  <li><span><a href="#engineimpl">Implementing Your Own Script
    2.25 @@ -466,10 +477,10 @@
    2.26  </code>
    2.27  </pre> 
    2.28  
    2.29 -Note that the name of the type is always a string for a fully qualified name. You can use any of these types to create new instances, e.g.:
    2.30 +Note that the name of the type is always a string for a fully qualified name. You can use any of these expressions to create new instances, e.g.:
    2.31  
    2.32  <pre><code>
    2.33 - var anArrayList = new Java.type("java.util.ArrayList")
    2.34 + var anArrayList = new (Java.type("java.util.ArrayList"))
    2.35  </code></pre> 
    2.36  
    2.37  or
    2.38 @@ -496,6 +507,37 @@
    2.39  <p>
    2.40  You can access both static and non-static inner classes. If you want to create an instance of a non-static inner class, remember to pass an instance of its outer class as the first argument to the constructor.
    2.41  </p>
    2.42 +<p>
    2.43 +In addition to creating new instances, the type objects returned from <code>Java.type</code> calls can also be used to access the
    2.44 +static fields and methods of the classes:
    2.45 +<pre><code>
    2.46 + var File = Java.type("java.io.File")
    2.47 + File.createTempFile("nashorn", ".tmp")
    2.48 +</code></pre> 
    2.49 +<p>
    2.50 +Methods with names of the form <code>isXxx()</code>, <code>getXxx()</code>, and <code>setXxx()</code> can also be used as properties, for both instances and statics.
    2.51 +</p>
    2.52 +<p>
    2.53 +A type object returned from <code>Java.type</code> is distinct from a <code>java.lang.Class</code> object. You can obtain one from the other using properties <code>class</code> and <code>static</code> on them.
    2.54 +<pre><code>
    2.55 + var ArrayList = Java.type("java.util.ArrayList")
    2.56 + var a = new ArrayList
    2.57 +
    2.58 + // All of the following print true:
    2.59 + print("Type acts as target of instanceof: " + (a instanceof ArrayList))
    2.60 + print("Class doesn't act as target of instanceof: " + !(a instanceof a.getClass()))
    2.61 + print("Type is not same as instance's getClass(): " + (a.getClass() !== ArrayList))
    2.62 + print("Type's `class` property is same as instance getClass(): " + (a.getClass() === ArrayList.class))
    2.63 + print("Type is same as instance getClass()'s `static` property: " + (a.getClass().static === ArrayList))
    2.64 +</code></pre> 
    2.65 +<p>
    2.66 +You can think of the type object as similar to the class names as used in Java source code: you use them as the
    2.67 +arguments to the <code>new</code> and <code>instanceof</code> operators and as the namespace for the static fields
    2.68 +and methods, but they are different than the runtime <code>Class</code> objects returned by <code>getClass()</code> calls.
    2.69 +Syntactically and semantically, this separation produces code that is most similar to Java code, where a distinction
    2.70 +between compile-time class expressions and runtime class objects also exists. (Also, Java can't have the equivalent of <code>static</code>
    2.71 +property on a <code>Class</code> object since compile-time class expressions are never reified as objects).
    2.72 +</p>
    2.73  <hr>
    2.74  <a name="jsimport" id="jsimport"></a>
    2.75  <h3>Importing Java Packages, Classes</h3>
    2.76 @@ -558,10 +600,7 @@
    2.77  <a name="jsarrays" id="jsarrays"></a>
    2.78  <h3>Creating, Converting and Using Java Arrays</h3>
    2.79  <p>
    2.80 -Array element access or length access is
    2.81 -the same as in Java. Also, a script array can be used when a Java
    2.82 -method expects a Java array (auto conversion). So in most cases we
    2.83 -don't have to create Java arrays explicitly.</p>
    2.84 +Array element access or length access is the same as in Java.</p>
    2.85  <pre><code>
    2.86  // <a href="source/javaarray.js">javaarray.js</a>
    2.87  
    2.88 @@ -577,27 +616,31 @@
    2.89  </pre>
    2.90  <p>
    2.91  It is also possible to convert between JavaScript and Java arrays.
    2.92 -Given a JavaScript array and a Java type, <code>Java.toJavaArray</code> returns a Java array with the same initial contents, and with the specified component type. 
    2.93 +Given a JavaScript array and a Java type, <code>Java.to</code> returns a Java array with the same initial contents, and with the specified array type. 
    2.94  </p>
    2.95  <pre><code>
    2.96   var anArray = [1, "13", false]
    2.97 - var javaIntArray = Java.toJavaArray(anArray, "int")
    2.98 + var javaIntArray = Java.to(anArray, "int[]")
    2.99   print(javaIntArray[0]) // prints 1
   2.100   print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
   2.101   print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
   2.102  </code></pre>
   2.103  <p>
   2.104 -Given a Java array or Collection, <code>Java.toJavaScriptArray</code> returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.i
   2.105 +You can use either a string or a type object returned from <code>Java.type()</code> to specify the type of the array. 
   2.106 +You can also omit the array type, in which case a <code>Object[]</code> will be created.
   2.107 +</p>
   2.108 +<p>
   2.109 +Given a Java array or Collection, <code>Java.from</code> returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.
   2.110  </p>
   2.111  <pre><code>
   2.112  var File = Java.type("java.io.File");
   2.113  var listCurDir = new File(".").listFiles();
   2.114 -var jsList = Java.toJavaScriptArray(listCurDir);
   2.115 +var jsList = Java.from(listCurDir);
   2.116  print(jsList);
   2.117  </code></pre>
   2.118  <hr>
   2.119  <a name="jsimplement" id="jsimplement"></a>
   2.120 -<h3>Implementing Java Interfaces</h3>
   2.121 +<h3>Implementing Java interfaces</h3>
   2.122  <p>A Java interface can be implemented in JavaScript by using a
   2.123  Java anonymous class-like syntax:</p>
   2.124  <pre><code>
   2.125 @@ -631,8 +674,8 @@
   2.126  </code>
   2.127  </pre>
   2.128  <hr>
   2.129 -<a name="jsextend" id="jsextend"></a>
   2.130 -<h3>Extending Java classes</h3>
   2.131 +<a name="jsextendabstract" id="jsextendabstract"></a>
   2.132 +<h3>Extending Abstract Java Classes</h3>
   2.133  <p>
   2.134  If a Java class is abstract, you can instantiate an anonymous subclass of it using an argument list that is applicable to any of its public or protected constructors, but inserting a JavaScript object with functions properties that provide JavaScript implementations of the abstract methods. If method names are overloaded, the JavaScript function will provide implementation for all overloads. E.g.:
   2.135  </p>
   2.136 @@ -671,6 +714,9 @@
   2.137  
   2.138  Here, <code>Timer.schedule()</code> expects a <code>TimerTask</code> as its argument, so Nashorn creates an instance of a TimerTask subclass and uses the passed function to implement its only abstract method, run(). In this usage though, you can't use non-default constructors; the type must be either an interface, or must have a protected or public no-arg constructor.
   2.139  
   2.140 +<hr>
   2.141 +<a name="jsextendconcrete" id="jsextendconcrete"></a>
   2.142 +<h3>Extending Concrete Java Classes</h3>
   2.143  <p>
   2.144  To extend a concrete Java class, you have to use <code>Java.extend</code> function.
   2.145  <code>Java.extend</code> returns a type object for a subclass of the specified Java class (or implementation of the specified interface) that acts as a script-to-Java adapter for it.  
   2.146 @@ -695,26 +741,178 @@
   2.147  printSizeInvokedArrayList.size();
   2.148  printAddInvokedArrayList.add(33, 33);
   2.149  </code></pre>
   2.150 +<p>
   2.151 +The reason you must use <code>Java.extend()</code> with concrete classes is that with concrete classes, there can be a 
   2.152 +syntactic ambiguity if you just invoke their constructor. Consider this example:
   2.153 +</p>
   2.154 +<pre><code>
   2.155 +var t = new java.lang.Thread({ run: function() { print("Hello!") } })
   2.156 +</code></pre>
   2.157 +<p>
   2.158 +If we allowed subclassing of concrete classes with constructor syntax, Nashorn couldn't tell if you're creating a new 
   2.159 +<code>Thread</code> and passing it a <code>Runnable</code> at this point, or you are subclassing <code>Thread</code> and
   2.160 +passing it a new implementation for its own <code>run()</code> method.
   2.161 +</p>
   2.162 +<hr>
   2.163 +<a name="jsimplementmultiple" id="jsimplementmultiple"></a>
   2.164 +<h3>Implementing Multiple Interfaces</h3>
   2.165 +<p>
   2.166 +<code>Java.extend</code> can in fact take a list of multiple types. At most one of the types can be a class, and the rest must
   2.167 +be interfaces (the class doesn't have to be the first in the list). You will get back an object that extends the class and 
   2.168 +implements all the interfaces. (Obviously, if you only specify interfaces and no class, the object will extend <code>java.lang.Object</code>).
   2.169 +<hr>
   2.170 +<a name="classBoundImplementations" id="classBoundImplementations"></a>
   2.171 +<h3>Class-Bound Implementations</h3>
   2.172 +<p>
   2.173 +The methods shown so far for extending Java classes and implementing interfaces &ndash; passing an implementation JavaScript object 
   2.174 +or function to a constructor, or using <code>Java.extend</code> with <code>new</code> &ndash; all produce classes that take an
   2.175 +extra JavaScript object parameter in their constructors that specifies the implementation. The implementation is therefore always bound
   2.176 +to the actual instance being created with <code>new</code>, and not to the whole class. This has some advantages, for example in the
   2.177 +memory footprint of the runtime, as Nashorn can just create a single "universal adapter" for every combination of types being implemented.
   2.178 +In reality, the below code shows that different instantiations of, say, <code>Runnable</code> have the same class regardless of them having
   2.179 +different JavaScript implementation objects:
   2.180 +</p>
   2.181 +<pre><code>
   2.182 +var Runnable = java.lang.Runnable;
   2.183 +var r1 = new Runnable(function() { print("I'm runnable 1!") })
   2.184 +var r2 = new Runnable(function() { print("I'm runnable 2!") })
   2.185 +r1.run()
   2.186 +r2.run()
   2.187 +print("We share the same class: " + (r1.class === r2.class))
   2.188 +</code></pre>
   2.189 +<p>
   2.190 +prints:
   2.191 +</p>
   2.192 +<pre><code>
   2.193 +I'm runnable 1!
   2.194 +I'm runnable 2!
   2.195 +We share the same class: true
   2.196 +</code></pre>
   2.197 +<p>
   2.198 +Sometimes, however, you'll want to extend a Java class or implement an interface with implementation bound to the class, not to
   2.199 +its instances. Such a need arises, for example, when you need to pass the class for instantiation to an external API; prime example
   2.200 +of this is the JavaFX framework where you need to pass an Application class to the FX API and let it instantiate it.
   2.201 +</p>
   2.202 +<p>
   2.203 +Fortunately, there's a solution for that: <code>Java.extend()</code> &ndash; aside from being able to take any number of type parameters
   2.204 +denoting a class to extend and interfaces to implement &ndash; can also take one last argument that has to be a JavaScript object
   2.205 +that serves as the implementation for the methods. In this case, <code>Java.extend()</code> will create a class that has the same
   2.206 +constructors as the original class had, as they don't need to take an an extra implementation object parameter. The example below
   2.207 +shows how you can create class-bound implementations, and shows that in this case, the implementation classes for different invocations
   2.208 +are indeed different:
   2.209 +</p>
   2.210 +<pre><code>
   2.211 +var RunnableImpl1 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
   2.212 +var RunnableImpl2 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 2!") })
   2.213 +var r1 = new RunnableImpl1()
   2.214 +var r2 = new RunnableImpl2()
   2.215 +r1.run()
   2.216 +r2.run()
   2.217 +print("We share the same class: " + (r1.class === r2.class))
   2.218 +</code></pre>
   2.219 +<p>
   2.220 +prints:
   2.221 +</p>
   2.222 +<pre><code>
   2.223 +I'm runnable 1!
   2.224 +I'm runnable 2!
   2.225 +We share the same class: false
   2.226 +</code></pre>
   2.227 +<p>
   2.228 +As you can see, the major difference here is that we moved the implementation object into the invocation of <code>Java.extend</code>
   2.229 +from the constructor invocations &ndash; indeed the constructor invocations now don't even need to take an extra parameter! Since
   2.230 +the implementations are bound to a class, the two classes obviously can't be the same, and we indeed see that the two runnables no
   2.231 +longer share the same class &ndash; every invocation of <code>Java.extend()</code> with a class-specific implementation object triggers
   2.232 +the creation of a new Java adapter class.
   2.233 +</p>
   2.234 +<p>
   2.235 +Finally, the adapter classes with class-bound implementations can <i>still</i> take an additional constructor parameter to further
   2.236 +override the behavior on a per-instance basis. Thus, you can even combine the two approaches: you can provide part of the implementation
   2.237 +in a class-based JavaScript implementation object passed to <code>Java.extend</code>, and part in another object passed to the constructor.
   2.238 +Whatever functions are provided by the constructor-passed object will override the functions in the class-bound object.
   2.239 +</p>
   2.240 +<pre><code>
   2.241 +var RunnableImpl = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
   2.242 +var r1 = new RunnableImpl()
   2.243 +var r2 = new RunnableImpl(function() { print("I'm runnable 2!") })
   2.244 +r1.run()
   2.245 +r2.run()
   2.246 +print("We share the same class: " + (r1.class === r2.class))
   2.247 +</code></pre>
   2.248 +<p>
   2.249 +prints:
   2.250 +</p>
   2.251 +<pre><code>
   2.252 +I'm runnable 1!
   2.253 +I'm runnable 2!
   2.254 +We share the same class: true
   2.255 +</code></pre>
   2.256  <hr>
   2.257  <a name="jsoverload" id="jsoverload"></a>
   2.258  <h3>Overload Resolution</h3>
   2.259  <p>Java methods can be overloaded by argument types. In Java,
   2.260  overload resolution occurs at compile time (performed by javac).
   2.261 -When calling Java methods from a script, the script
   2.262 -interpreter/compiler needs to select the appropriate method. With
   2.263 -the JavaScript engine, you do not need to do anything special - the
   2.264 -correct Java method overload variant is selected based on the
   2.265 -argument types. But, sometimes you may want (or have) to explicitly
   2.266 -select a particular overload variant.</p>
   2.267 +When calling Java methods from Nashorn, the appropriate method will be
   2.268 +selected based on the argument types at invocation time. You do not need
   2.269 +to do anything special &ndash; the correct Java method overload variant 
   2.270 +is selected based automatically. You still have the option of explicitly
   2.271 +specifying a particular overload variant. Reasons for this include 
   2.272 +either running into a genuine ambiguity with actual argument types, or 
   2.273 +rarely reasons of performance &ndash; if you specify the actual overload
   2.274 +then the engine doesn't have to perform resolution during invocation.
   2.275 +Individual overloads of a Java methods are exposed as special properties
   2.276 +with the name of the method followed with its signature in parentheses. 
   2.277 +You can invoke them like this:</p>
   2.278  <pre><code>
   2.279  // <a href="source/overload.js">overload.js</a>
   2.280  
   2.281  var out = java.lang.System.out;
   2.282  
   2.283  // select a particular print function 
   2.284 -out["println(java.lang.Object)"]("hello");
   2.285 +out["println(Object)"]("hello");
   2.286  </code>
   2.287  </pre>
   2.288 +<p>
   2.289 +Note that you normally don't even have to use qualified class names in 
   2.290 +the signatures as long as the unqualified name of the type is sufficient
   2.291 +for uniquely identifying the signature. In practice this means that only
   2.292 +in the extremely unlikely case that two overloads only differ in 
   2.293 +parameter types that have identical unqualified names but come from 
   2.294 +different packages would you need to use the fully qualified name of the
   2.295 +class.
   2.296 +</p>
   2.297 +<hr>
   2.298 +<a name="dataTypeMapping" id="dataTypeMapping"></a>
   2.299 +<h3>Mapping of Data Types Between Java and JavaScript</h3>
   2.300 +<p>
   2.301 +We have previously shown some of the data type mappings between Java and JavaScript.
   2.302 +We saw that arrays need to be explicitly converted. We have also shown that JavaScript functions
   2.303 +are automatically converted to SAM types when passed as parameters to Java methods. Most other
   2.304 +conversions work as you would expect.
   2.305 +</p>
   2.306 +<p>
   2.307 +Every JavaScript object is also a <code>java.util.Map</code> so APIs receiving maps will receive them directly.
   2.308 +</p>
   2.309 +<p>
   2.310 +When numbers are passed to a Java API, they will be converted to the expected target numeric type, either boxed or
   2.311 +primitive, but if the target type is less specific, say <code>Number</code> or <code>Object</code>, you can only
   2.312 +count on them being a <code>Number</code>, and have to test specifically for whether it's a boxed <code>Double</code>,
   2.313 +<code>Integer</code>, <code>Long</code>, etc. &ndash; it can be any of these due to internal optimizations. Also, you 
   2.314 +can pass any JavaScript value to a Java API expecting either a boxed or primitive number; the JavaScript specification's
   2.315 +<code>ToNumber</code> conversion algorithm will be applied to the value.
   2.316 +</p>
   2.317 +<p>
   2.318 +In a similar vein, if a Java method expects a <code>String</code> or a <code>Boolean</code>, the values will be
   2.319 +converted using all conversions allowed by the JavaScript specification's <code>ToString</code> and <code>ToBoolean</code>
   2.320 +conversions.
   2.321 +</p>
   2.322 +<p>
   2.323 +Finally, a word of caution about strings. Due to internal performance optimizations of string operations, JavaScript strings are
   2.324 +not always necessarily of type <code>java.lang.String</code>, but they will always be of type <code>java.lang.CharSequence</code>.
   2.325 +If you pass them to a Java method that expects a <code>java.lang.String</code> parameter, then you will naturally receive a Java
   2.326 +String, but if the signature of your method is more generic, i.e. it receives a <code>java.lang.Object</code> parameter, you can 
   2.327 +end up with an object of private engine implementation class that implements <code>CharSequence</code> but is not a Java String.
   2.328 +</p>
   2.329  <hr>
   2.330  <a name="engineimpl" id="engineimpl"></a>
   2.331  <h2>Implementing Your Own Script Engine</h2>
     3.1 --- a/docs/source/javaarray.js	Thu May 30 10:58:35 2013 -0700
     3.2 +++ b/docs/source/javaarray.js	Mon Jun 03 23:24:36 2013 -0700
     3.3 @@ -40,7 +40,7 @@
     3.4  
     3.5  // convert a script array to Java array
     3.6  var anArray = [1, "13", false];
     3.7 -var javaIntArray = Java.toJavaArray(anArray, "int");
     3.8 +var javaIntArray = Java.to(anArray, "int[]");
     3.9  print(javaIntArray[0]);// prints 1
    3.10  print(javaIntArray[1]); // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
    3.11  print(javaIntArray[2]);// prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
    3.12 @@ -48,5 +48,5 @@
    3.13  // convert a Java array to a JavaScript array
    3.14  var File = Java.type("java.io.File");
    3.15  var listCurDir = new File(".").listFiles();
    3.16 -var jsList = Java.toJavaScriptArray(listCurDir);
    3.17 +var jsList = Java.from(listCurDir);
    3.18  print(jsList);
     4.1 --- a/make/build-benchmark.xml	Thu May 30 10:58:35 2013 -0700
     4.2 +++ b/make/build-benchmark.xml	Mon Jun 03 23:24:36 2013 -0700
     4.3 @@ -24,258 +24,270 @@
     4.4  <project name="nashorn-benchmarks" default="all" basedir="..">
     4.5  
     4.6    <target name="octane-init" depends="jar">
     4.7 -    <fileset id="octane-set"
     4.8 -	     dir="${octane-test-sys-prop.test.js.roots}"
     4.9 -	     excludes="${octane-test-sys-prop.test.js.exclude.list}">
    4.10 -      <include name="*.js"/>
    4.11 -    </fileset>
    4.12 -    <pathconvert pathsep=" " property="octane-tests" refid="octane-set"/>
    4.13 +    <property name="octane-tests" value="box2d code-load crypto deltablue earley-boyer gbemu navier-stokes pdfjs raytrace regexp richards splay"/>
    4.14 +  </target>
    4.15 +  
    4.16 +  <!-- ignore benchmarks where rhino crashes -->
    4.17 +  <target name="octane-init-rhino" depends="jar">
    4.18 +    <property name="octane-tests" value="box2d code-load crypto deltablue earley-boyer gbemu navier-stokes raytrace regexp richards splay"/>
    4.19    </target>
    4.20  
    4.21    <!-- box2d -->
    4.22    <target name="octane-box2d" depends="jar">
    4.23      <antcall target="run-octane">
    4.24 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/box2d.js"/>
    4.25 +      <param name="octane-tests" value="box2d"/>
    4.26      </antcall>
    4.27    </target>
    4.28  
    4.29    <target name="octane-box2d-v8" depends="jar">
    4.30      <antcall target="run-octane-v8">
    4.31 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/box2d.js"/>
    4.32 +      <param name="octane-tests" value="box2d"/>
    4.33      </antcall>
    4.34    </target>
    4.35  
    4.36    <target name="octane-box2d-rhino" depends="jar">
    4.37      <antcall target="run-octane-rhino">
    4.38 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/box2d.js"/>
    4.39 +      <param name="octane-tests" value="box2d"/>
    4.40      </antcall>
    4.41    </target>
    4.42  
    4.43 +
    4.44    <!-- code-load -->  
    4.45    <target name="octane-code-load" depends="jar">
    4.46      <antcall target="run-octane">
    4.47 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/code-load.js"/>
    4.48 +      <param name="octane-tests" value="code-load"/>
    4.49      </antcall>
    4.50    </target>
    4.51  
    4.52    <target name="octane-code-load-v8" depends="jar">
    4.53      <antcall target="run-octane-v8">
    4.54 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/code-load.js"/>
    4.55 +      <param name="octane-tests" value="code-load"/>
    4.56      </antcall>
    4.57    </target>
    4.58  
    4.59    <target name="octane-code-load-rhino" depends="jar">
    4.60      <antcall target="run-octane-rhino">
    4.61 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/code-load.js"/>
    4.62 +      <param name="octane-tests" value="code-load"/>
    4.63      </antcall>
    4.64    </target>
    4.65  
    4.66 +
    4.67    <!-- crypto -->
    4.68    <target name="octane-crypto" depends="jar">
    4.69      <antcall target="run-octane">
    4.70 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/crypto.js"/>
    4.71 +      <param name="octane-tests" value="crypto"/>
    4.72      </antcall>
    4.73    </target>
    4.74  
    4.75    <target name="octane-crypto-v8" depends="jar">
    4.76      <antcall target="run-octane-v8">
    4.77 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/crypto.js"/>
    4.78 +      <param name="octane-tests" value="crypto"/>
    4.79      </antcall>
    4.80    </target>
    4.81  
    4.82    <target name="octane-crypto-rhino" depends="jar">
    4.83      <antcall target="run-octane-rhino">
    4.84 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/crypto.js"/>
    4.85 +      <param name="octane-tests" value="crypto"/>
    4.86      </antcall>
    4.87    </target>
    4.88  
    4.89 +
    4.90    <!-- deltablue -->
    4.91    <target name="octane-deltablue" depends="jar">
    4.92      <antcall target="run-octane">
    4.93 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/deltablue.js"/>
    4.94 +      <param name="octane-tests" value="deltablue"/>
    4.95      </antcall>
    4.96    </target>
    4.97  
    4.98    <target name="octane-deltablue-v8" depends="jar">
    4.99      <antcall target="run-octane-v8">
   4.100 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/deltablue.js"/>
   4.101 +      <param name="octane-tests" value="deltablue"/>
   4.102      </antcall>
   4.103    </target>
   4.104  
   4.105    <target name="octane-deltablue-rhino" depends="jar">
   4.106      <antcall target="run-octane-rhino">
   4.107 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/deltablue.js"/>
   4.108 +      <param name="octane-tests" value="deltablue"/>
   4.109      </antcall>
   4.110    </target>
   4.111  
   4.112 +
   4.113    <!-- earley-boyer -->
   4.114    <target name="octane-earley-boyer" depends="jar">
   4.115      <antcall target="run-octane">
   4.116 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/earley-boyer.js"/>
   4.117 +      <param name="octane-tests" value="earley-boyer"/>
   4.118      </antcall>
   4.119    </target>
   4.120  
   4.121    <target name="octane-earley-boyer-v8" depends="jar">
   4.122      <antcall target="run-octane-v8">
   4.123 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/earley-boyer.js"/>
   4.124 +      <param name="octane-tests" value="earley-boyer"/>
   4.125      </antcall>
   4.126    </target>
   4.127  
   4.128    <target name="octane-earley-boyer-rhino" depends="jar">
   4.129      <antcall target="run-octane-rhino">
   4.130 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/earley-boyer.js"/>
   4.131 +      <param name="octane-tests" value="earley-boyer"/>
   4.132      </antcall>
   4.133    </target>
   4.134  
   4.135 +
   4.136    <!-- gbemu -->  
   4.137    <target name="octane-gbemu" depends="jar">
   4.138      <antcall target="run-octane">
   4.139 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/gbemu.js"/>
   4.140 +      <param name="octane-tests" value="gbemu"/>
   4.141      </antcall>
   4.142    </target>
   4.143  
   4.144    <target name="octane-gbemu-v8" depends="jar">
   4.145      <antcall target="run-octane-v8">
   4.146 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/gbemu.js"/>
   4.147 +      <param name="octane-tests" value="gbemu"/>
   4.148      </antcall>
   4.149    </target>
   4.150  
   4.151    <target name="octane-gbemu-rhino" depends="jar">
   4.152      <antcall target="run-octane-rhino">
   4.153 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/gbemu.js"/>
   4.154 +      <param name="octane-tests" value="gbemu"/>
   4.155      </antcall>
   4.156    </target>
   4.157  
   4.158 +
   4.159    <!-- mandreel -->  
   4.160    <target name="octane-mandreel" depends="jar">
   4.161      <antcall target="run-octane">
   4.162 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/mandreel.js"/>
   4.163 +      <param name="octane-tests" value="mandreel"/>
   4.164      </antcall>
   4.165    </target>
   4.166  
   4.167    <target name="octane-mandreel-v8" depends="jar">
   4.168      <antcall target="run-octane-v8">
   4.169 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/mandreel.js"/>
   4.170 +      <param name="octane-tests" value="mandreel"/>
   4.171      </antcall>
   4.172    </target>
   4.173  
   4.174    <target name="octane-mandreel-rhino" depends="jar">
   4.175      <antcall target="run-octane-rhino">
   4.176 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/mandreel.js"/>
   4.177 +      <param name="octane-tests" value="mandreel"/>
   4.178      </antcall>
   4.179    </target>
   4.180  
   4.181 +
   4.182    <!-- navier-stokes -->
   4.183    <target name="octane-navier-stokes" depends="jar">
   4.184      <antcall target="run-octane">
   4.185 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/navier-stokes.js"/>
   4.186 +      <param name="octane-tests" value="navier-stokes"/>
   4.187      </antcall>
   4.188    </target>
   4.189  
   4.190    <target name="octane-navier-stokes-v8" depends="jar">
   4.191      <antcall target="run-octane-v8">
   4.192 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/navier-stokes.js"/>
   4.193 +      <param name="octane-tests" value="navier-stokes"/>
   4.194      </antcall>
   4.195    </target>
   4.196  
   4.197    <target name="octane-navier-stokes-rhino" depends="jar">
   4.198      <antcall target="run-octane-rhino">
   4.199 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/navier-stokes.js"/>
   4.200 +      <param name="octane-tests" value="navier-stokes"/>
   4.201      </antcall>
   4.202    </target>
   4.203  
   4.204 +
   4.205    <!-- pdfjs -->  
   4.206    <target name="octane-pdfjs" depends="jar">
   4.207      <antcall target="run-octane">
   4.208 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/pdfjs.js"/>
   4.209 +      <param name="octane-tests" value="pdfjs"/>
   4.210      </antcall>
   4.211    </target>
   4.212  
   4.213    <target name="octane-pdfjs-v8" depends="jar">
   4.214      <antcall target="run-octane-v8">
   4.215 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/pdfjs.js"/>
   4.216 +      <param name="octane-tests" value="pdfjs"/>
   4.217      </antcall>
   4.218    </target>
   4.219  
   4.220    <target name="octane-pdfjs-rhino" depends="jar">
   4.221      <antcall target="run-octane-rhino">
   4.222 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/pdfjs.js"/>
   4.223 +      <param name="octane-tests" value="pdfjs"/>
   4.224      </antcall>
   4.225    </target>
   4.226  
   4.227 +
   4.228    <!-- raytrace -->
   4.229    <target name="octane-raytrace" depends="jar">
   4.230      <antcall target="run-octane">
   4.231 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/raytrace.js"/>
   4.232 +      <param name="octane-tests" value="raytrace"/>
   4.233      </antcall>
   4.234    </target>
   4.235  
   4.236    <target name="octane-raytrace-v8" depends="jar">
   4.237      <antcall target="run-octane-v8">
   4.238 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/raytrace.js"/>
   4.239 +      <param name="octane-tests" value="raytrace"/>
   4.240      </antcall>
   4.241    </target>
   4.242  
   4.243    <target name="octane-raytrace-rhino" depends="jar">
   4.244      <antcall target="run-octane-rhino">
   4.245 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/raytrace.js"/>
   4.246 +      <param name="octane-tests" value="raytrace"/>
   4.247      </antcall>
   4.248    </target>
   4.249  
   4.250 +
   4.251    <!-- regexp -->
   4.252    <target name="octane-regexp" depends="jar">
   4.253      <antcall target="run-octane">
   4.254 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/regexp.js"/>
   4.255 +      <param name="octane-tests" value="regexp"/>
   4.256      </antcall>
   4.257    </target>
   4.258  
   4.259    <target name="octane-regexp-octane-v8" depends="jar">
   4.260      <antcall target="run-octane-v8">
   4.261 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/regexp.js"/>
   4.262 +      <param name="octane-tests" value="regexp"/>
   4.263      </antcall>
   4.264    </target>
   4.265  
   4.266    <target name="octane-regexp-rhino" depends="jar">
   4.267      <antcall target="run-octane-rhino">
   4.268 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/regexp.js"/>
   4.269 +      <param name="octane-tests" value="regexp"/>
   4.270      </antcall>
   4.271    </target>
   4.272  
   4.273 +
   4.274    <!-- richards -->
   4.275    <target name="octane-richards" depends="jar">
   4.276      <antcall target="run-octane">
   4.277 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/richards.js"/>
   4.278 +      <param name="octane-tests" value="richards"/>
   4.279      </antcall>
   4.280    </target>
   4.281  
   4.282    <target name="octane-richards-v8" depends="jar">
   4.283      <antcall target="run-octane-v8">
   4.284 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/richards.js"/>
   4.285 +      <param name="octane-tests" value="richards"/>
   4.286      </antcall>
   4.287    </target>
   4.288  
   4.289    <target name="octane-richards-rhino" depends="jar">
   4.290      <antcall target="run-octane-rhino">
   4.291 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/richards.js"/>
   4.292 +      <param name="octane-tests" value="richards"/>
   4.293      </antcall>
   4.294    </target>
   4.295  
   4.296 +
   4.297    <!-- splay -->
   4.298    <target name="octane-splay" depends="jar">
   4.299      <antcall target="run-octane">
   4.300 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/splay.js"/>
   4.301 +      <param name="octane-tests" value="splay"/>
   4.302      </antcall>
   4.303    </target>
   4.304  
   4.305    <target name="octane-splay-v8" depends="jar">
   4.306      <antcall target="run-octane-v8">
   4.307 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/splay.js"/>
   4.308 +      <param name="octane-tests" value="splay"/>
   4.309      </antcall>
   4.310    </target>
   4.311  
   4.312    <target name="octane-splay-rhino" depends="jar">
   4.313      <antcall target="run-octane-rhino">
   4.314 -      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/splay.js"/>
   4.315 +      <param name="octane-tests" value="splay"/>
   4.316      </antcall>
   4.317    </target>
   4.318  
   4.319 @@ -307,7 +319,7 @@
   4.320    </target>
   4.321  
   4.322    <!-- run octane benchmarks using Rhino as runtime -->
   4.323 -  <target name="octane-rhino" depends="octane-init">
   4.324 +  <target name="octane-rhino" depends="octane-init-rhino">
   4.325      <antcall target="run-octane-rhino"/>
   4.326    </target>
   4.327    
     5.1 --- a/make/build.xml	Thu May 30 10:58:35 2013 -0700
     5.2 +++ b/make/build.xml	Mon Jun 03 23:24:36 2013 -0700
     5.3 @@ -212,7 +212,9 @@
     5.4             target="${javac.target}"
     5.5             debug="${javac.debug}"
     5.6             encoding="${javac.encoding}"
     5.7 -           includeantruntime="false"/>
     5.8 +           includeantruntime="false">
     5.9 +        <compilerarg line="-extdirs &quot;&quot;"/>
    5.10 +    </javac>
    5.11  
    5.12      <!-- tests that check nashorn internals and internal API -->
    5.13      <jar jarfile="${nashorn.internal.tests.jar}">
    5.14 @@ -305,6 +307,8 @@
    5.15        <include name="**/codegen/*Test.class"/>
    5.16        <include name="**/parser/*Test.class"/>
    5.17        <include name="**/runtime/*Test.class"/>
    5.18 +      <include name="**/runtime/regexp/*Test.class"/>
    5.19 +      <include name="**/runtime/regexp/joni/*Test.class"/>
    5.20        <include name="**/framework/*Test.class"/>
    5.21      </fileset>
    5.22  
     6.1 --- a/make/code_coverage.xml	Thu May 30 10:58:35 2013 -0700
     6.2 +++ b/make/code_coverage.xml	Mon Jun 03 23:24:36 2013 -0700
     6.3 @@ -139,6 +139,32 @@
     6.4        <arg value="${cc.merged.xml}"/>
     6.5        <arg value="-exclude"/>
     6.6        <arg value="com\.oracle\.nashorn\.runtime\.ScriptRuntime*"/>
     6.7 +      <arg value="-exclude"/>
     6.8 +      <arg value="jdk\.nashorn\.internal\.javaadapters*"/>
     6.9 +      <arg value="-exclude"/>
    6.10 +      <arg value="jdk\.nashorn\.internal\.objects\.annotations*"/>
    6.11 +      <arg value="-exclude"/>
    6.12 +      <arg value="jdk\.nashorn\.internal\.scripts*"/>
    6.13 +      <arg value="-exclude"/>
    6.14 +      <arg value="jdk\.nashorn\.internal\.lookup\.MethodHandleFactory*"/>
    6.15 +      <arg value="-exclude"/>
    6.16 +      <arg value="jdk\.nashorn\.internal\.test\.framework*"/>
    6.17 +      <arg value="-exclude"/>
    6.18 +      <arg value="jdk\.nashorn\.test\.models*"/>
    6.19 +      <arg value="-exclude"/>
    6.20 +      <arg value="jdk\.nashorn\.internal\.ir\.debug*"/>
    6.21 +      <arg value="-exclude"/>
    6.22 +      <arg value="jdk\.nashorn\.internal\.runtime\.regexp\.joni\.bench*"/>
    6.23 +      <arg value="-exclude"/>
    6.24 +      <arg value="jdk\.nashorn\.internal\.runtime\.DebugLogger*"/>
    6.25 +      <arg value="-exclude"/>
    6.26 +      <arg value="jdk\.nashorn\.internal\.runtime\.Timing*"/>
    6.27 +      <arg value="-exclude"/>
    6.28 +      <arg value="jdk\.nashorn\.internal\.runtime\.Logging*"/>
    6.29 +      <arg value="-exclude"/>
    6.30 +      <arg value="jdk\.nashorn\.internal\.runtime\.Debug*"/>
    6.31 +      <arg value="-exclude"/>
    6.32 +      <arg value="jdk\.nashorn\.internal\.objects\.NativeDebug*"/>
    6.33        <arg line="${cc.all.xmls}"/>
    6.34        <classpath>
    6.35          <pathelement location="${jcov.jar}"/>
     7.1 --- a/make/project.properties	Thu May 30 10:58:35 2013 -0700
     7.2 +++ b/make/project.properties	Mon Jun 03 23:24:36 2013 -0700
     7.3 @@ -87,6 +87,7 @@
     7.4  
     7.5  testng.listeners=\
     7.6   org.testng.reporters.SuiteHTMLReporter, \
     7.7 + org.testng.reporters.TestHTMLReporter, \
     7.8   org.testng.reporters.jq.Main, \
     7.9   org.testng.reporters.FailedReporter, \
    7.10   org.testng.reporters.XMLReporter \
    7.11 @@ -214,9 +215,13 @@
    7.12  run.test.xmx=3G
    7.13  run.test.xms=2G
    7.14  
    7.15 +run.test.user.language=tr
    7.16 +run.test.user.country=TR
    7.17 +
    7.18  #  -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods
    7.19  # add '-Dtest.js.outofprocess' to run each test in a new sub-process
    7.20 -run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dnashorn.debug=true -Dfile.encoding=UTF-8
    7.21 +run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country}
    7.22 +
    7.23  #-XX:+HeapDumpOnOutOfMemoryError -XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M  
    7.24  run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.main}
    7.25  
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/jdk/nashorn/api/scripting/JSObject.java	Mon Jun 03 23:24:36 2013 -0700
     8.3 @@ -0,0 +1,87 @@
     8.4 +/*
     8.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.  Oracle designates this
    8.11 + * particular file as subject to the "Classpath" exception as provided
    8.12 + * by Oracle in the LICENSE file that accompanied this code.
    8.13 + *
    8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.17 + * version 2 for more details (a copy is included in the LICENSE file that
    8.18 + * accompanied this code).
    8.19 + *
    8.20 + * You should have received a copy of the GNU General Public License version
    8.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.23 + *
    8.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.25 + * or visit www.oracle.com if you need additional information or have any
    8.26 + * questions.
    8.27 + */
    8.28 +
    8.29 +package jdk.nashorn.api.scripting;
    8.30 +
    8.31 +/**
    8.32 + * netscape.javascript.JSObject-like interface for nashorn script objects.
    8.33 + */
    8.34 +public abstract class JSObject {
    8.35 +    /**
    8.36 +     * Call a JavaScript method
    8.37 +     *
    8.38 +     * @param methodName name of method
    8.39 +     * @param args arguments to method
    8.40 +     * @return result of call
    8.41 +     */
    8.42 +    public abstract Object call(String methodName, Object args[]);
    8.43 +
    8.44 +    /**
    8.45 +     * Evaluate a JavaScript expression
    8.46 +     *
    8.47 +     * @param s JavaScript expression to evaluate
    8.48 +     * @return evaluation result
    8.49 +     */
    8.50 +    public abstract Object eval(String s);
    8.51 +
    8.52 +    /**
    8.53 +     * Retrieves a named member of a JavaScript object.
    8.54 +     *
    8.55 +     * @param name of member
    8.56 +     * @return member
    8.57 +     */
    8.58 +    public abstract Object getMember(String name);
    8.59 +
    8.60 +    /**
    8.61 +     * Retrieves an indexed member of a JavaScript object.
    8.62 +     *
    8.63 +     * @param index index of member slot
    8.64 +     * @return member
    8.65 +     */
    8.66 +    public abstract Object getSlot(int index);
    8.67 +
    8.68 +    /**
    8.69 +     * Remove a named member from a JavaScript object
    8.70 +     *
    8.71 +     * @param name name of member
    8.72 +     */
    8.73 +    public abstract void removeMember(String name);
    8.74 +
    8.75 +    /**
    8.76 +     * Set a named member in a JavaScript object
    8.77 +     *
    8.78 +     * @param name  name of member
    8.79 +     * @param value value of member
    8.80 +     */
    8.81 +    public abstract void setMember(String name, Object value);
    8.82 +
    8.83 +    /**
    8.84 +     * Set an indexed member in a JavaScript object
    8.85 +     *
    8.86 +     * @param index index of member slot
    8.87 +     * @param value value of member
    8.88 +     */
    8.89 +    public abstract void setSlot(int index, Object value);
    8.90 +}
     9.1 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Thu May 30 10:58:35 2013 -0700
     9.2 +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Mon Jun 03 23:24:36 2013 -0700
     9.3 @@ -42,7 +42,6 @@
     9.4  import jdk.nashorn.internal.runtime.ScriptFunction;
     9.5  import jdk.nashorn.internal.runtime.ScriptObject;
     9.6  import jdk.nashorn.internal.runtime.ScriptRuntime;
     9.7 -import netscape.javascript.JSObject;
     9.8  
     9.9  /**
    9.10   * Mirror object that wraps a given ScriptObject instance. User can
    10.1 --- a/src/jdk/nashorn/api/scripting/resources/engine.js	Thu May 30 10:58:35 2013 -0700
    10.2 +++ b/src/jdk/nashorn/api/scripting/resources/engine.js	Mon Jun 03 23:24:36 2013 -0700
    10.3 @@ -88,7 +88,7 @@
    10.4              }
    10.5          }
    10.6  
    10.7 -        array = Java.toJavaArray(array);
    10.8 +        array = Java.to(array);
    10.9          return Packages.jdk.nashorn.api.scripting.ScriptUtils.format(format, array);
   10.10      }
   10.11  });
    11.1 --- a/src/jdk/nashorn/internal/codegen/Attr.java	Thu May 30 10:58:35 2013 -0700
    11.2 +++ b/src/jdk/nashorn/internal/codegen/Attr.java	Mon Jun 03 23:24:36 2013 -0700
    11.3 @@ -84,8 +84,8 @@
    11.4  import jdk.nashorn.internal.ir.UnaryNode;
    11.5  import jdk.nashorn.internal.ir.VarNode;
    11.6  import jdk.nashorn.internal.ir.WithNode;
    11.7 +import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    11.8  import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
    11.9 -import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   11.10  import jdk.nashorn.internal.parser.TokenType;
   11.11  import jdk.nashorn.internal.runtime.Context;
   11.12  import jdk.nashorn.internal.runtime.Debug;
   11.13 @@ -111,7 +111,7 @@
   11.14   * computed.
   11.15   */
   11.16  
   11.17 -final class Attr extends NodeOperatorVisitor {
   11.18 +final class Attr extends NodeOperatorVisitor<LexicalContext> {
   11.19  
   11.20      /**
   11.21       * Local definitions in current block (to discriminate from function
   11.22 @@ -138,6 +138,7 @@
   11.23       * Constructor.
   11.24       */
   11.25      Attr(final TemporarySymbols temporarySymbols) {
   11.26 +        super(new LexicalContext());
   11.27          this.temporarySymbols = temporarySymbols;
   11.28          this.localDefs   = new ArrayDeque<>();
   11.29          this.localUses   = new ArrayDeque<>();
   11.30 @@ -202,7 +203,7 @@
   11.31      private void acceptDeclarations(final FunctionNode functionNode, final Block body) {
   11.32          // This visitor will assign symbol to all declared variables, except function declarations (which are taken care
   11.33          // in a separate step above) and "var" declarations in for loop initializers.
   11.34 -        body.accept(new NodeOperatorVisitor() {
   11.35 +        body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   11.36              @Override
   11.37              public boolean enterFunctionNode(final FunctionNode nestedFn) {
   11.38                  return false;
   11.39 @@ -218,7 +219,7 @@
   11.40                      if (varNode.isFunctionDeclaration()) {
   11.41                          newType(symbol, FunctionNode.FUNCTION_TYPE);
   11.42                      }
   11.43 -                    return varNode.setName((IdentNode)ident.setSymbol(getLexicalContext(), symbol));
   11.44 +                    return varNode.setName((IdentNode)ident.setSymbol(lc, symbol));
   11.45                  }
   11.46                  return varNode;
   11.47              }
   11.48 @@ -227,8 +228,8 @@
   11.49  
   11.50      private void enterFunctionBody() {
   11.51  
   11.52 -        final FunctionNode functionNode = getLexicalContext().getCurrentFunction();
   11.53 -        final Block body = getLexicalContext().getCurrentBlock();
   11.54 +        final FunctionNode functionNode = lc.getCurrentFunction();
   11.55 +        final Block body = lc.getCurrentBlock();
   11.56  
   11.57          initFunctionWideVariables(functionNode, body);
   11.58  
   11.59 @@ -256,7 +257,7 @@
   11.60          //the symbols in the block should really be stateless
   11.61          block.clearSymbols();
   11.62  
   11.63 -        if (getLexicalContext().isFunctionBody()) {
   11.64 +        if (lc.isFunctionBody()) {
   11.65              enterFunctionBody();
   11.66          }
   11.67          pushLocalsBlock();
   11.68 @@ -283,7 +284,7 @@
   11.69      @Override
   11.70      public boolean enterCatchNode(final CatchNode catchNode) {
   11.71          final IdentNode exception = catchNode.getException();
   11.72 -        final Block     block     = getLexicalContext().getCurrentBlock();
   11.73 +        final Block     block     = lc.getCurrentBlock();
   11.74  
   11.75          start(catchNode);
   11.76  
   11.77 @@ -298,10 +299,10 @@
   11.78      @Override
   11.79      public Node leaveCatchNode(final CatchNode catchNode) {
   11.80          final IdentNode exception = catchNode.getException();
   11.81 -        final Block  block        = getLexicalContext().getCurrentBlock();
   11.82 +        final Block  block        = lc.getCurrentBlock();
   11.83          final Symbol symbol       = findSymbol(block, exception.getName());
   11.84          assert symbol != null;
   11.85 -        return end(catchNode.setException((IdentNode)exception.setSymbol(getLexicalContext(), symbol)));
   11.86 +        return end(catchNode.setException((IdentNode)exception.setSymbol(lc, symbol)));
   11.87      }
   11.88  
   11.89      /**
   11.90 @@ -320,7 +321,7 @@
   11.91              flags |= IS_SCOPE;
   11.92          }
   11.93  
   11.94 -        final FunctionNode function = getLexicalContext().getFunction(block);
   11.95 +        final FunctionNode function = lc.getFunction(block);
   11.96          if (symbol != null) {
   11.97              // Symbol was already defined. Check if it needs to be redefined.
   11.98              if ((flags & KINDMASK) == IS_PARAM) {
   11.99 @@ -353,12 +354,12 @@
  11.100              if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
  11.101                  symbolBlock = block; //internal vars are always defined in the block closest to them
  11.102              } else {
  11.103 -                symbolBlock = getLexicalContext().getFunctionBody(function);
  11.104 +                symbolBlock = lc.getFunctionBody(function);
  11.105              }
  11.106  
  11.107              // Create and add to appropriate block.
  11.108              symbol = new Symbol(name, flags);
  11.109 -            symbolBlock.putSymbol(getLexicalContext(), symbol);
  11.110 +            symbolBlock.putSymbol(lc, symbol);
  11.111  
  11.112              if ((flags & Symbol.KINDMASK) != IS_GLOBAL) {
  11.113                  symbol.setNeedsSlot(true);
  11.114 @@ -381,7 +382,7 @@
  11.115          //an outermost function in our lexical context that is not a program (runScript)
  11.116          //is possible - it is a function being compiled lazily
  11.117          if (functionNode.isDeclared()) {
  11.118 -            final Iterator<Block> blocks = getLexicalContext().getBlocks();
  11.119 +            final Iterator<Block> blocks = lc.getBlocks();
  11.120              if (blocks.hasNext()) {
  11.121                  defineSymbol(blocks.next(), functionNode.getIdent().getName(), IS_VAR);
  11.122              }
  11.123 @@ -397,13 +398,11 @@
  11.124      public Node leaveFunctionNode(final FunctionNode functionNode) {
  11.125          FunctionNode newFunctionNode = functionNode;
  11.126  
  11.127 -        final LexicalContext lc = getLexicalContext();
  11.128 -
  11.129          final Block body = newFunctionNode.getBody();
  11.130  
  11.131          //look for this function in the parent block
  11.132          if (functionNode.isDeclared()) {
  11.133 -            final Iterator<Block> blocks = getLexicalContext().getBlocks();
  11.134 +            final Iterator<Block> blocks = lc.getBlocks();
  11.135              if (blocks.hasNext()) {
  11.136                  newFunctionNode = (FunctionNode)newFunctionNode.setSymbol(lc, findSymbol(blocks.next(), functionNode.getIdent().getName()));
  11.137              }
  11.138 @@ -411,7 +410,7 @@
  11.139              final boolean anonymous = functionNode.isAnonymous();
  11.140              final String  name      = anonymous ? null : functionNode.getIdent().getName();
  11.141              if (anonymous || body.getExistingSymbol(name) != null) {
  11.142 -                newFunctionNode = (FunctionNode)ensureSymbol(lc, FunctionNode.FUNCTION_TYPE, newFunctionNode);
  11.143 +                newFunctionNode = (FunctionNode)ensureSymbol(FunctionNode.FUNCTION_TYPE, newFunctionNode);
  11.144              } else {
  11.145                  assert name != null;
  11.146                  final Symbol self = body.getExistingSymbol(name);
  11.147 @@ -490,8 +489,6 @@
  11.148  
  11.149          start(identNode);
  11.150  
  11.151 -        final LexicalContext lc = getLexicalContext();
  11.152 -
  11.153          if (identNode.isPropertyName()) {
  11.154              // assign a pseudo symbol to property name
  11.155              final Symbol pseudoSymbol = pseudoSymbol(name);
  11.156 @@ -549,7 +546,7 @@
  11.157       */
  11.158      private void maybeForceScope(final Symbol symbol) {
  11.159          if (!symbol.isScope() && symbolNeedsToBeScope(symbol)) {
  11.160 -            Symbol.setSymbolIsScope(getLexicalContext(), symbol);
  11.161 +            Symbol.setSymbolIsScope(lc, symbol);
  11.162          }
  11.163      }
  11.164  
  11.165 @@ -558,7 +555,7 @@
  11.166              return false;
  11.167          }
  11.168          boolean previousWasBlock = false;
  11.169 -        for(final Iterator<LexicalContextNode> it = getLexicalContext().getAllNodes(); it.hasNext();) {
  11.170 +        for(final Iterator<LexicalContextNode> it = lc.getAllNodes(); it.hasNext();) {
  11.171              final LexicalContextNode node = it.next();
  11.172              if(node instanceof FunctionNode) {
  11.173                  // We reached the function boundary without seeing a definition for the symbol - it needs to be in
  11.174 @@ -594,10 +591,8 @@
  11.175          }
  11.176  
  11.177          if (symbol.isScope()) {
  11.178 -            final LexicalContext lc = getLexicalContext();
  11.179 -
  11.180              Block scopeBlock = null;
  11.181 -            for (final Iterator<LexicalContextNode> contextNodeIter = getLexicalContext().getAllNodes(); contextNodeIter.hasNext(); ) {
  11.182 +            for (final Iterator<LexicalContextNode> contextNodeIter = lc.getAllNodes(); contextNodeIter.hasNext(); ) {
  11.183                  final LexicalContextNode node = contextNodeIter.next();
  11.184                  if (node instanceof Block) {
  11.185                      if (((Block)node).getExistingSymbol(name) != null) {
  11.186 @@ -610,7 +605,7 @@
  11.187              }
  11.188  
  11.189              if (scopeBlock != null) {
  11.190 -                assert getLexicalContext().contains(scopeBlock);
  11.191 +                assert lc.contains(scopeBlock);
  11.192                  lc.setFlag(scopeBlock, Block.NEEDS_SCOPE);
  11.193              }
  11.194          }
  11.195 @@ -622,8 +617,8 @@
  11.196       * @see #needsParentScope()
  11.197       */
  11.198      private void setUsesGlobalSymbol() {
  11.199 -        for (final Iterator<FunctionNode> fns = getLexicalContext().getFunctions(); fns.hasNext();) {
  11.200 -            getLexicalContext().setFlag(fns.next(), FunctionNode.USES_ANCESTOR_SCOPE);
  11.201 +        for (final Iterator<FunctionNode> fns = lc.getFunctions(); fns.hasNext();) {
  11.202 +            lc.setFlag(fns.next(), FunctionNode.USES_ANCESTOR_SCOPE);
  11.203          }
  11.204      }
  11.205  
  11.206 @@ -635,7 +630,7 @@
  11.207      private Symbol findSymbol(final Block block, final String name) {
  11.208          // Search up block chain to locate symbol.
  11.209  
  11.210 -        for (final Iterator<Block> blocks = getLexicalContext().getBlocks(block); blocks.hasNext();) {
  11.211 +        for (final Iterator<Block> blocks = lc.getBlocks(block); blocks.hasNext();) {
  11.212              // Find name.
  11.213              final Symbol symbol = blocks.next().getExistingSymbol(name);
  11.214              // If found then we are good.
  11.215 @@ -656,11 +651,11 @@
  11.216      public Node leaveLiteralNode(final LiteralNode literalNode) {
  11.217          assert !literalNode.isTokenType(TokenType.THIS) : "tokentype for " + literalNode + " is this"; //guard against old dead code case. literal nodes should never inherit tokens
  11.218          assert literalNode instanceof ArrayLiteralNode || !(literalNode.getValue() instanceof Node) : "literals with Node values not supported";
  11.219 -        final Symbol symbol = new Symbol(getLexicalContext().getCurrentFunction().uniqueName(LITERAL_PREFIX.symbolName()), IS_CONSTANT, literalNode.getType());
  11.220 +        final Symbol symbol = new Symbol(lc.getCurrentFunction().uniqueName(LITERAL_PREFIX.symbolName()), IS_CONSTANT, literalNode.getType());
  11.221          if (literalNode instanceof ArrayLiteralNode) {
  11.222              ((ArrayLiteralNode)literalNode).analyze();
  11.223          }
  11.224 -        return end(literalNode.setSymbol(getLexicalContext(), symbol));
  11.225 +        return end(literalNode.setSymbol(lc, symbol));
  11.226      }
  11.227  
  11.228      @Override
  11.229 @@ -676,7 +671,7 @@
  11.230      @Override
  11.231      public Node leavePropertyNode(final PropertyNode propertyNode) {
  11.232          // assign a pseudo symbol to property name, see NASHORN-710
  11.233 -        return propertyNode.setSymbol(getLexicalContext(), new Symbol(propertyNode.getKeyName(), 0, Type.OBJECT));
  11.234 +        return propertyNode.setSymbol(lc, new Symbol(propertyNode.getKeyName(), 0, Type.OBJECT));
  11.235      }
  11.236  
  11.237      @Override
  11.238 @@ -734,11 +729,11 @@
  11.239              type = Type.OBJECT;
  11.240          }
  11.241  
  11.242 -        switchNode.setTag(newInternal(getLexicalContext().getCurrentFunction().uniqueName(SWITCH_TAG_PREFIX.symbolName()), type));
  11.243 +        switchNode.setTag(newInternal(lc.getCurrentFunction().uniqueName(SWITCH_TAG_PREFIX.symbolName()), type));
  11.244  
  11.245          end(switchNode);
  11.246  
  11.247 -        return switchNode.setCases(getLexicalContext(), newCases);
  11.248 +        return switchNode.setCases(lc, newCases);
  11.249      }
  11.250  
  11.251      @Override
  11.252 @@ -761,7 +756,7 @@
  11.253          final IdentNode ident = varNode.getName();
  11.254          final String    name  = ident.getName();
  11.255  
  11.256 -        final Symbol symbol = defineSymbol(getLexicalContext().getCurrentBlock(), name, IS_VAR);
  11.257 +        final Symbol symbol = defineSymbol(lc.getCurrentBlock(), name, IS_VAR);
  11.258          assert symbol != null;
  11.259  
  11.260          // NASHORN-467 - use before definition of vars - conservative
  11.261 @@ -781,7 +776,6 @@
  11.262          final IdentNode ident = newVarNode.getName();
  11.263          final String    name  = ident.getName();
  11.264  
  11.265 -        final LexicalContext lc = getLexicalContext();
  11.266          final Symbol  symbol = findSymbol(lc.getCurrentBlock(), ident.getName());
  11.267  
  11.268          if (init == null) {
  11.269 @@ -834,7 +828,7 @@
  11.270  
  11.271      @Override
  11.272      public Node leaveDELETE(final UnaryNode unaryNode) {
  11.273 -        final FunctionNode   currentFunctionNode = getLexicalContext().getCurrentFunction();
  11.274 +        final FunctionNode   currentFunctionNode = lc.getCurrentFunction();
  11.275          final boolean        strictMode          = currentFunctionNode.isStrict();
  11.276          final Node           rhs                 = unaryNode.rhs();
  11.277          final Node           strictFlagNode      = LiteralNode.newInstance(unaryNode, strictMode).accept(this);
  11.278 @@ -894,10 +888,10 @@
  11.279       * @return true if the symbol denoted by the specified name in the current lexical context defined in the program level.
  11.280       */
  11.281      private boolean isProgramLevelSymbol(final String name) {
  11.282 -        for(final Iterator<Block> it = getLexicalContext().getBlocks(); it.hasNext();) {
  11.283 +        for(final Iterator<Block> it = lc.getBlocks(); it.hasNext();) {
  11.284              final Block next = it.next();
  11.285              if(next.getExistingSymbol(name) != null) {
  11.286 -                return next == getLexicalContext().getFunctionBody(getLexicalContext().getOutermostFunction());
  11.287 +                return next == lc.getFunctionBody(lc.getOutermostFunction());
  11.288              }
  11.289          }
  11.290          throw new AssertionError("Couldn't find symbol " + name + " in the context");
  11.291 @@ -914,14 +908,14 @@
  11.292      }
  11.293  
  11.294      private IdentNode compilerConstant(CompilerConstants cc) {
  11.295 -        final FunctionNode functionNode = getLexicalContext().getCurrentFunction();
  11.296 +        final FunctionNode functionNode = lc.getCurrentFunction();
  11.297          return (IdentNode)
  11.298              new IdentNode(
  11.299                  functionNode.getToken(),
  11.300                  functionNode.getFinish(),
  11.301                  cc.symbolName()).
  11.302                  setSymbol(
  11.303 -                    getLexicalContext(),
  11.304 +                    lc,
  11.305                      functionNode.compilerConstant(cc));
  11.306      }
  11.307  
  11.308 @@ -999,7 +993,7 @@
  11.309          final Node lhs = binaryNode.lhs();
  11.310  
  11.311          if (lhs instanceof IdentNode) {
  11.312 -            final Block     block = getLexicalContext().getCurrentBlock();
  11.313 +            final Block     block = lc.getCurrentBlock();
  11.314              final IdentNode ident = (IdentNode)lhs;
  11.315              final String    name  = ident.getName();
  11.316  
  11.317 @@ -1043,7 +1037,7 @@
  11.318      }
  11.319  
  11.320      private boolean isLocal(FunctionNode function, Symbol symbol) {
  11.321 -        final FunctionNode definingFn = getLexicalContext().getDefiningFunction(symbol);
  11.322 +        final FunctionNode definingFn = lc.getDefiningFunction(symbol);
  11.323          // Temp symbols are not assigned to a block, so their defining fn is null; those can be assumed local
  11.324          return definingFn == null || definingFn == function;
  11.325      }
  11.326 @@ -1329,7 +1323,7 @@
  11.327      @Override
  11.328      public Node leaveForNode(final ForNode forNode) {
  11.329          if (forNode.isForIn()) {
  11.330 -            forNode.setIterator(newInternal(getLexicalContext().getCurrentFunction().uniqueName(ITERATOR_PREFIX.symbolName()), Type.OBJECT)); //NASHORN-73
  11.331 +            forNode.setIterator(newInternal(lc.getCurrentFunction().uniqueName(ITERATOR_PREFIX.symbolName()), Type.OBJECT)); //NASHORN-73
  11.332              /*
  11.333               * Iterators return objects, so we need to widen the scope of the
  11.334               * init variable if it, for example, has been assigned double type
  11.335 @@ -1407,7 +1401,7 @@
  11.336              final Symbol paramSymbol = functionNode.getBody().getExistingSymbol(param.getName());
  11.337              assert paramSymbol != null;
  11.338              assert paramSymbol.isParam();
  11.339 -            newParams.add((IdentNode)param.setSymbol(getLexicalContext(), paramSymbol));
  11.340 +            newParams.add((IdentNode)param.setSymbol(lc, paramSymbol));
  11.341  
  11.342              assert paramSymbol != null;
  11.343              Type type = functionNode.getHints().getParameterType(pos);
  11.344 @@ -1439,10 +1433,10 @@
  11.345          FunctionNode newFunctionNode = functionNode;
  11.346  
  11.347          if (nparams == 0 || (specialize * 2) < nparams) {
  11.348 -            newFunctionNode = newFunctionNode.clearSnapshot(getLexicalContext());
  11.349 +            newFunctionNode = newFunctionNode.clearSnapshot(lc);
  11.350          }
  11.351  
  11.352 -        return newFunctionNode.setParameters(getLexicalContext(), newParams);
  11.353 +        return newFunctionNode.setParameters(lc, newParams);
  11.354      }
  11.355  
  11.356      /**
  11.357 @@ -1506,7 +1500,7 @@
  11.358      }
  11.359  
  11.360      private Symbol exceptionSymbol() {
  11.361 -        return newInternal(getLexicalContext().getCurrentFunction().uniqueName(EXCEPTION_PREFIX.symbolName()), Type.typeFor(ECMAException.class));
  11.362 +        return newInternal(lc.getCurrentFunction().uniqueName(EXCEPTION_PREFIX.symbolName()), Type.typeFor(ECMAException.class));
  11.363      }
  11.364  
  11.365      /**
  11.366 @@ -1520,8 +1514,8 @@
  11.367       * @param assignmentDest the destination node of the assignment, e.g. lhs for binary nodes
  11.368       */
  11.369      private Node ensureAssignmentSlots(final Node assignmentDest) {
  11.370 -        final LexicalContext attrLexicalContext = getLexicalContext();
  11.371 -        return assignmentDest.accept(new NodeVisitor() {
  11.372 +        final LexicalContext attrLexicalContext = lc;
  11.373 +        return assignmentDest.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  11.374              @Override
  11.375              public Node leaveIndexNode(final IndexNode indexNode) {
  11.376                  assert indexNode.getSymbol().isTemp();
  11.377 @@ -1565,7 +1559,7 @@
  11.378          FunctionNode currentFunctionNode = functionNode;
  11.379          do {
  11.380              changed.clear();
  11.381 -            final FunctionNode newFunctionNode = (FunctionNode)currentFunctionNode.accept(new NodeVisitor() {
  11.382 +            final FunctionNode newFunctionNode = (FunctionNode)currentFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  11.383  
  11.384                  private Node widen(final Node node, final Type to) {
  11.385                      if (node instanceof LiteralNode) {
  11.386 @@ -1579,7 +1573,7 @@
  11.387                              symbol = temporarySymbols.getTypedTemporarySymbol(to);
  11.388                          }
  11.389                          newType(symbol, to);
  11.390 -                        final Node newNode = node.setSymbol(getLexicalContext(), symbol);
  11.391 +                        final Node newNode = node.setSymbol(lc, symbol);
  11.392                          changed.add(newNode);
  11.393                          return newNode;
  11.394                      }
  11.395 @@ -1622,7 +1616,7 @@
  11.396                      return newBinaryNode;
  11.397                  }
  11.398              });
  11.399 -            getLexicalContext().replace(currentFunctionNode, newFunctionNode);
  11.400 +            lc.replace(currentFunctionNode, newFunctionNode);
  11.401              currentFunctionNode = newFunctionNode;
  11.402          } while (!changed.isEmpty());
  11.403          return currentFunctionNode;
  11.404 @@ -1643,12 +1637,12 @@
  11.405      }
  11.406  
  11.407      private Node ensureSymbol(final Type type, final Node node) {
  11.408 -        LOG.info("New TEMPORARY added to ", getLexicalContext().getCurrentFunction().getName(), " type=", type);
  11.409 -        return ensureSymbol(getLexicalContext(), type, node);
  11.410 +        LOG.info("New TEMPORARY added to ", lc.getCurrentFunction().getName(), " type=", type);
  11.411 +        return temporarySymbols.ensureSymbol(lc, type, node);
  11.412      }
  11.413  
  11.414      private Symbol newInternal(final String name, final Type type) {
  11.415 -        final Symbol iter = defineSymbol(getLexicalContext().getCurrentBlock(), name, IS_VAR | IS_INTERNAL);
  11.416 +        final Symbol iter = defineSymbol(lc.getCurrentBlock(), name, IS_VAR | IS_INTERNAL);
  11.417          iter.setType(type); // NASHORN-73
  11.418          return iter;
  11.419      }
  11.420 @@ -1705,10 +1699,6 @@
  11.421          localUses.peek().add(name);
  11.422      }
  11.423  
  11.424 -    private Node ensureSymbol(final LexicalContext lc, final Type type, final Node node) {
  11.425 -        return temporarySymbols.ensureSymbol(lc, type, node);
  11.426 -    }
  11.427 -
  11.428      /**
  11.429       * Pessimistically promote all symbols in current function node to Object types
  11.430       * This is done when the function contains unevaluated black boxes such as
  11.431 @@ -1717,7 +1707,7 @@
  11.432       * @param body body for the function node we are leaving
  11.433       */
  11.434      private static void objectifySymbols(final Block body) {
  11.435 -        body.accept(new NodeVisitor() {
  11.436 +        body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  11.437              private void toObject(final Block block) {
  11.438                  for (final Symbol symbol : block.getSymbols()) {
  11.439                      if (!symbol.isTemp()) {
  11.440 @@ -1761,7 +1751,7 @@
  11.441                  append("] ").
  11.442                  append(printNode ? node.toString() : "").
  11.443                  append(" in '").
  11.444 -                append(getLexicalContext().getCurrentFunction().getName()).
  11.445 +                append(lc.getCurrentFunction().getName()).
  11.446                  append("'");
  11.447              LOG.info(sb);
  11.448              LOG.indent();
  11.449 @@ -1787,7 +1777,7 @@
  11.450                  append("] ").
  11.451                  append(printNode ? node.toString() : "").
  11.452                  append(" in '").
  11.453 -                append(getLexicalContext().getCurrentFunction().getName());
  11.454 +                append(lc.getCurrentFunction().getName());
  11.455  
  11.456              if (node.getSymbol() == null) {
  11.457                  sb.append(" <NO SYMBOL>");
    12.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu May 30 10:58:35 2013 -0700
    12.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Mon Jun 03 23:24:36 2013 -0700
    12.3 @@ -52,16 +52,13 @@
    12.4  import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
    12.5  
    12.6  import java.io.PrintWriter;
    12.7 -import java.util.ArrayDeque;
    12.8  import java.util.ArrayList;
    12.9  import java.util.Arrays;
   12.10 -import java.util.Deque;
   12.11  import java.util.EnumSet;
   12.12 -import java.util.HashMap;
   12.13  import java.util.Iterator;
   12.14  import java.util.LinkedList;
   12.15  import java.util.List;
   12.16 -import java.util.Map;
   12.17 +import java.util.Locale;
   12.18  import java.util.TreeMap;
   12.19  
   12.20  import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
   12.21 @@ -83,11 +80,11 @@
   12.22  import jdk.nashorn.internal.ir.ExecuteNode;
   12.23  import jdk.nashorn.internal.ir.ForNode;
   12.24  import jdk.nashorn.internal.ir.FunctionNode;
   12.25 +import jdk.nashorn.internal.ir.LexicalContext;
   12.26  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
   12.27  import jdk.nashorn.internal.ir.IdentNode;
   12.28  import jdk.nashorn.internal.ir.IfNode;
   12.29  import jdk.nashorn.internal.ir.IndexNode;
   12.30 -import jdk.nashorn.internal.ir.LexicalContext;
   12.31  import jdk.nashorn.internal.ir.LexicalContextNode;
   12.32  import jdk.nashorn.internal.ir.LiteralNode;
   12.33  import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
   12.34 @@ -150,7 +147,7 @@
   12.35   * The CodeGenerator visits nodes only once, tags them as resolved and emits
   12.36   * bytecode for them.
   12.37   */
   12.38 -final class CodeGenerator extends NodeOperatorVisitor {
   12.39 +final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContext> {
   12.40  
   12.41      /** Name of the Global object, cannot be referred to as .class, @see CodeGenerator */
   12.42      private static final String GLOBAL_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "Global";
   12.43 @@ -168,23 +165,12 @@
   12.44      /** How many regexp fields have been emitted */
   12.45      private int regexFieldCount;
   12.46  
   12.47 -    /** Map of shared scope call sites */
   12.48 -    private final Map<SharedScopeCall, SharedScopeCall> scopeCalls = new HashMap<>();
   12.49 -
   12.50 -    /** Compile unit stack - every time we start a sub method (e.g. a split) we push one */
   12.51 -    private final Deque<CompileUnit> compileUnits = new ArrayDeque<>();
   12.52 -
   12.53 -    /** Method emitter stack - every time we start a sub method (e.g. a split) we push one */
   12.54 -    private final Deque<MethodEmitter> methodEmitters = new ArrayDeque<>();
   12.55 -
   12.56 -    /** The discard stack - whenever we enter a discard node we keep track of its return value status -
   12.57 -     *  i.e. should we keep it or throw it away */
   12.58 -    private final Deque<Node> discard = new ArrayDeque<>();
   12.59 -
   12.60 -    // A stack tracking the next free local variable slot in the blocks. There's one entry for every block
   12.61 -    // currently on the lexical context stack.
   12.62 -    private int[] nextFreeSlots = new int[16];
   12.63 -    private int nextFreeSlotsSize = 0;
   12.64 +    /** Line number for last statement. If we encounter a new line number, line number bytecode information
   12.65 +     *  needs to be generated */
   12.66 +    private int lastLineNumber = -1;
   12.67 +
   12.68 +    /** When should we stop caching regexp expressions in fields to limit bytecode size? */
   12.69 +    private static final int MAX_REGEX_FIELDS = 2 * 1024;
   12.70  
   12.71      /** Current method emitter */
   12.72      private MethodEmitter method;
   12.73 @@ -192,20 +178,16 @@
   12.74      /** Current compile unit */
   12.75      private CompileUnit unit;
   12.76  
   12.77 -    private int lastLineNumber = -1;
   12.78 -
   12.79 -    /** When should we stop caching regexp expressions in fields to limit bytecode size? */
   12.80 -    private static final int MAX_REGEX_FIELDS = 2 * 1024;
   12.81 -
   12.82      private static final DebugLogger LOG   = new DebugLogger("codegen", "nashorn.codegen.debug");
   12.83  
   12.84 +
   12.85      /**
   12.86       * Constructor.
   12.87       *
   12.88       * @param compiler
   12.89       */
   12.90      CodeGenerator(final Compiler compiler) {
   12.91 -        super(new DynamicScopeTrackingLexicalContext());
   12.92 +        super(new CodeGeneratorLexicalContext());
   12.93          this.compiler      = compiler;
   12.94          this.callSiteFlags = compiler.getEnv()._callsite_flags;
   12.95      }
   12.96 @@ -217,37 +199,7 @@
   12.97       * @return the correct flags for a call site in the current function
   12.98       */
   12.99      int getCallSiteFlags() {
  12.100 -        return getLexicalContext().getCurrentFunction().isStrict() ? callSiteFlags | CALLSITE_STRICT : callSiteFlags;
  12.101 -    }
  12.102 -
  12.103 -    private void pushMethodEmitter(final MethodEmitter newMethod) {
  12.104 -        methodEmitters.push(newMethod);
  12.105 -        this.method = newMethod;
  12.106 -    }
  12.107 -
  12.108 -    private void popMethodEmitter(final MethodEmitter oldMethod) {
  12.109 -        assert methodEmitters.peek() == oldMethod;
  12.110 -        methodEmitters.pop();
  12.111 -        if (!methodEmitters.isEmpty()) {
  12.112 -            this.method = methodEmitters.peek();
  12.113 -        } else {
  12.114 -            this.method = null;
  12.115 -        }
  12.116 -    }
  12.117 -
  12.118 -    private void push(final CompileUnit newUnit) {
  12.119 -        compileUnits.push(newUnit);
  12.120 -        this.unit = newUnit;
  12.121 -    }
  12.122 -
  12.123 -    private void pop(final CompileUnit oldUnit) {
  12.124 -        assert compileUnits.peek() == oldUnit;
  12.125 -        compileUnits.pop();
  12.126 -        if (!compileUnits.isEmpty()) {
  12.127 -            this.unit = compileUnits.peek();
  12.128 -        } else {
  12.129 -            this.unit = null;
  12.130 -        }
  12.131 +        return lc.getCurrentFunction().isStrict() ? callSiteFlags | CALLSITE_STRICT : callSiteFlags;
  12.132      }
  12.133  
  12.134      /**
  12.135 @@ -265,7 +217,7 @@
  12.136          }
  12.137  
  12.138          final String name   = symbol.getName();
  12.139 -        final Source source = getLexicalContext().getCurrentFunction().getSource();
  12.140 +        final Source source = lc.getCurrentFunction().getSource();
  12.141  
  12.142          if (CompilerConstants.__FILE__.name().equals(name)) {
  12.143              return method.load(source.getName());
  12.144 @@ -291,88 +243,43 @@
  12.145      }
  12.146  
  12.147      /**
  12.148 -     * A lexical context that also tracks if we have any dynamic scopes in the context. Such scopes can have new
  12.149 -     * variables introduced into them at run time - a with block or a function directly containing an eval call.
  12.150 -     */
  12.151 -    private static class DynamicScopeTrackingLexicalContext extends LexicalContext {
  12.152 -        int dynamicScopeCount = 0;
  12.153 -
  12.154 -        @Override
  12.155 -        public <T extends LexicalContextNode> T push(T node) {
  12.156 -            if(isDynamicScopeBoundary(node)) {
  12.157 -                ++dynamicScopeCount;
  12.158 -            }
  12.159 -            return super.push(node);
  12.160 -        }
  12.161 -
  12.162 -        @Override
  12.163 -        public <T extends LexicalContextNode> T pop(T node) {
  12.164 -            final T popped = super.pop(node);
  12.165 -            if(isDynamicScopeBoundary(popped)) {
  12.166 -                --dynamicScopeCount;
  12.167 -            }
  12.168 -            return popped;
  12.169 -        }
  12.170 -
  12.171 -        private boolean isDynamicScopeBoundary(LexicalContextNode node) {
  12.172 -            if(node instanceof Block) {
  12.173 -                // Block's immediate parent is a with node. Note we aren't testing for a WithNode, as that'd capture
  12.174 -                // processing of WithNode.expression too, but it should be unaffected.
  12.175 -                return !isEmpty() && peek() instanceof WithNode;
  12.176 -            } else if(node instanceof FunctionNode) {
  12.177 -                // Function has a direct eval in it (so a top-level "var ..." in the eval code can introduce a new
  12.178 -                // variable into the function's scope), and it isn't strict (as evals in strict functions get an
  12.179 -                // isolated scope).
  12.180 -                return isFunctionDynamicScope((FunctionNode)node);
  12.181 -            }
  12.182 -            return false;
  12.183 -        }
  12.184 -    }
  12.185 -
  12.186 -    boolean inDynamicScope() {
  12.187 -        return ((DynamicScopeTrackingLexicalContext)getLexicalContext()).dynamicScopeCount > 0;
  12.188 -    }
  12.189 -
  12.190 -    static boolean isFunctionDynamicScope(FunctionNode fn) {
  12.191 -        return fn.hasEval() && !fn.isStrict();
  12.192 -    }
  12.193 -
  12.194 -    /**
  12.195       * Check if this symbol can be accessed directly with a putfield or getfield or dynamic load
  12.196       *
  12.197       * @param function function to check for fast scope
  12.198       * @return true if fast scope
  12.199       */
  12.200      private boolean isFastScope(final Symbol symbol) {
  12.201 -        if(!symbol.isScope()) {
  12.202 +        if (!symbol.isScope()) {
  12.203              return false;
  12.204          }
  12.205 -        final LexicalContext lc = getLexicalContext();
  12.206 -        if(!inDynamicScope()) {
  12.207 +
  12.208 +        if (!lc.inDynamicScope()) {
  12.209              // If there's no with or eval in context, and the symbol is marked as scoped, it is fast scoped. Such a
  12.210              // symbol must either be global, or its defining block must need scope.
  12.211              assert symbol.isGlobal() || lc.getDefiningBlock(symbol).needsScope() : symbol.getName();
  12.212              return true;
  12.213          }
  12.214 -        if(symbol.isGlobal()) {
  12.215 +
  12.216 +        if (symbol.isGlobal()) {
  12.217              // Shortcut: if there's a with or eval in context, globals can't be fast scoped
  12.218              return false;
  12.219          }
  12.220 +
  12.221          // Otherwise, check if there's a dynamic scope between use of the symbol and its definition
  12.222          final String name = symbol.getName();
  12.223          boolean previousWasBlock = false;
  12.224          for (final Iterator<LexicalContextNode> it = lc.getAllNodes(); it.hasNext();) {
  12.225              final LexicalContextNode node = it.next();
  12.226 -            if(node instanceof Block) {
  12.227 +            if (node instanceof Block) {
  12.228                  // If this block defines the symbol, then we can fast scope the symbol.
  12.229                  final Block block = (Block)node;
  12.230 -                if(block.getExistingSymbol(name) == symbol) {
  12.231 +                if (block.getExistingSymbol(name) == symbol) {
  12.232                      assert block.needsScope();
  12.233                      return true;
  12.234                  }
  12.235                  previousWasBlock = true;
  12.236              } else {
  12.237 -                if((node instanceof WithNode && previousWasBlock) || (node instanceof FunctionNode && isFunctionDynamicScope((FunctionNode)node))) {
  12.238 +                if ((node instanceof WithNode && previousWasBlock) || (node instanceof FunctionNode && CodeGeneratorLexicalContext.isFunctionDynamicScope((FunctionNode)node))) {
  12.239                      // If we hit a scope that can have symbols introduced into it at run time before finding the defining
  12.240                      // block, the symbol can't be fast scoped. A WithNode only counts if we've immediately seen a block
  12.241                      // before - its block. Otherwise, we are currently processing the WithNode's expression, and that's
  12.242 @@ -387,16 +294,14 @@
  12.243      }
  12.244  
  12.245      private MethodEmitter loadSharedScopeVar(final Type valueType, final Symbol symbol, final int flags) {
  12.246 -        method.load(isFastScope(symbol) ? getScopeProtoDepth(getLexicalContext().getCurrentBlock(), symbol) : -1);
  12.247 -        final SharedScopeCall scopeCall = getScopeGet(valueType, symbol, flags | CALLSITE_FAST_SCOPE);
  12.248 -        scopeCall.generateInvoke(method);
  12.249 -        return method;
  12.250 +        method.load(isFastScope(symbol) ? getScopeProtoDepth(lc.getCurrentBlock(), symbol) : -1);
  12.251 +        final SharedScopeCall scopeCall = lc.getScopeGet(unit, valueType, symbol, flags | CALLSITE_FAST_SCOPE);
  12.252 +        return scopeCall.generateInvoke(method);
  12.253      }
  12.254  
  12.255      private MethodEmitter loadFastScopeVar(final Type valueType, final Symbol symbol, final int flags, final boolean isMethod) {
  12.256          loadFastScopeProto(symbol, false);
  12.257 -        method.dynamicGet(valueType, symbol.getName(), flags | CALLSITE_FAST_SCOPE, isMethod);
  12.258 -        return method;
  12.259 +        return method.dynamicGet(valueType, symbol.getName(), flags | CALLSITE_FAST_SCOPE, isMethod);
  12.260      }
  12.261  
  12.262      private MethodEmitter storeFastScopeVar(final Type valueType, final Symbol symbol, final int flags) {
  12.263 @@ -408,7 +313,7 @@
  12.264      private int getScopeProtoDepth(final Block startingBlock, final Symbol symbol) {
  12.265          int depth = 0;
  12.266          final String name = symbol.getName();
  12.267 -        for(final Iterator<Block> blocks = getLexicalContext().getBlocks(startingBlock); blocks.hasNext();) {
  12.268 +        for(final Iterator<Block> blocks = lc.getBlocks(startingBlock); blocks.hasNext();) {
  12.269              final Block currentBlock = blocks.next();
  12.270              if (currentBlock.getExistingSymbol(name) == symbol) {
  12.271                  return depth;
  12.272 @@ -421,7 +326,7 @@
  12.273      }
  12.274  
  12.275      private void loadFastScopeProto(final Symbol symbol, final boolean swap) {
  12.276 -        final int depth = getScopeProtoDepth(getLexicalContext().getCurrentBlock(), symbol);
  12.277 +        final int depth = getScopeProtoDepth(lc.getCurrentBlock(), symbol);
  12.278          assert depth != -1;
  12.279          if (depth > 0) {
  12.280              if (swap) {
  12.281 @@ -464,7 +369,7 @@
  12.282           */
  12.283          final CodeGenerator codegen = this;
  12.284  
  12.285 -        node.accept(new NodeVisitor() {
  12.286 +        node.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  12.287              @Override
  12.288              public boolean enterIdentNode(final IdentNode identNode) {
  12.289                  loadIdent(identNode);
  12.290 @@ -538,7 +443,7 @@
  12.291              final boolean isInternal = symbol.isParam() || symbol.isInternal() || symbol.isThis() || !symbol.canBeUndefined();
  12.292  
  12.293              if (symbol.hasSlot() && !isInternal) {
  12.294 -                assert symbol.getSymbolType().isNumber() || symbol.getSymbolType().isObject() : "no potentially undefined narrower local vars than doubles are allowed: " + symbol + " in " + getLexicalContext().getCurrentFunction();
  12.295 +                assert symbol.getSymbolType().isNumber() || symbol.getSymbolType().isObject() : "no potentially undefined narrower local vars than doubles are allowed: " + symbol + " in " + lc.getCurrentFunction();
  12.296                  if (symbol.getSymbolType().isNumber()) {
  12.297                      numbers.add(symbol);
  12.298                  } else if (symbol.getSymbolType().isObject()) {
  12.299 @@ -595,7 +500,6 @@
  12.300          if (block.needsScope() && !block.isTerminal()) {
  12.301              popBlockScope(block);
  12.302          }
  12.303 -        --nextFreeSlotsSize;
  12.304          return block;
  12.305      }
  12.306  
  12.307 @@ -624,11 +528,11 @@
  12.308      public boolean enterBreakNode(final BreakNode breakNode) {
  12.309          lineNumber(breakNode);
  12.310  
  12.311 -        final BreakableNode breakFrom = getLexicalContext().getBreakable(breakNode.getLabel());
  12.312 -        for (int i = 0; i < getLexicalContext().getScopeNestingLevelTo(breakFrom); i++) {
  12.313 +        final BreakableNode breakFrom = lc.getBreakable(breakNode.getLabel());
  12.314 +        for (int i = 0; i < lc.getScopeNestingLevelTo(breakFrom); i++) {
  12.315              closeWith();
  12.316          }
  12.317 -        method.splitAwareGoto(getLexicalContext(), breakFrom.getBreakLabel());
  12.318 +        method.splitAwareGoto(lc, breakFrom.getBreakLabel());
  12.319  
  12.320          return false;
  12.321      }
  12.322 @@ -672,11 +576,12 @@
  12.323  
  12.324          final List<Node>   args            = callNode.getArgs();
  12.325          final Node         function        = callNode.getFunction();
  12.326 -        final Block        currentBlock    = getLexicalContext().getCurrentBlock();
  12.327 -
  12.328 -        function.accept(new NodeVisitor() {
  12.329 -
  12.330 -            private void sharedScopeCall(final IdentNode identNode, final int flags) {
  12.331 +        final Block        currentBlock    = lc.getCurrentBlock();
  12.332 +        final CodeGeneratorLexicalContext codegenLexicalContext = lc;
  12.333 +
  12.334 +        function.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  12.335 +
  12.336 +            private MethodEmitter sharedScopeCall(final IdentNode identNode, final int flags) {
  12.337                  final Symbol symbol = identNode.getSymbol();
  12.338                  int    scopeCallFlags = flags;
  12.339                  method.loadCompilerConstant(SCOPE);
  12.340 @@ -688,8 +593,8 @@
  12.341                  }
  12.342                  loadArgs(args);
  12.343                  final Type[] paramTypes = method.getTypesFromStack(args.size());
  12.344 -                final SharedScopeCall scopeCall = getScopeCall(symbol, identNode.getType(), callNode.getType(), paramTypes, scopeCallFlags);
  12.345 -                scopeCall.generateInvoke(method);
  12.346 +                final SharedScopeCall scopeCall = codegenLexicalContext.getScopeCall(unit, symbol, identNode.getType(), callNode.getType(), paramTypes, scopeCallFlags);
  12.347 +                return scopeCall.generateInvoke(method);
  12.348              }
  12.349  
  12.350              private void scopeCall(final IdentNode node, final int flags) {
  12.351 @@ -756,7 +661,7 @@
  12.352                          evalCall(node, flags);
  12.353                      } else if (useCount <= SharedScopeCall.FAST_SCOPE_CALL_THRESHOLD
  12.354                              || (!isFastScope(symbol) && useCount <= SharedScopeCall.SLOW_SCOPE_CALL_THRESHOLD)
  12.355 -                            || CodeGenerator.this.inDynamicScope()) {
  12.356 +                            || CodeGenerator.this.lc.inDynamicScope()) {
  12.357                          scopeCall(node, flags);
  12.358                      } else {
  12.359                          sharedScopeCall(node, flags);
  12.360 @@ -845,11 +750,11 @@
  12.361      public boolean enterContinueNode(final ContinueNode continueNode) {
  12.362          lineNumber(continueNode);
  12.363  
  12.364 -        final LoopNode continueTo = getLexicalContext().getContinueTo(continueNode.getLabel());
  12.365 -        for (int i = 0; i < getLexicalContext().getScopeNestingLevelTo(continueTo); i++) {
  12.366 +        final LoopNode continueTo = lc.getContinueTo(continueNode.getLabel());
  12.367 +        for (int i = 0; i < lc.getScopeNestingLevelTo(continueTo); i++) {
  12.368              closeWith();
  12.369          }
  12.370 -        method.splitAwareGoto(getLexicalContext(), continueTo.getContinueLabel());
  12.371 +        method.splitAwareGoto(lc, continueTo.getContinueLabel());
  12.372  
  12.373          return false;
  12.374      }
  12.375 @@ -875,90 +780,89 @@
  12.376      public boolean enterForNode(final ForNode forNode) {
  12.377          lineNumber(forNode);
  12.378  
  12.379 +        if (forNode.isForIn()) {
  12.380 +            enterForIn(forNode);
  12.381 +        } else {
  12.382 +            enterFor(forNode);
  12.383 +        }
  12.384 +
  12.385 +        return false;
  12.386 +    }
  12.387 +
  12.388 +    private void enterFor(final ForNode forNode) {
  12.389 +        final Node  init   = forNode.getInit();
  12.390          final Node  test   = forNode.getTest();
  12.391          final Block body   = forNode.getBody();
  12.392          final Node  modify = forNode.getModify();
  12.393  
  12.394 -        final Label breakLabel    = forNode.getBreakLabel();
  12.395 -        final Label continueLabel = forNode.getContinueLabel();
  12.396 -        final Label loopLabel     = new Label("loop");
  12.397 +        if (init != null) {
  12.398 +            init.accept(this);
  12.399 +        }
  12.400 +
  12.401 +        final Label loopLabel = new Label("loop");
  12.402 +        final Label testLabel = new Label("test");
  12.403 +
  12.404 +        method._goto(testLabel);
  12.405 +        method.label(loopLabel);
  12.406 +        body.accept(this);
  12.407 +        method.label(forNode.getContinueLabel());
  12.408 +
  12.409 +        if (!body.isTerminal() && modify != null) {
  12.410 +            load(modify);
  12.411 +        }
  12.412 +
  12.413 +        method.label(testLabel);
  12.414 +        if (test != null) {
  12.415 +            new BranchOptimizer(this, method).execute(test, loopLabel, true);
  12.416 +        } else {
  12.417 +            method._goto(loopLabel);
  12.418 +        }
  12.419 +
  12.420 +        method.label(forNode.getBreakLabel());
  12.421 +    }
  12.422 +
  12.423 +    private void enterForIn(final ForNode forNode) {
  12.424 +        final Block body   = forNode.getBody();
  12.425 +        final Node  modify = forNode.getModify();
  12.426 +
  12.427 +        final Symbol iter      = forNode.getIterator();
  12.428 +        final Label  loopLabel = new Label("loop");
  12.429  
  12.430          Node init = forNode.getInit();
  12.431  
  12.432 -        if (forNode.isForIn()) {
  12.433 -            final Symbol iter = forNode.getIterator();
  12.434 -
  12.435 -            // We have to evaluate the optional initializer expression
  12.436 -            // of the iterator variable of the for-in statement.
  12.437 -            if (init instanceof VarNode) {
  12.438 -                init.accept(this);
  12.439 -                init = ((VarNode)init).getName();
  12.440 +        // We have to evaluate the optional initializer expression
  12.441 +        // of the iterator variable of the for-in statement.
  12.442 +        if (init instanceof VarNode) {
  12.443 +            init.accept(this);
  12.444 +            init = ((VarNode)init).getName();
  12.445 +        }
  12.446 +
  12.447 +        load(modify);
  12.448 +        assert modify.getType().isObject();
  12.449 +        method.invoke(forNode.isForEach() ? ScriptRuntime.TO_VALUE_ITERATOR : ScriptRuntime.TO_PROPERTY_ITERATOR);
  12.450 +        method.store(iter);
  12.451 +        method._goto(forNode.getContinueLabel());
  12.452 +        method.label(loopLabel);
  12.453 +
  12.454 +        new Store<Node>(init) {
  12.455 +            @Override
  12.456 +            protected void storeNonDiscard() {
  12.457 +                return;
  12.458              }
  12.459 -
  12.460 -            load(modify);
  12.461 -            assert modify.getType().isObject();
  12.462 -            method.invoke(forNode.isForEach() ? ScriptRuntime.TO_VALUE_ITERATOR : ScriptRuntime.TO_PROPERTY_ITERATOR);
  12.463 -            method.store(iter);
  12.464 -            method._goto(continueLabel);
  12.465 -            method.label(loopLabel);
  12.466 -
  12.467 -            new Store<Node>(init) {
  12.468 -                @Override
  12.469 -                protected void storeNonDiscard() {
  12.470 -                    return;
  12.471 -                }
  12.472 -                @Override
  12.473 -                protected void evaluate() {
  12.474 -                    method.load(iter);
  12.475 -                    method.invoke(interfaceCallNoLookup(Iterator.class, "next", Object.class));
  12.476 -                }
  12.477 -            }.store();
  12.478 -
  12.479 -            body.accept(this);
  12.480 -
  12.481 -            method.label(continueLabel);
  12.482 -            method.load(iter);
  12.483 -            method.invoke(interfaceCallNoLookup(Iterator.class, "hasNext", boolean.class));
  12.484 -            method.ifne(loopLabel);
  12.485 -            method.label(breakLabel);
  12.486 -        } else {
  12.487 -            if (init != null) {
  12.488 -                init.accept(this);
  12.489 +            @Override
  12.490 +            protected void evaluate() {
  12.491 +                method.load(iter);
  12.492 +                method.invoke(interfaceCallNoLookup(Iterator.class, "next", Object.class));
  12.493              }
  12.494 -
  12.495 -            final Label testLabel = new Label("test");
  12.496 -
  12.497 -            method._goto(testLabel);
  12.498 -            method.label(loopLabel);
  12.499 -            body.accept(this);
  12.500 -            method.label(continueLabel);
  12.501 -
  12.502 -            if (!body.isTerminal() && modify != null) {
  12.503 -                load(modify);
  12.504 -            }
  12.505 -
  12.506 -            method.label(testLabel);
  12.507 -            if (test != null) {
  12.508 -                new BranchOptimizer(this, method).execute(test, loopLabel, true);
  12.509 -            } else {
  12.510 -                method._goto(loopLabel);
  12.511 -            }
  12.512 -
  12.513 -            method.label(breakLabel);
  12.514 -        }
  12.515 -
  12.516 -        return false;
  12.517 -    }
  12.518 -
  12.519 -    private static int assignSlots(final Block block, final int firstSlot) {
  12.520 -        int nextSlot = firstSlot;
  12.521 -        for (final Symbol symbol : block.getSymbols()) {
  12.522 -            if (symbol.hasSlot()) {
  12.523 -                symbol.setSlot(nextSlot);
  12.524 -                nextSlot += symbol.slotCount();
  12.525 -            }
  12.526 -        }
  12.527 -        return nextSlot;
  12.528 +        }.store();
  12.529 +
  12.530 +        body.accept(this);
  12.531 +
  12.532 +        method.label(forNode.getContinueLabel());
  12.533 +        method.load(iter);
  12.534 +        method.invoke(interfaceCallNoLookup(Iterator.class, "hasNext", boolean.class));
  12.535 +        method.ifne(loopLabel);
  12.536 +        method.label(forNode.getBreakLabel());
  12.537      }
  12.538  
  12.539      /**
  12.540 @@ -967,24 +871,11 @@
  12.541       * @param block block with local vars.
  12.542       */
  12.543      private void initLocals(final Block block) {
  12.544 -        final boolean isFunctionBody = getLexicalContext().isFunctionBody();
  12.545 -
  12.546 -        final int nextFreeSlot;
  12.547 -        if (isFunctionBody) {
  12.548 -            // On entry to function, start with slot 0
  12.549 -            nextFreeSlot = 0;
  12.550 -        } else {
  12.551 -            // Otherwise, continue from previous block's first free slot
  12.552 -            nextFreeSlot = nextFreeSlots[nextFreeSlotsSize - 1];
  12.553 -        }
  12.554 -        if(nextFreeSlotsSize == nextFreeSlots.length) {
  12.555 -            final int[] newNextFreeSlots = new int[nextFreeSlotsSize * 2];
  12.556 -            System.arraycopy(nextFreeSlots, 0, newNextFreeSlots, 0, nextFreeSlotsSize);
  12.557 -            nextFreeSlots = newNextFreeSlots;
  12.558 -        }
  12.559 -        nextFreeSlots[nextFreeSlotsSize++] = assignSlots(block, nextFreeSlot);
  12.560 -
  12.561 -        final FunctionNode function = getLexicalContext().getCurrentFunction();
  12.562 +        lc.nextFreeSlot(block);
  12.563 +
  12.564 +        final boolean isFunctionBody = lc.isFunctionBody();
  12.565 +
  12.566 +        final FunctionNode function = lc.getCurrentFunction();
  12.567          if (isFunctionBody) {
  12.568              /* Fix the predefined slots so they have numbers >= 0, like varargs. */
  12.569              if (function.needsParentScope()) {
  12.570 @@ -1023,7 +914,7 @@
  12.571                  }
  12.572  
  12.573                  if (symbol.isVar()) {
  12.574 -                    if(varsInScope || symbol.isScope()) {
  12.575 +                    if (varsInScope || symbol.isScope()) {
  12.576                          nameList.add(symbol.getName());
  12.577                          newSymbols.add(symbol);
  12.578                          values.add(null);
  12.579 @@ -1062,7 +953,7 @@
  12.580  
  12.581                  @Override
  12.582                  protected void loadScope(MethodEmitter m) {
  12.583 -                    if(function.needsParentScope()) {
  12.584 +                    if (function.needsParentScope()) {
  12.585                          m.loadCompilerConstant(SCOPE);
  12.586                      } else {
  12.587                          m.loadNull();
  12.588 @@ -1096,7 +987,7 @@
  12.589  
  12.590      private void initArguments(final FunctionNode function) {
  12.591          method.loadCompilerConstant(VARARGS);
  12.592 -        if(function.needsCallee()) {
  12.593 +        if (function.needsCallee()) {
  12.594              method.loadCompilerConstant(CALLEE);
  12.595          } else {
  12.596              // If function is strict mode, "arguments.callee" is not populated, so we don't necessarily need the
  12.597 @@ -1126,10 +1017,10 @@
  12.598          LOG.info("=== BEGIN ", functionNode.getName());
  12.599  
  12.600          assert functionNode.getCompileUnit() != null : "no compile unit for " + functionNode.getName() + " " + Debug.id(functionNode);
  12.601 -        push(functionNode.getCompileUnit());
  12.602 -        assert !compileUnits.isEmpty();
  12.603 -
  12.604 -        pushMethodEmitter(unit.getClassEmitter().method(functionNode));
  12.605 +        unit = lc.pushCompileUnit(functionNode.getCompileUnit());
  12.606 +        assert lc.hasCompileUnits();
  12.607 +
  12.608 +        method = lc.pushMethodEmitter(unit.getClassEmitter().method(functionNode));
  12.609          // Mark end for variable tables.
  12.610          method.begin();
  12.611  
  12.612 @@ -1140,11 +1031,11 @@
  12.613      public Node leaveFunctionNode(final FunctionNode functionNode) {
  12.614          try {
  12.615              method.end(); // wrap up this method
  12.616 -            pop(functionNode.getCompileUnit());
  12.617 -            popMethodEmitter(method);
  12.618 +            unit   = lc.popCompileUnit(functionNode.getCompileUnit());
  12.619 +            method = lc.popMethodEmitter(method);
  12.620              LOG.info("=== END ", functionNode.getName());
  12.621  
  12.622 -            final FunctionNode newFunctionNode = functionNode.setState(getLexicalContext(), CompilationState.EMITTED);
  12.623 +            final FunctionNode newFunctionNode = functionNode.setState(lc, CompilationState.EMITTED);
  12.624  
  12.625              newFunctionObject(newFunctionNode, functionNode);
  12.626              return newFunctionNode;
  12.627 @@ -1238,16 +1129,16 @@
  12.628              final MethodEmitter savedMethod = method;
  12.629  
  12.630              for (final ArrayUnit arrayUnit : units) {
  12.631 -                push(arrayUnit.getCompileUnit());
  12.632 +                unit = lc.pushCompileUnit(arrayUnit.getCompileUnit());
  12.633  
  12.634                  final String className = unit.getUnitClassName();
  12.635 -                final String name      = getLexicalContext().getCurrentFunction().uniqueName(SPLIT_PREFIX.symbolName());
  12.636 +                final String name      = lc.getCurrentFunction().uniqueName(SPLIT_PREFIX.symbolName());
  12.637                  final String signature = methodDescriptor(type, Object.class, ScriptFunction.class, ScriptObject.class, type);
  12.638  
  12.639                  final MethodEmitter me = unit.getClassEmitter().method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), name, signature);
  12.640 -                pushMethodEmitter(me);
  12.641 -
  12.642 -                method.setFunctionNode(getLexicalContext().getCurrentFunction());
  12.643 +                method = lc.pushMethodEmitter(me);
  12.644 +
  12.645 +                method.setFunctionNode(lc.getCurrentFunction());
  12.646                  method.begin();
  12.647  
  12.648                  fixScopeSlot();
  12.649 @@ -1260,7 +1151,7 @@
  12.650  
  12.651                  method._return();
  12.652                  method.end();
  12.653 -                popMethodEmitter(me);
  12.654 +                method = lc.popMethodEmitter(me);
  12.655  
  12.656                  assert method == savedMethod;
  12.657                  method.loadCompilerConstant(THIS);
  12.658 @@ -1271,7 +1162,7 @@
  12.659                  method.swap();
  12.660                  method.invokestatic(className, name, signature);
  12.661  
  12.662 -                pop(unit);
  12.663 +                unit = lc.popCompileUnit(unit);
  12.664              }
  12.665  
  12.666              return method;
  12.667 @@ -1407,7 +1298,7 @@
  12.668              return loadRegexToken(regexToken);
  12.669          }
  12.670          // emit field
  12.671 -        final String       regexName    = getLexicalContext().getCurrentFunction().uniqueName(REGEX_PREFIX.symbolName());
  12.672 +        final String       regexName    = lc.getCurrentFunction().uniqueName(REGEX_PREFIX.symbolName());
  12.673          final ClassEmitter classEmitter = unit.getClassEmitter();
  12.674  
  12.675          classEmitter.field(EnumSet.of(PRIVATE, STATIC), regexName, Object.class);
  12.676 @@ -1545,7 +1436,7 @@
  12.677  
  12.678          method.registerReturn();
  12.679  
  12.680 -        final Type returnType = getLexicalContext().getCurrentFunction().getReturnType();
  12.681 +        final Type returnType = lc.getCurrentFunction().getReturnType();
  12.682  
  12.683          final Node expression = returnNode.getExpression();
  12.684          if (expression != null) {
  12.685 @@ -1756,7 +1647,7 @@
  12.686  
  12.687          final CompileUnit splitCompileUnit = splitNode.getCompileUnit();
  12.688  
  12.689 -        final FunctionNode fn   = getLexicalContext().getCurrentFunction();
  12.690 +        final FunctionNode fn   = lc.getCurrentFunction();
  12.691          final String className  = splitCompileUnit.getUnitClassName();
  12.692          final String name       = splitNode.getName();
  12.693  
  12.694 @@ -1767,7 +1658,7 @@
  12.695                  new Class<?>[] {ScriptFunction.class, Object.class, ScriptObject.class};
  12.696  
  12.697          final MethodEmitter caller = method;
  12.698 -        push(splitCompileUnit);
  12.699 +        unit = lc.pushCompileUnit(splitCompileUnit);
  12.700  
  12.701          final Call splitCall = staticCallNoLookup(
  12.702              className,
  12.703 @@ -1781,8 +1672,7 @@
  12.704                          rtype,
  12.705                          ptypes);
  12.706  
  12.707 -        pushMethodEmitter(splitEmitter);
  12.708 -
  12.709 +        method = lc.pushMethodEmitter(splitEmitter);
  12.710          method.setFunctionNode(fn);
  12.711  
  12.712          if (fn.needsCallee()) {
  12.713 @@ -1809,7 +1699,7 @@
  12.714      }
  12.715  
  12.716      private void fixScopeSlot() {
  12.717 -        if (getLexicalContext().getCurrentFunction().compilerConstant(SCOPE).getSlot() != SCOPE.slot()) {
  12.718 +        if (lc.getCurrentFunction().compilerConstant(SCOPE).getSlot() != SCOPE.slot()) {
  12.719              // TODO hack to move the scope to the expected slot (that's needed because split methods reuse the same slots as the root method)
  12.720              method.load(Type.typeFor(ScriptObject.class), SCOPE.slot());
  12.721              method.storeCompilerConstant(SCOPE);
  12.722 @@ -1826,15 +1716,15 @@
  12.723              // Wrap up this method.
  12.724  
  12.725              method.loadCompilerConstant(RETURN);
  12.726 -            method._return(getLexicalContext().getCurrentFunction().getReturnType());
  12.727 +            method._return(lc.getCurrentFunction().getReturnType());
  12.728              method.end();
  12.729  
  12.730 -            pop(splitNode.getCompileUnit());
  12.731 -            popMethodEmitter(method);
  12.732 +            unit   = lc.popCompileUnit(splitNode.getCompileUnit());
  12.733 +            method = lc.popMethodEmitter(method);
  12.734  
  12.735          } catch (final Throwable t) {
  12.736              Context.printStackTrace(t);
  12.737 -            final VerifyError e = new VerifyError("Code generation bug in \"" + splitNode.getName() + "\": likely stack misaligned: " + t + " " + getLexicalContext().getCurrentFunction().getSource().getName());
  12.738 +            final VerifyError e = new VerifyError("Code generation bug in \"" + splitNode.getName() + "\": likely stack misaligned: " + t + " " + lc.getCurrentFunction().getSource().getName());
  12.739              e.initCause(t);
  12.740              throw e;
  12.741          }
  12.742 @@ -1862,7 +1752,7 @@
  12.743              //has to be zero
  12.744              caller.label(new Label("split_return"));
  12.745              method.loadCompilerConstant(RETURN);
  12.746 -            caller._return(getLexicalContext().getCurrentFunction().getReturnType());
  12.747 +            caller._return(lc.getCurrentFunction().getReturnType());
  12.748              caller.label(breakLabel);
  12.749          } else {
  12.750              assert !targets.isEmpty();
  12.751 @@ -1879,14 +1769,14 @@
  12.752                  caller.label(labels[i - low]);
  12.753                  if (i == 0) {
  12.754                      caller.loadCompilerConstant(RETURN);
  12.755 -                    caller._return(getLexicalContext().getCurrentFunction().getReturnType());
  12.756 +                    caller._return(lc.getCurrentFunction().getReturnType());
  12.757                  } else {
  12.758                      // Clear split state.
  12.759                      caller.loadCompilerConstant(SCOPE);
  12.760                      caller.checkcast(Scope.class);
  12.761                      caller.load(-1);
  12.762                      caller.invoke(Scope.SET_SPLIT_STATE);
  12.763 -                    caller.splitAwareGoto(getLexicalContext(), targets.get(i - 1));
  12.764 +                    caller.splitAwareGoto(lc, targets.get(i - 1));
  12.765                  }
  12.766              }
  12.767              caller.label(breakLabel);
  12.768 @@ -2028,9 +1918,16 @@
  12.769      public boolean enterThrowNode(final ThrowNode throwNode) {
  12.770          lineNumber(throwNode);
  12.771  
  12.772 +        if (throwNode.isSyntheticRethrow()) {
  12.773 +            //do not wrap whatever this is in an ecma exception, just rethrow it
  12.774 +            load(throwNode.getExpression());
  12.775 +            method.athrow();
  12.776 +            return false;
  12.777 +        }
  12.778 +
  12.779          method._new(ECMAException.class).dup();
  12.780  
  12.781 -        final Source source     = getLexicalContext().getCurrentFunction().getSource();
  12.782 +        final Source source     = lc.getCurrentFunction().getSource();
  12.783  
  12.784          final Node   expression = throwNode.getExpression();
  12.785          final int    position   = throwNode.position();
  12.786 @@ -2081,7 +1978,7 @@
  12.787              //TODO this is very ugly - try not to call enter/leave methods directly
  12.788              //better to use the implicit lexical context scoping given by the visitor's
  12.789              //accept method.
  12.790 -            getLexicalContext().push(catchBlock);
  12.791 +            lc.push(catchBlock);
  12.792              enterBlock(catchBlock);
  12.793  
  12.794              final CatchNode catchNode          = (CatchNode)catchBlocks.get(i).getStatements().get(0);
  12.795 @@ -2094,15 +1991,19 @@
  12.796                  protected void storeNonDiscard() {
  12.797                      return;
  12.798                  }
  12.799 +
  12.800                  @Override
  12.801                  protected void evaluate() {
  12.802 +                    if (catchNode.isSyntheticRethrow()) {
  12.803 +                        method.load(symbol);
  12.804 +                        return;
  12.805 +                    }
  12.806                      /*
  12.807                       * If caught object is an instance of ECMAException, then
  12.808                       * bind obj.thrown to the script catch var. Or else bind the
  12.809                       * caught object itself to the script catch var.
  12.810                       */
  12.811                      final Label notEcmaException = new Label("no_ecma_exception");
  12.812 -
  12.813                      method.load(symbol).dup()._instanceof(ECMAException.class).ifeq(notEcmaException);
  12.814                      method.checkcast(ECMAException.class); //TODO is this necessary?
  12.815                      method.getField(ECMAException.THROWN);
  12.816 @@ -2137,7 +2038,7 @@
  12.817              }
  12.818  
  12.819              leaveBlock(catchBlock);
  12.820 -            getLexicalContext().pop(catchBlock);
  12.821 +            lc.pop(catchBlock);
  12.822          }
  12.823  
  12.824          method.label(skip);
  12.825 @@ -2234,7 +2135,7 @@
  12.826          final boolean hasScope = method.hasScope();
  12.827  
  12.828          final Label tryLabel;
  12.829 -        if(hasScope) {
  12.830 +        if (hasScope) {
  12.831              tryLabel = new Label("with_try");
  12.832              method.label(tryLabel);
  12.833              method.loadCompilerConstant(SCOPE);
  12.834 @@ -2245,7 +2146,7 @@
  12.835          load(expression);
  12.836          assert expression.getType().isObject() : "with expression needs to be object: " + expression;
  12.837  
  12.838 -        if(hasScope) {
  12.839 +        if (hasScope) {
  12.840              // Construct a WithObject if we have a scope
  12.841              method.invoke(ScriptRuntime.OPEN_WITH);
  12.842              method.storeCompilerConstant(SCOPE);
  12.843 @@ -2285,7 +2186,7 @@
  12.844      @Override
  12.845      public boolean enterADD(final UnaryNode unaryNode) {
  12.846          load(unaryNode.rhs());
  12.847 -        assert unaryNode.rhs().getType().isNumber();
  12.848 +        assert unaryNode.rhs().getType().isNumber() : unaryNode.rhs().getType() + " "+ unaryNode.getSymbol();
  12.849          method.store(unaryNode.getSymbol());
  12.850  
  12.851          return false;
  12.852 @@ -2320,7 +2221,7 @@
  12.853                  }
  12.854                  method.convert(Type.OBJECT);
  12.855              } else if (value instanceof Boolean) {
  12.856 -                method.getField(staticField(Boolean.class, value.toString().toUpperCase(), Boolean.class));
  12.857 +                method.getField(staticField(Boolean.class, value.toString().toUpperCase(Locale.ENGLISH), Boolean.class));
  12.858              } else {
  12.859                  load(rhs);
  12.860                  method.convert(unaryNode.getType());
  12.861 @@ -2387,13 +2288,13 @@
  12.862      public boolean enterDISCARD(final UnaryNode unaryNode) {
  12.863          final Node rhs = unaryNode.rhs();
  12.864  
  12.865 -        discard.push(rhs);
  12.866 +        lc.pushDiscard(rhs);
  12.867          load(rhs);
  12.868  
  12.869 -        if (discard.peek() == rhs) {
  12.870 +        if (lc.getCurrentDiscard() == rhs) {
  12.871              assert !rhs.isAssignment();
  12.872              method.pop();
  12.873 -            discard.pop();
  12.874 +            lc.popDiscard();
  12.875          }
  12.876  
  12.877          return false;
  12.878 @@ -2445,7 +2346,7 @@
  12.879          assert lhs.getType().equals(rhs.getType()) && lhs.getType().equals(type) : lhs.getType() + " != " + rhs.getType() + " != " + type + " " + new ASTWriter(lhs) + " " + new ASTWriter(rhs);
  12.880          load(lhs);
  12.881          load(rhs);
  12.882 -        method.add();
  12.883 +        method.add(); //if the symbol is optimistic, it always needs to be written, not on the stack?
  12.884          method.store(symbol);
  12.885          return null;
  12.886      }
  12.887 @@ -2989,53 +2890,12 @@
  12.888       * Generate all shared scope calls generated during codegen.
  12.889       */
  12.890      protected void generateScopeCalls() {
  12.891 -        for (final SharedScopeCall scopeAccess : scopeCalls.values()) {
  12.892 +        for (final SharedScopeCall scopeAccess : lc.getScopeCalls()) {
  12.893              scopeAccess.generateScopeCall();
  12.894          }
  12.895      }
  12.896  
  12.897      /**
  12.898 -     * Get a shared static method representing a dynamic scope callsite.
  12.899 -     *
  12.900 -     * @param symbol the symbol
  12.901 -     * @param valueType the value type of the symbol
  12.902 -     * @param returnType the return type
  12.903 -     * @param paramTypes the parameter types
  12.904 -     * @param flags the callsite flags
  12.905 -     * @return an object representing a shared scope call
  12.906 -     */
  12.907 -    private SharedScopeCall getScopeCall(final Symbol symbol, final Type valueType, final Type returnType,
  12.908 -                                         final Type[] paramTypes, final int flags) {
  12.909 -
  12.910 -        final SharedScopeCall scopeCall = new SharedScopeCall(symbol, valueType, returnType, paramTypes, flags);
  12.911 -        if (scopeCalls.containsKey(scopeCall)) {
  12.912 -            return scopeCalls.get(scopeCall);
  12.913 -        }
  12.914 -        scopeCall.setClassAndName(unit, getLexicalContext().getCurrentFunction().uniqueName("scopeCall"));
  12.915 -        scopeCalls.put(scopeCall, scopeCall);
  12.916 -        return scopeCall;
  12.917 -    }
  12.918 -
  12.919 -    /**
  12.920 -     * Get a shared static method representing a dynamic scope get access.
  12.921 -     *
  12.922 -     * @param type the type of the variable
  12.923 -     * @param symbol the symbol
  12.924 -     * @param flags the callsite flags
  12.925 -     * @return an object representing a shared scope call
  12.926 -     */
  12.927 -    private SharedScopeCall getScopeGet(final Type type, final Symbol symbol, final int flags) {
  12.928 -
  12.929 -        final SharedScopeCall scopeCall = new SharedScopeCall(symbol, type, type, null, flags);
  12.930 -        if (scopeCalls.containsKey(scopeCall)) {
  12.931 -            return scopeCalls.get(scopeCall);
  12.932 -        }
  12.933 -        scopeCall.setClassAndName(unit, getLexicalContext().getCurrentFunction().uniqueName("scopeCall"));
  12.934 -        scopeCalls.put(scopeCall, scopeCall);
  12.935 -        return scopeCall;
  12.936 -    }
  12.937 -
  12.938 -    /**
  12.939       * Debug code used to print symbols
  12.940       *
  12.941       * @param block the block we are in
  12.942 @@ -3129,14 +2989,14 @@
  12.943  
  12.944          private void prologue() {
  12.945              final Symbol targetSymbol = target.getSymbol();
  12.946 -            final Symbol scopeSymbol  = getLexicalContext().getCurrentFunction().compilerConstant(SCOPE);
  12.947 +            final Symbol scopeSymbol  = lc.getCurrentFunction().compilerConstant(SCOPE);
  12.948  
  12.949              /**
  12.950               * This loads the parts of the target, e.g base and index. they are kept
  12.951               * on the stack throughout the store and used at the end to execute it
  12.952               */
  12.953  
  12.954 -            target.accept(new NodeVisitor() {
  12.955 +            target.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  12.956                  @Override
  12.957                  public boolean enterIdentNode(final IdentNode node) {
  12.958                      if (targetSymbol.isScope()) {
  12.959 @@ -3203,22 +3063,21 @@
  12.960           * @return the quick symbol
  12.961           */
  12.962          private Symbol quickSymbol(final Type type, final String prefix) {
  12.963 -            final String name = getLexicalContext().getCurrentFunction().uniqueName(prefix);
  12.964 +            final String name = lc.getCurrentFunction().uniqueName(prefix);
  12.965              final Symbol symbol = new Symbol(name, IS_TEMP | IS_INTERNAL);
  12.966  
  12.967              symbol.setType(type);
  12.968 -            final int quickSlot = nextFreeSlots[nextFreeSlotsSize - 1];
  12.969 -            nextFreeSlots[nextFreeSlotsSize - 1] = quickSlot + symbol.slotCount();
  12.970 -            symbol.setSlot(quickSlot);
  12.971 +
  12.972 +            symbol.setSlot(lc.quickSlot(symbol));
  12.973  
  12.974              return symbol;
  12.975          }
  12.976  
  12.977          // store the result that "lives on" after the op, e.g. "i" in i++ postfix.
  12.978          protected void storeNonDiscard() {
  12.979 -            if (discard.peek() == assignNode) {
  12.980 +            if (lc.getCurrentDiscard() == assignNode) {
  12.981                  assert assignNode.isAssignment();
  12.982 -                discard.pop();
  12.983 +                lc.popDiscard();
  12.984                  return;
  12.985              }
  12.986  
  12.987 @@ -3246,7 +3105,7 @@
  12.988               */
  12.989              method.convert(target.getType());
  12.990  
  12.991 -            target.accept(new NodeVisitor() {
  12.992 +            target.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  12.993                  @Override
  12.994                  protected boolean enterDefault(Node node) {
  12.995                      throw new AssertionError("Unexpected node " + node + " in store epilogue");
  12.996 @@ -3308,7 +3167,6 @@
  12.997      }
  12.998  
  12.999      private void newFunctionObject(final FunctionNode functionNode, final FunctionNode originalFunctionNode) {
 12.1000 -        final LexicalContext lc = getLexicalContext();
 12.1001          assert lc.peek() == functionNode;
 12.1002          // We don't emit a ScriptFunction on stack for:
 12.1003          // 1. the outermost compiled function (as there's no code being generated in its outer context that'd need it
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGeneratorLexicalContext.java	Mon Jun 03 23:24:36 2013 -0700
    13.3 @@ -0,0 +1,235 @@
    13.4 +/*
    13.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 + *
    13.8 + * This code is free software; you can redistribute it and/or modify it
    13.9 + * under the terms of the GNU General Public License version 2 only, as
   13.10 + * published by the Free Software Foundation.  Oracle designates this
   13.11 + * particular file as subject to the "Classpath" exception as provided
   13.12 + * by Oracle in the LICENSE file that accompanied this code.
   13.13 + *
   13.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   13.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.17 + * version 2 for more details (a copy is included in the LICENSE file that
   13.18 + * accompanied this code).
   13.19 + *
   13.20 + * You should have received a copy of the GNU General Public License version
   13.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   13.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.23 + *
   13.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.25 + * or visit www.oracle.com if you need additional information or have any
   13.26 + * questions.
   13.27 + */
   13.28 +
   13.29 +package jdk.nashorn.internal.codegen;
   13.30 +
   13.31 +import java.util.ArrayDeque;
   13.32 +import java.util.Collection;
   13.33 +import java.util.Collections;
   13.34 +import java.util.Deque;
   13.35 +import java.util.HashMap;
   13.36 +import java.util.Map;
   13.37 +
   13.38 +import jdk.nashorn.internal.codegen.types.Type;
   13.39 +import jdk.nashorn.internal.ir.Block;
   13.40 +import jdk.nashorn.internal.ir.FunctionNode;
   13.41 +import jdk.nashorn.internal.ir.LexicalContext;
   13.42 +import jdk.nashorn.internal.ir.LexicalContextNode;
   13.43 +import jdk.nashorn.internal.ir.Node;
   13.44 +import jdk.nashorn.internal.ir.Symbol;
   13.45 +import jdk.nashorn.internal.ir.WithNode;
   13.46 +
   13.47 +/**
   13.48 + * A lexical context that also tracks if we have any dynamic scopes in the context. Such scopes can have new
   13.49 + * variables introduced into them at run time - a with block or a function directly containing an eval call.
   13.50 + * Furthermore, this class keeps track of current discard state, which the current method emitter being used is,
   13.51 + * the current compile unit, and local variable indexes
   13.52 + */
   13.53 +final class CodeGeneratorLexicalContext extends LexicalContext {
   13.54 +    private int dynamicScopeCount;
   13.55 +
   13.56 +    /** Map of shared scope call sites */
   13.57 +    private final Map<SharedScopeCall, SharedScopeCall> scopeCalls = new HashMap<>();
   13.58 +
   13.59 +    /** Compile unit stack - every time we start a sub method (e.g. a split) we push one */
   13.60 +    private final Deque<CompileUnit> compileUnits = new ArrayDeque<>();
   13.61 +
   13.62 +    /** Method emitter stack - every time we start a sub method (e.g. a split) we push one */
   13.63 +    private final Deque<MethodEmitter> methodEmitters = new ArrayDeque<>();
   13.64 +
   13.65 +    /** The discard stack - whenever we enter a discard node we keep track of its return value status -
   13.66 +     *  i.e. should we keep it or throw it away */
   13.67 +    private final Deque<Node> discard = new ArrayDeque<>();
   13.68 +
   13.69 +    /** A stack tracking the next free local variable slot in the blocks. There's one entry for every block
   13.70 +     *  currently on the lexical context stack. */
   13.71 +    private int[] nextFreeSlots = new int[16];
   13.72 +
   13.73 +    /** size of next free slot vector */
   13.74 +    private int nextFreeSlotsSize;
   13.75 +
   13.76 +    @Override
   13.77 +    public <T extends LexicalContextNode> T push(final T node) {
   13.78 +        if (isDynamicScopeBoundary(node)) {
   13.79 +            ++dynamicScopeCount;
   13.80 +        }
   13.81 +        return super.push(node);
   13.82 +    }
   13.83 +
   13.84 +    @Override
   13.85 +    public <T extends LexicalContextNode> T pop(final T node) {
   13.86 +        final T popped = super.pop(node);
   13.87 +        if (isDynamicScopeBoundary(popped)) {
   13.88 +            --dynamicScopeCount;
   13.89 +        }
   13.90 +        if (node instanceof Block) {
   13.91 +            --nextFreeSlotsSize;
   13.92 +        }
   13.93 +        return popped;
   13.94 +    }
   13.95 +
   13.96 +    private boolean isDynamicScopeBoundary(final LexicalContextNode node) {
   13.97 +        if (node instanceof Block) {
   13.98 +            // Block's immediate parent is a with node. Note we aren't testing for a WithNode, as that'd capture
   13.99 +            // processing of WithNode.expression too, but it should be unaffected.
  13.100 +            return !isEmpty() && peek() instanceof WithNode;
  13.101 +        } else if (node instanceof FunctionNode) {
  13.102 +            // Function has a direct eval in it (so a top-level "var ..." in the eval code can introduce a new
  13.103 +            // variable into the function's scope), and it isn't strict (as evals in strict functions get an
  13.104 +            // isolated scope).
  13.105 +            return isFunctionDynamicScope((FunctionNode)node);
  13.106 +        }
  13.107 +        return false;
  13.108 +    }
  13.109 +
  13.110 +    boolean inDynamicScope() {
  13.111 +        return dynamicScopeCount > 0;
  13.112 +    }
  13.113 +
  13.114 +    static boolean isFunctionDynamicScope(FunctionNode fn) {
  13.115 +        return fn.hasEval() && !fn.isStrict();
  13.116 +    }
  13.117 +
  13.118 +    MethodEmitter pushMethodEmitter(final MethodEmitter newMethod) {
  13.119 +        methodEmitters.push(newMethod);
  13.120 +        return newMethod;
  13.121 +    }
  13.122 +
  13.123 +    MethodEmitter popMethodEmitter(final MethodEmitter oldMethod) {
  13.124 +        assert methodEmitters.peek() == oldMethod;
  13.125 +        methodEmitters.pop();
  13.126 +        return methodEmitters.isEmpty() ? null : methodEmitters.peek();
  13.127 +    }
  13.128 +
  13.129 +    CompileUnit pushCompileUnit(final CompileUnit newUnit) {
  13.130 +        compileUnits.push(newUnit);
  13.131 +        return newUnit;
  13.132 +    }
  13.133 +
  13.134 +    CompileUnit popCompileUnit(final CompileUnit oldUnit) {
  13.135 +        assert compileUnits.peek() == oldUnit;
  13.136 +        compileUnits.pop();
  13.137 +        return compileUnits.isEmpty() ? null : compileUnits.peek();
  13.138 +    }
  13.139 +
  13.140 +    boolean hasCompileUnits() {
  13.141 +        return !compileUnits.isEmpty();
  13.142 +    }
  13.143 +
  13.144 +    Collection<SharedScopeCall> getScopeCalls() {
  13.145 +        return Collections.unmodifiableCollection(scopeCalls.values());
  13.146 +    }
  13.147 +
  13.148 +    /**
  13.149 +     * Get a shared static method representing a dynamic scope callsite.
  13.150 +     *
  13.151 +     * @param unit current compile unit
  13.152 +     * @param symbol the symbol
  13.153 +     * @param valueType the value type of the symbol
  13.154 +     * @param returnType the return type
  13.155 +     * @param paramTypes the parameter types
  13.156 +     * @param flags the callsite flags
  13.157 +     * @return an object representing a shared scope call
  13.158 +     */
  13.159 +    SharedScopeCall getScopeCall(final CompileUnit unit, final Symbol symbol, final Type valueType, final Type returnType, final Type[] paramTypes, final int flags) {
  13.160 +        final SharedScopeCall scopeCall = new SharedScopeCall(symbol, valueType, returnType, paramTypes, flags);
  13.161 +        if (scopeCalls.containsKey(scopeCall)) {
  13.162 +            return scopeCalls.get(scopeCall);
  13.163 +        }
  13.164 +        scopeCall.setClassAndName(unit, getCurrentFunction().uniqueName("scopeCall"));
  13.165 +        scopeCalls.put(scopeCall, scopeCall);
  13.166 +        return scopeCall;
  13.167 +    }
  13.168 +
  13.169 +    /**
  13.170 +     * Get a shared static method representing a dynamic scope get access.
  13.171 +     *
  13.172 +     * @param unit current compile unit
  13.173 +     * @param type the type of the variable
  13.174 +     * @param symbol the symbol
  13.175 +     * @param flags the callsite flags
  13.176 +     * @return an object representing a shared scope call
  13.177 +     */
  13.178 +    SharedScopeCall getScopeGet(final CompileUnit unit, final Type type, final Symbol symbol, final int flags) {
  13.179 +        final SharedScopeCall scopeCall = new SharedScopeCall(symbol, type, type, null, flags);
  13.180 +        if (scopeCalls.containsKey(scopeCall)) {
  13.181 +            return scopeCalls.get(scopeCall);
  13.182 +        }
  13.183 +        scopeCall.setClassAndName(unit, getCurrentFunction().uniqueName("scopeCall"));
  13.184 +        scopeCalls.put(scopeCall, scopeCall);
  13.185 +        return scopeCall;
  13.186 +    }
  13.187 +
  13.188 +
  13.189 +    void nextFreeSlot(final Block block) {
  13.190 +        final boolean isFunctionBody = isFunctionBody();
  13.191 +
  13.192 +        final int nextFreeSlot;
  13.193 +        if (isFunctionBody) {
  13.194 +            // On entry to function, start with slot 0
  13.195 +            nextFreeSlot = 0;
  13.196 +        } else {
  13.197 +            // Otherwise, continue from previous block's first free slot
  13.198 +            nextFreeSlot = nextFreeSlots[nextFreeSlotsSize - 1];
  13.199 +        }
  13.200 +        if (nextFreeSlotsSize == nextFreeSlots.length) {
  13.201 +            final int[] newNextFreeSlots = new int[nextFreeSlotsSize * 2];
  13.202 +            System.arraycopy(nextFreeSlots, 0, newNextFreeSlots, 0, nextFreeSlotsSize);
  13.203 +            nextFreeSlots = newNextFreeSlots;
  13.204 +        }
  13.205 +        nextFreeSlots[nextFreeSlotsSize++] = assignSlots(block, nextFreeSlot);
  13.206 +    }
  13.207 +
  13.208 +    private static int assignSlots(final Block block, final int firstSlot) {
  13.209 +        int nextSlot = firstSlot;
  13.210 +        for (final Symbol symbol : block.getSymbols()) {
  13.211 +            if (symbol.hasSlot()) {
  13.212 +                symbol.setSlot(nextSlot);
  13.213 +                nextSlot += symbol.slotCount();
  13.214 +            }
  13.215 +        }
  13.216 +        return nextSlot;
  13.217 +    }
  13.218 +
  13.219 +    void pushDiscard(final Node node) {
  13.220 +        discard.push(node);
  13.221 +    }
  13.222 +
  13.223 +    Node popDiscard() {
  13.224 +        return discard.pop();
  13.225 +    }
  13.226 +
  13.227 +    Node getCurrentDiscard() {
  13.228 +        return discard.peek();
  13.229 +    }
  13.230 +
  13.231 +    int quickSlot(final Symbol symbol) {
  13.232 +        final int quickSlot = nextFreeSlots[nextFreeSlotsSize - 1];
  13.233 +        nextFreeSlots[nextFreeSlotsSize - 1] = quickSlot + symbol.slotCount();
  13.234 +        return quickSlot;
  13.235 +    }
  13.236 +
  13.237 +}
  13.238 +
    14.1 --- a/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Thu May 30 10:58:35 2013 -0700
    14.2 +++ b/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Mon Jun 03 23:24:36 2013 -0700
    14.3 @@ -11,20 +11,27 @@
    14.4  import java.io.File;
    14.5  import java.io.FileOutputStream;
    14.6  import java.io.IOException;
    14.7 +import java.util.ArrayDeque;
    14.8 +import java.util.ArrayList;
    14.9 +import java.util.Deque;
   14.10  import java.util.EnumSet;
   14.11  import java.util.HashSet;
   14.12 +import java.util.List;
   14.13  import java.util.Set;
   14.14 +
   14.15 +import jdk.nashorn.internal.codegen.types.Range;
   14.16  import jdk.nashorn.internal.codegen.types.Type;
   14.17  import jdk.nashorn.internal.ir.Block;
   14.18  import jdk.nashorn.internal.ir.CallNode;
   14.19  import jdk.nashorn.internal.ir.FunctionNode;
   14.20 +import jdk.nashorn.internal.ir.LexicalContext;
   14.21 +import jdk.nashorn.internal.ir.ReturnNode;
   14.22 +import jdk.nashorn.internal.ir.Symbol;
   14.23  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
   14.24 -import jdk.nashorn.internal.ir.LexicalContext;
   14.25  import jdk.nashorn.internal.ir.Node;
   14.26  import jdk.nashorn.internal.ir.TemporarySymbols;
   14.27  import jdk.nashorn.internal.ir.debug.ASTWriter;
   14.28  import jdk.nashorn.internal.ir.debug.PrintVisitor;
   14.29 -import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
   14.30  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   14.31  import jdk.nashorn.internal.runtime.ECMAErrors;
   14.32  import jdk.nashorn.internal.runtime.ScriptEnvironment;
   14.33 @@ -66,7 +73,7 @@
   14.34  
   14.35              FunctionNode newFunctionNode = outermostFunctionNode;
   14.36  
   14.37 -            newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor() {
   14.38 +            newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   14.39                  // self references are done with invokestatic and thus cannot
   14.40                  // have trampolines - never lazy
   14.41                  @Override
   14.42 @@ -99,10 +106,9 @@
   14.43                  lazy.remove(node);
   14.44              }
   14.45  
   14.46 -            newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeOperatorVisitor() {
   14.47 +            newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   14.48                  @Override
   14.49                  public Node leaveFunctionNode(final FunctionNode functionNode) {
   14.50 -                    final LexicalContext lc = getLexicalContext();
   14.51                      if (lazy.contains(functionNode)) {
   14.52                          Compiler.LOG.fine(
   14.53                                  "Marking ",
   14.54 @@ -174,7 +180,7 @@
   14.55          FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
   14.56              final TemporarySymbols ts = compiler.getTemporarySymbols();
   14.57              final FunctionNode newFunctionNode = (FunctionNode)enterAttr(fn, ts).accept(new Attr(ts));
   14.58 -            if(compiler.getEnv()._print_mem_usage) {
   14.59 +            if (compiler.getEnv()._print_mem_usage) {
   14.60                  Compiler.LOG.info("Attr temporary symbol count: " + ts.getTotalSymbolCount());
   14.61              }
   14.62              return newFunctionNode;
   14.63 @@ -186,12 +192,11 @@
   14.64           * @param functionNode node where to start iterating
   14.65           */
   14.66          private FunctionNode enterAttr(final FunctionNode functionNode, final TemporarySymbols ts) {
   14.67 -            return (FunctionNode)functionNode.accept(new NodeVisitor() {
   14.68 +            return (FunctionNode)functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   14.69                  @Override
   14.70                  public Node leaveFunctionNode(final FunctionNode node) {
   14.71 -                    final LexicalContext lc = getLexicalContext();
   14.72                      if (node.isLazy()) {
   14.73 -                        FunctionNode newNode = node.setReturnType(getLexicalContext(), Type.OBJECT);
   14.74 +                        FunctionNode newNode = node.setReturnType(lc, Type.OBJECT);
   14.75                          return ts.ensureSymbol(lc, Type.OBJECT, newNode);
   14.76                      }
   14.77                      //node may have a reference here that needs to be nulled if it was referred to by
   14.78 @@ -208,6 +213,89 @@
   14.79      },
   14.80  
   14.81      /*
   14.82 +     * Range analysis
   14.83 +     *    Conservatively prove that certain variables can be narrower than
   14.84 +     *    the most generic number type
   14.85 +     */
   14.86 +    RANGE_ANALYSIS_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR)) {
   14.87 +        @Override
   14.88 +        FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
   14.89 +            if (!compiler.getEnv()._range_analysis) {
   14.90 +                return fn;
   14.91 +            }
   14.92 +
   14.93 +            FunctionNode newFunctionNode = (FunctionNode)fn.accept(new RangeAnalyzer());
   14.94 +            final List<ReturnNode> returns = new ArrayList<>();
   14.95 +
   14.96 +            newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   14.97 +                private final Deque<ArrayList<ReturnNode>> returnStack = new ArrayDeque<>();
   14.98 +
   14.99 +                @Override
  14.100 +                public boolean enterFunctionNode(final FunctionNode functionNode) {
  14.101 +                    returnStack.push(new ArrayList<ReturnNode>());
  14.102 +                    return true;
  14.103 +                }
  14.104 +
  14.105 +                @Override
  14.106 +                public Node leaveFunctionNode(final FunctionNode functionNode) {
  14.107 +                    Type returnType = Type.UNKNOWN;
  14.108 +                    for (final ReturnNode ret : returnStack.pop()) {
  14.109 +                        if (ret.getExpression() == null) {
  14.110 +                            returnType = Type.OBJECT;
  14.111 +                            break;
  14.112 +                        }
  14.113 +                        returnType = Type.widest(returnType, ret.getExpression().getType());
  14.114 +                    }
  14.115 +                    return functionNode.setReturnType(lc, returnType);
  14.116 +                }
  14.117 +
  14.118 +                @Override
  14.119 +                public Node leaveReturnNode(final ReturnNode returnNode) {
  14.120 +                    final ReturnNode result = (ReturnNode)leaveDefault(returnNode);
  14.121 +                    returns.add(result);
  14.122 +                    return result;
  14.123 +                }
  14.124 +
  14.125 +                @Override
  14.126 +                public Node leaveDefault(final Node node) {
  14.127 +                    final Symbol symbol = node.getSymbol();
  14.128 +                    if (symbol != null) {
  14.129 +                        final Range range  = symbol.getRange();
  14.130 +                        final Type  symbolType = symbol.getSymbolType();
  14.131 +                        if (!symbolType.isNumeric()) {
  14.132 +                            return node;
  14.133 +                        }
  14.134 +                        final Type  rangeType  = range.getType();
  14.135 +                        if (!Type.areEquivalent(symbolType, rangeType) && Type.widest(symbolType, rangeType) == symbolType) { //we can narrow range
  14.136 +                            RangeAnalyzer.LOG.info("[", lc.getCurrentFunction().getName(), "] ", symbol, " can be ", range.getType(), " ", symbol.getRange());
  14.137 +                            return node.setSymbol(lc, symbol.setTypeOverrideShared(range.getType(), compiler.getTemporarySymbols()));
  14.138 +                        }
  14.139 +                    }
  14.140 +                    return node;
  14.141 +                }
  14.142 +            });
  14.143 +
  14.144 +            Type returnType = Type.UNKNOWN;
  14.145 +            for (final ReturnNode node : returns) {
  14.146 +                if (node.getExpression() != null) {
  14.147 +                    returnType = Type.widest(returnType, node.getExpression().getType());
  14.148 +                } else {
  14.149 +                    returnType = Type.OBJECT;
  14.150 +                    break;
  14.151 +                }
  14.152 +            }
  14.153 +
  14.154 +            return newFunctionNode.setReturnType(null, returnType);
  14.155 +        }
  14.156 +
  14.157 +        @Override
  14.158 +        public String toString() {
  14.159 +            return "[Range Analysis]";
  14.160 +        }
  14.161 +    },
  14.162 +
  14.163 +
  14.164 +    /*
  14.165       * Splitter Split the AST into several compile units based on a size
  14.166       * heuristic Splitter needs attributed AST for weight calculations (e.g. is
  14.167       * a + b a ScriptRuntime.ADD with call overhead or a dadd with much less).
  14.168 @@ -218,7 +306,6 @@
  14.169          FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
  14.170              final CompileUnit outermostCompileUnit = compiler.addCompileUnit(compiler.firstCompileUnitName());
  14.171  
  14.172 -//            assert fn.isProgram() ;
  14.173              final FunctionNode newFunctionNode = new Splitter(compiler, fn, outermostCompileUnit).split(fn);
  14.174  
  14.175              assert newFunctionNode.getCompileUnit() == outermostCompileUnit : "fn.compileUnit (" + newFunctionNode.getCompileUnit() + ") != " + outermostCompileUnit;
    15.1 --- a/src/jdk/nashorn/internal/codegen/Compiler.java	Thu May 30 10:58:35 2013 -0700
    15.2 +++ b/src/jdk/nashorn/internal/codegen/Compiler.java	Mon Jun 03 23:24:36 2013 -0700
    15.3 @@ -99,7 +99,7 @@
    15.4  
    15.5      private boolean strict;
    15.6  
    15.7 -    private CodeInstaller<ScriptEnvironment> installer;
    15.8 +    private final CodeInstaller<ScriptEnvironment> installer;
    15.9  
   15.10      private final TemporarySymbols temporarySymbols = new TemporarySymbols();
   15.11  
   15.12 @@ -219,6 +219,7 @@
   15.13          CompilationPhase.CONSTANT_FOLDING_PHASE,
   15.14          CompilationPhase.LOWERING_PHASE,
   15.15          CompilationPhase.ATTRIBUTION_PHASE,
   15.16 +        CompilationPhase.RANGE_ANALYSIS_PHASE,
   15.17          CompilationPhase.SPLITTING_PHASE,
   15.18          CompilationPhase.TYPE_FINALIZATION_PHASE,
   15.19          CompilationPhase.BYTECODE_GENERATION_PHASE);
   15.20 @@ -384,6 +385,8 @@
   15.21          if (info) {
   15.22              final StringBuilder sb = new StringBuilder();
   15.23              sb.append("Compile job for '").
   15.24 +                append(newFunctionNode.getSource()).
   15.25 +                append(':').
   15.26                  append(newFunctionNode.getName()).
   15.27                  append("' finished");
   15.28  
   15.29 @@ -487,7 +490,7 @@
   15.30          }
   15.31  
   15.32          if (sb != null) {
   15.33 -            LOG.info(sb);
   15.34 +            LOG.fine(sb);
   15.35          }
   15.36  
   15.37          return rootClass;
    16.1 --- a/src/jdk/nashorn/internal/codegen/CompilerConstants.java	Thu May 30 10:58:35 2013 -0700
    16.2 +++ b/src/jdk/nashorn/internal/codegen/CompilerConstants.java	Mon Jun 03 23:24:36 2013 -0700
    16.3 @@ -262,7 +262,7 @@
    16.4       * @return the internal descriptor for this type
    16.5       */
    16.6      public static String typeDescriptor(final Class<?> clazz) {
    16.7 -        return Type.getDescriptor(clazz);
    16.8 +        return Type.typeFor(clazz).getDescriptor();
    16.9      }
   16.10  
   16.11      /**
    17.1 --- a/src/jdk/nashorn/internal/codegen/FinalizeTypes.java	Thu May 30 10:58:35 2013 -0700
    17.2 +++ b/src/jdk/nashorn/internal/codegen/FinalizeTypes.java	Mon Jun 03 23:24:36 2013 -0700
    17.3 @@ -31,6 +31,7 @@
    17.4  import java.util.ArrayList;
    17.5  import java.util.HashSet;
    17.6  import java.util.List;
    17.7 +
    17.8  import jdk.nashorn.internal.codegen.types.Type;
    17.9  import jdk.nashorn.internal.ir.AccessNode;
   17.10  import jdk.nashorn.internal.ir.Assignment;
   17.11 @@ -84,13 +85,14 @@
   17.12   * and frame optimizations
   17.13   */
   17.14  
   17.15 -final class FinalizeTypes extends NodeOperatorVisitor {
   17.16 +final class FinalizeTypes extends NodeOperatorVisitor<LexicalContext> {
   17.17  
   17.18      private static final DebugLogger LOG = new DebugLogger("finalize");
   17.19  
   17.20      private final TemporarySymbols temporarySymbols;
   17.21  
   17.22      FinalizeTypes(final TemporarySymbols temporarySymbols) {
   17.23 +        super(new LexicalContext());
   17.24          this.temporarySymbols = temporarySymbols;
   17.25      }
   17.26  
   17.27 @@ -233,7 +235,7 @@
   17.28  
   17.29      private boolean symbolIsInteger(Node node) {
   17.30          final Symbol symbol = node.getSymbol();
   17.31 -        assert symbol != null && symbol.getSymbolType().isInteger() : "int coercion expected: " + Debug.id(symbol) + " " + symbol + " " + getLexicalContext().getCurrentFunction().getSource();
   17.32 +        assert symbol != null && symbol.getSymbolType().isInteger() : "int coercion expected: " + Debug.id(symbol) + " " + symbol + " " + lc.getCurrentFunction().getSource();
   17.33          return true;
   17.34      }
   17.35  
   17.36 @@ -382,12 +384,10 @@
   17.37          final Node test   = forNode.getTest();
   17.38          final Node modify = forNode.getModify();
   17.39  
   17.40 -        final LexicalContext lc = getLexicalContext();
   17.41 -
   17.42          if (forNode.isForIn()) {
   17.43              return forNode.setModify(lc, convert(forNode.getModify(), Type.OBJECT)); // NASHORN-400
   17.44          }
   17.45 -        assert test != null || forNode.hasGoto() : "forNode " + forNode + " needs goto and is missing it in " + getLexicalContext().getCurrentFunction();
   17.46 +        assert test != null || forNode.hasGoto() : "forNode " + forNode + " needs goto and is missing it in " + lc.getCurrentFunction();
   17.47  
   17.48          return forNode.
   17.49              setInit(lc, init == null ? null : discard(init)).
   17.50 @@ -419,7 +419,7 @@
   17.51  
   17.52      @Override
   17.53      public Node leaveFunctionNode(final FunctionNode functionNode) {
   17.54 -        return functionNode.setState(getLexicalContext(), CompilationState.FINALIZED);
   17.55 +        return functionNode.setState(lc, CompilationState.FINALIZED);
   17.56      }
   17.57  
   17.58      @Override
   17.59 @@ -450,7 +450,7 @@
   17.60      public Node leaveReturnNode(final ReturnNode returnNode) {
   17.61          final Node expr = returnNode.getExpression();
   17.62          if (expr != null) {
   17.63 -            return returnNode.setExpression(convert(expr, getLexicalContext().getCurrentFunction().getReturnType()));
   17.64 +            return returnNode.setExpression(convert(expr, lc.getCurrentFunction().getReturnType()));
   17.65          }
   17.66          return returnNode;
   17.67      }
   17.68 @@ -482,8 +482,8 @@
   17.69          }
   17.70  
   17.71          return switchNode.
   17.72 -            setExpression(getLexicalContext(), convert(expression, Type.OBJECT)).
   17.73 -            setCases(getLexicalContext(), newCases);
   17.74 +            setExpression(lc, convert(expression, Type.OBJECT)).
   17.75 +            setCases(lc, newCases);
   17.76      }
   17.77  
   17.78      @Override
   17.79 @@ -519,14 +519,14 @@
   17.80      public Node leaveWhileNode(final WhileNode whileNode) {
   17.81          final Node test = whileNode.getTest();
   17.82          if (test != null) {
   17.83 -            return whileNode.setTest(getLexicalContext(), convert(test, Type.BOOLEAN));
   17.84 +            return whileNode.setTest(lc, convert(test, Type.BOOLEAN));
   17.85          }
   17.86          return whileNode;
   17.87      }
   17.88  
   17.89      @Override
   17.90      public Node leaveWithNode(final WithNode withNode) {
   17.91 -        return withNode.setExpression(getLexicalContext(), convert(withNode.getExpression(), Type.OBJECT));
   17.92 +        return withNode.setExpression(lc, convert(withNode.getExpression(), Type.OBJECT));
   17.93      }
   17.94  
   17.95      private static void updateSymbolsLog(final FunctionNode functionNode, final Symbol symbol, final boolean loseSlot) {
   17.96 @@ -550,7 +550,6 @@
   17.97              return; // nothing to do
   17.98          }
   17.99  
  17.100 -        final LexicalContext lc             = getLexicalContext();
  17.101          final FunctionNode   functionNode   = lc.getFunction(block);
  17.102          final boolean        allVarsInScope = functionNode.allVarsInScope();
  17.103          final boolean        isVarArg       = functionNode.isVarArg();
  17.104 @@ -652,7 +651,7 @@
  17.105      private static void setCanBePrimitive(final Node node, final Type to) {
  17.106          final HashSet<Node> exclude = new HashSet<>();
  17.107  
  17.108 -        node.accept(new NodeVisitor() {
  17.109 +        node.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  17.110              private void setCanBePrimitive(final Symbol symbol) {
  17.111                  LOG.info("*** can be primitive symbol ", symbol, " ", Debug.id(symbol));
  17.112                  symbol.setCanBePrimitive(to);
  17.113 @@ -762,7 +761,7 @@
  17.114              }
  17.115          }
  17.116          LOG.info("Type override for lhs in '", node, "' => ", to);
  17.117 -        return ((TypeOverride<T>)node).setType(temporarySymbols, getLexicalContext(), to);
  17.118 +        return ((TypeOverride<T>)node).setType(temporarySymbols, lc, to);
  17.119      }
  17.120  
  17.121      /**
  17.122 @@ -785,8 +784,8 @@
  17.123      private Node convert(final Node node, final Type to) {
  17.124          assert !to.isUnknown() : "unknown type for " + node + " class=" + node.getClass();
  17.125          assert node != null : "node is null";
  17.126 -        assert node.getSymbol() != null : "node " + node + " " + node.getClass() + " has no symbol! " + getLexicalContext().getCurrentFunction();
  17.127 -        assert node.tokenType() != TokenType.CONVERT : "assert convert in convert " + node + " in " + getLexicalContext().getCurrentFunction();
  17.128 +        assert node.getSymbol() != null : "node " + node + " " + node.getClass() + " has no symbol! " + lc.getCurrentFunction();
  17.129 +        assert node.tokenType() != TokenType.CONVERT : "assert convert in convert " + node + " in " + lc.getCurrentFunction();
  17.130  
  17.131          final Type from = node.getType();
  17.132  
  17.133 @@ -800,7 +799,7 @@
  17.134  
  17.135          Node resultNode = node;
  17.136  
  17.137 -        if (node instanceof LiteralNode && !to.isObject()) {
  17.138 +        if (node instanceof LiteralNode && !(node instanceof ArrayLiteralNode) && !to.isObject()) {
  17.139              final LiteralNode<?> newNode = new LiteralNodeConstantEvaluator((LiteralNode<?>)node, to).eval();
  17.140              if (newNode != null) {
  17.141                  resultNode = newNode;
  17.142 @@ -817,7 +816,6 @@
  17.143  
  17.144          assert !node.isTerminal();
  17.145  
  17.146 -        final LexicalContext lc = getLexicalContext();
  17.147          //This is the only place in this file that can create new temporaries
  17.148          //FinalizeTypes may not introduce ANY node that is not a conversion.
  17.149          return temporarySymbols.ensureSymbol(lc, to, resultNode);
  17.150 @@ -854,7 +852,7 @@
  17.151              symbol = symbol.setTypeOverrideShared(to, temporarySymbols);
  17.152              LOG.info("Type override for temporary in '", node, "' => ", to);
  17.153          }
  17.154 -        return node.setSymbol(getLexicalContext(), symbol);
  17.155 +        return node.setSymbol(lc, symbol);
  17.156      }
  17.157  
  17.158      /**
  17.159 @@ -907,7 +905,7 @@
  17.160  
  17.161              if (literalNode != null) {
  17.162                  //inherit literal symbol for attr.
  17.163 -                literalNode = (LiteralNode<?>)literalNode.setSymbol(getLexicalContext(), parent.getSymbol());
  17.164 +                literalNode = (LiteralNode<?>)literalNode.setSymbol(lc, parent.getSymbol());
  17.165              }
  17.166  
  17.167              return literalNode;
    18.1 --- a/src/jdk/nashorn/internal/codegen/FoldConstants.java	Thu May 30 10:58:35 2013 -0700
    18.2 +++ b/src/jdk/nashorn/internal/codegen/FoldConstants.java	Mon Jun 03 23:24:36 2013 -0700
    18.3 @@ -33,7 +33,9 @@
    18.4  import jdk.nashorn.internal.ir.FunctionNode;
    18.5  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    18.6  import jdk.nashorn.internal.ir.IfNode;
    18.7 +import jdk.nashorn.internal.ir.LexicalContext;
    18.8  import jdk.nashorn.internal.ir.LiteralNode;
    18.9 +import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
   18.10  import jdk.nashorn.internal.ir.Node;
   18.11  import jdk.nashorn.internal.ir.TernaryNode;
   18.12  import jdk.nashorn.internal.ir.UnaryNode;
   18.13 @@ -45,11 +47,12 @@
   18.14  /**
   18.15   * Simple constant folding pass, executed before IR is starting to be lowered.
   18.16   */
   18.17 -final class FoldConstants extends NodeVisitor {
   18.18 +final class FoldConstants extends NodeVisitor<LexicalContext> {
   18.19  
   18.20      private static final DebugLogger LOG = new DebugLogger("fold");
   18.21  
   18.22      FoldConstants() {
   18.23 +        super(new LexicalContext());
   18.24      }
   18.25  
   18.26      @Override
   18.27 @@ -79,7 +82,7 @@
   18.28  
   18.29      @Override
   18.30      public Node leaveFunctionNode(final FunctionNode functionNode) {
   18.31 -        return functionNode.setState(getLexicalContext(), CompilationState.CONSTANT_FOLDED);
   18.32 +        return functionNode.setState(lc, CompilationState.CONSTANT_FOLDED);
   18.33      }
   18.34  
   18.35      @Override
   18.36 @@ -141,6 +144,10 @@
   18.37                  return null;
   18.38              }
   18.39  
   18.40 +            if (rhsNode instanceof ArrayLiteralNode) {
   18.41 +                return null;
   18.42 +            }
   18.43 +
   18.44              final LiteralNode<?> rhs = (LiteralNode<?>)rhsNode;
   18.45              final boolean rhsInteger = rhs.getType().isInteger();
   18.46  
   18.47 @@ -212,6 +219,10 @@
   18.48              final LiteralNode<?> lhs = (LiteralNode<?>)parent.lhs();
   18.49              final LiteralNode<?> rhs = (LiteralNode<?>)parent.rhs();
   18.50  
   18.51 +            if (lhs instanceof ArrayLiteralNode || rhs instanceof ArrayLiteralNode) {
   18.52 +                return null;
   18.53 +            }
   18.54 +
   18.55              final Type widest = Type.widest(lhs.getType(), rhs.getType());
   18.56  
   18.57              boolean isInteger = widest.isInteger();
   18.58 @@ -279,9 +290,9 @@
   18.59              isLong    &= value != 0.0 && JSType.isRepresentableAsLong(value);
   18.60  
   18.61              if (isInteger) {
   18.62 -                return LiteralNode.newInstance(token, finish, JSType.toInt32(value));
   18.63 +                return LiteralNode.newInstance(token, finish, (int)value);
   18.64              } else if (isLong) {
   18.65 -                return LiteralNode.newInstance(token, finish, JSType.toLong(value));
   18.66 +                return LiteralNode.newInstance(token, finish, (long)value);
   18.67              }
   18.68  
   18.69              return LiteralNode.newInstance(token, finish, value);
    19.1 --- a/src/jdk/nashorn/internal/codegen/Lower.java	Thu May 30 10:58:35 2013 -0700
    19.2 +++ b/src/jdk/nashorn/internal/codegen/Lower.java	Mon Jun 03 23:24:36 2013 -0700
    19.3 @@ -80,7 +80,7 @@
    19.4   * finalized.
    19.5   */
    19.6  
    19.7 -final class Lower extends NodeOperatorVisitor {
    19.8 +final class Lower extends NodeOperatorVisitor<BlockLexicalContext> {
    19.9  
   19.10      private static final DebugLogger LOG = new DebugLogger("lower");
   19.11  
   19.12 @@ -105,7 +105,7 @@
   19.13                              terminated = true;
   19.14                          }
   19.15                      } else {
   19.16 -                        statement.accept(new NodeVisitor() {
   19.17 +                        statement.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   19.18                              @Override
   19.19                              public boolean enterVarNode(final VarNode varNode) {
   19.20                                  newStatements.add(varNode.setInit(null));
   19.21 @@ -121,7 +121,6 @@
   19.22  
   19.23      @Override
   19.24      public boolean enterBlock(final Block block) {
   19.25 -        final LexicalContext lc = getLexicalContext();
   19.26          final FunctionNode   function = lc.getCurrentFunction();
   19.27          if (lc.isFunctionBody() && function.isProgram() && !function.hasDeclaredFunctions()) {
   19.28              new ExecuteNode(block.getLineNumber(), block.getToken(), block.getFinish(), LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)).accept(this);
   19.29 @@ -134,12 +133,10 @@
   19.30          //now we have committed the entire statement list to the block, but we need to truncate
   19.31          //whatever is after the last terminal. block append won't append past it
   19.32  
   19.33 -        final BlockLexicalContext lc = (BlockLexicalContext)getLexicalContext();
   19.34 -
   19.35          Statement last = lc.getLastStatement();
   19.36  
   19.37          if (lc.isFunctionBody()) {
   19.38 -            final FunctionNode currentFunction = getLexicalContext().getCurrentFunction();
   19.39 +            final FunctionNode currentFunction = lc.getCurrentFunction();
   19.40              final boolean isProgram = currentFunction.isProgram();
   19.41              final ReturnNode returnNode = new ReturnNode(
   19.42                  last == null ? block.getLineNumber() : last.getLineNumber(), //TODO?
   19.43 @@ -191,7 +188,7 @@
   19.44          final Node expr = executeNode.getExpression();
   19.45          ExecuteNode node = executeNode;
   19.46  
   19.47 -        final FunctionNode currentFunction = getLexicalContext().getCurrentFunction();
   19.48 +        final FunctionNode currentFunction = lc.getCurrentFunction();
   19.49  
   19.50          if (currentFunction.isProgram()) {
   19.51              if (!(expr instanceof Block) || expr instanceof FunctionNode) { // it's not a block, but can be a function
   19.52 @@ -216,7 +213,7 @@
   19.53  
   19.54          final Node  test = forNode.getTest();
   19.55          if (!forNode.isForIn() && conservativeAlwaysTrue(test)) {
   19.56 -            newForNode = forNode.setTest(getLexicalContext(), null);
   19.57 +            newForNode = forNode.setTest(lc, null);
   19.58          }
   19.59  
   19.60          return addStatement(checkEscape(newForNode));
   19.61 @@ -230,7 +227,7 @@
   19.62      @Override
   19.63      public Node leaveFunctionNode(final FunctionNode functionNode) {
   19.64          LOG.info("END FunctionNode: ", functionNode.getName());
   19.65 -        return functionNode.setState(getLexicalContext(), CompilationState.LOWERED);
   19.66 +        return functionNode.setState(lc, CompilationState.LOWERED);
   19.67      }
   19.68  
   19.69      @Override
   19.70 @@ -261,19 +258,25 @@
   19.71          return throwNode;
   19.72      }
   19.73  
   19.74 -    private static Node ensureUniqueLabelsIn(final Node node) {
   19.75 -        return node.accept(new NodeVisitor() {
   19.76 -           @Override
   19.77 -           public Node leaveDefault(final Node labelledNode) {
   19.78 -               return labelledNode.ensureUniqueLabels(getLexicalContext());
   19.79 -           }
   19.80 +    private static Node ensureUniqueNamesIn(final LexicalContext lc, final Node node) {
   19.81 +        return node.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   19.82 +            @Override
   19.83 +            public Node leaveFunctionNode(final FunctionNode functionNode) {
   19.84 +                final String name = functionNode.getName();
   19.85 +                return functionNode.setName(lc, lc.getCurrentFunction().uniqueName(name));
   19.86 +            }
   19.87 +
   19.88 +            @Override
   19.89 +            public Node leaveDefault(final Node labelledNode) {
   19.90 +                return labelledNode.ensureUniqueLabels(lc);
   19.91 +            }
   19.92          });
   19.93      }
   19.94  
   19.95 -    private static List<Statement> copyFinally(final Block finallyBody) {
   19.96 +    private static List<Statement> copyFinally(final LexicalContext lc, final Block finallyBody) {
   19.97          final List<Statement> newStatements = new ArrayList<>();
   19.98          for (final Statement statement : finallyBody.getStatements()) {
   19.99 -            newStatements.add((Statement)ensureUniqueLabelsIn(statement));
  19.100 +            newStatements.add((Statement)ensureUniqueNamesIn(lc, statement));
  19.101              if (statement.hasTerminalFlags()) {
  19.102                  return newStatements;
  19.103              }
  19.104 @@ -286,12 +289,12 @@
  19.105          final long token      = tryNode.getToken();
  19.106          final int  finish     = tryNode.getFinish();
  19.107  
  19.108 -        final IdentNode exception = new IdentNode(token, finish, getLexicalContext().getCurrentFunction().uniqueName("catch_all"));
  19.109 +        final IdentNode exception = new IdentNode(token, finish, lc.getCurrentFunction().uniqueName("catch_all"));
  19.110  
  19.111 -        final Block catchBody = new Block(lineNumber, token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception))).
  19.112 -                setIsTerminal(getLexicalContext(), true); //ends with throw, so terminal
  19.113 +        final Block catchBody = new Block(lineNumber, token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception), ThrowNode.IS_SYNTHETIC_RETHROW)).
  19.114 +                setIsTerminal(lc, true); //ends with throw, so terminal
  19.115  
  19.116 -        final CatchNode catchAllNode  = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody);
  19.117 +        final CatchNode catchAllNode  = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody, CatchNode.IS_SYNTHETIC_RETHROW);
  19.118          final Block     catchAllBlock = new Block(lineNumber, token, finish, catchAllNode);
  19.119  
  19.120          //catchallblock -> catchallnode (catchnode) -> exception -> throw
  19.121 @@ -300,7 +303,7 @@
  19.122      }
  19.123  
  19.124      private IdentNode compilerConstant(final CompilerConstants cc) {
  19.125 -        final FunctionNode functionNode = getLexicalContext().getCurrentFunction();
  19.126 +        final FunctionNode functionNode = lc.getCurrentFunction();
  19.127          return new IdentNode(functionNode.getToken(), functionNode.getFinish(), cc.symbolName());
  19.128      }
  19.129  
  19.130 @@ -316,11 +319,10 @@
  19.131       * @return new try node after splicing finally code (same if nop)
  19.132       */
  19.133      private Node spliceFinally(final TryNode tryNode, final List<ThrowNode> rethrows, final Block finallyBody) {
  19.134 -        final int finish = tryNode.getFinish();
  19.135 +        assert tryNode.getFinallyBody() == null;
  19.136 +        final int            finish = tryNode.getFinish();
  19.137  
  19.138 -        assert tryNode.getFinallyBody() == null;
  19.139 -
  19.140 -        final TryNode newTryNode = (TryNode)tryNode.accept(new NodeVisitor() {
  19.141 +        final TryNode newTryNode = (TryNode)tryNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  19.142              final List<Node> insideTry = new ArrayList<>();
  19.143  
  19.144              @Override
  19.145 @@ -338,7 +340,7 @@
  19.146              @Override
  19.147              public Node leaveThrowNode(final ThrowNode throwNode) {
  19.148                  if (rethrows.contains(throwNode)) {
  19.149 -                    final List<Statement> newStatements = copyFinally(finallyBody);
  19.150 +                    final List<Statement> newStatements = copyFinally(lc, finallyBody);
  19.151                      if (!isTerminal(newStatements)) {
  19.152                          newStatements.add(throwNode);
  19.153                      }
  19.154 @@ -349,12 +351,12 @@
  19.155  
  19.156              @Override
  19.157              public Node leaveBreakNode(final BreakNode breakNode) {
  19.158 -                return copy(breakNode, Lower.this.getLexicalContext().getBreakable(breakNode.getLabel()));
  19.159 +                return copy(breakNode, Lower.this.lc.getBreakable(breakNode.getLabel()));
  19.160              }
  19.161  
  19.162              @Override
  19.163              public Node leaveContinueNode(final ContinueNode continueNode) {
  19.164 -                return copy(continueNode, Lower.this.getLexicalContext().getContinueTo(continueNode.getLabel()));
  19.165 +                return copy(continueNode, Lower.this.lc.getContinueTo(continueNode.getLabel()));
  19.166              }
  19.167  
  19.168              @Override
  19.169 @@ -372,17 +374,17 @@
  19.170                      resultNode = null;
  19.171                  }
  19.172  
  19.173 -                newStatements.addAll(copyFinally(finallyBody));
  19.174 +                newStatements.addAll(copyFinally(lc, finallyBody));
  19.175                  if (!isTerminal(newStatements)) {
  19.176                      newStatements.add(expr == null ? returnNode : returnNode.setExpression(resultNode));
  19.177                  }
  19.178  
  19.179 -                return new ExecuteNode(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new Block(returnNode.getLineNumber(), returnNode.getToken(), getLexicalContext().getCurrentBlock().getFinish(), newStatements));
  19.180 +                return new ExecuteNode(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new Block(returnNode.getLineNumber(), returnNode.getToken(), lc.getCurrentBlock().getFinish(), newStatements));
  19.181              }
  19.182  
  19.183              private Node copy(final Statement endpoint, final Node targetNode) {
  19.184                  if (!insideTry.contains(targetNode)) {
  19.185 -                    final List<Statement> newStatements = copyFinally(finallyBody);
  19.186 +                    final List<Statement> newStatements = copyFinally(lc, finallyBody);
  19.187                      if (!isTerminal(newStatements)) {
  19.188                          newStatements.add(endpoint);
  19.189                      }
  19.190 @@ -436,7 +438,7 @@
  19.191          final Block catchAll = catchAllBlock(tryNode);
  19.192  
  19.193          final List<ThrowNode> rethrows = new ArrayList<>();
  19.194 -        catchAll.accept(new NodeVisitor() {
  19.195 +        catchAll.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  19.196              @Override
  19.197              public boolean enterThrowNode(final ThrowNode throwNode) {
  19.198                  rethrows.add(throwNode);
  19.199 @@ -464,7 +466,7 @@
  19.200      @Override
  19.201      public Node leaveVarNode(final VarNode varNode) {
  19.202          addStatement(varNode);
  19.203 -        if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION) && getLexicalContext().getCurrentFunction().isProgram()) {
  19.204 +        if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION) && lc.getCurrentFunction().isProgram()) {
  19.205              new ExecuteNode(varNode.getLineNumber(), varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this);
  19.206          }
  19.207          return varNode;
  19.208 @@ -478,7 +480,7 @@
  19.209          if (conservativeAlwaysTrue(test)) {
  19.210              //turn it into a for node without a test.
  19.211              final ForNode forNode = (ForNode)new ForNode(whileNode.getLineNumber(), whileNode.getToken(), whileNode.getFinish(), null, null, body, null, ForNode.IS_FOR).accept(this);
  19.212 -            getLexicalContext().replace(whileNode, forNode);
  19.213 +            lc.replace(whileNode, forNode);
  19.214              return forNode;
  19.215          }
  19.216  
  19.217 @@ -513,7 +515,7 @@
  19.218       * @return eval location
  19.219       */
  19.220      private String evalLocation(final IdentNode node) {
  19.221 -        final Source source = getLexicalContext().getCurrentFunction().getSource();
  19.222 +        final Source source = lc.getCurrentFunction().getSource();
  19.223          return new StringBuilder().
  19.224              append(source.getName()).
  19.225              append('#').
  19.226 @@ -545,10 +547,10 @@
  19.227  
  19.228              // 'eval' call with at least one argument
  19.229              if (args.size() >= 1 && EVAL.symbolName().equals(callee.getName())) {
  19.230 -                final FunctionNode currentFunction = getLexicalContext().getCurrentFunction();
  19.231 +                final FunctionNode currentFunction = lc.getCurrentFunction();
  19.232                  return callNode.setEvalArgs(
  19.233                      new CallNode.EvalArgs(
  19.234 -                        ensureUniqueLabelsIn(args.get(0)).accept(this),
  19.235 +                        ensureUniqueNamesIn(lc, args.get(0)).accept(this),
  19.236                          compilerConstant(THIS),
  19.237                          evalLocation(callee),
  19.238                          currentFunction.isStrict()));
  19.239 @@ -574,7 +576,7 @@
  19.240      private static boolean controlFlowEscapes(final LexicalContext lex, final Block loopBody) {
  19.241          final List<Node> escapes = new ArrayList<>();
  19.242  
  19.243 -        loopBody.accept(new NodeVisitor() {
  19.244 +        loopBody.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  19.245              @Override
  19.246              public Node leaveBreakNode(final BreakNode node) {
  19.247                  escapes.add(node);
  19.248 @@ -595,7 +597,6 @@
  19.249      }
  19.250  
  19.251      private LoopNode checkEscape(final LoopNode loopNode) {
  19.252 -        final LexicalContext lc = getLexicalContext();
  19.253          final boolean escapes = controlFlowEscapes(lc, loopNode.getBody());
  19.254          if (escapes) {
  19.255              return loopNode.
  19.256 @@ -607,7 +608,7 @@
  19.257  
  19.258  
  19.259      private Node addStatement(final Statement statement) {
  19.260 -        ((BlockLexicalContext)getLexicalContext()).appendStatement(statement);
  19.261 +        lc.appendStatement(statement);
  19.262          return statement;
  19.263      }
  19.264  
    20.1 --- a/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Thu May 30 10:58:35 2013 -0700
    20.2 +++ b/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Mon Jun 03 23:24:36 2013 -0700
    20.3 @@ -2081,7 +2081,9 @@
    20.4       * @param args debug information to print
    20.5       */
    20.6      private void debug(final Object... args) {
    20.7 -        debug(30, args);
    20.8 +        if (DEBUG) {
    20.9 +            debug(30, args);
   20.10 +        }
   20.11      }
   20.12  
   20.13      /**
   20.14 @@ -2091,7 +2093,9 @@
   20.15       * @param args debug information to print
   20.16       */
   20.17      private void debug_label(final Object... args) {
   20.18 -        debug(26, args);
   20.19 +        if (DEBUG) {
   20.20 +            debug(22, args);
   20.21 +        }
   20.22      }
   20.23  
   20.24      private void debug(final int padConstant, final Object... args) {
   20.25 @@ -2164,7 +2168,6 @@
   20.26                      new Throwable().printStackTrace(LOG.getOutputStream());
   20.27                  }
   20.28              }
   20.29 -
   20.30          }
   20.31      }
   20.32  
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java	Mon Jun 03 23:24:36 2013 -0700
    21.3 @@ -0,0 +1,476 @@
    21.4 +/*
    21.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    21.7 + *
    21.8 + * This code is free software; you can redistribute it and/or modify it
    21.9 + * under the terms of the GNU General Public License version 2 only, as
   21.10 + * published by the Free Software Foundation.  Oracle designates this
   21.11 + * particular file as subject to the "Classpath" exception as provided
   21.12 + * by Oracle in the LICENSE file that accompanied this code.
   21.13 + *
   21.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   21.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   21.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   21.17 + * version 2 for more details (a copy is included in the LICENSE file that
   21.18 + * accompanied this code).
   21.19 + *
   21.20 + * You should have received a copy of the GNU General Public License version
   21.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   21.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   21.23 + *
   21.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   21.25 + * or visit www.oracle.com if you need additional information or have any
   21.26 + * questions.
   21.27 + */
   21.28 +
   21.29 +package jdk.nashorn.internal.codegen;
   21.30 +
   21.31 +import java.util.HashMap;
   21.32 +import java.util.HashSet;
   21.33 +import java.util.Map;
   21.34 +
   21.35 +import jdk.nashorn.internal.codegen.types.Range;
   21.36 +import jdk.nashorn.internal.codegen.types.Type;
   21.37 +import jdk.nashorn.internal.ir.Assignment;
   21.38 +import jdk.nashorn.internal.ir.BinaryNode;
   21.39 +import jdk.nashorn.internal.ir.ForNode;
   21.40 +import jdk.nashorn.internal.ir.IdentNode;
   21.41 +import jdk.nashorn.internal.ir.LexicalContext;
   21.42 +import jdk.nashorn.internal.ir.LiteralNode;
   21.43 +import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
   21.44 +import jdk.nashorn.internal.ir.LoopNode;
   21.45 +import jdk.nashorn.internal.ir.Node;
   21.46 +import jdk.nashorn.internal.ir.RuntimeNode;
   21.47 +import jdk.nashorn.internal.ir.Symbol;
   21.48 +import jdk.nashorn.internal.ir.UnaryNode;
   21.49 +import jdk.nashorn.internal.ir.VarNode;
   21.50 +import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
   21.51 +import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   21.52 +import jdk.nashorn.internal.parser.TokenType;
   21.53 +import jdk.nashorn.internal.runtime.DebugLogger;
   21.54 +
   21.55 +/**
   21.56 + * Range analysis and narrowing of type where it can be proven
   21.57 + * that there is no spillover, e.g.
   21.58 + *
   21.59 + *  function func(c) {
   21.60 + *    var v = c & 0xfff;
   21.61 + *    var w = c & 0xeee;
   21.62 + *    var x = v * w;
   21.63 + *    return x;
   21.64 + *  }
   21.65 + *
   21.66 + *  Proves that the multiplication never exceeds 24 bits and can thus be an int
   21.67 + */
   21.68 +final class RangeAnalyzer extends NodeOperatorVisitor<LexicalContext> {
   21.69 +    static final DebugLogger LOG = new DebugLogger("ranges");
   21.70 +
   21.71 +    private static final Range.Functionality RANGE = new Range.Functionality(LOG);
   21.72 +
   21.73 +    private final Map<LoopNode, Symbol> loopCounters = new HashMap<>();
   21.74 +
   21.75 +    RangeAnalyzer() {
   21.76 +        super(new LexicalContext());
   21.77 +    }
   21.78 +
   21.79 +    @Override
   21.80 +    public boolean enterForNode(final ForNode forNode) {
   21.81 +        //conservatively attempt to identify the loop counter. Null means that it wasn't
   21.82 +        //properly identified and that no optimizations can be made with it - its range is
   21.83 +        //simply unknown in that case, if it is assigned in the loop
   21.84 +        final Symbol counter = findLoopCounter(forNode);
   21.85 +        LOG.fine("Entering forNode " + forNode + " counter = " + counter);
   21.86 +        if (counter != null && !assignedInLoop(forNode,  counter)) {
   21.87 +            loopCounters.put(forNode, counter);
   21.88 +        }
   21.89 +        return true;
   21.90 +    }
   21.91 +
   21.92 +    //destination visited
   21.93 +    private Symbol setRange(final Node dest, final Range range) {
   21.94 +        if (range.isUnknown()) {
   21.95 +            return null;
   21.96 +        }
   21.97 +
   21.98 +        final Symbol symbol = dest.getSymbol();
   21.99 +        assert symbol != null : dest + " " + dest.getClass() + " has no symbol";
  21.100 +        assert symbol.getRange() != null : symbol + " has no range";
  21.101 +        final Range symRange = RANGE.join(symbol.getRange(), range);
  21.102 +
  21.103 +        //anything assigned in the loop, not being the safe loop counter(s) invalidates its entire range
  21.104 +        if (lc.inLoop() && !isLoopCounter(lc.getCurrentLoop(), symbol)) {
  21.105 +            symbol.setRange(Range.createGenericRange());
  21.106 +            return symbol;
  21.107 +        }
  21.108 +
  21.109 +        if (!symRange.equals(symbol.getRange())) {
  21.110 +            LOG.fine("Modify range for " + dest + " " + symbol + " from " + symbol.getRange() + " to " + symRange + " (in node = " + dest + ")" );
  21.111 +            symbol.setRange(symRange);
  21.112 +        }
  21.113 +
  21.114 +        return null;
  21.115 +    }
  21.116 +
  21.117 +    @Override
  21.118 +    public Node leaveADD(final BinaryNode node) {
  21.119 +        setRange(node, RANGE.add(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.120 +        return node;
  21.121 +    }
  21.122 +
  21.123 +    @Override
  21.124 +    public Node leaveSUB(final BinaryNode node) {
  21.125 +        setRange(node, RANGE.sub(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.126 +        return node;
  21.127 +    }
  21.128 +
  21.129 +    @Override
  21.130 +    public Node leaveMUL(final BinaryNode node) {
  21.131 +        setRange(node, RANGE.mul(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.132 +        return node;
  21.133 +    }
  21.134 +
  21.135 +    @Override
  21.136 +    public Node leaveDIV(final BinaryNode node) {
  21.137 +        setRange(node, RANGE.div(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.138 +        return node;
  21.139 +    }
  21.140 +
  21.141 +    @Override
  21.142 +    public Node leaveMOD(final BinaryNode node) {
  21.143 +        setRange(node, RANGE.mod(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.144 +        return node;
  21.145 +    }
  21.146 +
  21.147 +    @Override
  21.148 +    public Node leaveBIT_AND(final BinaryNode node) {
  21.149 +        setRange(node, RANGE.and(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.150 +        return node;
  21.151 +    }
  21.152 +
  21.153 +    @Override
  21.154 +    public Node leaveBIT_OR(final BinaryNode node) {
  21.155 +        setRange(node, RANGE.or(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.156 +        return node;
  21.157 +    }
  21.158 +
  21.159 +    @Override
  21.160 +    public Node leaveBIT_XOR(final BinaryNode node) {
  21.161 +        setRange(node, RANGE.xor(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.162 +        return node;
  21.163 +    }
  21.164 +
  21.165 +    @Override
  21.166 +    public Node leaveSAR(final BinaryNode node) {
  21.167 +        setRange(node, RANGE.sar(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.168 +        return node;
  21.169 +    }
  21.170 +
  21.171 +    @Override
  21.172 +    public Node leaveSHL(final BinaryNode node) {
  21.173 +        setRange(node, RANGE.shl(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.174 +        return node;
  21.175 +    }
  21.176 +
  21.177 +    @Override
  21.178 +    public Node leaveSHR(final BinaryNode node) {
  21.179 +        setRange(node, RANGE.shr(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.180 +        return node;
  21.181 +    }
  21.182 +
  21.183 +    private Node leaveCmp(final BinaryNode node) {
  21.184 +        setRange(node, Range.createTypeRange(Type.BOOLEAN));
  21.185 +        return node;
  21.186 +    }
  21.187 +
  21.188 +    @Override
  21.189 +    public Node leaveEQ(final BinaryNode node) {
  21.190 +        return leaveCmp(node);
  21.191 +    }
  21.192 +
  21.193 +    @Override
  21.194 +    public Node leaveEQ_STRICT(final BinaryNode node) {
  21.195 +        return leaveCmp(node);
  21.196 +    }
  21.197 +
  21.198 +    @Override
  21.199 +    public Node leaveNE(final BinaryNode node) {
  21.200 +        return leaveCmp(node);
  21.201 +    }
  21.202 +
  21.203 +    @Override
  21.204 +    public Node leaveNE_STRICT(final BinaryNode node) {
  21.205 +        return leaveCmp(node);
  21.206 +    }
  21.207 +
  21.208 +    @Override
  21.209 +    public Node leaveLT(final BinaryNode node) {
  21.210 +        return leaveCmp(node);
  21.211 +    }
  21.212 +
  21.213 +    @Override
  21.214 +    public Node leaveLE(final BinaryNode node) {
  21.215 +        return leaveCmp(node);
  21.216 +    }
  21.217 +
  21.218 +    @Override
  21.219 +    public Node leaveGT(final BinaryNode node) {
  21.220 +        return leaveCmp(node);
  21.221 +    }
  21.222 +
  21.223 +    @Override
  21.224 +    public Node leaveGE(final BinaryNode node) {
  21.225 +        return leaveCmp(node);
  21.226 +    }
  21.227 +
  21.228 +    @Override
  21.229 +    public Node leaveASSIGN(final BinaryNode node) {
  21.230 +        Range range = node.rhs().getSymbol().getRange();
  21.231 +        if (range.isUnknown()) {
  21.232 +            range = Range.createGenericRange();
  21.233 +        }
  21.234 +
  21.235 +        setRange(node.lhs(), range);
  21.236 +        setRange(node, range);
  21.237 +
  21.238 +        return node;
  21.239 +    }
  21.240 +
  21.241 +    private Node leaveSelfModifyingAssign(final BinaryNode node, final Range range) {
  21.242 +        setRange(node.lhs(), range);
  21.243 +        setRange(node, range);
  21.244 +        return node;
  21.245 +    }
  21.246 +
  21.247 +    private Node leaveSelfModifyingAssign(final UnaryNode node, final Range range) {
  21.248 +        setRange(node.rhs(), range);
  21.249 +        setRange(node, range);
  21.250 +        return node;
  21.251 +    }
  21.252 +
  21.253 +    @Override
  21.254 +    public Node leaveASSIGN_ADD(final BinaryNode node) {
  21.255 +        return leaveSelfModifyingAssign(node, RANGE.add(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.256 +    }
  21.257 +
  21.258 +    @Override
  21.259 +    public Node leaveASSIGN_SUB(final BinaryNode node) {
  21.260 +        return leaveSelfModifyingAssign(node, RANGE.sub(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.261 +    }
  21.262 +
  21.263 +    @Override
  21.264 +    public Node leaveASSIGN_MUL(final BinaryNode node) {
  21.265 +        return leaveSelfModifyingAssign(node, RANGE.mul(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.266 +    }
  21.267 +
  21.268 +    @Override
  21.269 +    public Node leaveASSIGN_DIV(final BinaryNode node) {
  21.270 +        return leaveSelfModifyingAssign(node, Range.createTypeRange(Type.NUMBER));
  21.271 +    }
  21.272 +
  21.273 +    @Override
  21.274 +    public Node leaveASSIGN_MOD(final BinaryNode node) {
  21.275 +        return leaveSelfModifyingAssign(node, Range.createTypeRange(Type.NUMBER));
  21.276 +    }
  21.277 +
  21.278 +    @Override
  21.279 +    public Node leaveASSIGN_BIT_AND(final BinaryNode node) {
  21.280 +        return leaveSelfModifyingAssign(node, RANGE.and(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.281 +    }
  21.282 +
  21.283 +    @Override
  21.284 +    public Node leaveASSIGN_BIT_OR(final BinaryNode node) {
  21.285 +        return leaveSelfModifyingAssign(node, RANGE.or(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.286 +    }
  21.287 +
  21.288 +    @Override
  21.289 +    public Node leaveASSIGN_BIT_XOR(final BinaryNode node) {
  21.290 +        return leaveSelfModifyingAssign(node, RANGE.xor(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.291 +    }
  21.292 +
  21.293 +    @Override
  21.294 +    public Node leaveASSIGN_SAR(final BinaryNode node) {
  21.295 +        return leaveSelfModifyingAssign(node, RANGE.sar(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.296 +    }
  21.297 +
  21.298 +    @Override
  21.299 +    public Node leaveASSIGN_SHR(final BinaryNode node) {
  21.300 +        return leaveSelfModifyingAssign(node, RANGE.shr(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.301 +    }
  21.302 +
  21.303 +    @Override
  21.304 +    public Node leaveASSIGN_SHL(final BinaryNode node) {
  21.305 +        return leaveSelfModifyingAssign(node, RANGE.shl(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
  21.306 +    }
  21.307 +
  21.308 +    @Override
  21.309 +    public Node leaveDECINC(final UnaryNode node) {
  21.310 +        switch (node.tokenType()) {
  21.311 +        case DECPREFIX:
  21.312 +        case DECPOSTFIX:
  21.313 +            return leaveSelfModifyingAssign(node, RANGE.sub(node.rhs().getSymbol().getRange(), Range.createRange(1)));
  21.314 +        case INCPREFIX:
  21.315 +        case INCPOSTFIX:
  21.316 +            return leaveSelfModifyingAssign(node, RANGE.add(node.rhs().getSymbol().getRange(), Range.createRange(1)));
  21.317 +        default:
  21.318 +            assert false;
  21.319 +            return node;
  21.320 +        }
  21.321 +    }
  21.322 +
  21.323 +    @Override
  21.324 +    public Node leaveADD(final UnaryNode node) {
  21.325 +        Range range = node.rhs().getSymbol().getRange();
  21.326 +        if (!range.getType().isNumeric()) {
  21.327 +           range = Range.createTypeRange(Type.NUMBER);
  21.328 +        }
  21.329 +        setRange(node, range);
  21.330 +        return node;
  21.331 +    }
  21.332 +
  21.333 +    @Override
  21.334 +    public Node leaveBIT_NOT(final UnaryNode node) {
  21.335 +        setRange(node, Range.createTypeRange(Type.INT));
  21.336 +        return node;
  21.337 +    }
  21.338 +
  21.339 +    @Override
  21.340 +    public Node leaveNOT(final UnaryNode node) {
  21.341 +        setRange(node, Range.createTypeRange(Type.BOOLEAN));
  21.342 +        return node;
  21.343 +    }
  21.344 +
  21.345 +    @Override
  21.346 +    public Node leaveSUB(final UnaryNode node) {
  21.347 +        setRange(node, RANGE.neg(node.rhs().getSymbol().getRange()));
  21.348 +        return node;
  21.349 +    }
  21.350 +
  21.351 +    @Override
  21.352 +    public Node leaveVarNode(final VarNode node) {
  21.353 +        if (node.isAssignment()) {
  21.354 +            Range range = node.getInit().getSymbol().getRange();
  21.355 +            range = range.isUnknown() ? Range.createGenericRange() : range;
  21.356 +
  21.357 +            setRange(node.getName(), range);
  21.358 +            setRange(node, range);
  21.359 +        }
  21.360 +
  21.361 +        return node;
  21.362 +    }
  21.363 +
  21.364 +    @SuppressWarnings("rawtypes")
  21.365 +    @Override
  21.366 +    public boolean enterLiteralNode(final LiteralNode node) {
  21.367 +        // ignore array literals
  21.368 +        return !(node instanceof ArrayLiteralNode);
  21.369 +    }
  21.370 +
  21.371 +    @Override
  21.372 +    public Node leaveLiteralNode(@SuppressWarnings("rawtypes") final LiteralNode node) {
  21.373 +        if (node.getType().isInteger()) {
  21.374 +            setRange(node, Range.createRange(node.getInt32()));
  21.375 +        } else if (node.getType().isNumber()) {
  21.376 +            setRange(node, Range.createRange(node.getNumber()));
  21.377 +        } else if (node.getType().isLong()) {
  21.378 +            setRange(node, Range.createRange(node.getLong()));
  21.379 +        } else if (node.getType().isBoolean()) {
  21.380 +            setRange(node, Range.createTypeRange(Type.BOOLEAN));
  21.381 +        } else {
  21.382 +            setRange(node, Range.createGenericRange());
  21.383 +        }
  21.384 +        return node;
  21.385 +    }
  21.386 +
  21.387 +    @Override
  21.388 +    public boolean enterRuntimeNode(final RuntimeNode node) {
  21.389 +        // a runtime node that cannot be specialized is no point entering
  21.390 +        return node.getRequest().canSpecialize();
  21.391 +    }
  21.392 +
  21.393 +    /**
  21.394 +     * Check whether a symbol is unsafely assigned in a loop - i.e. repeteadly assigned and
  21.395 +     * not being identified as the loop counter. That means we don't really know anything
  21.396 +     * about its range.
  21.397 +     * @param loopNode loop node
  21.398 +     * @param symbol   symbol
  21.399 +     * @return true if assigned in loop
  21.400 +     */
  21.401 +    // TODO - this currently checks for nodes only - needs to be augmented for while nodes
  21.402 +    // assignment analysis is also very conservative
  21.403 +    private static boolean assignedInLoop(final LoopNode loopNode, final Symbol symbol) {
  21.404 +        final HashSet<Node> skip = new HashSet<>();
  21.405 +        final HashSet<Node> assignmentsInLoop = new HashSet<>();
  21.406 +
  21.407 +        loopNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
  21.408 +            private boolean assigns(final Node node, final Symbol s) {
  21.409 +                return node.isAssignment() && ((Assignment<?>)node).getAssignmentDest().getSymbol() == s;
  21.410 +            }
  21.411 +
  21.412 +            @Override
  21.413 +            public boolean enterForNode(final ForNode forNode) {
  21.414 +                if (forNode.getInit() != null) {
  21.415 +                    skip.add(forNode.getInit());
  21.416 +                }
  21.417 +                if (forNode.getModify() != null) {
  21.418 +                    skip.add(forNode.getModify());
  21.419 +                }
  21.420 +                return true;
  21.421 +            }
  21.422 +
  21.423 +            @Override
  21.424 +            public Node leaveDefault(final Node node) {
  21.425 +                //if this is an assignment to symbol
  21.426 +                if (!skip.contains(node) && assigns(node, symbol)) {
  21.427 +                    assignmentsInLoop.add(node);
  21.428 +                }
  21.429 +                return node;
  21.430 +            }
  21.431 +        });
  21.432 +
  21.433 +        return !assignmentsInLoop.isEmpty();
  21.434 +    }
  21.435 +
  21.436 +    /**
  21.437 +     * Check for a loop counter. This is currently quite conservative, in that it only handles
  21.438 +     * x <= counter and x < counter.
  21.439 +     *
  21.440 +     * @param node loop node to check
  21.441 +     * @return
  21.442 +     */
  21.443 +    private static Symbol findLoopCounter(final LoopNode node) {
  21.444 +        final Node test = node.getTest();
  21.445 +
  21.446 +        if (test != null && test.isComparison()) {
  21.447 +            final BinaryNode binaryNode = (BinaryNode)test;
  21.448 +            final Node lhs = binaryNode.lhs();
  21.449 +            final Node rhs = binaryNode.rhs();
  21.450 +
  21.451 +            //detect ident cmp int_literal
  21.452 +            if (lhs instanceof IdentNode && rhs instanceof LiteralNode && ((LiteralNode<?>)rhs).getType().isInteger()) {
  21.453 +                final Symbol    symbol = lhs.getSymbol();
  21.454 +                final int       margin = ((LiteralNode<?>)rhs).getInt32();
  21.455 +                final TokenType op     = test.tokenType();
  21.456 +
  21.457 +                switch (op) {
  21.458 +                case LT:
  21.459 +                case LE:
  21.460 +                    symbol.setRange(RANGE.join(symbol.getRange(), Range.createRange(op == TokenType.LT ? margin - 1 : margin)));
  21.461 +                    return symbol;
  21.462 +                case GT:
  21.463 +                case GE:
  21.464 +                    //setRange(lhs, Range.createRange(op == TokenType.GT ? margin + 1 : margin));
  21.465 +                    //return symbol;
  21.466 +                default:
  21.467 +                    break;
  21.468 +                }
  21.469 +            }
  21.470 +        }
  21.471 +
  21.472 +        return null;
  21.473 +    }
  21.474 +
  21.475 +    private boolean isLoopCounter(final LoopNode loopNode, final Symbol symbol) {
  21.476 +        //this only works if loop nodes aren't replaced by other ones during this transform, but they are not
  21.477 +        return loopCounters.get(loopNode) == symbol;
  21.478 +    }
  21.479 +}
    22.1 --- a/src/jdk/nashorn/internal/codegen/SharedScopeCall.java	Thu May 30 10:58:35 2013 -0700
    22.2 +++ b/src/jdk/nashorn/internal/codegen/SharedScopeCall.java	Mon Jun 03 23:24:36 2013 -0700
    22.3 @@ -116,9 +116,10 @@
    22.4      /**
    22.5       * Generate the invoke instruction for this shared scope call.
    22.6       * @param method the method emitter
    22.7 +     * @return the method emitter
    22.8       */
    22.9 -    public void generateInvoke(final MethodEmitter method) {
   22.10 -        method.invokestatic(compileUnit.getUnitClassName(), methodName, getStaticSignature());
   22.11 +    public MethodEmitter generateInvoke(final MethodEmitter method) {
   22.12 +        return method.invokestatic(compileUnit.getUnitClassName(), methodName, getStaticSignature());
   22.13      }
   22.14  
   22.15      /**
    23.1 --- a/src/jdk/nashorn/internal/codegen/Splitter.java	Thu May 30 10:58:35 2013 -0700
    23.2 +++ b/src/jdk/nashorn/internal/codegen/Splitter.java	Mon Jun 03 23:24:36 2013 -0700
    23.3 @@ -49,12 +49,12 @@
    23.4  /**
    23.5   * Split the IR into smaller compile units.
    23.6   */
    23.7 -final class Splitter extends NodeVisitor {
    23.8 +final class Splitter extends NodeVisitor<LexicalContext> {
    23.9      /** Current compiler. */
   23.10      private final Compiler compiler;
   23.11  
   23.12      /** IR to be broken down. */
   23.13 -    private FunctionNode outermost;
   23.14 +    private final FunctionNode outermost;
   23.15  
   23.16      /** Compile unit for the main script. */
   23.17      private final CompileUnit outermostCompileUnit;
   23.18 @@ -75,6 +75,7 @@
   23.19       * @param outermostCompileUnit  compile unit for outermost function, if non-lazy this is the script's compile unit
   23.20       */
   23.21      public Splitter(final Compiler compiler, final FunctionNode functionNode, final CompileUnit outermostCompileUnit) {
   23.22 +        super(new LexicalContext());
   23.23          this.compiler             = compiler;
   23.24          this.outermost            = functionNode;
   23.25          this.outermostCompileUnit = outermostCompileUnit;
   23.26 @@ -93,8 +94,6 @@
   23.27  
   23.28          LOG.finest("Initiating split of '", functionNode.getName(), "'");
   23.29  
   23.30 -        final LexicalContext lc = getLexicalContext();
   23.31 -
   23.32          long weight = WeighNodes.weigh(functionNode);
   23.33          final boolean top = fn.isProgram(); //compiler.getFunctionNode() == outermost;
   23.34  
   23.35 @@ -127,7 +126,7 @@
   23.36          final Block body = functionNode.getBody();
   23.37          final List<FunctionNode> dc = directChildren(functionNode);
   23.38  
   23.39 -        final Block newBody = (Block)body.accept(new NodeVisitor() {
   23.40 +        final Block newBody = (Block)body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   23.41              @Override
   23.42              public boolean enterFunctionNode(final FunctionNode nestedFunction) {
   23.43                  return dc.contains(nestedFunction);
   23.44 @@ -136,7 +135,7 @@
   23.45              @Override
   23.46              public Node leaveFunctionNode(final FunctionNode nestedFunction) {
   23.47                  FunctionNode split = new Splitter(compiler, nestedFunction, outermostCompileUnit).split(nestedFunction);
   23.48 -                getLexicalContext().replace(nestedFunction, split);
   23.49 +                lc.replace(nestedFunction, split);
   23.50                  return split;
   23.51              }
   23.52          });
   23.53 @@ -149,13 +148,13 @@
   23.54  
   23.55      private static List<FunctionNode> directChildren(final FunctionNode functionNode) {
   23.56          final List<FunctionNode> dc = new ArrayList<>();
   23.57 -        functionNode.accept(new NodeVisitor() {
   23.58 +        functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   23.59              @Override
   23.60              public boolean enterFunctionNode(final FunctionNode child) {
   23.61                  if (child == functionNode) {
   23.62                      return true;
   23.63                  }
   23.64 -                if (getLexicalContext().getParentFunction(child) == functionNode) {
   23.65 +                if (lc.getParentFunction(child) == functionNode) {
   23.66                      dc.add(child);
   23.67                  }
   23.68                  return false;
   23.69 @@ -181,7 +180,7 @@
   23.70       * @return new weight for the resulting block.
   23.71       */
   23.72      private Block splitBlock(final Block block, final FunctionNode function) {
   23.73 -        getLexicalContext().setFlag(getLexicalContext().getCurrentFunction(), FunctionNode.IS_SPLIT);
   23.74 +        lc.setFlag(lc.getCurrentFunction(), FunctionNode.IS_SPLIT);
   23.75  
   23.76          final List<Statement> splits = new ArrayList<>();
   23.77          List<Statement> statements = new ArrayList<>();
   23.78 @@ -210,7 +209,7 @@
   23.79              splits.add(createBlockSplitNode(block, function, statements, statementsWeight));
   23.80          }
   23.81  
   23.82 -        return block.setStatements(getLexicalContext(), splits);
   23.83 +        return block.setStatements(lc, splits);
   23.84      }
   23.85  
   23.86      /**
   23.87 @@ -258,7 +257,7 @@
   23.88          // been split already, so weigh again before splitting.
   23.89          long weight = WeighNodes.weigh(block, weightCache);
   23.90          if (weight >= SPLIT_THRESHOLD) {
   23.91 -            newBlock = splitBlock(block, getLexicalContext().getFunction(block));
   23.92 +            newBlock = splitBlock(block, lc.getFunction(block));
   23.93              weight   = WeighNodes.weigh(newBlock, weightCache);
   23.94          }
   23.95          weightCache.put(newBlock, weight);
   23.96 @@ -274,9 +273,9 @@
   23.97              return literal;
   23.98          }
   23.99  
  23.100 -        final FunctionNode functionNode = getLexicalContext().getCurrentFunction();
  23.101 +        final FunctionNode functionNode = lc.getCurrentFunction();
  23.102  
  23.103 -        getLexicalContext().setFlag(functionNode, FunctionNode.IS_SPLIT);
  23.104 +        lc.setFlag(functionNode, FunctionNode.IS_SPLIT);
  23.105  
  23.106          if (literal instanceof ArrayLiteralNode) {
  23.107              final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode) literal;
    24.1 --- a/src/jdk/nashorn/internal/codegen/WeighNodes.java	Thu May 30 10:58:35 2013 -0700
    24.2 +++ b/src/jdk/nashorn/internal/codegen/WeighNodes.java	Mon Jun 03 23:24:36 2013 -0700
    24.3 @@ -27,6 +27,7 @@
    24.4  
    24.5  import java.util.List;
    24.6  import java.util.Map;
    24.7 +
    24.8  import jdk.nashorn.internal.codegen.types.Type;
    24.9  import jdk.nashorn.internal.ir.AccessNode;
   24.10  import jdk.nashorn.internal.ir.BinaryNode;
   24.11 @@ -41,6 +42,7 @@
   24.12  import jdk.nashorn.internal.ir.IdentNode;
   24.13  import jdk.nashorn.internal.ir.IfNode;
   24.14  import jdk.nashorn.internal.ir.IndexNode;
   24.15 +import jdk.nashorn.internal.ir.LexicalContext;
   24.16  import jdk.nashorn.internal.ir.LiteralNode;
   24.17  import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
   24.18  import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
   24.19 @@ -63,7 +65,7 @@
   24.20   * Computes the "byte code" weight of an AST segment. This is used
   24.21   * for Splitting too large class files
   24.22   */
   24.23 -final class WeighNodes extends NodeOperatorVisitor {
   24.24 +final class WeighNodes extends NodeOperatorVisitor<LexicalContext> {
   24.25      /*
   24.26       * Weight constants.
   24.27       */
   24.28 @@ -100,7 +102,7 @@
   24.29       * @param weightCache cache of already calculated block weights
   24.30       */
   24.31      private WeighNodes(FunctionNode topFunction, final Map<Node, Long> weightCache) {
   24.32 -        super();
   24.33 +        super(new LexicalContext());
   24.34          this.topFunction = topFunction;
   24.35          this.weightCache = weightCache;
   24.36      }
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/src/jdk/nashorn/internal/codegen/types/Range.java	Mon Jun 03 23:24:36 2013 -0700
    25.3 @@ -0,0 +1,705 @@
    25.4 +/*
    25.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    25.7 + *
    25.8 + * This code is free software; you can redistribute it and/or modify it
    25.9 + * under the terms of the GNU General Public License version 2 only, as
   25.10 + * published by the Free Software Foundation.  Oracle designates this
   25.11 + * particular file as subject to the "Classpath" exception as provided
   25.12 + * by Oracle in the LICENSE file that accompanied this code.
   25.13 + *
   25.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   25.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   25.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   25.17 + * version 2 for more details (a copy is included in the LICENSE file that
   25.18 + * accompanied this code).
   25.19 + *
   25.20 + * You should have received a copy of the GNU General Public License version
   25.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   25.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   25.23 + *
   25.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   25.25 + * or visit www.oracle.com if you need additional information or have any
   25.26 + * questions.
   25.27 + */
   25.28 +
   25.29 +package jdk.nashorn.internal.codegen.types;
   25.30 +
   25.31 +import java.util.Arrays;
   25.32 +import java.util.Collections;
   25.33 +import java.util.List;
   25.34 +
   25.35 +import jdk.nashorn.internal.runtime.DebugLogger;
   25.36 +import jdk.nashorn.internal.runtime.JSType;
   25.37 +
   25.38 +/**
   25.39 + * Represents the value range of a symbol.
   25.40 + */
   25.41 +public abstract class Range {
   25.42 +
   25.43 +    private static final Range GENERIC_RANGE = new Range() {
   25.44 +        @Override
   25.45 +        public Type getType() {
   25.46 +            return Type.OBJECT;
   25.47 +        }
   25.48 +    };
   25.49 +
   25.50 +    private static final Range NUMBER_RANGE = new Range() {
   25.51 +        @Override
   25.52 +        public Type getType() {
   25.53 +            return Type.NUMBER;
   25.54 +        }
   25.55 +    };
   25.56 +
   25.57 +    private static final Range UNKNOWN_RANGE = new Range() {
   25.58 +        @Override
   25.59 +        public Type getType() {
   25.60 +            return Type.UNKNOWN;
   25.61 +        }
   25.62 +
   25.63 +        @Override
   25.64 +        public boolean isUnknown() {
   25.65 +            return true;
   25.66 +        }
   25.67 +    };
   25.68 +
   25.69 +    private static class IntegerRange extends Range {
   25.70 +        private final long min;
   25.71 +        private final long max;
   25.72 +        private final Type type;
   25.73 +
   25.74 +        private IntegerRange(final long min, final long max) {
   25.75 +            assert min <= max;
   25.76 +            this.min  = min;
   25.77 +            this.max  = max;
   25.78 +            this.type = typeFromRange(min, max);
   25.79 +        }
   25.80 +
   25.81 +        private static Type typeFromRange(final long from, final long to) {
   25.82 +            if (from >= Integer.MIN_VALUE && to <= Integer.MAX_VALUE) {
   25.83 +                return Type.INT;
   25.84 +            }
   25.85 +            return Type.LONG;
   25.86 +        }
   25.87 +
   25.88 +        @Override
   25.89 +        public Type getType() {
   25.90 +            return type;
   25.91 +        }
   25.92 +
   25.93 +        public long getMin() {
   25.94 +            return min;
   25.95 +        }
   25.96 +
   25.97 +        public long getMax() {
   25.98 +            return max;
   25.99 +        }
  25.100 +
  25.101 +        @Override
  25.102 +        public boolean isIntegerConst() {
  25.103 +            return getMin() == getMax();
  25.104 +        }
  25.105 +
  25.106 +        private long getBitMask() {
  25.107 +            if (min == max) {
  25.108 +                return min;
  25.109 +            }
  25.110 +
  25.111 +            if (min < 0) {
  25.112 +                return ~0L;
  25.113 +            }
  25.114 +
  25.115 +            long mask = 1;
  25.116 +            while (mask < max) {
  25.117 +                mask = (mask << 1) | 1;
  25.118 +            }
  25.119 +            return mask;
  25.120 +        }
  25.121 +
  25.122 +        @Override
  25.123 +        public boolean equals(final Object obj) {
  25.124 +            if (obj instanceof IntegerRange) {
  25.125 +                final IntegerRange other = (IntegerRange)obj;
  25.126 +                return this.type == other.type && this.min == other.min && this.max == other.max;
  25.127 +            }
  25.128 +            return false;
  25.129 +        }
  25.130 +
  25.131 +        @Override
  25.132 +        public int hashCode() {
  25.133 +            return Long.hashCode(min) ^ Long.hashCode(max);
  25.134 +        }
  25.135 +
  25.136 +        @Override
  25.137 +        public String toString() {
  25.138 +            return super.toString() + "[" + min +", " + max + "]";
  25.139 +        }
  25.140 +    }
  25.141 +
  25.142 +    /**
  25.143 +     * Get narrowest type for this range
  25.144 +     * @return type
  25.145 +     */
  25.146 +    public abstract Type getType();
  25.147 +
  25.148 +    /**
  25.149 +     * Is this range unknown
  25.150 +     * @return true if unknown
  25.151 +     */
  25.152 +    public boolean isUnknown() {
  25.153 +        return false;
  25.154 +    }
  25.155 +
  25.156 +    /**
  25.157 +     * Check if an integer is enough to span this range
  25.158 +     * @return true if integer is enough
  25.159 +     */
  25.160 +    public boolean isIntegerType() {
  25.161 +        return this instanceof IntegerRange;
  25.162 +    }
  25.163 +
  25.164 +    /**
  25.165 +     * Check if an integer is enough to span this range
  25.166 +     * @return true if integer is enough
  25.167 +     */
  25.168 +    public boolean isIntegerConst() {
  25.169 +        return false;
  25.170 +    }
  25.171 +
  25.172 +    /**
  25.173 +     * Create an unknown range - this is most likely a singleton object
  25.174 +     * and it represents "we have no known range information"
  25.175 +     * @return the range
  25.176 +     */
  25.177 +    public static Range createUnknownRange() {
  25.178 +        return UNKNOWN_RANGE;
  25.179 +    }
  25.180 +
  25.181 +    /**
  25.182 +     * Create a constant range: [value, value]
  25.183 +     * @param value value
  25.184 +     * @return the range
  25.185 +     */
  25.186 +    public static Range createRange(final int value) {
  25.187 +        return createIntegerRange(value, value);
  25.188 +    }
  25.189 +
  25.190 +    /**
  25.191 +     * Create a constant range: [value, value]
  25.192 +     * @param value value
  25.193 +     * @return the range
  25.194 +     */
  25.195 +    public static Range createRange(final long value) {
  25.196 +        return createIntegerRange(value, value);
  25.197 +    }
  25.198 +
  25.199 +    /**
  25.200 +     * Create a constant range: [value, value]
  25.201 +     * @param value value
  25.202 +     * @return the range
  25.203 +     */
  25.204 +    public static Range createRange(final double value) {
  25.205 +        if (isRepresentableAsLong(value)) {
  25.206 +            return createIntegerRange((long) value, (long) value);
  25.207 +        }
  25.208 +        return createNumberRange();
  25.209 +    }
  25.210 +
  25.211 +    /**
  25.212 +     * Create a constant range: [value, value]
  25.213 +     * @param value value
  25.214 +     * @return the range
  25.215 +     */
  25.216 +    public static Range createRange(final Object value) {
  25.217 +        if (value instanceof Integer) {
  25.218 +            return createRange((int)value);
  25.219 +        } else if (value instanceof Long) {
  25.220 +            return createRange((long)value);
  25.221 +        } else if (value instanceof Double) {
  25.222 +            return createRange((double)value);
  25.223 +        }
  25.224 +
  25.225 +        return createGenericRange();
  25.226 +    }
  25.227 +
  25.228 +    /**
  25.229 +     * Create a generic range - object symbol that carries no range
  25.230 +     * information
  25.231 +     * @return the range
  25.232 +     */
  25.233 +    public static Range createGenericRange() {
  25.234 +        return GENERIC_RANGE;
  25.235 +    }
  25.236 +
  25.237 +    /**
  25.238 +     * Create a number range - number symbol that carries no range
  25.239 +     * information
  25.240 +     * @return the range
  25.241 +     */
  25.242 +    public static Range createNumberRange() {
  25.243 +        return NUMBER_RANGE;
  25.244 +    }
  25.245 +
  25.246 +    /**
  25.247 +     * Create an integer range [min, max]
  25.248 +     * @param min minimum value, inclusive
  25.249 +     * @param max maximum value, inclusive
  25.250 +     * @return the range
  25.251 +     */
  25.252 +    public static IntegerRange createIntegerRange(final long min, final long max) {
  25.253 +        return new IntegerRange(min, max);
  25.254 +    }
  25.255 +
  25.256 +    /**
  25.257 +     * Create an integer range of maximum type width for the given type
  25.258 +     * @param type the type
  25.259 +     * @return the range
  25.260 +     */
  25.261 +    public static IntegerRange createIntegerRange(final Type type) {
  25.262 +        assert type.isNumeric() && !type.isNumber();
  25.263 +        final long min;
  25.264 +        final long max;
  25.265 +        if (type.isInteger()) {
  25.266 +            min = Integer.MIN_VALUE;
  25.267 +            max = Integer.MAX_VALUE;
  25.268 +        } else if (type.isLong()) {
  25.269 +            min = Long.MIN_VALUE;
  25.270 +            max = Long.MAX_VALUE;
  25.271 +        } else {
  25.272 +            throw new AssertionError(); //type incompatible with integer range
  25.273 +        }
  25.274 +        return new IntegerRange(min, max);
  25.275 +    }
  25.276 +
  25.277 +    /**
  25.278 +     * Create an range of maximum type width for the given type
  25.279 +     * @param type the type
  25.280 +     * @return the range
  25.281 +     */
  25.282 +    public static Range createTypeRange(final Type type) {
  25.283 +        if (type.isNumber()) {
  25.284 +            return createNumberRange();
  25.285 +        } else if (type.isNumeric()) {
  25.286 +            return createIntegerRange(type);
  25.287 +        } else {
  25.288 +            return createGenericRange();
  25.289 +        }
  25.290 +    }
  25.291 +
  25.292 +    // check that add doesn't overflow
  25.293 +    private static boolean checkAdd(final long a, final long b) {
  25.294 +        final long result = a + b;
  25.295 +        return ((a ^ result) & (b ^ result)) >= 0;
  25.296 +    }
  25.297 +
  25.298 +    // check that sub doesn't overflow
  25.299 +    private static boolean checkSub(final long a, final long b) {
  25.300 +        final long result = a - b;
  25.301 +        return ((a ^ result) & (b ^ result)) >= 0;
  25.302 +    }
  25.303 +
  25.304 +    private static boolean checkMul(final long a, final long b) {
  25.305 +        // TODO correct overflow check
  25.306 +        return a >= Integer.MIN_VALUE && a <= Integer.MAX_VALUE && b >= Integer.MIN_VALUE && b <= Integer.MAX_VALUE;
  25.307 +    }
  25.308 +
  25.309 +    /**
  25.310 +     * The range functionality class responsible for merging ranges and drawing
  25.311 +     * range conclusions from operations executed
  25.312 +     */
  25.313 +    public static class Functionality {
  25.314 +        /** logger */
  25.315 +        protected final DebugLogger log;
  25.316 +
  25.317 +        /**
  25.318 +         * Constructor
  25.319 +         * @param log logger
  25.320 +         */
  25.321 +        public Functionality(final DebugLogger log) {
  25.322 +            this.log = log;
  25.323 +        }
  25.324 +
  25.325 +        /**
  25.326 +         * Join two ranges
  25.327 +         * @param a first range
  25.328 +         * @param b second range
  25.329 +         * @return the joined range
  25.330 +         */
  25.331 +        public Range join(final Range a, final Range b) {
  25.332 +            if (a.equals(b)) {
  25.333 +                return a;
  25.334 +            }
  25.335 +
  25.336 +            Type joinedType = a.getType();
  25.337 +            if (a.getType() != b.getType()) {
  25.338 +                if (a.isUnknown()) {
  25.339 +                    return b;
  25.340 +                }
  25.341 +                if (b.isUnknown()) {
  25.342 +                    return a;
  25.343 +                }
  25.344 +
  25.345 +                joinedType = Type.widest(a.getType(), b.getType());
  25.346 +            }
  25.347 +
  25.348 +            if (joinedType.isInteger() || joinedType.isLong()) {
  25.349 +                return createIntegerRange(
  25.350 +                        Math.min(((IntegerRange) a).getMin(), ((IntegerRange) b).getMin()),
  25.351 +                        Math.max(((IntegerRange) a).getMax(), ((IntegerRange) b).getMax()));
  25.352 +            }
  25.353 +
  25.354 +            return createTypeRange(joinedType);
  25.355 +        }
  25.356 +
  25.357 +        /**
  25.358 +         * Add operation
  25.359 +         * @param a range of first symbol to be added
  25.360 +         * @param b range of second symbol to be added
  25.361 +         * @return resulting range representing the value range after add
  25.362 +         */
  25.363 +        public Range add(final Range a, final Range b) {
  25.364 +            if (a.isIntegerType() && b.isIntegerType()) {
  25.365 +                final IntegerRange lhs = (IntegerRange)a;
  25.366 +                final IntegerRange rhs = (IntegerRange)b;
  25.367 +                if (checkAdd(lhs.getMin(), rhs.getMin()) && checkAdd(lhs.getMax(), rhs.getMax())) {
  25.368 +                    return createIntegerRange(lhs.getMin() + rhs.getMin(), lhs.getMax() + rhs.getMax());
  25.369 +                }
  25.370 +            }
  25.371 +
  25.372 +            if (a.getType().isNumeric() && b.getType().isNumeric()) {
  25.373 +                return createNumberRange();
  25.374 +            }
  25.375 +
  25.376 +            return createGenericRange();
  25.377 +        }
  25.378 +
  25.379 +        /**
  25.380 +         * Sub operation
  25.381 +         * @param a range of first symbol to be subtracted
  25.382 +         * @param b range of second symbol to be subtracted
  25.383 +         * @return resulting range representing the value range after subtraction
  25.384 +         */
  25.385 +        public Range sub(final Range a, final Range b) {
  25.386 +            if (a.isIntegerType() && b.isIntegerType()) {
  25.387 +                final IntegerRange lhs = (IntegerRange)a;
  25.388 +                final IntegerRange rhs = (IntegerRange)b;
  25.389 +                if (checkSub(lhs.getMin(), rhs.getMax()) && checkSub(lhs.getMax(), rhs.getMin())) {
  25.390 +                    return createIntegerRange(lhs.getMin() - rhs.getMax(), lhs.getMax() - rhs.getMin());
  25.391 +                }
  25.392 +            }
  25.393 +
  25.394 +            if (a.getType().isNumeric() && b.getType().isNumeric()) {
  25.395 +                return createNumberRange();
  25.396 +            }
  25.397 +
  25.398 +            return createGenericRange();
  25.399 +        }
  25.400 +
  25.401 +        /**
  25.402 +         * Mul operation
  25.403 +         * @param a range of first symbol to be multiplied
  25.404 +         * @param b range of second symbol to be multiplied
  25.405 +         * @return resulting range representing the value range after multiplication
  25.406 +         */
  25.407 +        public Range mul(final Range a, final Range b) {
  25.408 +            if (a.isIntegerType() && b.isIntegerType()) {
  25.409 +                final IntegerRange lhs = (IntegerRange)a;
  25.410 +                final IntegerRange rhs = (IntegerRange)b;
  25.411 +
  25.412 +                //ensure that nothing ever overflows or underflows
  25.413 +                if (checkMul(lhs.getMin(), rhs.getMin()) &&
  25.414 +                    checkMul(lhs.getMax(), rhs.getMax()) &&
  25.415 +                    checkMul(lhs.getMin(), rhs.getMax()) &&
  25.416 +                    checkMul(lhs.getMax(), rhs.getMin())) {
  25.417 +
  25.418 +                    final List<Long> results =
  25.419 +                        Arrays.asList(
  25.420 +                            lhs.getMin() * rhs.getMin(),
  25.421 +                            lhs.getMin() * rhs.getMax(),
  25.422 +                            lhs.getMax() * rhs.getMin(),
  25.423 +                            lhs.getMax() * rhs.getMax());
  25.424 +                    return createIntegerRange(Collections.min(results), Collections.max(results));
  25.425 +                }
  25.426 +            }
  25.427 +
  25.428 +            if (a.getType().isNumeric() && b.getType().isNumeric()) {
  25.429 +                return createNumberRange();
  25.430 +            }
  25.431 +
  25.432 +            return createGenericRange();
  25.433 +        }
  25.434 +
  25.435 +        /**
  25.436 +         * Neg operation
  25.437 +         * @param a range of value symbol to be negated
  25.438 +         * @return resulting range representing the value range after neg
  25.439 +         */
  25.440 +        public Range neg(final Range a) {
  25.441 +            if (a.isIntegerType()) {
  25.442 +                final IntegerRange rhs = (IntegerRange)a;
  25.443 +                if (rhs.getMin() != Long.MIN_VALUE && rhs.getMax() != Long.MIN_VALUE) {
  25.444 +                    return createIntegerRange(-rhs.getMax(), -rhs.getMin());
  25.445 +                }
  25.446 +            }
  25.447 +
  25.448 +            if (a.getType().isNumeric()) {
  25.449 +                return createNumberRange();
  25.450 +            }
  25.451 +
  25.452 +            return createGenericRange();
  25.453 +        }
  25.454 +
  25.455 +        /**
  25.456 +         * Bitwise and operation
  25.457 +         * @param a range of first symbol to be and:ed
  25.458 +         * @param b range of second symbol to be and:ed
  25.459 +         * @return resulting range representing the value range after and
  25.460 +         */
  25.461 +        public Range and(final Range a, final Range b) {
  25.462 +            if (a.isIntegerType() && b.isIntegerType()) {
  25.463 +                final int resultMask = (int) (((IntegerRange)a).getBitMask() & ((IntegerRange)b).getBitMask());
  25.464 +                if (resultMask >= 0) {
  25.465 +                    return createIntegerRange(0, resultMask);
  25.466 +                }
  25.467 +            } else if (a.isUnknown() && b.isIntegerType()) {
  25.468 +                final long operandMask = ((IntegerRange)b).getBitMask();
  25.469 +                if (operandMask >= 0) {
  25.470 +                    return createIntegerRange(0, operandMask);
  25.471 +                }
  25.472 +            } else if (a.isIntegerType() && b.isUnknown()) {
  25.473 +                final long operandMask = ((IntegerRange)a).getBitMask();
  25.474 +                if (operandMask >= 0) {
  25.475 +                    return createIntegerRange(0, operandMask);
  25.476 +                }
  25.477 +            }
  25.478 +
  25.479 +            return createTypeRange(Type.INT);
  25.480 +        }
  25.481 +
  25.482 +        /**
  25.483 +         * Bitwise or operation
  25.484 +         * @param a range of first symbol to be or:ed
  25.485 +         * @param b range of second symbol to be or:ed
  25.486 +         * @return resulting range representing the value range after or
  25.487 +         */
  25.488 +        public Range or(final Range a, final Range b) {
  25.489 +            if (a.isIntegerType() && b.isIntegerType()) {
  25.490 +                final int resultMask = (int)(((IntegerRange)a).getBitMask() | ((IntegerRange)b).getBitMask());
  25.491 +                if (resultMask >= 0) {
  25.492 +                    return createIntegerRange(0, resultMask);
  25.493 +                }
  25.494 +            }
  25.495 +
  25.496 +            return createTypeRange(Type.INT);
  25.497 +        }
  25.498 +
  25.499 +        /**
  25.500 +         * Bitwise xor operation
  25.501 +         * @param a range of first symbol to be xor:ed
  25.502 +         * @param b range of second symbol to be xor:ed
  25.503 +         * @return resulting range representing the value range after and
  25.504 +         */
  25.505 +        public Range xor(final Range a, final Range b) {
  25.506 +            if (a.isIntegerConst() && b.isIntegerConst()) {
  25.507 +                return createRange(((IntegerRange)a).getMin() ^ ((IntegerRange)b).getMin());
  25.508 +            }
  25.509 +
  25.510 +            if (a.isIntegerType() && b.isIntegerType()) {
  25.511 +                final int resultMask = (int)(((IntegerRange)a).getBitMask() | ((IntegerRange)b).getBitMask());
  25.512 +                if (resultMask >= 0) {
  25.513 +                    return createIntegerRange(0, createIntegerRange(0, resultMask).getBitMask());
  25.514 +                }
  25.515 +            }
  25.516 +            return createTypeRange(Type.INT);
  25.517 +        }
  25.518 +
  25.519 +        /**
  25.520 +         * Bitwise shl operation
  25.521 +         * @param a range of first symbol to be shl:ed
  25.522 +         * @param b range of second symbol to be shl:ed
  25.523 +         * @return resulting range representing the value range after shl
  25.524 +         */
  25.525 +        public Range shl(final Range a, final Range b) {
  25.526 +            if (b.isIntegerType() && b.isIntegerConst()) {
  25.527 +                final IntegerRange left  = (IntegerRange)(a.isIntegerType() ? a : createTypeRange(Type.INT));
  25.528 +                final int          shift = (int)((IntegerRange) b).getMin() & 0x1f;
  25.529 +                final int          min   = (int)left.getMin() << shift;
  25.530 +                final int          max   = (int)left.getMax() << shift;
  25.531 +                if (min >> shift == left.getMin() && max >> shift == left.getMax()) {
  25.532 +                    return createIntegerRange(min, max);
  25.533 +                }
  25.534 +            }
  25.535 +
  25.536 +            return createTypeRange(Type.INT);
  25.537 +        }
  25.538 +
  25.539 +        /**
  25.540 +         * Bitwise shr operation
  25.541 +         * @param a range of first symbol to be shr:ed
  25.542 +         * @param b range of second symbol to be shr:ed
  25.543 +         * @return resulting range representing the value range after shr
  25.544 +         */
  25.545 +        public Range shr(final Range a, final Range b) {
  25.546 +            if (b.isIntegerType() && b.isIntegerConst()) {
  25.547 +                final long         shift = ((IntegerRange) b).getMin() & 0x1f;
  25.548 +                final IntegerRange left  = (IntegerRange)(a.isIntegerType() ? a : createTypeRange(Type.INT));
  25.549 +                if (left.getMin() >= 0) {
  25.550 +                    long min = left.getMin() >>> shift;
  25.551 +                    long max = left.getMax() >>> shift;
  25.552 +                    return createIntegerRange(min, max);
  25.553 +                } else if (shift >= 1) {
  25.554 +                    return createIntegerRange(0, JSType.MAX_UINT >>> shift);
  25.555 +                }
  25.556 +            }
  25.557 +
  25.558 +            return createTypeRange(Type.INT);
  25.559 +        }
  25.560 +
  25.561 +        /**
  25.562 +         * Bitwise sar operation
  25.563 +         * @param a range of first symbol to be sar:ed
  25.564 +         * @param b range of second symbol to be sar:ed
  25.565 +         * @return resulting range representing the value range after sar
  25.566 +         */
  25.567 +        public Range sar(final Range a, final Range b) {
  25.568 +            if (b.isIntegerType() && b.isIntegerConst()) {
  25.569 +                final IntegerRange left  = (IntegerRange)(a.isIntegerType() ? a : createTypeRange(Type.INT));
  25.570 +                final long         shift = ((IntegerRange) b).getMin() & 0x1f;
  25.571 +                final long         min   = left.getMin() >> shift;
  25.572 +                final long         max   = left.getMax() >> shift;
  25.573 +                return createIntegerRange(min, max);
  25.574 +            }
  25.575 +
  25.576 +            return createTypeRange(Type.INT);
  25.577 +        }
  25.578 +
  25.579 +        /**
  25.580 +         * Modulo operation
  25.581 +         * @param a range of first symbol to the mod operation
  25.582 +         * @param b range of second symbol to be mod operation
  25.583 +         * @return resulting range representing the value range after mod
  25.584 +         */
  25.585 +        public Range mod(final Range a, final Range b) {
  25.586 +            if (a.isIntegerType() && b.isIntegerType()) {
  25.587 +                final IntegerRange rhs = (IntegerRange) b;
  25.588 +                if (rhs.getMin() > 0 || rhs.getMax() < 0) { // divisor range must not include 0
  25.589 +                    final long absmax = Math.max(Math.abs(rhs.getMin()), Math.abs(rhs.getMax())) - 1;
  25.590 +                    return createIntegerRange(rhs.getMin() > 0 ? 0 : -absmax, rhs.getMax() < 0 ? 0 : +absmax);
  25.591 +                }
  25.592 +            }
  25.593 +            return createTypeRange(Type.NUMBER);
  25.594 +        }
  25.595 +
  25.596 +        /**
  25.597 +         * Division operation
  25.598 +         * @param a range of first symbol to the division
  25.599 +         * @param b range of second symbol to be division
  25.600 +         * @return resulting range representing the value range after division
  25.601 +         */
  25.602 +        public Range div(final Range a, final Range b) {
  25.603 +            // TODO
  25.604 +            return createTypeRange(Type.NUMBER);
  25.605 +        }
  25.606 +    }
  25.607 +
  25.608 +    /**
  25.609 +     * Simple trace functionality that will log range creation
  25.610 +     */
  25.611 +    public static class TraceFunctionality extends Functionality {
  25.612 +        TraceFunctionality(final DebugLogger log) {
  25.613 +            super(log);
  25.614 +        }
  25.615 +
  25.616 +        private Range trace(final Range result, final String operation, final Range... operands) {
  25.617 +            log.fine("range::" + operation + Arrays.toString(operands) + " => " + result);
  25.618 +            return result;
  25.619 +        }
  25.620 +
  25.621 +        @Override
  25.622 +        public Range join(final Range a, final Range b) {
  25.623 +            final Range result = super.join(a, b);
  25.624 +            if (!a.equals(b)) {
  25.625 +                trace(result, "join", a, b);
  25.626 +            }
  25.627 +            return result;
  25.628 +        }
  25.629 +
  25.630 +        @Override
  25.631 +        public Range add(final Range a, final Range b) {
  25.632 +            return trace(super.add(a, b), "add", a, b);
  25.633 +        }
  25.634 +
  25.635 +        @Override
  25.636 +        public Range sub(final Range a, final Range b) {
  25.637 +            return trace(super.sub(a, b), "sub", a, b);
  25.638 +        }
  25.639 +
  25.640 +        @Override
  25.641 +        public Range mul(final Range a, final Range b) {
  25.642 +            return trace(super.mul(a, b), "mul", a, b);
  25.643 +        }
  25.644 +
  25.645 +        @Override
  25.646 +        public Range neg(final Range a) {
  25.647 +            return trace(super.neg(a), "neg", a);
  25.648 +        }
  25.649 +
  25.650 +        @Override
  25.651 +        public Range and(final Range a, final Range b) {
  25.652 +            return trace(super.and(a, b), "and", a, b);
  25.653 +        }
  25.654 +
  25.655 +        @Override
  25.656 +        public Range or(final Range a, final Range b) {
  25.657 +            return trace(super.or(a, b), "or", a, b);
  25.658 +        }
  25.659 +
  25.660 +        @Override
  25.661 +        public Range xor(final Range a, final Range b) {
  25.662 +            return trace(super.xor(a, b), "xor", a, b);
  25.663 +        }
  25.664 +
  25.665 +        @Override
  25.666 +        public Range shl(final Range a, final Range b) {
  25.667 +            return trace(super.shl(a, b), "shl", a, b);
  25.668 +        }
  25.669 +
  25.670 +        @Override
  25.671 +        public Range shr(final Range a, final Range b) {
  25.672 +            return trace(super.shr(a, b), "shr", a, b);
  25.673 +        }
  25.674 +
  25.675 +        @Override
  25.676 +        public Range sar(final Range a, final Range b) {
  25.677 +            return trace(super.sar(a, b), "sar", a, b);
  25.678 +        }
  25.679 +
  25.680 +        @Override
  25.681 +        public Range mod(final Range a, final Range b) {
  25.682 +            return trace(super.mod(a, b), "mod", a, b);
  25.683 +        }
  25.684 +
  25.685 +        @Override
  25.686 +        public Range div(final Range a, final Range b) {
  25.687 +            return trace(super.div(a, b), "div", a, b);
  25.688 +        }
  25.689 +    }
  25.690 +
  25.691 +    @Override
  25.692 +    public String toString() {
  25.693 +        return String.valueOf(getType());
  25.694 +    }
  25.695 +
  25.696 +    @SuppressWarnings("unused")
  25.697 +    private static boolean isRepresentableAsInt(final double number) {
  25.698 +        return (int)number == number && !isNegativeZero(number);
  25.699 +    }
  25.700 +
  25.701 +    private static boolean isRepresentableAsLong(final double number) {
  25.702 +        return (long)number == number && !isNegativeZero(number);
  25.703 +    }
  25.704 +
  25.705 +    private static boolean isNegativeZero(final double number) {
  25.706 +        return Double.doubleToLongBits(number) == Double.doubleToLongBits(-0.0);
  25.707 +    }
  25.708 +}
    26.1 --- a/src/jdk/nashorn/internal/codegen/types/Type.java	Thu May 30 10:58:35 2013 -0700
    26.2 +++ b/src/jdk/nashorn/internal/codegen/types/Type.java	Mon Jun 03 23:24:36 2013 -0700
    26.3 @@ -106,23 +106,13 @@
    26.4      Type(final String name, final Class<?> clazz, final int weight, final int slots) {
    26.5          this.name       = name;
    26.6          this.clazz      = clazz;
    26.7 -        this.descriptor = Type.getDescriptor(clazz);
    26.8 +        this.descriptor = jdk.internal.org.objectweb.asm.Type.getDescriptor(clazz);
    26.9          this.weight     = weight;
   26.10          assert weight >= MIN_WEIGHT && weight <= MAX_WEIGHT : "illegal type weight: " + weight;
   26.11          this.slots      = slots;
   26.12      }
   26.13  
   26.14      /**
   26.15 -     * Return an internal descriptor for a type
   26.16 -     *
   26.17 -     * @param type the type
   26.18 -     * @return descriptor string
   26.19 -     */
   26.20 -    public static String getDescriptor(final Class<?> type) {
   26.21 -        return jdk.internal.org.objectweb.asm.Type.getDescriptor(type);
   26.22 -    }
   26.23 -
   26.24 -    /**
   26.25       * Get the weight of this type - use this e.g. for sorting method descriptors
   26.26       * @return the weight
   26.27       */
    27.1 --- a/src/jdk/nashorn/internal/ir/AccessNode.java	Thu May 30 10:58:35 2013 -0700
    27.2 +++ b/src/jdk/nashorn/internal/ir/AccessNode.java	Mon Jun 03 23:24:36 2013 -0700
    27.3 @@ -60,7 +60,7 @@
    27.4       * @param visitor IR navigating visitor.
    27.5       */
    27.6      @Override
    27.7 -    public Node accept(final NodeVisitor visitor) {
    27.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    27.9          if (visitor.enterAccessNode(this)) {
   27.10              return visitor.leaveAccessNode(
   27.11                  setBase(base.accept(visitor)).
   27.12 @@ -110,7 +110,6 @@
   27.13          return new AccessNode(this, base, property, isFunction(), hasCallSiteType());
   27.14      }
   27.15  
   27.16 -
   27.17      private AccessNode setProperty(final IdentNode property) {
   27.18          if (this.property == property) {
   27.19              return this;
    28.1 --- a/src/jdk/nashorn/internal/ir/BinaryNode.java	Thu May 30 10:58:35 2013 -0700
    28.2 +++ b/src/jdk/nashorn/internal/ir/BinaryNode.java	Mon Jun 03 23:24:36 2013 -0700
    28.3 @@ -59,6 +59,23 @@
    28.4          this.rhs = rhs;
    28.5      }
    28.6  
    28.7 +    @Override
    28.8 +    public boolean isComparison() {
    28.9 +        switch (tokenType()) {
   28.10 +        case EQ:
   28.11 +        case EQ_STRICT:
   28.12 +        case NE:
   28.13 +        case NE_STRICT:
   28.14 +        case LE:
   28.15 +        case LT:
   28.16 +        case GE:
   28.17 +        case GT:
   28.18 +            return true;
   28.19 +        default:
   28.20 +            return false;
   28.21 +        }
   28.22 +    }
   28.23 +
   28.24      /**
   28.25       * Return the widest possible type for this operation. This is used for compile time
   28.26       * static type inference
   28.27 @@ -143,7 +160,7 @@
   28.28       * @param visitor IR navigating visitor.
   28.29       */
   28.30      @Override
   28.31 -    public Node accept(final NodeVisitor visitor) {
   28.32 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   28.33          if (visitor.enterBinaryNode(this)) {
   28.34              return visitor.leaveBinaryNode(setLHS(lhs.accept(visitor)).setRHS(rhs.accept(visitor)));
   28.35          }
    29.1 --- a/src/jdk/nashorn/internal/ir/Block.java	Thu May 30 10:58:35 2013 -0700
    29.2 +++ b/src/jdk/nashorn/internal/ir/Block.java	Mon Jun 03 23:24:36 2013 -0700
    29.3 @@ -131,7 +131,7 @@
    29.4       * @return new or same node
    29.5       */
    29.6      @Override
    29.7 -    public Node accept(final LexicalContext lc, final NodeVisitor visitor) {
    29.8 +    public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
    29.9          if (visitor.enterBlock(this)) {
   29.10              return visitor.leaveBlock(setStatements(lc, Node.accept(visitor, Statement.class, statements)));
   29.11          }
    30.1 --- a/src/jdk/nashorn/internal/ir/BreakNode.java	Thu May 30 10:58:35 2013 -0700
    30.2 +++ b/src/jdk/nashorn/internal/ir/BreakNode.java	Mon Jun 03 23:24:36 2013 -0700
    30.3 @@ -59,7 +59,7 @@
    30.4       * @param visitor IR navigating visitor.
    30.5       */
    30.6      @Override
    30.7 -    public Node accept(final NodeVisitor visitor) {
    30.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    30.9          if (visitor.enterBreakNode(this)) {
   30.10              return visitor.leaveBreakNode(this);
   30.11          }
    31.1 --- a/src/jdk/nashorn/internal/ir/CallNode.java	Thu May 30 10:58:35 2013 -0700
    31.2 +++ b/src/jdk/nashorn/internal/ir/CallNode.java	Mon Jun 03 23:24:36 2013 -0700
    31.3 @@ -27,6 +27,7 @@
    31.4  
    31.5  import java.util.Collections;
    31.6  import java.util.List;
    31.7 +
    31.8  import jdk.nashorn.internal.codegen.types.Type;
    31.9  import jdk.nashorn.internal.ir.annotations.Ignore;
   31.10  import jdk.nashorn.internal.ir.annotations.Immutable;
   31.11 @@ -194,7 +195,7 @@
   31.12       * @return node or replacement
   31.13       */
   31.14      @Override
   31.15 -    public Node accept(final LexicalContext lc, final NodeVisitor visitor) {
   31.16 +    public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
   31.17          if (visitor.enterCallNode(this)) {
   31.18              final CallNode newCallNode = (CallNode)visitor.leaveCallNode(
   31.19                      setFunction(function.accept(visitor)).
    32.1 --- a/src/jdk/nashorn/internal/ir/CaseNode.java	Thu May 30 10:58:35 2013 -0700
    32.2 +++ b/src/jdk/nashorn/internal/ir/CaseNode.java	Mon Jun 03 23:24:36 2013 -0700
    32.3 @@ -78,7 +78,7 @@
    32.4       * @param visitor IR navigating visitor.
    32.5       */
    32.6      @Override
    32.7 -    public Node accept(final NodeVisitor visitor) {
    32.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    32.9          if (visitor.enterCaseNode(this)) {
   32.10              final Node  newTest = test == null ? null : test.accept(visitor);
   32.11              final Block newBody = body == null ? null : (Block)body.accept(visitor);
    33.1 --- a/src/jdk/nashorn/internal/ir/CatchNode.java	Thu May 30 10:58:35 2013 -0700
    33.2 +++ b/src/jdk/nashorn/internal/ir/CatchNode.java	Mon Jun 03 23:24:36 2013 -0700
    33.3 @@ -42,6 +42,11 @@
    33.4      /** Catch body. */
    33.5      private final Block body;
    33.6  
    33.7 +    private final int flags;
    33.8 +
    33.9 +    /** Is this block a synthethic rethrow created by finally inlining? */
   33.10 +    public static final int IS_SYNTHETIC_RETHROW = 1;
   33.11 +
   33.12      /**
   33.13       * Constructors
   33.14       *
   33.15 @@ -51,19 +56,22 @@
   33.16       * @param exception          variable name of exception
   33.17       * @param exceptionCondition exception condition
   33.18       * @param body               catch body
   33.19 +     * @param flags              flags
   33.20       */
   33.21 -    public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception, final Node exceptionCondition, final Block body) {
   33.22 +    public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception, final Node exceptionCondition, final Block body, final int flags) {
   33.23          super(lineNumber, token, finish);
   33.24          this.exception          = exception;
   33.25          this.exceptionCondition = exceptionCondition;
   33.26          this.body               = body;
   33.27 +        this.flags              = flags;
   33.28      }
   33.29  
   33.30 -    private CatchNode(final CatchNode catchNode, final IdentNode exception, final Node exceptionCondition, final Block body) {
   33.31 +    private CatchNode(final CatchNode catchNode, final IdentNode exception, final Node exceptionCondition, final Block body, final int flags) {
   33.32          super(catchNode);
   33.33          this.exception          = exception;
   33.34          this.exceptionCondition = exceptionCondition;
   33.35          this.body               = body;
   33.36 +        this.flags              = flags;
   33.37      }
   33.38  
   33.39      /**
   33.40 @@ -71,7 +79,7 @@
   33.41       * @param visitor IR navigating visitor.
   33.42       */
   33.43      @Override
   33.44 -    public Node accept(final NodeVisitor visitor) {
   33.45 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   33.46          if (visitor.enterCatchNode(this)) {
   33.47              return visitor.leaveCatchNode(
   33.48                  setException((IdentNode)exception.accept(visitor)).
   33.49 @@ -124,7 +132,7 @@
   33.50          if (this.exceptionCondition == exceptionCondition) {
   33.51              return this;
   33.52          }
   33.53 -        return new CatchNode(this, exception, exceptionCondition, body);
   33.54 +        return new CatchNode(this, exception, exceptionCondition, body, flags);
   33.55      }
   33.56  
   33.57      /**
   33.58 @@ -144,13 +152,25 @@
   33.59          if (this.exception == exception) {
   33.60              return this;
   33.61          }
   33.62 -        return new CatchNode(this, exception, exceptionCondition, body);
   33.63 +        return new CatchNode(this, exception, exceptionCondition, body, flags);
   33.64      }
   33.65  
   33.66      private CatchNode setBody(final Block body) {
   33.67          if (this.body == body) {
   33.68              return this;
   33.69          }
   33.70 -        return new CatchNode(this, exception, exceptionCondition, body);
   33.71 +        return new CatchNode(this, exception, exceptionCondition, body, flags);
   33.72      }
   33.73 +
   33.74 +    /**
   33.75 +     * Is this catch block a non-JavaScript constructor, for example created as
   33.76 +     * part of the rethrow mechanism of a finally block in Lower? Then we just
   33.77 +     * pass the exception on and need not unwrap whatever is in the ECMAException
   33.78 +     * object catch symbol
   33.79 +     * @return true if a finally synthetic rethrow
   33.80 +     */
   33.81 +    public boolean isSyntheticRethrow() {
   33.82 +        return (flags & IS_SYNTHETIC_RETHROW) == IS_SYNTHETIC_RETHROW;
   33.83 +    }
   33.84 +
   33.85  }
    34.1 --- a/src/jdk/nashorn/internal/ir/ContinueNode.java	Thu May 30 10:58:35 2013 -0700
    34.2 +++ b/src/jdk/nashorn/internal/ir/ContinueNode.java	Mon Jun 03 23:24:36 2013 -0700
    34.3 @@ -55,7 +55,7 @@
    34.4      }
    34.5  
    34.6      @Override
    34.7 -    public Node accept(final NodeVisitor visitor) {
    34.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    34.9          if (visitor.enterContinueNode(this)) {
   34.10              return visitor.leaveContinueNode(this);
   34.11          }
    35.1 --- a/src/jdk/nashorn/internal/ir/EmptyNode.java	Thu May 30 10:58:35 2013 -0700
    35.2 +++ b/src/jdk/nashorn/internal/ir/EmptyNode.java	Mon Jun 03 23:24:36 2013 -0700
    35.3 @@ -56,7 +56,7 @@
    35.4  
    35.5  
    35.6      @Override
    35.7 -    public Node accept(final NodeVisitor visitor) {
    35.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    35.9          if (visitor.enterEmptyNode(this)) {
   35.10              return visitor.leaveEmptyNode(this);
   35.11          }
    36.1 --- a/src/jdk/nashorn/internal/ir/ExecuteNode.java	Thu May 30 10:58:35 2013 -0700
    36.2 +++ b/src/jdk/nashorn/internal/ir/ExecuteNode.java	Mon Jun 03 23:24:36 2013 -0700
    36.3 @@ -62,7 +62,7 @@
    36.4      }
    36.5  
    36.6      @Override
    36.7 -    public Node accept(final NodeVisitor visitor) {
    36.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    36.9          if (visitor.enterExecuteNode(this)) {
   36.10              return visitor.leaveExecuteNode(setExpression(expression.accept(visitor)));
   36.11          }
    37.1 --- a/src/jdk/nashorn/internal/ir/ForNode.java	Thu May 30 10:58:35 2013 -0700
    37.2 +++ b/src/jdk/nashorn/internal/ir/ForNode.java	Mon Jun 03 23:24:36 2013 -0700
    37.3 @@ -86,7 +86,7 @@
    37.4      }
    37.5  
    37.6      @Override
    37.7 -    protected Node accept(final LexicalContext lc, final NodeVisitor visitor) {
    37.8 +    protected Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
    37.9          if (visitor.enterForNode(this)) {
   37.10              return visitor.leaveForNode(
   37.11                  setInit(lc, init == null ? null : init.accept(visitor)).
    38.1 --- a/src/jdk/nashorn/internal/ir/FunctionNode.java	Thu May 30 10:58:35 2013 -0700
    38.2 +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java	Mon Jun 03 23:24:36 2013 -0700
    38.3 @@ -250,6 +250,7 @@
    38.4          final FunctionNode functionNode,
    38.5          final long lastToken,
    38.6          final int flags,
    38.7 +        final String name,
    38.8          final Type returnType,
    38.9          final CompileUnit compileUnit,
   38.10          final EnumSet<CompilationState> compilationState,
   38.11 @@ -260,6 +261,7 @@
   38.12          super(functionNode);
   38.13  
   38.14          this.flags            = flags;
   38.15 +        this.name             = name;
   38.16          this.returnType       = returnType;
   38.17          this.compileUnit      = compileUnit;
   38.18          this.lastToken        = lastToken;
   38.19 @@ -271,7 +273,6 @@
   38.20  
   38.21          // the fields below never change - they are final and assigned in constructor
   38.22          this.source          = functionNode.source;
   38.23 -        this.name            = functionNode.name;
   38.24          this.ident           = functionNode.ident;
   38.25          this.namespace       = functionNode.namespace;
   38.26          this.declaredSymbols = functionNode.declaredSymbols;
   38.27 @@ -280,7 +281,7 @@
   38.28      }
   38.29  
   38.30      @Override
   38.31 -    public Node accept(final LexicalContext lc, final NodeVisitor visitor) {
   38.32 +    public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
   38.33          if (visitor.enterFunctionNode(this)) {
   38.34              return visitor.leaveFunctionNode(setBody(lc, (Block)body.accept(visitor)));
   38.35          }
   38.36 @@ -315,7 +316,7 @@
   38.37          if (this.snapshot == null) {
   38.38              return this;
   38.39          }
   38.40 -        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, null, hints));
   38.41 +        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, null, hints));
   38.42      }
   38.43  
   38.44      /**
   38.45 @@ -331,7 +332,7 @@
   38.46          if (isProgram() || parameters.isEmpty()) {
   38.47              return this; //never specialize anything that won't be recompiled
   38.48          }
   38.49 -        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, this, hints));
   38.50 +        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, this, hints));
   38.51      }
   38.52  
   38.53      /**
   38.54 @@ -339,7 +340,7 @@
   38.55       * @return true if specialization is possible
   38.56       */
   38.57      public boolean canSpecialize() {
   38.58 -        return getFlag(CAN_SPECIALIZE);
   38.59 +        return snapshot != null && getFlag(CAN_SPECIALIZE);
   38.60      }
   38.61  
   38.62      /**
   38.63 @@ -389,7 +390,7 @@
   38.64          }
   38.65          final EnumSet<CompilationState> newState = EnumSet.copyOf(this.compilationState);
   38.66          newState.add(state);
   38.67 -        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, newState, body, parameters, snapshot, hints));
   38.68 +        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, newState, body, parameters, snapshot, hints));
   38.69      }
   38.70  
   38.71      /**
   38.72 @@ -410,7 +411,7 @@
   38.73          if (this.hints == hints) {
   38.74              return this;
   38.75          }
   38.76 -        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
   38.77 +        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
   38.78      }
   38.79  
   38.80      /**
   38.81 @@ -463,7 +464,7 @@
   38.82          if (this.flags == flags) {
   38.83              return this;
   38.84          }
   38.85 -        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
   38.86 +        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
   38.87      }
   38.88  
   38.89      @Override
   38.90 @@ -529,7 +530,7 @@
   38.91      }
   38.92  
   38.93      /**
   38.94 -     * Get the identifier for this function
   38.95 +     * Get the identifier for this function, this is its symbol.
   38.96       * @return the identifier as an IdentityNode
   38.97       */
   38.98      public IdentNode getIdent() {
   38.99 @@ -572,7 +573,7 @@
  38.100          if(this.body == body) {
  38.101              return this;
  38.102          }
  38.103 -        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
  38.104 +        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
  38.105      }
  38.106  
  38.107      /**
  38.108 @@ -640,7 +641,7 @@
  38.109          if (this.lastToken == lastToken) {
  38.110              return this;
  38.111          }
  38.112 -        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
  38.113 +        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
  38.114      }
  38.115  
  38.116      /**
  38.117 @@ -651,6 +652,20 @@
  38.118          return name;
  38.119      }
  38.120  
  38.121 +
  38.122 +    /**
  38.123 +     * Set the internal name for this function
  38.124 +     * @param lc    lexical context
  38.125 +     * @param name new name
  38.126 +     * @return new function node if changed, otherwise the same
  38.127 +     */
  38.128 +    public FunctionNode setName(final LexicalContext lc, final String name) {
  38.129 +        if (this.name.equals(name)) {
  38.130 +            return this;
  38.131 +        }
  38.132 +        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
  38.133 +    }
  38.134 +
  38.135      /**
  38.136       * Check if this function should have all its variables in its own scope. Scripts, split sub-functions, and
  38.137       * functions having with and/or eval blocks are such.
  38.138 @@ -698,7 +713,7 @@
  38.139          if (this.parameters == parameters) {
  38.140              return this;
  38.141          }
  38.142 -        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
  38.143 +        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
  38.144      }
  38.145  
  38.146      /**
  38.147 @@ -762,6 +777,7 @@
  38.148                  this,
  38.149                  lastToken,
  38.150                  flags,
  38.151 +                name,
  38.152                  Type.widest(this.returnType, returnType.isObject() ?
  38.153                      Type.OBJECT :
  38.154                      returnType),
  38.155 @@ -801,7 +817,7 @@
  38.156          if (this.compileUnit == compileUnit) {
  38.157              return this;
  38.158          }
  38.159 -        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
  38.160 +        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
  38.161      }
  38.162  
  38.163      /**
    39.1 --- a/src/jdk/nashorn/internal/ir/IdentNode.java	Thu May 30 10:58:35 2013 -0700
    39.2 +++ b/src/jdk/nashorn/internal/ir/IdentNode.java	Mon Jun 03 23:24:36 2013 -0700
    39.3 @@ -29,7 +29,6 @@
    39.4  import static jdk.nashorn.internal.codegen.CompilerConstants.__FILE__;
    39.5  import static jdk.nashorn.internal.codegen.CompilerConstants.__LINE__;
    39.6  import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
    39.7 -
    39.8  import jdk.nashorn.internal.codegen.ObjectClassGenerator;
    39.9  import jdk.nashorn.internal.codegen.types.Type;
   39.10  import jdk.nashorn.internal.ir.annotations.Immutable;
   39.11 @@ -119,7 +118,7 @@
   39.12       * @param visitor IR navigating visitor.
   39.13       */
   39.14      @Override
   39.15 -    public Node accept(final NodeVisitor visitor) {
   39.16 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   39.17          if (visitor.enterIdentNode(this)) {
   39.18              return visitor.leaveIdentNode(this);
   39.19          }
    40.1 --- a/src/jdk/nashorn/internal/ir/IfNode.java	Thu May 30 10:58:35 2013 -0700
    40.2 +++ b/src/jdk/nashorn/internal/ir/IfNode.java	Mon Jun 03 23:24:36 2013 -0700
    40.3 @@ -72,7 +72,7 @@
    40.4      }
    40.5  
    40.6      @Override
    40.7 -    public Node accept(final NodeVisitor visitor) {
    40.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    40.9          if (visitor.enterIfNode(this)) {
   40.10              return visitor.leaveIfNode(
   40.11                  setTest(test.accept(visitor)).
    41.1 --- a/src/jdk/nashorn/internal/ir/IndexNode.java	Thu May 30 10:58:35 2013 -0700
    41.2 +++ b/src/jdk/nashorn/internal/ir/IndexNode.java	Mon Jun 03 23:24:36 2013 -0700
    41.3 @@ -56,19 +56,12 @@
    41.4      }
    41.5  
    41.6      @Override
    41.7 -    public Node accept(final NodeVisitor visitor) {
    41.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    41.9          if (visitor.enterIndexNode(this)) {
   41.10 -            final Node      newBase  = base.accept(visitor);
   41.11 -            final Node      newIndex = index.accept(visitor);
   41.12 -            final IndexNode newNode;
   41.13 -            if (newBase != base || newIndex != index) {
   41.14 -                newNode = new IndexNode(this, newBase, newIndex, isFunction(), hasCallSiteType());
   41.15 -            } else {
   41.16 -                newNode = this;
   41.17 -            }
   41.18 -            return visitor.leaveIndexNode(newNode);
   41.19 +            return visitor.leaveIndexNode(
   41.20 +                setBase(base.accept(visitor)).
   41.21 +                setIndex(index.accept(visitor)));
   41.22          }
   41.23 -
   41.24          return this;
   41.25      }
   41.26  
   41.27 @@ -106,6 +99,13 @@
   41.28          return index;
   41.29      }
   41.30  
   41.31 +    private IndexNode setBase(final Node base) {
   41.32 +        if (this.base == base) {
   41.33 +            return this;
   41.34 +        }
   41.35 +        return new IndexNode(this, base, index, isFunction(), hasCallSiteType());
   41.36 +    }
   41.37 +
   41.38      /**
   41.39       * Set the index expression for this node
   41.40       * @param index new index expression
    42.1 --- a/src/jdk/nashorn/internal/ir/LabelNode.java	Thu May 30 10:58:35 2013 -0700
    42.2 +++ b/src/jdk/nashorn/internal/ir/LabelNode.java	Mon Jun 03 23:24:36 2013 -0700
    42.3 @@ -67,11 +67,11 @@
    42.4      }
    42.5  
    42.6      @Override
    42.7 -    public Node accept(final LexicalContext lc, final NodeVisitor visitor) {
    42.8 +    public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
    42.9          if (visitor.enterLabelNode(this)) {
   42.10              return visitor.leaveLabelNode(
   42.11 -                setLabel(visitor.getLexicalContext(), (IdentNode)label.accept(visitor)).
   42.12 -                setBody(visitor.getLexicalContext(), (Block)body.accept(visitor)));
   42.13 +                setLabel(lc, (IdentNode)label.accept(visitor)).
   42.14 +                setBody(lc, (Block)body.accept(visitor)));
   42.15          }
   42.16  
   42.17          return this;
    43.1 --- a/src/jdk/nashorn/internal/ir/LexicalContext.java	Thu May 30 10:58:35 2013 -0700
    43.2 +++ b/src/jdk/nashorn/internal/ir/LexicalContext.java	Mon Jun 03 23:24:36 2013 -0700
    43.3 @@ -440,6 +440,23 @@
    43.4      }
    43.5  
    43.6      /**
    43.7 +     * Check whether the lexical context is currently inside a loop
    43.8 +     * @return true if inside a loop
    43.9 +     */
   43.10 +    public boolean inLoop() {
   43.11 +        return getCurrentLoop() != null;
   43.12 +    }
   43.13 +
   43.14 +    /**
   43.15 +     * Returns the loop header of the current loop, or null if not inside a loop
   43.16 +     * @return loop header
   43.17 +     */
   43.18 +    public LoopNode getCurrentLoop() {
   43.19 +        final Iterator<LoopNode> iter = new NodeIterator<>(LoopNode.class, getCurrentFunction());
   43.20 +        return iter.hasNext() ? iter.next() : null;
   43.21 +    }
   43.22 +
   43.23 +    /**
   43.24       * Find the breakable node corresponding to this label.
   43.25       * @param label label to search for, if null the closest breakable node will be returned unconditionally, e.g. a while loop with no label
   43.26       * @return closest breakable node
   43.27 @@ -461,8 +478,7 @@
   43.28      }
   43.29  
   43.30      private LoopNode getContinueTo() {
   43.31 -        final Iterator<LoopNode> iter = new NodeIterator<>(LoopNode.class, getCurrentFunction());
   43.32 -        return iter.hasNext() ? iter.next() : null;
   43.33 +        return getCurrentLoop();
   43.34      }
   43.35  
   43.36      /**
    44.1 --- a/src/jdk/nashorn/internal/ir/LexicalContextNode.java	Thu May 30 10:58:35 2013 -0700
    44.2 +++ b/src/jdk/nashorn/internal/ir/LexicalContextNode.java	Mon Jun 03 23:24:36 2013 -0700
    44.3 @@ -60,10 +60,10 @@
    44.4       *
    44.5       * @return new node or same node depending on state change
    44.6       */
    44.7 -    protected abstract Node accept(final LexicalContext lc, final NodeVisitor visitor);
    44.8 +    protected abstract Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor);
    44.9  
   44.10      @Override
   44.11 -    public Node accept(final NodeVisitor visitor) {
   44.12 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   44.13          final LexicalContext lc = visitor.getLexicalContext();
   44.14          lc.push(this);
   44.15          final LexicalContextNode newNode = (LexicalContextNode)accept(lc, visitor);
    45.1 --- a/src/jdk/nashorn/internal/ir/LiteralNode.java	Thu May 30 10:58:35 2013 -0700
    45.2 +++ b/src/jdk/nashorn/internal/ir/LiteralNode.java	Mon Jun 03 23:24:36 2013 -0700
    45.3 @@ -28,6 +28,7 @@
    45.4  import java.util.Arrays;
    45.5  import java.util.Collections;
    45.6  import java.util.List;
    45.7 +
    45.8  import jdk.nashorn.internal.codegen.CompileUnit;
    45.9  import jdk.nashorn.internal.codegen.types.Type;
   45.10  import jdk.nashorn.internal.ir.annotations.Immutable;
   45.11 @@ -208,7 +209,7 @@
   45.12       * @param visitor IR navigating visitor.
   45.13       */
   45.14      @Override
   45.15 -    public Node accept(final NodeVisitor visitor) {
   45.16 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   45.17          if (visitor.enterLiteralNode(this)) {
   45.18              return visitor.leaveLiteralNode(this);
   45.19          }
   45.20 @@ -514,7 +515,7 @@
   45.21          }
   45.22  
   45.23          @Override
   45.24 -        public Node accept(final NodeVisitor visitor) {
   45.25 +        public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   45.26              if (visitor.enterLiteralNode(this)) {
   45.27                  if (value != null) {
   45.28                      final Node newValue = value.accept(visitor);
   45.29 @@ -840,7 +841,7 @@
   45.30          }
   45.31  
   45.32          @Override
   45.33 -        public Node accept(final NodeVisitor visitor) {
   45.34 +        public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   45.35              if (visitor.enterLiteralNode(this)) {
   45.36                  final List<Node> oldValue = Arrays.asList(value);
   45.37                  final List<Node> newValue = Node.accept(visitor, Node.class, oldValue);
    46.1 --- a/src/jdk/nashorn/internal/ir/Node.java	Thu May 30 10:58:35 2013 -0700
    46.2 +++ b/src/jdk/nashorn/internal/ir/Node.java	Mon Jun 03 23:24:36 2013 -0700
    46.3 @@ -27,6 +27,7 @@
    46.4  
    46.5  import java.util.ArrayList;
    46.6  import java.util.List;
    46.7 +
    46.8  import jdk.nashorn.internal.codegen.types.Type;
    46.9  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   46.10  import jdk.nashorn.internal.parser.Token;
   46.11 @@ -153,6 +154,14 @@
   46.12      }
   46.13  
   46.14      /**
   46.15 +     * Returns true if this node represents a comparison operator
   46.16 +     * @return true if comparison
   46.17 +     */
   46.18 +    public boolean isComparison() {
   46.19 +        return false;
   46.20 +    }
   46.21 +
   46.22 +    /**
   46.23       * For reference copies - ensure that labels in the copy node are unique
   46.24       * using an appropriate copy constructor
   46.25       * @param lc lexical context
   46.26 @@ -167,7 +176,7 @@
   46.27       * @param visitor Node visitor.
   46.28       * @return node the node or its replacement after visitation, null if no further visitations are required
   46.29       */
   46.30 -    public abstract Node accept(NodeVisitor visitor);
   46.31 +    public abstract Node accept(NodeVisitor<? extends LexicalContext> visitor);
   46.32  
   46.33      @Override
   46.34      public String toString() {
   46.35 @@ -329,7 +338,7 @@
   46.36      }
   46.37  
   46.38      //on change, we have to replace the entire list, that's we can't simple do ListIterator.set
   46.39 -    static <T extends Node> List<T> accept(final NodeVisitor visitor, final Class<T> clazz, final List<T> list) {
   46.40 +    static <T extends Node> List<T> accept(final NodeVisitor<? extends LexicalContext> visitor, final Class<T> clazz, final List<T> list) {
   46.41          boolean changed = false;
   46.42          final List<T> newList = new ArrayList<>();
   46.43  
    47.1 --- a/src/jdk/nashorn/internal/ir/ObjectNode.java	Thu May 30 10:58:35 2013 -0700
    47.2 +++ b/src/jdk/nashorn/internal/ir/ObjectNode.java	Mon Jun 03 23:24:36 2013 -0700
    47.3 @@ -58,7 +58,7 @@
    47.4      }
    47.5  
    47.6      @Override
    47.7 -    public Node accept(final NodeVisitor visitor) {
    47.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    47.9          if (visitor.enterObjectNode(this)) {
   47.10              return visitor.leaveObjectNode(setElements(Node.accept(visitor, Node.class, elements)));
   47.11          }
    48.1 --- a/src/jdk/nashorn/internal/ir/PropertyNode.java	Thu May 30 10:58:35 2013 -0700
    48.2 +++ b/src/jdk/nashorn/internal/ir/PropertyNode.java	Mon Jun 03 23:24:36 2013 -0700
    48.3 @@ -81,7 +81,7 @@
    48.4      }
    48.5  
    48.6      @Override
    48.7 -    public Node accept(final NodeVisitor visitor) {
    48.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    48.9          if (visitor.enterPropertyNode(this)) {
   48.10              return visitor.leavePropertyNode(
   48.11                  setKey((PropertyKey)((Node)key).accept(visitor)).
    49.1 --- a/src/jdk/nashorn/internal/ir/ReturnNode.java	Thu May 30 10:58:35 2013 -0700
    49.2 +++ b/src/jdk/nashorn/internal/ir/ReturnNode.java	Mon Jun 03 23:24:36 2013 -0700
    49.3 @@ -86,7 +86,7 @@
    49.4      }
    49.5  
    49.6      @Override
    49.7 -    public Node accept(final NodeVisitor visitor) {
    49.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    49.9          if (visitor.enterReturnNode(this)) {
   49.10              if (expression != null) {
   49.11                  return visitor.leaveReturnNode(setExpression(expression.accept(visitor)));
    50.1 --- a/src/jdk/nashorn/internal/ir/RuntimeNode.java	Thu May 30 10:58:35 2013 -0700
    50.2 +++ b/src/jdk/nashorn/internal/ir/RuntimeNode.java	Mon Jun 03 23:24:36 2013 -0700
    50.3 @@ -29,6 +29,7 @@
    50.4  import java.util.Arrays;
    50.5  import java.util.Collections;
    50.6  import java.util.List;
    50.7 +
    50.8  import jdk.nashorn.internal.codegen.types.Type;
    50.9  import jdk.nashorn.internal.ir.annotations.Immutable;
   50.10  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   50.11 @@ -407,7 +408,7 @@
   50.12      }
   50.13  
   50.14      @Override
   50.15 -    public Node accept(final NodeVisitor visitor) {
   50.16 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   50.17          if (visitor.enterRuntimeNode(this)) {
   50.18              final List<Node> newArgs = new ArrayList<>();
   50.19              for (final Node arg : args) {
    51.1 --- a/src/jdk/nashorn/internal/ir/SplitNode.java	Thu May 30 10:58:35 2013 -0700
    51.2 +++ b/src/jdk/nashorn/internal/ir/SplitNode.java	Mon Jun 03 23:24:36 2013 -0700
    51.3 @@ -81,7 +81,7 @@
    51.4      }
    51.5  
    51.6      @Override
    51.7 -    public Node accept(final LexicalContext lc, final NodeVisitor visitor) {
    51.8 +    public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
    51.9          if (visitor.enterSplitNode(this)) {
   51.10              return visitor.leaveSplitNode(setBody(lc, body.accept(visitor)));
   51.11          }
    52.1 --- a/src/jdk/nashorn/internal/ir/SwitchNode.java	Thu May 30 10:58:35 2013 -0700
    52.2 +++ b/src/jdk/nashorn/internal/ir/SwitchNode.java	Mon Jun 03 23:24:36 2013 -0700
    52.3 @@ -100,11 +100,11 @@
    52.4      }
    52.5  
    52.6      @Override
    52.7 -    public Node accept(final LexicalContext lc, final NodeVisitor visitor) {
    52.8 +    public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
    52.9          if (visitor.enterSwitchNode(this)) {
   52.10              return visitor.leaveSwitchNode(
   52.11 -                setExpression(visitor.getLexicalContext(), expression.accept(visitor)).
   52.12 -                setCases(visitor.getLexicalContext(), Node.accept(visitor, CaseNode.class, cases), defaultCaseIndex));
   52.13 +                setExpression(lc, expression.accept(visitor)).
   52.14 +                setCases(lc, Node.accept(visitor, CaseNode.class, cases), defaultCaseIndex));
   52.15          }
   52.16  
   52.17          return this;
    53.1 --- a/src/jdk/nashorn/internal/ir/Symbol.java	Thu May 30 10:58:35 2013 -0700
    53.2 +++ b/src/jdk/nashorn/internal/ir/Symbol.java	Mon Jun 03 23:24:36 2013 -0700
    53.3 @@ -29,6 +29,8 @@
    53.4  import java.util.HashSet;
    53.5  import java.util.Set;
    53.6  import java.util.StringTokenizer;
    53.7 +
    53.8 +import jdk.nashorn.internal.codegen.types.Range;
    53.9  import jdk.nashorn.internal.codegen.types.Type;
   53.10  import jdk.nashorn.internal.runtime.Context;
   53.11  import jdk.nashorn.internal.runtime.Debug;
   53.12 @@ -89,6 +91,9 @@
   53.13      /** Number of times this symbol is used in code */
   53.14      private int useCount;
   53.15  
   53.16 +    /** Range for symbol */
   53.17 +    private Range range;
   53.18 +
   53.19      /** Debugging option - dump info and stack trace when symbols with given names are manipulated */
   53.20      private static final Set<String> TRACE_SYMBOLS;
   53.21      private static final Set<String> TRACE_SYMBOLS_STACKTRACE;
   53.22 @@ -131,6 +136,7 @@
   53.23          this.type       = type;
   53.24          this.slot       = slot;
   53.25          this.fieldIndex = -1;
   53.26 +        this.range      = Range.createUnknownRange();
   53.27          trace("CREATE SYMBOL");
   53.28      }
   53.29  
   53.30 @@ -157,12 +163,13 @@
   53.31  
   53.32      private Symbol(final Symbol base, final String name, final int flags) {
   53.33          this.flags = flags;
   53.34 -        this.name = name;
   53.35 +        this.name  = name;
   53.36  
   53.37          this.fieldIndex = base.fieldIndex;
   53.38 -        this.slot = base.slot;
   53.39 -        this.type = base.type;
   53.40 -        this.useCount = base.useCount;
   53.41 +        this.slot       = base.slot;
   53.42 +        this.type       = base.type;
   53.43 +        this.useCount   = base.useCount;
   53.44 +        this.range      = base.range;
   53.45      }
   53.46  
   53.47      private static String align(final String string, final int max) {
   53.48 @@ -276,7 +283,7 @@
   53.49  
   53.50      @Override
   53.51      public String toString() {
   53.52 -        final StringBuilder sb   = new StringBuilder();
   53.53 +        final StringBuilder sb = new StringBuilder();
   53.54  
   53.55          sb.append(name).
   53.56              append(' ').
   53.57 @@ -410,6 +417,22 @@
   53.58      }
   53.59  
   53.60      /**
   53.61 +     * Get the range for this symbol
   53.62 +     * @return range for symbol
   53.63 +     */
   53.64 +    public Range getRange() {
   53.65 +        return range;
   53.66 +    }
   53.67 +
   53.68 +    /**
   53.69 +     * Set the range for this symbol
   53.70 +     * @param range range
   53.71 +     */
   53.72 +    public void setRange(final Range range) {
   53.73 +        this.range = range;
   53.74 +    }
   53.75 +
   53.76 +    /**
   53.77       * Check if this symbol is a function parameter of known
   53.78       * narrowest type
   53.79       * @return true if parameter
    54.1 --- a/src/jdk/nashorn/internal/ir/TernaryNode.java	Thu May 30 10:58:35 2013 -0700
    54.2 +++ b/src/jdk/nashorn/internal/ir/TernaryNode.java	Mon Jun 03 23:24:36 2013 -0700
    54.3 @@ -63,7 +63,7 @@
    54.4      }
    54.5  
    54.6      @Override
    54.7 -    public Node accept(final NodeVisitor visitor) {
    54.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    54.9          if (visitor.enterTernaryNode(this)) {
   54.10              final Node newLhs = lhs().accept(visitor);
   54.11              final Node newRhs = rhs().accept(visitor);
    55.1 --- a/src/jdk/nashorn/internal/ir/ThrowNode.java	Thu May 30 10:58:35 2013 -0700
    55.2 +++ b/src/jdk/nashorn/internal/ir/ThrowNode.java	Mon Jun 03 23:24:36 2013 -0700
    55.3 @@ -36,6 +36,11 @@
    55.4      /** Exception expression. */
    55.5      private final Node expression;
    55.6  
    55.7 +    private final int flags;
    55.8 +
    55.9 +    /** Is this block a synthethic rethrow created by finally inlining? */
   55.10 +    public static final int IS_SYNTHETIC_RETHROW = 1;
   55.11 +
   55.12      /**
   55.13       * Constructor
   55.14       *
   55.15 @@ -43,15 +48,18 @@
   55.16       * @param token      token
   55.17       * @param finish     finish
   55.18       * @param expression expression to throw
   55.19 +     * @param flags      flags
   55.20       */
   55.21 -    public ThrowNode(final int lineNumber, final long token, final int finish, final Node expression) {
   55.22 +    public ThrowNode(final int lineNumber, final long token, final int finish, final Node expression, final int flags) {
   55.23          super(lineNumber, token, finish);
   55.24          this.expression = expression;
   55.25 +        this.flags = flags;
   55.26      }
   55.27  
   55.28 -    private ThrowNode(final ThrowNode node, final Node expression) {
   55.29 +    private ThrowNode(final ThrowNode node, final Node expression, final int flags) {
   55.30          super(node);
   55.31          this.expression = expression;
   55.32 +        this.flags = flags;
   55.33      }
   55.34  
   55.35      @Override
   55.36 @@ -64,7 +72,7 @@
   55.37       * @param visitor IR navigating visitor.
   55.38       */
   55.39      @Override
   55.40 -    public Node accept(final NodeVisitor visitor) {
   55.41 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   55.42          if (visitor.enterThrowNode(this)) {
   55.43              return visitor.leaveThrowNode(setExpression(expression.accept(visitor)));
   55.44          }
   55.45 @@ -98,7 +106,17 @@
   55.46          if (this.expression == expression) {
   55.47              return this;
   55.48          }
   55.49 -        return new ThrowNode(this, expression);
   55.50 +        return new ThrowNode(this, expression, flags);
   55.51 +    }
   55.52 +
   55.53 +    /**
   55.54 +     * Is this a throw a synthetic rethrow in a synthetic catch-all block
   55.55 +     * created when inlining finally statements? In that case we never
   55.56 +     * wrap whatever is thrown into an ECMAException, just rethrow it.
   55.57 +     * @return true if synthetic throw node
   55.58 +     */
   55.59 +    public boolean isSyntheticRethrow() {
   55.60 +        return (flags & IS_SYNTHETIC_RETHROW) == IS_SYNTHETIC_RETHROW;
   55.61      }
   55.62  
   55.63  }
    56.1 --- a/src/jdk/nashorn/internal/ir/TryNode.java	Thu May 30 10:58:35 2013 -0700
    56.2 +++ b/src/jdk/nashorn/internal/ir/TryNode.java	Mon Jun 03 23:24:36 2013 -0700
    56.3 @@ -106,7 +106,7 @@
    56.4       * @param visitor IR navigating visitor.
    56.5       */
    56.6      @Override
    56.7 -    public Node accept(final NodeVisitor visitor) {
    56.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    56.9          if (visitor.enterTryNode(this)) {
   56.10              // Need to do finallybody first for termination analysis. TODO still necessary?
   56.11              final Block newFinallyBody = finallyBody == null ? null : (Block)finallyBody.accept(visitor);
    57.1 --- a/src/jdk/nashorn/internal/ir/UnaryNode.java	Thu May 30 10:58:35 2013 -0700
    57.2 +++ b/src/jdk/nashorn/internal/ir/UnaryNode.java	Mon Jun 03 23:24:36 2013 -0700
    57.3 @@ -29,7 +29,6 @@
    57.4  import static jdk.nashorn.internal.parser.TokenType.CONVERT;
    57.5  import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX;
    57.6  import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
    57.7 -
    57.8  import jdk.nashorn.internal.codegen.types.Type;
    57.9  import jdk.nashorn.internal.ir.annotations.Immutable;
   57.10  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   57.11 @@ -121,7 +120,7 @@
   57.12       * @param visitor IR navigating visitor.
   57.13       */
   57.14      @Override
   57.15 -    public Node accept(final NodeVisitor visitor) {
   57.16 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   57.17          if (visitor.enterUnaryNode(this)) {
   57.18              return visitor.leaveUnaryNode(setRHS(rhs.accept(visitor)));
   57.19          }
    58.1 --- a/src/jdk/nashorn/internal/ir/VarNode.java	Thu May 30 10:58:35 2013 -0700
    58.2 +++ b/src/jdk/nashorn/internal/ir/VarNode.java	Mon Jun 03 23:24:36 2013 -0700
    58.3 @@ -121,7 +121,7 @@
    58.4       * @param visitor IR navigating visitor.
    58.5       */
    58.6      @Override
    58.7 -    public Node accept(final NodeVisitor visitor) {
    58.8 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
    58.9          if (visitor.enterVarNode(this)) {
   58.10              final IdentNode newName = (IdentNode)name.accept(visitor);
   58.11              final Node      newInit = init == null ? null : init.accept(visitor);
    59.1 --- a/src/jdk/nashorn/internal/ir/WhileNode.java	Thu May 30 10:58:35 2013 -0700
    59.2 +++ b/src/jdk/nashorn/internal/ir/WhileNode.java	Mon Jun 03 23:24:36 2013 -0700
    59.3 @@ -75,7 +75,7 @@
    59.4      }
    59.5  
    59.6      @Override
    59.7 -    protected Node accept(final LexicalContext lc, final NodeVisitor visitor) {
    59.8 +    protected Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
    59.9          if (visitor.enterWhileNode(this)) {
   59.10              if (isDoWhile()) {
   59.11                  return visitor.leaveWhileNode(
    60.1 --- a/src/jdk/nashorn/internal/ir/WithNode.java	Thu May 30 10:58:35 2013 -0700
    60.2 +++ b/src/jdk/nashorn/internal/ir/WithNode.java	Mon Jun 03 23:24:36 2013 -0700
    60.3 @@ -64,7 +64,7 @@
    60.4       * @param visitor IR navigating visitor.
    60.5       */
    60.6      @Override
    60.7 -    public Node accept(final LexicalContext lc, final NodeVisitor visitor) {
    60.8 +    public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
    60.9          if (visitor.enterWithNode(this)) {
   60.10               return visitor.leaveWithNode(
   60.11                  setExpression(lc, expression.accept(visitor)).
    61.1 --- a/src/jdk/nashorn/internal/ir/debug/JSONWriter.java	Thu May 30 10:58:35 2013 -0700
    61.2 +++ b/src/jdk/nashorn/internal/ir/debug/JSONWriter.java	Mon Jun 03 23:24:36 2013 -0700
    61.3 @@ -45,6 +45,7 @@
    61.4  import jdk.nashorn.internal.ir.IfNode;
    61.5  import jdk.nashorn.internal.ir.IndexNode;
    61.6  import jdk.nashorn.internal.ir.LabelNode;
    61.7 +import jdk.nashorn.internal.ir.LexicalContext;
    61.8  import jdk.nashorn.internal.ir.LiteralNode;
    61.9  import jdk.nashorn.internal.ir.Node;
   61.10  import jdk.nashorn.internal.ir.ObjectNode;
   61.11 @@ -74,7 +75,8 @@
   61.12  /**
   61.13   * This IR writer produces a JSON string that represents AST as a JSON string.
   61.14   */
   61.15 -public final class JSONWriter extends NodeVisitor {
   61.16 +public final class JSONWriter extends NodeVisitor<LexicalContext> {
   61.17 +
   61.18      /**
   61.19       * Returns AST as JSON compatible string.
   61.20       *
   61.21 @@ -867,7 +869,8 @@
   61.22      // Internals below
   61.23  
   61.24      private JSONWriter(final boolean includeLocation) {
   61.25 -        this.buf = new StringBuilder();
   61.26 +        super(new LexicalContext());
   61.27 +        this.buf             = new StringBuilder();
   61.28          this.includeLocation = includeLocation;
   61.29      }
   61.30  
   61.31 @@ -963,7 +966,7 @@
   61.32              objectStart("loc");
   61.33  
   61.34              // source name
   61.35 -            final Source src = getLexicalContext().getCurrentFunction().getSource();
   61.36 +            final Source src = lc.getCurrentFunction().getSource();
   61.37              property("source", src.getName());
   61.38              comma();
   61.39  
    62.1 --- a/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java	Thu May 30 10:58:35 2013 -0700
    62.2 +++ b/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java	Mon Jun 03 23:24:36 2013 -0700
    62.3 @@ -36,6 +36,7 @@
    62.4  import jdk.nashorn.internal.ir.FunctionNode;
    62.5  import jdk.nashorn.internal.ir.IfNode;
    62.6  import jdk.nashorn.internal.ir.LabelNode;
    62.7 +import jdk.nashorn.internal.ir.LexicalContext;
    62.8  import jdk.nashorn.internal.ir.Node;
    62.9  import jdk.nashorn.internal.ir.SplitNode;
   62.10  import jdk.nashorn.internal.ir.Statement;
   62.11 @@ -53,7 +54,7 @@
   62.12   *
   62.13   * see the flags --print-parse and --print-lower-parse
   62.14   */
   62.15 -public final class PrintVisitor extends NodeVisitor {
   62.16 +public final class PrintVisitor extends NodeVisitor<LexicalContext> {
   62.17      /** Tab width */
   62.18      private static final int TABWIDTH = 4;
   62.19  
   62.20 @@ -84,6 +85,7 @@
   62.21       * @param printLineNumbers  should line number nodes be included in the output?
   62.22       */
   62.23      public PrintVisitor(final boolean printLineNumbers) {
   62.24 +        super(new LexicalContext());
   62.25          this.EOLN             = System.lineSeparator();
   62.26          this.sb               = new StringBuilder();
   62.27          this.printLineNumbers = printLineNumbers;
    63.1 --- a/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java	Thu May 30 10:58:35 2013 -0700
    63.2 +++ b/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java	Mon Jun 03 23:24:36 2013 -0700
    63.3 @@ -32,21 +32,15 @@
    63.4  
    63.5  /**
    63.6   * Like NodeVisitor but navigating further into operators.
    63.7 + * @param <T> Lexical context class for this NodeOperatorVisitor
    63.8   */
    63.9 -public class NodeOperatorVisitor extends NodeVisitor {
   63.10 -    /**
   63.11 -     * Constructor
   63.12 -     */
   63.13 -    public NodeOperatorVisitor() {
   63.14 -        super();
   63.15 -    }
   63.16 -
   63.17 +public class NodeOperatorVisitor<T extends LexicalContext> extends NodeVisitor<T> {
   63.18      /**
   63.19       * Constructor
   63.20       *
   63.21       * @param lc a custom lexical context
   63.22       */
   63.23 -    public NodeOperatorVisitor(final LexicalContext lc) {
   63.24 +    public NodeOperatorVisitor(final T lc) {
   63.25          super(lc);
   63.26      }
   63.27  
    64.1 --- a/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java	Thu May 30 10:58:35 2013 -0700
    64.2 +++ b/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java	Mon Jun 03 23:24:36 2013 -0700
    64.3 @@ -60,23 +60,18 @@
    64.4  
    64.5  /**
    64.6   * Visitor used to navigate the IR.
    64.7 + * @param <T> lexical context class used by this visitor
    64.8   */
    64.9 -public abstract class NodeVisitor {
   64.10 -    private final LexicalContext lc;
   64.11 -
   64.12 -    /**
   64.13 -     * Constructor
   64.14 -     */
   64.15 -    public NodeVisitor() {
   64.16 -        this(new LexicalContext());
   64.17 -    }
   64.18 +public abstract class NodeVisitor<T extends LexicalContext> {
   64.19 +    /** lexical context in use */
   64.20 +    protected final T lc;
   64.21  
   64.22      /**
   64.23       * Constructor
   64.24       *
   64.25       * @param lc a custom lexical context
   64.26       */
   64.27 -    public NodeVisitor(final LexicalContext lc) {
   64.28 +    public NodeVisitor(final T lc) {
   64.29          this.lc = lc;
   64.30      }
   64.31  
   64.32 @@ -84,7 +79,7 @@
   64.33       * Get the lexical context of this node visitor
   64.34       * @return lexical context
   64.35       */
   64.36 -    public LexicalContext getLexicalContext() {
   64.37 +    public T getLexicalContext() {
   64.38          return lc;
   64.39      }
   64.40  
    65.1 --- a/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Thu May 30 10:58:35 2013 -0700
    65.2 +++ b/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Mon Jun 03 23:24:36 2013 -0700
    65.3 @@ -59,11 +59,6 @@
    65.4      }
    65.5  
    65.6      @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
    65.7 -    public static Object BYTES_PER_ELEMENT(final Object self) {
    65.8 -        return ((ArrayBufferView)self).bytesPerElement();
    65.9 -    }
   65.10 -
   65.11 -    @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
   65.12      public static Object buffer(final Object self) {
   65.13          return ((ArrayDataImpl)((ArrayBufferView)self).getArray()).buffer;
   65.14      }
    66.1 --- a/src/jdk/nashorn/internal/objects/DateParser.java	Thu May 30 10:58:35 2013 -0700
    66.2 +++ b/src/jdk/nashorn/internal/objects/DateParser.java	Mon Jun 03 23:24:36 2013 -0700
    66.3 @@ -32,6 +32,7 @@
    66.4  import static java.lang.Character.UPPERCASE_LETTER;
    66.5  
    66.6  import java.util.HashMap;
    66.7 +import java.util.Locale;
    66.8  
    66.9  /**
   66.10   * JavaScript date parser. This class first tries to parse a date string
   66.11 @@ -486,7 +487,7 @@
   66.12          while (pos < limit && isAsciiLetter(string.charAt(pos))) {
   66.13              pos++;
   66.14          }
   66.15 -        final String key = string.substring(start, pos).toLowerCase();
   66.16 +        final String key = string.substring(start, pos).toLowerCase(Locale.ENGLISH);
   66.17          final Name name = names.get(key);
   66.18          // then advance to end of name
   66.19          while (pos < length && isAsciiLetter(string.charAt(pos))) {
   66.20 @@ -683,7 +684,7 @@
   66.21  
   66.22          Name(final String name, final int type, final int value) {
   66.23              assert name != null;
   66.24 -            assert name.equals(name.toLowerCase());
   66.25 +            assert name.equals(name.toLowerCase(Locale.ENGLISH));
   66.26  
   66.27              this.name = name;
   66.28              // use first three characters as lookup key
    67.1 --- a/src/jdk/nashorn/internal/objects/NativeArguments.java	Thu May 30 10:58:35 2013 -0700
    67.2 +++ b/src/jdk/nashorn/internal/objects/NativeArguments.java	Mon Jun 03 23:24:36 2013 -0700
    67.3 @@ -603,6 +603,11 @@
    67.4          }
    67.5      }
    67.6  
    67.7 +    @Override
    67.8 +    public Object getLength() {
    67.9 +        return length;
   67.10 +    }
   67.11 +
   67.12      private Object getArgumentsLength() {
   67.13          return length;
   67.14      }
    68.1 --- a/src/jdk/nashorn/internal/objects/NativeArray.java	Thu May 30 10:58:35 2013 -0700
    68.2 +++ b/src/jdk/nashorn/internal/objects/NativeArray.java	Mon Jun 03 23:24:36 2013 -0700
    68.3 @@ -754,25 +754,11 @@
    68.4          final Object       obj                 = Global.toObject(self);
    68.5          final ScriptObject sobj                = (ScriptObject)obj;
    68.6          final long         len                 = JSType.toUint32(sobj.getLength());
    68.7 -        final double       startNum            = JSType.toNumber(start);
    68.8 -        final long         relativeStartUint32 = JSType.toUint32(startNum);
    68.9 -        final long         relativeStart       = JSType.toInteger(startNum);
   68.10 +        final long         relativeStart       = JSType.toLong(start);
   68.11 +        final long         relativeEnd         = (end == ScriptRuntime.UNDEFINED) ? len : JSType.toLong(end);
   68.12  
   68.13 -        long k = relativeStart < 0 ?
   68.14 -                Math.max(len + relativeStart, 0) :
   68.15 -                Math.min(
   68.16 -                    Math.max(relativeStartUint32, relativeStart),
   68.17 -                    len);
   68.18 -
   68.19 -        final double endNum = (end == ScriptRuntime.UNDEFINED)? Double.NaN : JSType.toNumber(end);
   68.20 -        final long relativeEndUint32 = (end == ScriptRuntime.UNDEFINED)? len : JSType.toUint32(endNum);
   68.21 -        final long relativeEnd       = (end == ScriptRuntime.UNDEFINED)? len : JSType.toInteger(endNum);
   68.22 -
   68.23 -        final long finale = relativeEnd < 0 ?
   68.24 -                Math.max(len + relativeEnd, 0) :
   68.25 -                Math.min(
   68.26 -                    Math.max(relativeEndUint32, relativeEnd),
   68.27 -                    len);
   68.28 +        long k = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len);
   68.29 +        final long finale = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len);
   68.30  
   68.31          if (k >= finale) {
   68.32              return new NativeArray(0);
   68.33 @@ -909,21 +895,10 @@
   68.34          final ScriptObject sobj                = (ScriptObject)obj;
   68.35          final boolean      strict              = Global.isStrict();
   68.36          final long         len                 = JSType.toUint32(sobj.getLength());
   68.37 -        final double       startNum            = JSType.toNumber(start);
   68.38 -        final long         relativeStartUint32 = JSType.toUint32(startNum);
   68.39 -        final long         relativeStart       = JSType.toInteger(startNum);
   68.40 +        final long         relativeStart       = JSType.toLong(start);
   68.41  
   68.42 -        //TODO: workaround overflow of relativeStart for start > Integer.MAX_VALUE
   68.43 -        final long actualStart = relativeStart < 0 ?
   68.44 -            Math.max(len + relativeStart, 0) :
   68.45 -            Math.min(
   68.46 -                Math.max(relativeStartUint32, relativeStart),
   68.47 -                len);
   68.48 -
   68.49 -        final long actualDeleteCount =
   68.50 -            Math.min(
   68.51 -                Math.max(JSType.toInteger(deleteCount), 0),
   68.52 -                len - actualStart);
   68.53 +        final long actualStart = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len);
   68.54 +        final long actualDeleteCount = Math.min(Math.max(JSType.toLong(deleteCount), 0), len - actualStart);
   68.55  
   68.56          final NativeArray array = new NativeArray(actualDeleteCount);
   68.57  
    69.1 --- a/src/jdk/nashorn/internal/objects/NativeDate.java	Thu May 30 10:58:35 2013 -0700
    69.2 +++ b/src/jdk/nashorn/internal/objects/NativeDate.java	Mon Jun 03 23:24:36 2013 -0700
    69.3 @@ -770,7 +770,7 @@
    69.4              nd.setTime(NaN);
    69.5              return nd.getTime();
    69.6          }
    69.7 -        int yearInt = JSType.toInteger(yearNum);
    69.8 +        int yearInt = (int)yearNum;
    69.9          if (0 <= yearInt && yearInt <= 99) {
   69.10              yearInt += 1900;
   69.11          }
    70.1 --- a/src/jdk/nashorn/internal/objects/NativeFloat32Array.java	Thu May 30 10:58:35 2013 -0700
    70.2 +++ b/src/jdk/nashorn/internal/objects/NativeFloat32Array.java	Mon Jun 03 23:24:36 2013 -0700
    70.3 @@ -28,7 +28,9 @@
    70.4  import jdk.nashorn.internal.objects.annotations.Attribute;
    70.5  import jdk.nashorn.internal.objects.annotations.Constructor;
    70.6  import jdk.nashorn.internal.objects.annotations.Function;
    70.7 +import jdk.nashorn.internal.objects.annotations.Property;
    70.8  import jdk.nashorn.internal.objects.annotations.ScriptClass;
    70.9 +import jdk.nashorn.internal.objects.annotations.Where;
   70.10  import jdk.nashorn.internal.runtime.JSType;
   70.11  import jdk.nashorn.internal.runtime.ScriptObject;
   70.12  import jdk.nashorn.internal.runtime.arrays.ArrayData;
   70.13 @@ -38,7 +40,12 @@
   70.14   */
   70.15  @ScriptClass("Float32Array")
   70.16  public final class NativeFloat32Array extends ArrayBufferView {
   70.17 -    private static final int BYTES_PER_ELEMENT = 4;
   70.18 +    /**
   70.19 +     * The size in bytes of each element in the array.
   70.20 +     */
   70.21 +    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
   70.22 +    public static final int BYTES_PER_ELEMENT = 4;
   70.23 +
   70.24      private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
   70.25          @Override
   70.26          public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    71.1 --- a/src/jdk/nashorn/internal/objects/NativeFloat64Array.java	Thu May 30 10:58:35 2013 -0700
    71.2 +++ b/src/jdk/nashorn/internal/objects/NativeFloat64Array.java	Mon Jun 03 23:24:36 2013 -0700
    71.3 @@ -28,7 +28,9 @@
    71.4  import jdk.nashorn.internal.objects.annotations.Attribute;
    71.5  import jdk.nashorn.internal.objects.annotations.Constructor;
    71.6  import jdk.nashorn.internal.objects.annotations.Function;
    71.7 +import jdk.nashorn.internal.objects.annotations.Property;
    71.8  import jdk.nashorn.internal.objects.annotations.ScriptClass;
    71.9 +import jdk.nashorn.internal.objects.annotations.Where;
   71.10  import jdk.nashorn.internal.runtime.JSType;
   71.11  import jdk.nashorn.internal.runtime.ScriptObject;
   71.12  import jdk.nashorn.internal.runtime.arrays.ArrayData;
   71.13 @@ -38,7 +40,12 @@
   71.14   */
   71.15  @ScriptClass("Float64Array")
   71.16  public final class NativeFloat64Array extends ArrayBufferView {
   71.17 -    private static final int BYTES_PER_ELEMENT = 8;
   71.18 +    /**
   71.19 +     * The size in bytes of each element in the array.
   71.20 +     */
   71.21 +    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
   71.22 +    public static final int BYTES_PER_ELEMENT = 8;
   71.23 +
   71.24      private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
   71.25          @Override
   71.26          public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    72.1 --- a/src/jdk/nashorn/internal/objects/NativeInt16Array.java	Thu May 30 10:58:35 2013 -0700
    72.2 +++ b/src/jdk/nashorn/internal/objects/NativeInt16Array.java	Mon Jun 03 23:24:36 2013 -0700
    72.3 @@ -28,7 +28,9 @@
    72.4  import jdk.nashorn.internal.objects.annotations.Attribute;
    72.5  import jdk.nashorn.internal.objects.annotations.Constructor;
    72.6  import jdk.nashorn.internal.objects.annotations.Function;
    72.7 +import jdk.nashorn.internal.objects.annotations.Property;
    72.8  import jdk.nashorn.internal.objects.annotations.ScriptClass;
    72.9 +import jdk.nashorn.internal.objects.annotations.Where;
   72.10  import jdk.nashorn.internal.runtime.ScriptObject;
   72.11  import jdk.nashorn.internal.runtime.arrays.ArrayData;
   72.12  
   72.13 @@ -37,7 +39,12 @@
   72.14   */
   72.15  @ScriptClass("Int16Array")
   72.16  public final class NativeInt16Array extends ArrayBufferView {
   72.17 -    private static final int BYTES_PER_ELEMENT = 2;
   72.18 +    /**
   72.19 +     * The size in bytes of each element in the array.
   72.20 +     */
   72.21 +    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
   72.22 +    public static final int BYTES_PER_ELEMENT = 2;
   72.23 +
   72.24      private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
   72.25          @Override
   72.26          public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    73.1 --- a/src/jdk/nashorn/internal/objects/NativeInt32Array.java	Thu May 30 10:58:35 2013 -0700
    73.2 +++ b/src/jdk/nashorn/internal/objects/NativeInt32Array.java	Mon Jun 03 23:24:36 2013 -0700
    73.3 @@ -28,7 +28,9 @@
    73.4  import jdk.nashorn.internal.objects.annotations.Attribute;
    73.5  import jdk.nashorn.internal.objects.annotations.Constructor;
    73.6  import jdk.nashorn.internal.objects.annotations.Function;
    73.7 +import jdk.nashorn.internal.objects.annotations.Property;
    73.8  import jdk.nashorn.internal.objects.annotations.ScriptClass;
    73.9 +import jdk.nashorn.internal.objects.annotations.Where;
   73.10  import jdk.nashorn.internal.runtime.ScriptObject;
   73.11  import jdk.nashorn.internal.runtime.arrays.ArrayData;
   73.12  
   73.13 @@ -37,7 +39,12 @@
   73.14   */
   73.15  @ScriptClass("Int32Array")
   73.16  public final class NativeInt32Array extends ArrayBufferView {
   73.17 -    private static final int BYTES_PER_ELEMENT = 4;
   73.18 +    /**
   73.19 +     * The size in bytes of each element in the array.
   73.20 +     */
   73.21 +    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
   73.22 +    public static final int BYTES_PER_ELEMENT = 4;
   73.23 +
   73.24      private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
   73.25          @Override
   73.26          public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    74.1 --- a/src/jdk/nashorn/internal/objects/NativeInt8Array.java	Thu May 30 10:58:35 2013 -0700
    74.2 +++ b/src/jdk/nashorn/internal/objects/NativeInt8Array.java	Mon Jun 03 23:24:36 2013 -0700
    74.3 @@ -28,7 +28,9 @@
    74.4  import jdk.nashorn.internal.objects.annotations.Attribute;
    74.5  import jdk.nashorn.internal.objects.annotations.Constructor;
    74.6  import jdk.nashorn.internal.objects.annotations.Function;
    74.7 +import jdk.nashorn.internal.objects.annotations.Property;
    74.8  import jdk.nashorn.internal.objects.annotations.ScriptClass;
    74.9 +import jdk.nashorn.internal.objects.annotations.Where;
   74.10  import jdk.nashorn.internal.runtime.ScriptObject;
   74.11  import jdk.nashorn.internal.runtime.arrays.ArrayData;
   74.12  
   74.13 @@ -37,7 +39,12 @@
   74.14   */
   74.15  @ScriptClass("Int8Array")
   74.16  public final class NativeInt8Array extends ArrayBufferView {
   74.17 -    private static final int BYTES_PER_ELEMENT = 1;
   74.18 +    /**
   74.19 +     * The size in bytes of each element in the array.
   74.20 +     */
   74.21 +    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
   74.22 +    public static final int BYTES_PER_ELEMENT = 1;
   74.23 +
   74.24      private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
   74.25          @Override
   74.26          public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    75.1 --- a/src/jdk/nashorn/internal/objects/NativeJava.java	Thu May 30 10:58:35 2013 -0700
    75.2 +++ b/src/jdk/nashorn/internal/objects/NativeJava.java	Mon Jun 03 23:24:36 2013 -0700
    75.3 @@ -30,6 +30,8 @@
    75.4  
    75.5  import java.lang.reflect.Array;
    75.6  import java.util.Collection;
    75.7 +import java.util.Deque;
    75.8 +import java.util.List;
    75.9  import jdk.internal.dynalink.beans.StaticClass;
   75.10  import jdk.internal.dynalink.support.TypeUtilities;
   75.11  import jdk.nashorn.internal.objects.annotations.Attribute;
   75.12 @@ -37,6 +39,7 @@
   75.13  import jdk.nashorn.internal.objects.annotations.ScriptClass;
   75.14  import jdk.nashorn.internal.objects.annotations.Where;
   75.15  import jdk.nashorn.internal.runtime.JSType;
   75.16 +import jdk.nashorn.internal.runtime.ListAdapter;
   75.17  import jdk.nashorn.internal.runtime.ScriptObject;
   75.18  import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
   75.19  
   75.20 @@ -240,39 +243,56 @@
   75.21      }
   75.22  
   75.23      /**
   75.24 -     * Given a JavaScript array and a Java type, returns a Java array with the same initial contents, and with the
   75.25 -     * specified component type. Example:
   75.26 +     * Given a script object and a Java type, converts the script object into the desired Java type. Currently it
   75.27 +     * performs shallow creation of Java arrays, as well as wrapping of objects in Lists and Dequeues. Example:
   75.28       * <pre>
   75.29       * var anArray = [1, "13", false]
   75.30 -     * var javaIntArray = Java.toJavaArray(anArray, "int")
   75.31 +     * var javaIntArray = Java.to(anArray, "int[]")
   75.32       * print(javaIntArray[0]) // prints 1
   75.33       * print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
   75.34       * print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
   75.35       * </pre>
   75.36       * @param self not used
   75.37 -     * @param objArray the JavaScript array. Can be null.
   75.38 -     * @param objType either a {@link #type(Object, Object) type object} or a String describing the component type of
   75.39 -     * the Java array to create. Can not be null. If undefined, Object is assumed (allowing the argument to be omitted).
   75.40 -     * @return a Java array with the copy of JavaScript array's contents, converted to the appropriate Java component
   75.41 -     * type. Returns null if objArray is null.
   75.42 +     * @param obj the script object. Can be null.
   75.43 +     * @param objType either a {@link #type(Object, Object) type object} or a String describing the type of the Java
   75.44 +     * object to create. Can not be null. If undefined, a "default" conversion is presumed (allowing the argument to be
   75.45 +     * omitted).
   75.46 +     * @return a Java object whose value corresponds to the original script object's value. Specifically, for array
   75.47 +     * target types, returns a Java array of the same type with contents converted to the array's component type. Does
   75.48 +     * not recursively convert for multidimensional arrays. For {@link List} or {@link Deque}, returns a live wrapper
   75.49 +     * around the object, see {@link ListAdapter} for details. Returns null if obj is null.
   75.50       * @throws ClassNotFoundException if the class described by objType is not found
   75.51       */
   75.52      @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
   75.53 -    public static Object toJavaArray(final Object self, final Object objArray, final Object objType) throws ClassNotFoundException {
   75.54 -        final StaticClass componentType =
   75.55 -            objType instanceof StaticClass ?
   75.56 -                (StaticClass)objType :
   75.57 -                objType == UNDEFINED ?
   75.58 -                    StaticClass.forClass(Object.class) :
   75.59 -                    type(objType);
   75.60 -
   75.61 -        if (objArray == null) {
   75.62 +    public static Object to(final Object self, final Object obj, final Object objType) throws ClassNotFoundException {
   75.63 +        if (obj == null) {
   75.64              return null;
   75.65          }
   75.66  
   75.67 -        Global.checkObject(objArray);
   75.68 +        Global.checkObject(obj);
   75.69  
   75.70 -        return ((ScriptObject)objArray).getArray().asArrayOfType(componentType.getRepresentedClass());
   75.71 +        final Class<?> targetClass;
   75.72 +        if(objType == UNDEFINED) {
   75.73 +            targetClass = Object[].class;
   75.74 +        } else {
   75.75 +            final StaticClass targetType;
   75.76 +            if(objType instanceof StaticClass) {
   75.77 +                targetType = (StaticClass)objType;
   75.78 +            } else {
   75.79 +                targetType = type(objType);
   75.80 +            }
   75.81 +            targetClass = targetType.getRepresentedClass();
   75.82 +        }
   75.83 +
   75.84 +        if(targetClass.isArray()) {
   75.85 +            return ((ScriptObject)obj).getArray().asArrayOfType(targetClass.getComponentType());
   75.86 +        }
   75.87 +
   75.88 +        if(targetClass == List.class || targetClass == Deque.class) {
   75.89 +            return new ListAdapter((ScriptObject)obj);
   75.90 +        }
   75.91 +
   75.92 +        throw typeError("unsupported.java.to.type", targetClass.getName());
   75.93      }
   75.94  
   75.95      /**
   75.96 @@ -283,7 +303,7 @@
   75.97       * <pre>
   75.98       * var File = Java.type("java.io.File")
   75.99       * var listHomeDir = new File("~").listFiles()
  75.100 -     * var jsListHome = Java.toJavaScriptArray(listHomeDir)
  75.101 +     * var jsListHome = Java.from(listHomeDir)
  75.102       * var jpegModifiedDates = jsListHome
  75.103       *     .filter(function(val) { return val.getName().endsWith(".jpg") })
  75.104       *     .map(function(val) { return val.lastModified() })
  75.105 @@ -294,7 +314,7 @@
  75.106       * null.
  75.107       */
  75.108      @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
  75.109 -    public static Object toJavaScriptArray(final Object self, final Object objArray) {
  75.110 +    public static Object from(final Object self, final Object objArray) {
  75.111          if (objArray == null) {
  75.112              return null;
  75.113          } else if (objArray instanceof Collection) {
    76.1 --- a/src/jdk/nashorn/internal/objects/NativeMath.java	Thu May 30 10:58:35 2013 -0700
    76.2 +++ b/src/jdk/nashorn/internal/objects/NativeMath.java	Mon Jun 03 23:24:36 2013 -0700
    76.3 @@ -611,13 +611,11 @@
    76.4       */
    76.5      @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
    76.6      public static Object round(final Object self, final Object x) {
    76.7 -        if (GlobalFunctions.isNaN(self, x)) {
    76.8 -            return Double.NaN;
    76.9 -        } else if (!GlobalFunctions.isFinite(self, x)) {
   76.10 -            return x;
   76.11 +        final double d = JSType.toNumber(x);
   76.12 +        if (Math.getExponent(d) >= 52) {
   76.13 +            return d;
   76.14          }
   76.15 -
   76.16 -        return Math.round(JSType.toNumber(x));
   76.17 +        return Math.copySign(Math.floor(d + 0.5), d);
   76.18      }
   76.19  
   76.20      /**
    77.1 --- a/src/jdk/nashorn/internal/objects/NativeString.java	Thu May 30 10:58:35 2013 -0700
    77.2 +++ b/src/jdk/nashorn/internal/objects/NativeString.java	Mon Jun 03 23:24:36 2013 -0700
    77.3 @@ -38,6 +38,7 @@
    77.4  import java.util.Arrays;
    77.5  import java.util.LinkedList;
    77.6  import java.util.List;
    77.7 +import java.util.Locale;
    77.8  import jdk.internal.dynalink.CallSiteDescriptor;
    77.9  import jdk.internal.dynalink.linker.GuardedInvocation;
   77.10  import jdk.internal.dynalink.linker.LinkRequest;
   77.11 @@ -630,17 +631,24 @@
   77.12  
   77.13          final String str       = checkObjectToString(self);
   77.14          final String searchStr = JSType.toString(search);
   77.15 +        final int length       = str.length();
   77.16  
   77.17 -        int from;
   77.18 +        int end;
   77.19  
   77.20          if (pos == UNDEFINED) {
   77.21 -            from = str.length();
   77.22 +            end = length;
   77.23          } else {
   77.24              final double numPos = JSType.toNumber(pos);
   77.25 -            from = !Double.isNaN(numPos) ? (int)numPos : (int)Double.POSITIVE_INFINITY;
   77.26 +            end = Double.isNaN(numPos) ? length : (int)numPos;
   77.27 +            if (end < 0) {
   77.28 +                end = 0;
   77.29 +            } else if (end > length) {
   77.30 +                end = length;
   77.31 +            }
   77.32          }
   77.33  
   77.34 -        return str.lastIndexOf(searchStr, from);
   77.35 +
   77.36 +        return str.lastIndexOf(searchStr, end);
   77.37      }
   77.38  
   77.39      /**
   77.40 @@ -997,7 +1005,7 @@
   77.41       */
   77.42      @Function(attributes = Attribute.NOT_ENUMERABLE)
   77.43      public static Object toLowerCase(final Object self) {
   77.44 -        return checkObjectToString(self).toLowerCase();
   77.45 +        return checkObjectToString(self).toLowerCase(Locale.ROOT);
   77.46      }
   77.47  
   77.48      /**
   77.49 @@ -1017,7 +1025,7 @@
   77.50       */
   77.51      @Function(attributes = Attribute.NOT_ENUMERABLE)
   77.52      public static Object toUpperCase(final Object self) {
   77.53 -        return checkObjectToString(self).toUpperCase();
   77.54 +        return checkObjectToString(self).toUpperCase(Locale.ROOT);
   77.55      }
   77.56  
   77.57      /**
    78.1 --- a/src/jdk/nashorn/internal/objects/NativeUint16Array.java	Thu May 30 10:58:35 2013 -0700
    78.2 +++ b/src/jdk/nashorn/internal/objects/NativeUint16Array.java	Mon Jun 03 23:24:36 2013 -0700
    78.3 @@ -28,7 +28,9 @@
    78.4  import jdk.nashorn.internal.objects.annotations.Attribute;
    78.5  import jdk.nashorn.internal.objects.annotations.Constructor;
    78.6  import jdk.nashorn.internal.objects.annotations.Function;
    78.7 +import jdk.nashorn.internal.objects.annotations.Property;
    78.8  import jdk.nashorn.internal.objects.annotations.ScriptClass;
    78.9 +import jdk.nashorn.internal.objects.annotations.Where;
   78.10  import jdk.nashorn.internal.runtime.ScriptObject;
   78.11  import jdk.nashorn.internal.runtime.arrays.ArrayData;
   78.12  
   78.13 @@ -37,7 +39,12 @@
   78.14   */
   78.15  @ScriptClass("Uint16Array")
   78.16  public final class NativeUint16Array extends ArrayBufferView {
   78.17 -    private static final int BYTES_PER_ELEMENT = 2;
   78.18 +    /**
   78.19 +     * The size in bytes of each element in the array.
   78.20 +     */
   78.21 +    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
   78.22 +    public static final int BYTES_PER_ELEMENT = 2;
   78.23 +
   78.24      private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
   78.25          @Override
   78.26          public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    79.1 --- a/src/jdk/nashorn/internal/objects/NativeUint32Array.java	Thu May 30 10:58:35 2013 -0700
    79.2 +++ b/src/jdk/nashorn/internal/objects/NativeUint32Array.java	Mon Jun 03 23:24:36 2013 -0700
    79.3 @@ -28,7 +28,9 @@
    79.4  import jdk.nashorn.internal.objects.annotations.Attribute;
    79.5  import jdk.nashorn.internal.objects.annotations.Constructor;
    79.6  import jdk.nashorn.internal.objects.annotations.Function;
    79.7 +import jdk.nashorn.internal.objects.annotations.Property;
    79.8  import jdk.nashorn.internal.objects.annotations.ScriptClass;
    79.9 +import jdk.nashorn.internal.objects.annotations.Where;
   79.10  import jdk.nashorn.internal.runtime.JSType;
   79.11  import jdk.nashorn.internal.runtime.ScriptObject;
   79.12  import jdk.nashorn.internal.runtime.arrays.ArrayData;
   79.13 @@ -38,7 +40,12 @@
   79.14   */
   79.15  @ScriptClass("Uint32Array")
   79.16  public final class NativeUint32Array extends ArrayBufferView {
   79.17 -    private static final int BYTES_PER_ELEMENT = 4;
   79.18 +    /**
   79.19 +     * The size in bytes of each element in the array.
   79.20 +     */
   79.21 +    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
   79.22 +    public static final int BYTES_PER_ELEMENT = 4;
   79.23 +
   79.24      private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
   79.25          @Override
   79.26          public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteBegin, final int length) {
    80.1 --- a/src/jdk/nashorn/internal/objects/NativeUint8Array.java	Thu May 30 10:58:35 2013 -0700
    80.2 +++ b/src/jdk/nashorn/internal/objects/NativeUint8Array.java	Mon Jun 03 23:24:36 2013 -0700
    80.3 @@ -28,7 +28,9 @@
    80.4  import jdk.nashorn.internal.objects.annotations.Attribute;
    80.5  import jdk.nashorn.internal.objects.annotations.Constructor;
    80.6  import jdk.nashorn.internal.objects.annotations.Function;
    80.7 +import jdk.nashorn.internal.objects.annotations.Property;
    80.8  import jdk.nashorn.internal.objects.annotations.ScriptClass;
    80.9 +import jdk.nashorn.internal.objects.annotations.Where;
   80.10  import jdk.nashorn.internal.runtime.ScriptObject;
   80.11  import jdk.nashorn.internal.runtime.arrays.ArrayData;
   80.12  
   80.13 @@ -37,7 +39,12 @@
   80.14   */
   80.15  @ScriptClass("Uint8Array")
   80.16  public final class NativeUint8Array extends ArrayBufferView {
   80.17 -    private static final int BYTES_PER_ELEMENT = 1;
   80.18 +    /**
   80.19 +     * The size in bytes of each element in the array.
   80.20 +     */
   80.21 +    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
   80.22 +    public static final int BYTES_PER_ELEMENT = 1;
   80.23 +
   80.24      private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
   80.25          @Override
   80.26          public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    81.1 --- a/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Thu May 30 10:58:35 2013 -0700
    81.2 +++ b/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Mon Jun 03 23:24:36 2013 -0700
    81.3 @@ -28,7 +28,9 @@
    81.4  import jdk.nashorn.internal.objects.annotations.Attribute;
    81.5  import jdk.nashorn.internal.objects.annotations.Constructor;
    81.6  import jdk.nashorn.internal.objects.annotations.Function;
    81.7 +import jdk.nashorn.internal.objects.annotations.Property;
    81.8  import jdk.nashorn.internal.objects.annotations.ScriptClass;
    81.9 +import jdk.nashorn.internal.objects.annotations.Where;
   81.10  import jdk.nashorn.internal.runtime.JSType;
   81.11  import jdk.nashorn.internal.runtime.ScriptObject;
   81.12  import jdk.nashorn.internal.runtime.arrays.ArrayData;
   81.13 @@ -38,7 +40,12 @@
   81.14   */
   81.15  @ScriptClass("Uint8ClampedArray")
   81.16  public final class NativeUint8ClampedArray extends ArrayBufferView {
   81.17 -    private static final int BYTES_PER_ELEMENT = 1;
   81.18 +    /**
   81.19 +     * The size in bytes of each element in the array.
   81.20 +     */
   81.21 +    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
   81.22 +    public static final int BYTES_PER_ELEMENT = 1;
   81.23 +
   81.24      private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
   81.25          @Override
   81.26          public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    82.1 --- a/src/jdk/nashorn/internal/parser/Parser.java	Thu May 30 10:58:35 2013 -0700
    82.2 +++ b/src/jdk/nashorn/internal/parser/Parser.java	Mon Jun 03 23:24:36 2013 -0700
    82.3 @@ -1537,7 +1537,7 @@
    82.4  
    82.5          endOfLine();
    82.6  
    82.7 -        appendStatement(new ThrowNode(throwLine, throwToken, finish, expression));
    82.8 +        appendStatement(new ThrowNode(throwLine, throwToken, finish, expression, 0));
    82.9      }
   82.10  
   82.11      /**
   82.12 @@ -1597,7 +1597,7 @@
   82.13                  try {
   82.14                      // Get CATCH body.
   82.15                      final Block catchBody = getBlock(true);
   82.16 -                    final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody);
   82.17 +                    final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody, 0);
   82.18                      appendStatement(catchNode);
   82.19                  } finally {
   82.20                      catchBlock = restoreBlock(catchBlock);
    83.1 --- a/src/jdk/nashorn/internal/parser/TokenType.java	Thu May 30 10:58:35 2013 -0700
    83.2 +++ b/src/jdk/nashorn/internal/parser/TokenType.java	Mon Jun 03 23:24:36 2013 -0700
    83.3 @@ -25,6 +25,7 @@
    83.4  
    83.5  package jdk.nashorn.internal.parser;
    83.6  
    83.7 +import java.util.Locale;
    83.8  import static jdk.nashorn.internal.parser.TokenKind.BINARY;
    83.9  import static jdk.nashorn.internal.parser.TokenKind.BRACKET;
   83.10  import static jdk.nashorn.internal.parser.TokenKind.FUTURE;
   83.11 @@ -249,7 +250,7 @@
   83.12      }
   83.13  
   83.14      public String getNameOrType() {
   83.15 -        return name == null ? super.name().toLowerCase() : name;
   83.16 +        return name == null ? super.name().toLowerCase(Locale.ENGLISH) : name;
   83.17      }
   83.18  
   83.19      public TokenType getNext() {
    84.1 --- a/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Thu May 30 10:58:35 2013 -0700
    84.2 +++ b/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Mon Jun 03 23:24:36 2013 -0700
    84.3 @@ -75,7 +75,23 @@
    84.4  
    84.5      private static final MethodType[] ACCESSOR_GETTER_TYPES = new MethodType[NOOF_TYPES];
    84.6      private static final MethodType[] ACCESSOR_SETTER_TYPES = new MethodType[NOOF_TYPES];
    84.7 -    private static final MethodHandle SPILLGETTER = MH.asType(MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class), Lookup.GET_OBJECT_TYPE);
    84.8 +    private static final MethodHandle SPILL_ELEMENT_GETTER;
    84.9 +    private static final MethodHandle SPILL_ELEMENT_SETTER;
   84.10 +
   84.11 +    private static final int SPILL_CACHE_SIZE = 8;
   84.12 +    private static final MethodHandle[] SPILL_ACCESSORS = new MethodHandle[SPILL_CACHE_SIZE * 2];
   84.13 +
   84.14 +    static {
   84.15 +        for (int i = 0; i < NOOF_TYPES; i++) {
   84.16 +            final Type type = ACCESSOR_TYPES.get(i);
   84.17 +            ACCESSOR_GETTER_TYPES[i] = MH.type(type.getTypeClass(), Object.class);
   84.18 +            ACCESSOR_SETTER_TYPES[i] = MH.type(void.class, Object.class, type.getTypeClass());
   84.19 +        }
   84.20 +
   84.21 +        final MethodHandle spillGetter = MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class);
   84.22 +        SPILL_ELEMENT_GETTER = MH.filterArguments(MH.arrayElementGetter(Object[].class), 0, spillGetter);
   84.23 +        SPILL_ELEMENT_SETTER = MH.filterArguments(MH.arrayElementSetter(Object[].class), 0, spillGetter);
   84.24 +    }
   84.25  
   84.26      /** Seed getter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
   84.27      private MethodHandle primitiveGetter;
   84.28 @@ -96,14 +112,6 @@
   84.29       */
   84.30      private Class<?> currentType;
   84.31  
   84.32 -    static {
   84.33 -        for (int i = 0; i < NOOF_TYPES; i++) {
   84.34 -            final Type type = ACCESSOR_TYPES.get(i);
   84.35 -            ACCESSOR_GETTER_TYPES[i] = MH.type(type.getTypeClass(), Object.class);
   84.36 -            ACCESSOR_SETTER_TYPES[i] = MH.type(void.class, Object.class, type.getTypeClass());
   84.37 -        }
   84.38 -    }
   84.39 -
   84.40      /**
   84.41       * Delegate constructor. This is used when adding properties to the Global scope, which
   84.42       * is necessary for outermost levels in a script (the ScriptObject is represented by
   84.43 @@ -114,19 +122,31 @@
   84.44       * @param delegate  delegate script object to rebind receiver to
   84.45       */
   84.46      public AccessorProperty(final AccessorProperty property, final ScriptObject delegate) {
   84.47 -        this(property);
   84.48 +        super(property);
   84.49  
   84.50 -        this.getters = new MethodHandle[NOOF_TYPES];
   84.51 -
   84.52 -        this.primitiveGetter = bindTo(primitiveGetter, delegate);
   84.53 -        this.primitiveSetter = bindTo(primitiveSetter, delegate);
   84.54 -        this.objectGetter    = bindTo(objectGetter, delegate);
   84.55 -        this.objectSetter    = bindTo(objectSetter, delegate);
   84.56 +        this.primitiveGetter = bindTo(property.primitiveGetter, delegate);
   84.57 +        this.primitiveSetter = bindTo(property.primitiveSetter, delegate);
   84.58 +        this.objectGetter    = bindTo(property.objectGetter, delegate);
   84.59 +        this.objectSetter    = bindTo(property.objectSetter, delegate);
   84.60  
   84.61          setCurrentType(property.getCurrentType());
   84.62      }
   84.63  
   84.64      /**
   84.65 +     * Constructor for spill properties. Array getters and setters will be created on demand.
   84.66 +     *
   84.67 +     * @param key    the property key
   84.68 +     * @param flags  the property flags
   84.69 +     * @param slot   spill slot
   84.70 +     */
   84.71 +    public AccessorProperty(final String key, final int flags, final int slot) {
   84.72 +        super(key, flags, slot);
   84.73 +        assert (flags & IS_SPILL) == IS_SPILL;
   84.74 +
   84.75 +        setCurrentType(Object.class);
   84.76 +    }
   84.77 +
   84.78 +    /**
   84.79       * Constructor. Similar to the constructor with both primitive getters and setters, the difference
   84.80       * here being that only one getter and setter (setter is optional for non writable fields) is given
   84.81       * to the constructor, and the rest are created from those. Used e.g. by Nasgen classes
   84.82 @@ -268,7 +288,40 @@
   84.83      }
   84.84  
   84.85      @Override
   84.86 +    protected void setObjectValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict)  {
   84.87 +        if (isSpill()) {
   84.88 +            self.spill[getSlot()] = value;
   84.89 +        } else {
   84.90 +            try {
   84.91 +                getSetter(Object.class, self.getMap()).invokeExact((Object)self, value);
   84.92 +            } catch (final Error|RuntimeException e) {
   84.93 +                throw e;
   84.94 +            } catch (final Throwable e) {
   84.95 +                throw new RuntimeException(e);
   84.96 +            }
   84.97 +        }
   84.98 +    }
   84.99 +
  84.100 +    @Override
  84.101 +    protected Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
  84.102 +        if (isSpill()) {
  84.103 +            return self.spill[getSlot()];
  84.104 +        }
  84.105 +
  84.106 +        try {
  84.107 +            return getGetter(Object.class).invokeExact((Object)self);
  84.108 +        } catch (final Error|RuntimeException e) {
  84.109 +            throw e;
  84.110 +        } catch (final Throwable e) {
  84.111 +            throw new RuntimeException(e);
  84.112 +        }
  84.113 +    }
  84.114 +
  84.115 +    @Override
  84.116      public MethodHandle getGetter(final Class<?> type) {
  84.117 +        if (isSpill() && objectGetter == null) {
  84.118 +            objectGetter = getSpillGetter();
  84.119 +        }
  84.120          final int i = getAccessorTypeIndex(type);
  84.121          if (getters[i] == null) {
  84.122              getters[i] = debug(
  84.123 @@ -284,7 +337,7 @@
  84.124                  "get");
  84.125          }
  84.126  
  84.127 -        return isSpill() ? MH.filterArguments(getters[i], 0, SPILLGETTER) : getters[i];
  84.128 +        return getters[i];
  84.129      }
  84.130  
  84.131      private Property getWiderProperty(final Class<?> type) {
  84.132 @@ -313,6 +366,9 @@
  84.133      }
  84.134  
  84.135      private MethodHandle generateSetter(final Class<?> forType, final Class<?> type) {
  84.136 +        if (isSpill() && objectSetter == null) {
  84.137 +            objectSetter = getSpillSetter();
  84.138 +        }
  84.139          MethodHandle mh = createSetter(forType, type, primitiveSetter, objectSetter);
  84.140          mh = MH.asType(mh, ACCESSOR_SETTER_TYPES[getAccessorTypeIndex(type)]); //has to be the case for invokeexact to work in ScriptObject
  84.141          mh = debug(mh, currentType, type, "set");
  84.142 @@ -343,7 +399,7 @@
  84.143              mh = generateSetter(forType, type);
  84.144          }
  84.145  
  84.146 -        return isSpill() ? MH.filterArguments(mh, 0, SPILLGETTER) : mh;
  84.147 +        return mh;
  84.148      }
  84.149  
  84.150      @Override
  84.151 @@ -363,6 +419,30 @@
  84.152          setCurrentType(newType);
  84.153      }
  84.154  
  84.155 +    private MethodHandle getSpillGetter() {
  84.156 +        final int slot = getSlot();
  84.157 +        MethodHandle getter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2] : null;
  84.158 +        if (getter == null) {
  84.159 +            getter = MH.asType(MH.insertArguments(SPILL_ELEMENT_GETTER, 1, slot), Lookup.GET_OBJECT_TYPE);
  84.160 +            if (slot < SPILL_CACHE_SIZE) {
  84.161 +                SPILL_ACCESSORS[slot * 2] = getter;
  84.162 +            }
  84.163 +        }
  84.164 +        return getter;
  84.165 +    }
  84.166 +
  84.167 +    private MethodHandle getSpillSetter() {
  84.168 +        final int slot = getSlot();
  84.169 +        MethodHandle setter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2 + 1] : null;
  84.170 +        if (setter == null) {
  84.171 +            setter = MH.asType(MH.insertArguments(SPILL_ELEMENT_SETTER, 1, slot), Lookup.SET_OBJECT_TYPE);
  84.172 +            if (slot < SPILL_CACHE_SIZE) {
  84.173 +                SPILL_ACCESSORS[slot * 2 + 1] = setter;
  84.174 +            }
  84.175 +        }
  84.176 +        return setter;
  84.177 +    }
  84.178 +
  84.179      private static void finest(final String str) {
  84.180          if (DEBUG_FIELDS) {
  84.181              LOG.finest(str);
    85.1 --- a/src/jdk/nashorn/internal/runtime/CompiledFunction.java	Thu May 30 10:58:35 2013 -0700
    85.2 +++ b/src/jdk/nashorn/internal/runtime/CompiledFunction.java	Mon Jun 03 23:24:36 2013 -0700
    85.3 @@ -35,21 +35,27 @@
    85.4   */
    85.5  final class CompiledFunction implements Comparable<CompiledFunction> {
    85.6  
    85.7 +    /** The method type may be more specific than the invoker, if. e.g.
    85.8 +     *  the invoker is guarded, and a guard with a generic object only
    85.9 +     *  fallback, while the target is more specific, we still need the
   85.10 +     *  more specific type for sorting */
   85.11 +    private final MethodType   type;
   85.12      private final MethodHandle invoker;
   85.13      private MethodHandle constructor;
   85.14  
   85.15 -    CompiledFunction(final MethodHandle invoker) {
   85.16 -        this(invoker, null);
   85.17 +    CompiledFunction(final MethodType type, final MethodHandle invoker) {
   85.18 +        this(type, invoker, null);
   85.19      }
   85.20  
   85.21 -    CompiledFunction(final MethodHandle invoker, final MethodHandle constructor) {
   85.22 -        this.invoker = invoker;
   85.23 -        this.constructor = constructor; //isConstructor
   85.24 +    CompiledFunction(final MethodType type, final MethodHandle invoker, final MethodHandle constructor) {
   85.25 +        this.type        = type;
   85.26 +        this.invoker     = invoker;
   85.27 +        this.constructor = constructor;
   85.28      }
   85.29  
   85.30      @Override
   85.31      public String toString() {
   85.32 -        return "<invoker=" + invoker + " ctor=" + constructor + ">";
   85.33 +        return "<callSiteType= " + type + " invoker=" + invoker + " ctor=" + constructor + ">";
   85.34      }
   85.35  
   85.36      MethodHandle getInvoker() {
   85.37 @@ -69,7 +75,7 @@
   85.38      }
   85.39  
   85.40      MethodType type() {
   85.41 -        return invoker.type();
   85.42 +        return type;
   85.43      }
   85.44  
   85.45      @Override
   85.46 @@ -103,8 +109,8 @@
   85.47          return weight() > o.weight();
   85.48      }
   85.49  
   85.50 -    boolean moreGenericThan(final MethodType type) {
   85.51 -        return weight() > weight(type);
   85.52 +    boolean moreGenericThan(final MethodType mt) {
   85.53 +        return weight() > weight(mt);
   85.54      }
   85.55  
   85.56      /**
   85.57 @@ -112,15 +118,15 @@
   85.58       * It is compatible if the types are narrower than the invocation type so that
   85.59       * a semantically equivalent linkage can be performed.
   85.60       *
   85.61 -     * @param typesc
   85.62 +     * @param mt type to check against
   85.63       * @return
   85.64       */
   85.65 -    boolean typeCompatible(final MethodType type) {
   85.66 -        final Class<?>[] wantedParams   = type.parameterArray();
   85.67 +    boolean typeCompatible(final MethodType mt) {
   85.68 +        final Class<?>[] wantedParams   = mt.parameterArray();
   85.69          final Class<?>[] existingParams = type().parameterArray();
   85.70  
   85.71          //if we are not examining a varargs type, the number of parameters must be the same
   85.72 -        if (wantedParams.length != existingParams.length && !isVarArgsType(type)) {
   85.73 +        if (wantedParams.length != existingParams.length && !isVarArgsType(mt)) {
   85.74              return false;
   85.75          }
   85.76  
    86.1 --- a/src/jdk/nashorn/internal/runtime/DebugLogger.java	Thu May 30 10:58:35 2013 -0700
    86.2 +++ b/src/jdk/nashorn/internal/runtime/DebugLogger.java	Mon Jun 03 23:24:36 2013 -0700
    86.3 @@ -35,7 +35,6 @@
    86.4   */
    86.5  
    86.6  public final class DebugLogger {
    86.7 -    @SuppressWarnings("NonConstantLogger")
    86.8      private final Logger  logger;
    86.9      private final boolean isEnabled;
   86.10  
    87.1 --- a/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Thu May 30 10:58:35 2013 -0700
    87.2 +++ b/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Mon Jun 03 23:24:36 2013 -0700
    87.3 @@ -78,9 +78,9 @@
    87.4              //only nasgen constructors: (boolean, self, args) are subject to binding a boolean newObj. isConstructor
    87.5              //is too conservative a check. However, isConstructor(mh) always implies isConstructor param
    87.6              assert isConstructor();
    87.7 -            code.add(new CompiledFunction(MH.insertArguments(mh, 0, false), composeConstructor(MH.insertArguments(mh, 0, true), needsCallee))); //make sure callee state can be determined when we reach constructor
    87.8 +            code.add(new CompiledFunction(mh.type(), MH.insertArguments(mh, 0, false), composeConstructor(MH.insertArguments(mh, 0, true), needsCallee))); //make sure callee state can be determined when we reach constructor
    87.9          } else {
   87.10 -            code.add(new CompiledFunction(mh));
   87.11 +            code.add(new CompiledFunction(mh.type(), mh));
   87.12          }
   87.13      }
   87.14  
    88.1 --- a/src/jdk/nashorn/internal/runtime/FindProperty.java	Thu May 30 10:58:35 2013 -0700
    88.2 +++ b/src/jdk/nashorn/internal/runtime/FindProperty.java	Mon Jun 03 23:24:36 2013 -0700
    88.3 @@ -153,5 +153,24 @@
    88.4          return prototype.isScope();
    88.5      }
    88.6  
    88.7 +    /**
    88.8 +     * Get the property value from self as object.
    88.9 +     *
   88.10 +     * @return the property value
   88.11 +     */
   88.12 +    public Object getObjectValue() {
   88.13 +        return property.getObjectValue(getGetterReceiver(), getOwner());
   88.14 +    }
   88.15 +
   88.16 +    /**
   88.17 +     * Set the property value in self.
   88.18 +     *
   88.19 +     * @param value the new value
   88.20 +     * @param strict strict flag
   88.21 +     */
   88.22 +    public void setObjectValue(final Object value, final boolean strict) {
   88.23 +        property.setObjectValue(getSetterReceiver(), getOwner(), value, strict);
   88.24 +    }
   88.25 +
   88.26  }
   88.27  
    89.1 --- a/src/jdk/nashorn/internal/runtime/GlobalFunctions.java	Thu May 30 10:58:35 2013 -0700
    89.2 +++ b/src/jdk/nashorn/internal/runtime/GlobalFunctions.java	Mon Jun 03 23:24:36 2013 -0700
    89.3 @@ -30,6 +30,7 @@
    89.4  
    89.5  import java.lang.invoke.MethodHandle;
    89.6  import java.lang.invoke.MethodHandles;
    89.7 +import java.util.Locale;
    89.8  
    89.9  /**
   89.10   * Utilities used by Global class.
   89.11 @@ -373,10 +374,10 @@
   89.12              } else if (ch < 256) {
   89.13                  sb.append('%');
   89.14                  final byte b = (byte)ch;
   89.15 -                sb.append(Integer.toHexString(b & 0xFF).toUpperCase());
   89.16 +                sb.append(Integer.toHexString(b & 0xFF).toUpperCase(Locale.ENGLISH));
   89.17              } else {
   89.18                  sb.append("%u");
   89.19 -                sb.append(Integer.toHexString(ch & 0xFFFF).toUpperCase());
   89.20 +                sb.append(Integer.toHexString(ch & 0xFFFF).toUpperCase(Locale.ENGLISH));
   89.21              }
   89.22          }
   89.23  
    90.1 --- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Thu May 30 10:58:35 2013 -0700
    90.2 +++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Mon Jun 03 23:24:36 2013 -0700
    90.3 @@ -36,6 +36,8 @@
    90.4  import jdk.nashorn.internal.parser.JSONParser;
    90.5  import jdk.nashorn.internal.parser.TokenType;
    90.6  import jdk.nashorn.internal.runtime.linker.Bootstrap;
    90.7 +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow;
    90.8 +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
    90.9  
   90.10  /**
   90.11   * Utilities used by "JSON" object implementation.
   90.12 @@ -94,7 +96,7 @@
   90.13          if (reviver instanceof ScriptFunction) {
   90.14              assert global instanceof GlobalObject;
   90.15              final ScriptObject root = ((GlobalObject)global).newObject();
   90.16 -            root.set("", unfiltered, root.isStrictContext());
   90.17 +            root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
   90.18              return walk(root, "", (ScriptFunction)reviver);
   90.19          }
   90.20          return unfiltered;
   90.21 @@ -115,7 +117,7 @@
   90.22                  if (newElement == ScriptRuntime.UNDEFINED) {
   90.23                      valueObj.delete(key, strict);
   90.24                  } else {
   90.25 -                    valueObj.set(key, newElement, strict);
   90.26 +                    setPropertyValue(valueObj, key, newElement, strict);
   90.27                  }
   90.28              }
   90.29          }
   90.30 @@ -175,7 +177,9 @@
   90.31                  final PropertyNode pNode     = (PropertyNode) elem;
   90.32                  final Node         valueNode = pNode.getValue();
   90.33  
   90.34 -                object.set(pNode.getKeyName(), convertNode(global, valueNode), strict);
   90.35 +                final String name = pNode.getKeyName();
   90.36 +                final Object value = convertNode(global, valueNode);
   90.37 +                setPropertyValue(object, name, value, strict);
   90.38              }
   90.39  
   90.40              return object;
   90.41 @@ -188,6 +192,21 @@
   90.42          }
   90.43      }
   90.44  
   90.45 +    // add a new property if does not exist already, or else set old property
   90.46 +    private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value, final boolean strict) {
   90.47 +        final int index = getArrayIndexNoThrow(name);
   90.48 +        if (isValidArrayIndex(index)) {
   90.49 +            // array index key
   90.50 +            sobj.defineOwnProperty(index, value);
   90.51 +        } else if (sobj.getMap().findProperty(name) != null) {
   90.52 +            // pre-existing non-inherited property, call set
   90.53 +            sobj.set(name, value, strict);
   90.54 +        } else {
   90.55 +            // add new property
   90.56 +            sobj.addOwnProperty(name, Property.WRITABLE_ENUMERABLE_CONFIGURABLE, value);
   90.57 +        }
   90.58 +    }
   90.59 +
   90.60      // does the given IR node represent a numeric array?
   90.61      private static boolean isNumericArray(final Node[] values) {
   90.62          for (final Node node : values) {
    91.1 --- a/src/jdk/nashorn/internal/runtime/JSType.java	Thu May 30 10:58:35 2013 -0700
    91.2 +++ b/src/jdk/nashorn/internal/runtime/JSType.java	Mon Jun 03 23:24:36 2013 -0700
    91.3 @@ -28,6 +28,7 @@
    91.4  import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
    91.5  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    91.6  
    91.7 +import java.util.Locale;
    91.8  import jdk.internal.dynalink.beans.StaticClass;
    91.9  import jdk.nashorn.internal.codegen.CompilerConstants.Call;
   91.10  import jdk.nashorn.internal.parser.Lexer;
   91.11 @@ -111,7 +112,7 @@
   91.12       */
   91.13      public final String typeName() {
   91.14          // For NULL, "object" has to be returned!
   91.15 -        return ((this == NULL) ? OBJECT : this).name().toLowerCase();
   91.16 +        return ((this == NULL) ? OBJECT : this).name().toLowerCase(Locale.ENGLISH);
   91.17      }
   91.18  
   91.19      /**
   91.20 @@ -565,8 +566,11 @@
   91.21      }
   91.22  
   91.23      /**
   91.24 -     * JavaScript compliant Object to integer conversion
   91.25 -     * See ECMA 9.4 ToInteger
   91.26 +     * JavaScript compliant Object to integer conversion. See ECMA 9.4 ToInteger
   91.27 +     *
   91.28 +     * <p>Note that this returns {@link java.lang.Integer#MAX_VALUE} or {@link java.lang.Integer#MIN_VALUE}
   91.29 +     * for double values that exceed the int range, including positive and negative Infinity. It is the
   91.30 +     * caller's responsibility to handle such values correctly.</p>
   91.31       *
   91.32       * @param obj  an object
   91.33       * @return an integer
   91.34 @@ -576,8 +580,11 @@
   91.35      }
   91.36  
   91.37      /**
   91.38 -     * JavaScript compliant Object to long conversion
   91.39 -     * See ECMA 9.4 ToInteger
   91.40 +     * JavaScript compliant Object to long conversion. See ECMA 9.4 ToInteger
   91.41 +     *
   91.42 +     * <p>Note that this returns {@link java.lang.Long#MAX_VALUE} or {@link java.lang.Long#MIN_VALUE}
   91.43 +     * for double values that exceed the long range, including positive and negative Infinity. It is the
   91.44 +     * caller's responsibility to handle such values correctly.</p>
   91.45       *
   91.46       * @param obj  an object
   91.47       * @return a long
    92.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.2 +++ b/src/jdk/nashorn/internal/runtime/ListAdapter.java	Mon Jun 03 23:24:36 2013 -0700
    92.3 @@ -0,0 +1,337 @@
    92.4 +package jdk.nashorn.internal.runtime;
    92.5 +
    92.6 +import java.util.AbstractList;
    92.7 +import java.util.Deque;
    92.8 +import java.util.Iterator;
    92.9 +import java.util.ListIterator;
   92.10 +import java.util.NoSuchElementException;
   92.11 +import java.util.RandomAccess;
   92.12 +import jdk.nashorn.internal.runtime.linker.InvokeByName;
   92.13 +
   92.14 +/**
   92.15 + * An adapter that can wrap any ECMAScript Array-like object (that adheres to the array rules for the property
   92.16 + * {@code length} and having conforming {@code push}, {@code pop}, {@code shift}, {@code unshift}, and {@code splice}
   92.17 + * methods) and expose it as both a Java list and double-ended queue. While script arrays aren't necessarily efficient
   92.18 + * as dequeues, it's still slightly more efficient to be able to translate dequeue operations into pushes, pops, shifts,
   92.19 + * and unshifts, than to blindly translate all list's add/remove operations into splices. Also, it is conceivable that a
   92.20 + * custom script object that implements an Array-like API can have a background data representation that is optimized
   92.21 + * for dequeue-like access. Note that with ECMAScript arrays, {@code push} and {@pop} operate at the end of the array,
   92.22 + * while in Java {@code Deque} they operate on the front of the queue and as such the Java dequeue {@link #push(Object)}
   92.23 + * and {@link #pop()} operations will translate to {@code unshift} and {@code shift} script operations respectively,
   92.24 + * while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and {@code pop}.
   92.25 + */
   92.26 +public class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> {
   92.27 +    // These add to the back and front of the list
   92.28 +    private static final InvokeByName PUSH    = new InvokeByName("push",    ScriptObject.class, void.class, Object.class);
   92.29 +    private static final InvokeByName UNSHIFT = new InvokeByName("unshift", ScriptObject.class, void.class, Object.class);
   92.30 +
   92.31 +    // These remove from the back and front of the list
   92.32 +    private static final InvokeByName POP   = new InvokeByName("pop",   ScriptObject.class, Object.class);
   92.33 +    private static final InvokeByName SHIFT = new InvokeByName("shift", ScriptObject.class, Object.class);
   92.34 +
   92.35 +    // These insert and remove in the middle of the list
   92.36 +    private static final InvokeByName SPLICE_ADD    = new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class, Object.class);
   92.37 +    private static final InvokeByName SPLICE_REMOVE = new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class);
   92.38 +
   92.39 +    private final ScriptObject obj;
   92.40 +
   92.41 +    /**
   92.42 +     * Creates a new list wrapper for the specified script object.
   92.43 +     * @param obj script the object to wrap
   92.44 +     */
   92.45 +    public ListAdapter(ScriptObject obj) {
   92.46 +        this.obj = obj;
   92.47 +    }
   92.48 +
   92.49 +    @Override
   92.50 +    public int size() {
   92.51 +        return JSType.toInt32(obj.getLength());
   92.52 +    }
   92.53 +
   92.54 +    @Override
   92.55 +    public Object get(int index) {
   92.56 +        checkRange(index);
   92.57 +        return obj.get(index);
   92.58 +    }
   92.59 +
   92.60 +    @Override
   92.61 +    public Object set(int index, Object element) {
   92.62 +        checkRange(index);
   92.63 +        final Object prevValue = get(index);
   92.64 +        obj.set(index, element, false);
   92.65 +        return prevValue;
   92.66 +    }
   92.67 +
   92.68 +    private void checkRange(int index) {
   92.69 +        if(index < 0 || index >= size()) {
   92.70 +            throw invalidIndex(index);
   92.71 +        }
   92.72 +    }
   92.73 +
   92.74 +    @Override
   92.75 +    public void push(Object e) {
   92.76 +        addFirst(e);
   92.77 +    }
   92.78 +
   92.79 +    @Override
   92.80 +    public boolean add(Object e) {
   92.81 +        addLast(e);
   92.82 +        return true;
   92.83 +    }
   92.84 +
   92.85 +    @Override
   92.86 +    public void addFirst(Object e) {
   92.87 +        try {
   92.88 +            final Object fn = UNSHIFT.getGetter().invokeExact(obj);
   92.89 +            checkFunction(fn, UNSHIFT);
   92.90 +            UNSHIFT.getInvoker().invokeExact(fn, obj, e);
   92.91 +        } catch(RuntimeException | Error ex) {
   92.92 +            throw ex;
   92.93 +        } catch(Throwable t) {
   92.94 +            throw new RuntimeException(t);
   92.95 +        }
   92.96 +    }
   92.97 +
   92.98 +    @Override
   92.99 +    public void addLast(Object e) {
  92.100 +        try {
  92.101 +            final Object fn = PUSH.getGetter().invokeExact(obj);
  92.102 +            checkFunction(fn, PUSH);
  92.103 +            PUSH.getInvoker().invokeExact(fn, obj, e);
  92.104 +        } catch(RuntimeException | Error ex) {
  92.105 +            throw ex;
  92.106 +        } catch(Throwable t) {
  92.107 +            throw new RuntimeException(t);
  92.108 +        }
  92.109 +    }
  92.110 +
  92.111 +    @Override
  92.112 +    public void add(int index, Object e) {
  92.113 +        try {
  92.114 +            if(index < 0) {
  92.115 +                throw invalidIndex(index);
  92.116 +            } else if(index == 0) {
  92.117 +                addFirst(e);
  92.118 +            } else {
  92.119 +                final int size = size();
  92.120 +                if(index < size) {
  92.121 +                    final Object fn = SPLICE_ADD.getGetter().invokeExact(obj);
  92.122 +                    checkFunction(fn, SPLICE_ADD);
  92.123 +                    SPLICE_ADD.getInvoker().invokeExact(fn, obj, index, 0, e);
  92.124 +                } else if(index == size) {
  92.125 +                    addLast(e);
  92.126 +                } else {
  92.127 +                    throw invalidIndex(index);
  92.128 +                }
  92.129 +            }
  92.130 +        } catch(RuntimeException | Error ex) {
  92.131 +            throw ex;
  92.132 +        } catch(Throwable t) {
  92.133 +            throw new RuntimeException(t);
  92.134 +        }
  92.135 +    }
  92.136 +    private static void checkFunction(Object fn, InvokeByName invoke) {
  92.137 +        if(!(fn instanceof ScriptFunction)) {
  92.138 +            throw new UnsupportedOperationException("The script object doesn't have a function named " + invoke.getName());
  92.139 +        }
  92.140 +    }
  92.141 +
  92.142 +    private static IndexOutOfBoundsException invalidIndex(int index) {
  92.143 +        return new IndexOutOfBoundsException(String.valueOf(index));
  92.144 +    }
  92.145 +
  92.146 +    @Override
  92.147 +    public boolean offer(Object e) {
  92.148 +        return offerLast(e);
  92.149 +    }
  92.150 +
  92.151 +    @Override
  92.152 +    public boolean offerFirst(Object e) {
  92.153 +        addFirst(e);
  92.154 +        return true;
  92.155 +    }
  92.156 +
  92.157 +    @Override
  92.158 +    public boolean offerLast(Object e) {
  92.159 +        addLast(e);
  92.160 +        return true;
  92.161 +    }
  92.162 +
  92.163 +    @Override
  92.164 +    public Object pop() {
  92.165 +        return removeFirst();
  92.166 +    }
  92.167 +
  92.168 +    @Override
  92.169 +    public Object remove() {
  92.170 +        return removeFirst();
  92.171 +    }
  92.172 +
  92.173 +    @Override
  92.174 +    public Object removeFirst() {
  92.175 +        checkNonEmpty();
  92.176 +        return invokeShift();
  92.177 +    }
  92.178 +
  92.179 +    @Override
  92.180 +    public Object removeLast() {
  92.181 +        checkNonEmpty();
  92.182 +        return invokePop();
  92.183 +    }
  92.184 +
  92.185 +    private void checkNonEmpty() {
  92.186 +        if(isEmpty()) {
  92.187 +            throw new NoSuchElementException();
  92.188 +        }
  92.189 +    }
  92.190 +
  92.191 +    @Override
  92.192 +    public Object remove(int index) {
  92.193 +        if(index < 0) {
  92.194 +            throw invalidIndex(index);
  92.195 +        } else if (index == 0) {
  92.196 +            return invokeShift();
  92.197 +        } else {
  92.198 +            final int maxIndex = size() - 1;
  92.199 +            if(index < maxIndex) {
  92.200 +                final Object prevValue = get(index);
  92.201 +                invokeSpliceRemove(index, 1);
  92.202 +                return prevValue;
  92.203 +            } else if(index == maxIndex) {
  92.204 +                return invokePop();
  92.205 +            } else {
  92.206 +                throw invalidIndex(index);
  92.207 +            }
  92.208 +        }
  92.209 +    }
  92.210 +
  92.211 +    private Object invokeShift() {
  92.212 +        try {
  92.213 +            final Object fn = SHIFT.getGetter().invokeExact(obj);
  92.214 +            checkFunction(fn, SHIFT);
  92.215 +            return SHIFT.getInvoker().invokeExact(fn, obj);
  92.216 +        } catch(RuntimeException | Error ex) {
  92.217 +            throw ex;
  92.218 +        } catch(Throwable t) {
  92.219 +            throw new RuntimeException(t);
  92.220 +        }
  92.221 +    }
  92.222 +
  92.223 +    private Object invokePop() {
  92.224 +        try {
  92.225 +            final Object fn = POP.getGetter().invokeExact(obj);
  92.226 +            checkFunction(fn, POP);
  92.227 +            return POP.getInvoker().invokeExact(fn, obj);
  92.228 +        } catch(RuntimeException | Error ex) {
  92.229 +            throw ex;
  92.230 +        } catch(Throwable t) {
  92.231 +            throw new RuntimeException(t);
  92.232 +        }
  92.233 +    }
  92.234 +
  92.235 +    @Override
  92.236 +    protected void removeRange(int fromIndex, int toIndex) {
  92.237 +        invokeSpliceRemove(fromIndex, toIndex - fromIndex);
  92.238 +    }
  92.239 +
  92.240 +    private void invokeSpliceRemove(int fromIndex, int count) {
  92.241 +        try {
  92.242 +            final Object fn = SPLICE_REMOVE.getGetter().invokeExact(obj);
  92.243 +            checkFunction(fn, SPLICE_REMOVE);
  92.244 +            SPLICE_REMOVE.getInvoker().invokeExact(fn, obj, fromIndex, count);
  92.245 +        } catch(RuntimeException | Error ex) {
  92.246 +            throw ex;
  92.247 +        } catch(Throwable t) {
  92.248 +            throw new RuntimeException(t);
  92.249 +        }
  92.250 +    }
  92.251 +
  92.252 +    @Override
  92.253 +    public Object poll() {
  92.254 +        return pollFirst();
  92.255 +    }
  92.256 +
  92.257 +    @Override
  92.258 +    public Object pollFirst() {
  92.259 +        return isEmpty() ? null : invokeShift();
  92.260 +    }
  92.261 +
  92.262 +    @Override
  92.263 +    public Object pollLast() {
  92.264 +        return isEmpty() ? null : invokePop();
  92.265 +    }
  92.266 +
  92.267 +    @Override
  92.268 +    public Object peek() {
  92.269 +        return peekFirst();
  92.270 +    }
  92.271 +
  92.272 +    @Override
  92.273 +    public Object peekFirst() {
  92.274 +        return isEmpty() ? null : get(0);
  92.275 +    }
  92.276 +
  92.277 +    @Override
  92.278 +    public Object peekLast() {
  92.279 +        return isEmpty() ? null : get(size() - 1);
  92.280 +    }
  92.281 +
  92.282 +    @Override
  92.283 +    public Object element() {
  92.284 +        return getFirst();
  92.285 +    }
  92.286 +
  92.287 +    @Override
  92.288 +    public Object getFirst() {
  92.289 +        checkNonEmpty();
  92.290 +        return get(0);
  92.291 +    }
  92.292 +
  92.293 +    @Override
  92.294 +    public Object getLast() {
  92.295 +        checkNonEmpty();
  92.296 +        return get(size() - 1);
  92.297 +    }
  92.298 +
  92.299 +    @Override
  92.300 +    public Iterator<Object> descendingIterator() {
  92.301 +        final ListIterator<Object> it = listIterator(size());
  92.302 +        return new Iterator<Object>() {
  92.303 +            @Override
  92.304 +            public boolean hasNext() {
  92.305 +                return it.hasPrevious();
  92.306 +            }
  92.307 +
  92.308 +            @Override
  92.309 +            public Object next() {
  92.310 +                return it.previous();
  92.311 +            }
  92.312 +
  92.313 +            @Override
  92.314 +            public void remove() {
  92.315 +                it.remove();
  92.316 +            }
  92.317 +        };
  92.318 +    }
  92.319 +
  92.320 +    @Override
  92.321 +    public boolean removeFirstOccurrence(Object o) {
  92.322 +        return removeOccurrence(o, iterator());
  92.323 +    }
  92.324 +
  92.325 +    @Override
  92.326 +    public boolean removeLastOccurrence(Object o) {
  92.327 +        return removeOccurrence(o, descendingIterator());
  92.328 +    }
  92.329 +
  92.330 +    private static boolean removeOccurrence(Object o, Iterator<Object> it) {
  92.331 +        while(it.hasNext()) {
  92.332 +            final Object e = it.next();
  92.333 +            if(o == null ? e == null : o.equals(e)) {
  92.334 +                it.remove();
  92.335 +                return true;
  92.336 +            }
  92.337 +        }
  92.338 +        return false;
  92.339 +    }
  92.340 +}
    93.1 --- a/src/jdk/nashorn/internal/runtime/Logging.java	Thu May 30 10:58:35 2013 -0700
    93.2 +++ b/src/jdk/nashorn/internal/runtime/Logging.java	Mon Jun 03 23:24:36 2013 -0700
    93.3 @@ -26,6 +26,7 @@
    93.4  package jdk.nashorn.internal.runtime;
    93.5  
    93.6  import java.util.HashMap;
    93.7 +import java.util.Locale;
    93.8  import java.util.Map;
    93.9  import java.util.Map.Entry;
   93.10  import java.util.logging.ConsoleHandler;
   93.11 @@ -117,7 +118,7 @@
   93.12                  if ("".equals(value)) {
   93.13                      level = Level.INFO;
   93.14                  } else {
   93.15 -                    level = Level.parse(value.toUpperCase());
   93.16 +                    level = Level.parse(value.toUpperCase(Locale.ENGLISH));
   93.17                  }
   93.18  
   93.19                  final String name = Logging.lastPart(key);
    94.1 --- a/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java	Thu May 30 10:58:35 2013 -0700
    94.2 +++ b/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java	Mon Jun 03 23:24:36 2013 -0700
    94.3 @@ -25,10 +25,16 @@
    94.4  
    94.5  package jdk.nashorn.internal.runtime;
    94.6  
    94.7 +import java.lang.invoke.MethodHandle;
    94.8 +import java.lang.invoke.MethodHandles;
    94.9 +import java.lang.invoke.MethodType;
   94.10  import jdk.internal.dynalink.CallSiteDescriptor;
   94.11  import jdk.internal.dynalink.beans.StaticClass;
   94.12  import jdk.internal.dynalink.linker.GuardedInvocation;
   94.13  import jdk.internal.dynalink.linker.LinkRequest;
   94.14 +import jdk.internal.dynalink.support.Guards;
   94.15 +import jdk.nashorn.internal.lookup.MethodHandleFactory;
   94.16 +import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
   94.17  import jdk.nashorn.internal.objects.NativeJava;
   94.18  import jdk.nashorn.internal.objects.annotations.Attribute;
   94.19  import jdk.nashorn.internal.objects.annotations.Function;
   94.20 @@ -65,6 +71,10 @@
   94.21   * </pre>
   94.22   */
   94.23  public final class NativeJavaPackage extends ScriptObject {
   94.24 +    private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
   94.25 +    private static final MethodHandle CLASS_NOT_FOUND = findOwnMH("classNotFound", Void.TYPE, NativeJavaPackage.class);
   94.26 +    private static final MethodHandle TYPE_GUARD = Guards.getClassGuard(NativeJavaPackage.class);
   94.27 +
   94.28      /** Full name of package (includes path.) */
   94.29      private final String name;
   94.30  
   94.31 @@ -123,6 +133,30 @@
   94.32          return super.getDefaultValue(hint);
   94.33      }
   94.34  
   94.35 +    @Override
   94.36 +    protected GuardedInvocation findNewMethod(CallSiteDescriptor desc) {
   94.37 +        return createClassNotFoundInvocation(desc);
   94.38 +    }
   94.39 +
   94.40 +    @Override
   94.41 +    protected GuardedInvocation findCallMethod(CallSiteDescriptor desc, LinkRequest request) {
   94.42 +        return createClassNotFoundInvocation(desc);
   94.43 +    }
   94.44 +
   94.45 +    private static GuardedInvocation createClassNotFoundInvocation(final CallSiteDescriptor desc) {
   94.46 +        // If NativeJavaPackage is invoked either as a constructor or as a function, throw a ClassNotFoundException as
   94.47 +        // we can assume the user attempted to instantiate a non-existent class.
   94.48 +        final MethodType type = desc.getMethodType();
   94.49 +        return new GuardedInvocation(
   94.50 +                MH.dropArguments(CLASS_NOT_FOUND, 1, type.parameterList().subList(1, type.parameterCount())),
   94.51 +                type.parameterType(0) == NativeJavaPackage.class ? null : TYPE_GUARD);
   94.52 +    }
   94.53 +
   94.54 +    @SuppressWarnings("unused")
   94.55 +    private static void classNotFound(final NativeJavaPackage pkg) throws ClassNotFoundException {
   94.56 +        throw new ClassNotFoundException(pkg.name);
   94.57 +    }
   94.58 +
   94.59      /**
   94.60       * "No such property" call placeholder.
   94.61       *
   94.62 @@ -188,4 +222,7 @@
   94.63          return noSuchProperty(desc, request);
   94.64      }
   94.65  
   94.66 +    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
   94.67 +        return MH.findStatic(MethodHandles.lookup(), NativeJavaPackage.class, name, MH.type(rtype, types));
   94.68 +    }
   94.69  }
    95.1 --- a/src/jdk/nashorn/internal/runtime/Property.java	Thu May 30 10:58:35 2013 -0700
    95.2 +++ b/src/jdk/nashorn/internal/runtime/Property.java	Mon Jun 03 23:24:36 2013 -0700
    95.3 @@ -52,6 +52,9 @@
    95.4       * we can use leave flag byte initialized with (the default) zero value.
    95.5       */
    95.6  
    95.7 +    /** Mask for property being both writable, enumerable and configurable */
    95.8 +    public static final int WRITABLE_ENUMERABLE_CONFIGURABLE = 0b0000_0000_0000;
    95.9 +
   95.10      /** ECMA 8.6.1 - Is this property not writable? */
   95.11      public static final int NOT_WRITABLE     = 0b0000_0000_0001;
   95.12  
   95.13 @@ -352,6 +355,27 @@
   95.14      }
   95.15  
   95.16      /**
   95.17 +     * Set the value of this property in {@code owner}. This allows to bypass creation of the
   95.18 +     * setter MethodHandle for spill and user accessor properties.
   95.19 +     *
   95.20 +     * @param self the this object
   95.21 +     * @param owner the owner object
   95.22 +     * @param value the new property value
   95.23 +     * @param strict is this a strict setter?
   95.24 +     */
   95.25 +    protected abstract void setObjectValue(ScriptObject self, ScriptObject owner, Object value, boolean strict);
   95.26 +
   95.27 +    /**
   95.28 +     * Set the Object value of this property from {@code owner}. This allows to bypass creation of the
   95.29 +     * getter MethodHandle for spill and user accessor properties.
   95.30 +     *
   95.31 +     * @param self the this object
   95.32 +     * @param owner the owner object
   95.33 +     * @return  the property value
   95.34 +     */
   95.35 +    protected abstract Object getObjectValue(ScriptObject self, ScriptObject owner);
   95.36 +
   95.37 +    /**
   95.38       * Abstract method for retrieving the setter for the property. We do not know
   95.39       * anything about the internal representation when we request the setter, we only
   95.40       * know that the setter will take the property as a parameter of the given type.
    96.1 --- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Thu May 30 10:58:35 2013 -0700
    96.2 +++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Mon Jun 03 23:24:36 2013 -0700
    96.3 @@ -30,6 +30,8 @@
    96.4  import java.lang.invoke.MethodHandle;
    96.5  import java.lang.invoke.MethodHandles;
    96.6  import java.lang.invoke.MethodType;
    96.7 +import java.util.ArrayList;
    96.8 +import java.util.Arrays;
    96.9  import java.util.LinkedList;
   96.10  
   96.11  import jdk.nashorn.internal.codegen.Compiler;
   96.12 @@ -49,9 +51,16 @@
   96.13   */
   96.14  public final class RecompilableScriptFunctionData extends ScriptFunctionData {
   96.15  
   96.16 +    /** FunctionNode with the code for this ScriptFunction */
   96.17      private FunctionNode functionNode;
   96.18 -    private final PropertyMap  allocatorMap;
   96.19 +
   96.20 +    /** Allocator map from makeMap() */
   96.21 +    private final PropertyMap allocatorMap;
   96.22 +
   96.23 +    /** Code installer used for all further recompilation/specialization of this ScriptFunction */
   96.24      private final CodeInstaller<ScriptEnvironment> installer;
   96.25 +
   96.26 +    /** Name of class where allocator function resides */
   96.27      private final String allocatorClassName;
   96.28  
   96.29      /** lazily generated allocator */
   96.30 @@ -60,6 +69,23 @@
   96.31      private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
   96.32  
   96.33      /**
   96.34 +     * Used for specialization based on runtime arguments. Whenever we specialize on
   96.35 +     * callsite parameter types at runtime, we need to use a parameter type guard to
   96.36 +     * ensure that the specialized version of the script function continues to be
   96.37 +     * applicable for a particular callsite *
   96.38 +     */
   96.39 +    private static final MethodHandle PARAM_TYPE_GUARD = findOwnMH("paramTypeGuard", boolean.class, Type[].class,  Object[].class);
   96.40 +
   96.41 +    /**
   96.42 +     * It is usually a good gamble whever we detect a runtime callsite with a double
   96.43 +     * (or java.lang.Number instance) to specialize the parameter to an integer, if the
   96.44 +     * parameter in question can be represented as one. The double typically only exists
   96.45 +     * because the compiler doesn't know any better than "a number type" and conservatively
   96.46 +     * picks doubles when it can't prove that an integer addition wouldn't overflow
   96.47 +     */
   96.48 +    private static final MethodHandle ENSURE_INT = findOwnMH("ensureInt", int.class, Object.class);
   96.49 +
   96.50 +    /**
   96.51       * Constructor - public as scripts use it
   96.52       *
   96.53       * @param functionNode       functionNode that represents this function code
   96.54 @@ -141,14 +167,6 @@
   96.55               return; // nothing to do, we have code, at least some.
   96.56           }
   96.57  
   96.58 -         // check if function node is lazy, need to compile it.
   96.59 -         // note that currently function cloning is not working completely, which
   96.60 -         // means that the compiler will mutate the function node it has been given
   96.61 -         // once it has been compiled, it cannot be recompiled. This means that
   96.62 -         // lazy compilation works (not compiled yet) but e.g. specializations won't
   96.63 -         // until the copy-on-write changes for IR are in, making cloning meaningless.
   96.64 -         // therefore, currently method specialization is disabled. TODO
   96.65 -
   96.66           if (functionNode.isLazy()) {
   96.67               Compiler.LOG.info("Trampoline hit: need to do lazy compilation of '", functionNode.getName(), "'");
   96.68               final Compiler compiler = new Compiler(installer);
   96.69 @@ -156,38 +174,55 @@
   96.70               assert !functionNode.isLazy();
   96.71               compiler.install(functionNode);
   96.72  
   96.73 -             // we don't need to update any flags - varArgs and needsCallee are instrincic
   96.74 -             // in the function world we need to get a destination node from the compile instead
   96.75 -             // and replace it with our function node. TODO
   96.76 +             /*
   96.77 +              * We don't need to update any flags - varArgs and needsCallee are instrincic
   96.78 +              * in the function world we need to get a destination node from the compile instead
   96.79 +              * and replace it with our function node. TODO
   96.80 +              */
   96.81           }
   96.82  
   96.83 -         // we can't get here unless we have bytecode, either from eager compilation or from
   96.84 -         // running a lazy compile on the lines above
   96.85 +         /*
   96.86 +          * We can't get to this program point unless we have bytecode, either from
   96.87 +          * eager compilation or from running a lazy compile on the lines above
   96.88 +          */
   96.89  
   96.90           assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
   96.91  
   96.92           // code exists - look it up and add it into the automatically sorted invoker list
   96.93 -         addCode(functionNode, null, null);
   96.94 +         addCode(functionNode);
   96.95      }
   96.96  
   96.97 -    private MethodHandle addCode(final FunctionNode fn, final MethodHandle guard, final MethodHandle fallback) {
   96.98 -        final MethodHandle target =
   96.99 +    private MethodHandle addCode(final FunctionNode fn) {
  96.100 +        return addCode(fn, null, null, null);
  96.101 +    }
  96.102 +
  96.103 +    private MethodHandle addCode(final FunctionNode fn, final MethodType runtimeType, final MethodHandle guard, final MethodHandle fallback) {
  96.104 +        final MethodType targetType = new FunctionSignature(fn).getMethodType();
  96.105 +        MethodHandle target =
  96.106              MH.findStatic(
  96.107                      LOOKUP,
  96.108                      fn.getCompileUnit().getCode(),
  96.109                      fn.getName(),
  96.110 -                    new FunctionSignature(fn).
  96.111 -                        getMethodType());
  96.112 -        MethodHandle mh = target;
  96.113 -        if (guard != null) {
  96.114 -            try {
  96.115 -                mh = MH.guardWithTest(MH.asCollector(guard, Object[].class, target.type().parameterCount()), MH.asType(target, fallback.type()), fallback);
  96.116 -            } catch (Throwable e) {
  96.117 -                e.printStackTrace();
  96.118 +                    targetType);
  96.119 +
  96.120 +        /*
  96.121 +         * For any integer argument. a double that is representable as an integer is OK.
  96.122 +         * otherwise the guard would have failed. in that case introduce a filter that
  96.123 +         * casts the double to an integer, which we know will preserve all precision.
  96.124 +         */
  96.125 +        for (int i = 0; i < targetType.parameterCount(); i++) {
  96.126 +            if (targetType.parameterType(i) == int.class) {
  96.127 +                //representable as int
  96.128 +                target = MH.filterArguments(target, i, ENSURE_INT);
  96.129              }
  96.130          }
  96.131  
  96.132 -        final CompiledFunction cf = new CompiledFunction(mh);
  96.133 +        MethodHandle mh = target;
  96.134 +        if (guard != null) {
  96.135 +            mh = MH.guardWithTest(MH.asCollector(guard, Object[].class, target.type().parameterCount()), MH.asType(target, fallback.type()), fallback);
  96.136 +        }
  96.137 +
  96.138 +        final CompiledFunction cf = new CompiledFunction(runtimeType == null ? targetType : runtimeType, mh);
  96.139          code.add(cf);
  96.140  
  96.141          return cf.getInvoker();
  96.142 @@ -212,69 +247,162 @@
  96.143          return Type.OBJECT;
  96.144      }
  96.145  
  96.146 -    @SuppressWarnings("unused")
  96.147 -    private static boolean paramTypeGuard(final Type[] compileTimeTypes, final Type[] runtimeTypes, Object... args) {
  96.148 -        //System.err.println("Param type guard " + Arrays.asList(args));
  96.149 +    private static boolean canCoerce(final Object arg, final Type type) {
  96.150 +        Type argType = runtimeType(arg);
  96.151 +        if (Type.widest(argType, type) == type || arg == ScriptRuntime.UNDEFINED) {
  96.152 +            return true;
  96.153 +        }
  96.154 +        System.err.println(arg + " does not fit in "+ argType + " " + type + " " + arg.getClass());
  96.155 +        new Throwable().printStackTrace();
  96.156          return false;
  96.157      }
  96.158  
  96.159 -    private static final MethodHandle PARAM_TYPE_GUARD = findOwnMH("paramTypeGuard", boolean.class, Type[].class, Type[].class, Object[].class);
  96.160 +    @SuppressWarnings("unused")
  96.161 +    private static boolean paramTypeGuard(final Type[] paramTypes, final Object... args) {
  96.162 +        final int length = args.length;
  96.163 +        assert args.length >= paramTypes.length;
  96.164 +
  96.165 +        //i==start, skip the this, callee params etc
  96.166 +        int start = args.length - paramTypes.length;
  96.167 +        for (int i = start; i < args.length; i++) {
  96.168 +            final Object arg = args[i];
  96.169 +            if (!canCoerce(arg, paramTypes[i - start])) {
  96.170 +                return false;
  96.171 +            }
  96.172 +        }
  96.173 +        return true;
  96.174 +    }
  96.175 +
  96.176 +    @SuppressWarnings("unused")
  96.177 +    private static int ensureInt(final Object arg) {
  96.178 +        if (arg instanceof Number) {
  96.179 +            return ((Number)arg).intValue();
  96.180 +        } else if (arg instanceof Undefined) {
  96.181 +            return 0;
  96.182 +        }
  96.183 +        throw new AssertionError(arg);
  96.184 +    }
  96.185 +
  96.186 +    /**
  96.187 +     * Given the runtime callsite args, compute a method type that is equivalent to what
  96.188 +     * was passed - this is typically a lot more specific that what the compiler has been
  96.189 +     * able to deduce
  96.190 +     * @param callSiteType callsite type for the compiled callsite target
  96.191 +     * @param args runtime arguments to the compiled callsite target
  96.192 +     * @return adjusted method type, narrowed as to conform to runtime callsite type instead
  96.193 +     */
  96.194 +    private static MethodType runtimeType(final MethodType callSiteType, final Object[] args) {
  96.195 +        if (args == null) {
  96.196 +            //for example bound, or otherwise runtime arguments to callsite unavailable, then
  96.197 +            //do not change the type
  96.198 +            return callSiteType;
  96.199 +        }
  96.200 +        final Class<?>[] paramTypes = new Class<?>[callSiteType.parameterCount()];
  96.201 +        final int        start      = args.length - callSiteType.parameterCount();
  96.202 +        for (int i = start; i < args.length; i++) {
  96.203 +            paramTypes[i - start] = runtimeType(args[i]).getTypeClass();
  96.204 +        }
  96.205 +        return MH.type(callSiteType.returnType(), paramTypes);
  96.206 +    }
  96.207 +
  96.208 +    private static ArrayList<Type> runtimeType(final MethodType mt) {
  96.209 +        final ArrayList<Type> type = new ArrayList<>();
  96.210 +        for (int i = 0; i < mt.parameterCount(); i++) {
  96.211 +            type.add(Type.typeFor(mt.parameterType(i)));
  96.212 +        }
  96.213 +        return type;
  96.214 +    }
  96.215  
  96.216      @Override
  96.217      MethodHandle getBestInvoker(final MethodType callSiteType, final Object[] args) {
  96.218 -        final MethodHandle mh = super.getBestInvoker(callSiteType, args);
  96.219 +        final MethodType runtimeType = runtimeType(callSiteType, args);
  96.220 +        assert runtimeType.parameterCount() == callSiteType.parameterCount();
  96.221  
  96.222 -        if (!functionNode.canSpecialize() || !code.isLessSpecificThan(callSiteType)) {
  96.223 +        final MethodHandle mh = super.getBestInvoker(runtimeType, args);
  96.224 +
  96.225 +        /*
  96.226 +         * Not all functions can be specialized, for example, if we deemed memory
  96.227 +         * footprint too large to store a parse snapshot, or if it is meaningless
  96.228 +         * to do so, such as e.g. for runScript
  96.229 +         */
  96.230 +        if (!functionNode.canSpecialize()) {
  96.231              return mh;
  96.232          }
  96.233  
  96.234 -        final FunctionNode snapshot = functionNode.getSnapshot();
  96.235 -        if (snapshot == null) {
  96.236 +        /*
  96.237 +         * Check if best invoker is equally specific or more specific than runtime
  96.238 +         * type. In that case, we don't need further specialization, but can use
  96.239 +         * whatever we have already. We know that it will match callSiteType, or it
  96.240 +         * would not have been returned from getBestInvoker
  96.241 +         */
  96.242 +        if (!code.isLessSpecificThan(runtimeType)) {
  96.243              return mh;
  96.244          }
  96.245  
  96.246          int i;
  96.247 +        final FunctionNode snapshot = functionNode.getSnapshot();
  96.248 +        assert snapshot != null;
  96.249  
  96.250 -        //classes known at runtime
  96.251 -        final LinkedList<Type> runtimeArgs = new LinkedList<>();
  96.252 -        for (i = args.length - 1; i >= args.length - snapshot.getParameters().size(); i--) {
  96.253 -            runtimeArgs.addLast(runtimeType(args[i]));
  96.254 +        /*
  96.255 +         * Create a list of the arg types that the compiler knows about
  96.256 +         * typically, the runtime args are a lot more specific, and we should aggressively
  96.257 +         * try to use those whenever possible
  96.258 +         * We WILL try to make an aggressive guess as possible, and add guards if needed.
  96.259 +         * For example, if the compiler can deduce that we have a number type, but the runtime
  96.260 +         * passes and int, we might still want to keep it an int, and the gamble to
  96.261 +         * check that whatever is passed is int representable usually pays off
  96.262 +         * If the compiler only knows that a parameter is an "Object", it is still worth
  96.263 +         * it to try to specialize it by looking at the runtime arg.
  96.264 +         */
  96.265 +        final LinkedList<Type> compileTimeArgs = new LinkedList<>();
  96.266 +        for (i = callSiteType.parameterCount() - 1; i >= 0 && compileTimeArgs.size() < snapshot.getParameters().size(); i--) {
  96.267 +            compileTimeArgs.addFirst(Type.typeFor(callSiteType.parameterType(i)));
  96.268          }
  96.269  
  96.270 -        //classes known at compile time
  96.271 -        final LinkedList<Type> compileTimeArgs = new LinkedList<>();
  96.272 -        for (i = callSiteType.parameterCount() - 1; i >= 0 && compileTimeArgs.size() < snapshot.getParameters().size(); i--) {
  96.273 -            compileTimeArgs.addLast(Type.typeFor(callSiteType.parameterType(i)));
  96.274 +        /*
  96.275 +         * The classes known at compile time are a safe to generate as primitives without parameter guards
  96.276 +         * But the classes known at runtime (if more specific than compile time types) are safe to generate as primitives
  96.277 +         * IFF there are parameter guards
  96.278 +         */
  96.279 +        MethodHandle guard = null;
  96.280 +        final ArrayList<Type> runtimeParamTypes = runtimeType(runtimeType);
  96.281 +        while (runtimeParamTypes.size() > functionNode.getParameters().size()) {
  96.282 +            runtimeParamTypes.remove(0);
  96.283          }
  96.284 +        for (i = 0; i < compileTimeArgs.size(); i++) {
  96.285 +            final Type rparam = Type.typeFor(runtimeType.parameterType(i));
  96.286 +            final Type cparam = compileTimeArgs.get(i);
  96.287  
  96.288 -        //the classes known at compile time are a safe to generate as primitives without parameter guards
  96.289 -        //the classes known at runtime are safe to generate as primitives IFF there are parameter guards
  96.290 -        MethodHandle guard = null;
  96.291 -        for (i = 0; i < compileTimeArgs.size(); i++) {
  96.292 -            final Type runtimeType = runtimeArgs.get(i);
  96.293 -            final Type compileType = compileTimeArgs.get(i);
  96.294 -
  96.295 -            if (compileType.isObject() && !runtimeType.isObject()) {
  96.296 +            if (cparam.isObject() && !rparam.isObject()) {
  96.297 +                //check that the runtime object is still coercible to the runtime type, because compiler can't prove it's always primitive
  96.298                  if (guard == null) {
  96.299 -                    guard = PARAM_TYPE_GUARD;
  96.300 -                    guard = MH.insertArguments(guard, 0, compileTimeArgs.toArray(new Type[compileTimeArgs.size()]), runtimeArgs.toArray(new Type[runtimeArgs.size()]));
  96.301 +                    guard = MH.insertArguments(PARAM_TYPE_GUARD, 0, (Object)runtimeParamTypes.toArray(new Type[runtimeParamTypes.size()]));
  96.302                  }
  96.303              }
  96.304          }
  96.305  
  96.306 -        //System.err.println("Specialized " + name + " " + runtimeArgs + " known=" + compileTimeArgs);
  96.307 +        Compiler.LOG.info("Callsite specialized ", name, " runtimeType=", runtimeType, " parameters=", snapshot.getParameters(), " args=", Arrays.asList(args));
  96.308  
  96.309          assert snapshot != null;
  96.310          assert snapshot != functionNode;
  96.311  
  96.312          final Compiler compiler = new Compiler(installer);
  96.313 -        final FunctionNode compiledSnapshot = compiler.compile(snapshot.setHints(null, new Compiler.Hints(compileTimeArgs.toArray(new Type[compileTimeArgs.size()]))));
  96.314  
  96.315 +        final FunctionNode compiledSnapshot = compiler.compile(
  96.316 +            snapshot.setHints(
  96.317 +                null,
  96.318 +                new Compiler.Hints(runtimeParamTypes.toArray(new Type[runtimeParamTypes.size()]))));
  96.319 +
  96.320 +        /*
  96.321 +         * No matter how narrow your types were, they can never be narrower than Attr during recompile made them. I.e. you
  96.322 +         * can put an int into the function here, if you see it as a runtime type, but if the function uses a multiplication
  96.323 +         * on it, it will still need to be a double. At least until we have overflow checks. Similarly, if an int is
  96.324 +         * passed but it is used as a string, it makes no sense to make the parameter narrower than Object. At least until
  96.325 +         * the "different types for one symbol in difference places" work is done
  96.326 +         */
  96.327          compiler.install(compiledSnapshot);
  96.328  
  96.329 -        final MethodHandle nmh = addCode(compiledSnapshot, guard, mh);
  96.330 -
  96.331 -        return nmh;
  96.332 +        return addCode(compiledSnapshot, runtimeType, guard, mh);
  96.333      }
  96.334  
  96.335      private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
    97.1 --- a/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Thu May 30 10:58:35 2013 -0700
    97.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Mon Jun 03 23:24:36 2013 -0700
    97.3 @@ -54,7 +54,7 @@
    97.4      private final Namespace namespace;
    97.5  
    97.6      /** Current Options object. */
    97.7 -    private Options options;
    97.8 +    private final Options options;
    97.9  
   97.10      /** Always allow functions as statements */
   97.11      public final boolean _anon_functions;
   97.12 @@ -155,6 +155,9 @@
   97.13      /** print symbols and their contents for the script */
   97.14      public final boolean _print_symbols;
   97.15  
   97.16 +    /** range analysis for known types */
   97.17 +    public final boolean _range_analysis;
   97.18 +
   97.19      /** is this environment in scripting mode? */
   97.20      public final boolean _scripting;
   97.21  
   97.22 @@ -183,7 +186,7 @@
   97.23       * @param out output print writer
   97.24       * @param err error print writer
   97.25       */
   97.26 -    ScriptEnvironment(final Options options, final PrintWriter out, final PrintWriter err) {
   97.27 +    public ScriptEnvironment(final Options options, final PrintWriter out, final PrintWriter err) {
   97.28          this.out = out;
   97.29          this.err = err;
   97.30          this.namespace = new Namespace();
   97.31 @@ -219,6 +222,7 @@
   97.32          _print_parse          = options.getBoolean("print.parse");
   97.33          _print_lower_parse    = options.getBoolean("print.lower.parse");
   97.34          _print_symbols        = options.getBoolean("print.symbols");
   97.35 +        _range_analysis       = options.getBoolean("range.analysis");
   97.36          _scripting            = options.getBoolean("scripting");
   97.37          _strict               = options.getBoolean("strict");
   97.38          _version              = options.getBoolean("version");
   97.39 @@ -258,14 +262,19 @@
   97.40          }
   97.41          this._callsite_flags = callSiteFlags;
   97.42  
   97.43 -        final Option<?> option = options.get("timezone");
   97.44 -        if (option != null) {
   97.45 -            this._timezone = (TimeZone)option.getValue();
   97.46 +        final Option<?> timezoneOption = options.get("timezone");
   97.47 +        if (timezoneOption != null) {
   97.48 +            this._timezone = (TimeZone)timezoneOption.getValue();
   97.49          } else {
   97.50              this._timezone  = TimeZone.getDefault();
   97.51          }
   97.52  
   97.53 -        this._locale = Locale.getDefault();
   97.54 +        final Option<?> localeOption = options.get("locale");
   97.55 +        if (localeOption != null) {
   97.56 +            this._locale = (Locale)localeOption.getValue();
   97.57 +        } else {
   97.58 +            this._locale = Locale.getDefault();
   97.59 +        }
   97.60      }
   97.61  
   97.62      /**
    98.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Thu May 30 10:58:35 2013 -0700
    98.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Mon Jun 03 23:24:36 2013 -0700
    98.3 @@ -25,14 +25,13 @@
    98.4  
    98.5  package jdk.nashorn.internal.runtime;
    98.6  
    98.7 +import static jdk.nashorn.internal.lookup.Lookup.MH;
    98.8  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    98.9  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
   98.10 -import static jdk.nashorn.internal.lookup.Lookup.MH;
   98.11  
   98.12  import java.lang.invoke.MethodHandle;
   98.13  import java.lang.invoke.MethodHandles;
   98.14  import java.lang.invoke.MethodType;
   98.15 -
   98.16  import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
   98.17  
   98.18  /**
   98.19 @@ -92,12 +91,13 @@
   98.20      CompiledFunction bind(final CompiledFunction originalInv, final ScriptFunction fn, final Object self, final Object[] args) {
   98.21          final MethodHandle boundInvoker = bindInvokeHandle(originalInv.getInvoker(), fn, self, args);
   98.22  
   98.23 +        //TODO the boundinvoker.type() could actually be more specific here
   98.24          if (isConstructor()) {
   98.25              ensureConstructor(originalInv);
   98.26 -            return new CompiledFunction(boundInvoker, bindConstructHandle(originalInv.getConstructor(), fn, args));
   98.27 +            return new CompiledFunction(boundInvoker.type(), boundInvoker, bindConstructHandle(originalInv.getConstructor(), fn, args));
   98.28          }
   98.29  
   98.30 -        return new CompiledFunction(boundInvoker);
   98.31 +        return new CompiledFunction(boundInvoker.type(), boundInvoker);
   98.32      }
   98.33  
   98.34      /**
   98.35 @@ -389,7 +389,9 @@
   98.36                  boundInvoker = noArgBoundInvoker;
   98.37              }
   98.38          } else {
   98.39 -            final Object[] boundArgs = new Object[Math.min(originalInvoker.type().parameterCount(), args.length + (isTargetBound ? 0 : (needsCallee  ? 2 : 1)))];
   98.40 +            // If target is already bound, insert additional bound arguments after "this" argument, at position 1.
   98.41 +            final int argInsertPos = isTargetBound ? 1 : 0;
   98.42 +            final Object[] boundArgs = new Object[Math.min(originalInvoker.type().parameterCount() - argInsertPos, args.length + (isTargetBound ? 0 : (needsCallee  ? 2 : 1)))];
   98.43              int next = 0;
   98.44              if (!isTargetBound) {
   98.45                  if (needsCallee) {
   98.46 @@ -403,7 +405,7 @@
   98.47              // "this" will get dropped anyway by the target invoker. We previously asserted that already bound functions
   98.48              // don't take a callee parameter, so we can know that the signature is (this[, args...]) therefore args
   98.49              // start at position 1. If the function is not bound, we start inserting arguments at position 0.
   98.50 -            boundInvoker = MH.insertArguments(originalInvoker, isTargetBound ? 1 : 0, boundArgs);
   98.51 +            boundInvoker = MH.insertArguments(originalInvoker, argInsertPos, boundArgs);
   98.52          }
   98.53  
   98.54          if (isTargetBound) {
    99.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Thu May 30 10:58:35 2013 -0700
    99.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Mon Jun 03 23:24:36 2013 -0700
    99.3 @@ -25,7 +25,6 @@
    99.4  
    99.5  package jdk.nashorn.internal.runtime;
    99.6  
    99.7 -import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
    99.8  import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCall;
    99.9  import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
   99.10  import static jdk.nashorn.internal.lookup.Lookup.MH;
   99.11 @@ -151,17 +150,6 @@
   99.12      /** Method handle for setting the user accessors of a ScriptObject */
   99.13      public static final Call SET_USER_ACCESSORS = virtualCall(ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
   99.14  
   99.15 -    /** Method handle for getter for {@link UserAccessorProperty}, given a slot */
   99.16 -    static final Call USER_ACCESSOR_GETTER = staticCall(MethodHandles.lookup(), ScriptObject.class, "userAccessorGetter", Object.class, ScriptObject.class, int.class, Object.class);
   99.17 -
   99.18 -    /** Method handle for setter for {@link UserAccessorProperty}, given a slot */
   99.19 -    static final Call USER_ACCESSOR_SETTER = staticCall(MethodHandles.lookup(), ScriptObject.class, "userAccessorSetter", void.class, ScriptObject.class, int.class, String.class, Object.class, Object.class);
   99.20 -
   99.21 -    private static final MethodHandle INVOKE_UA_GETTER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
   99.22 -            Object.class, Object.class);
   99.23 -    private static final MethodHandle INVOKE_UA_SETTER = Bootstrap.createDynamicInvoker("dyn:call", void.class,
   99.24 -            Object.class, Object.class, Object.class);
   99.25 -
   99.26      /**
   99.27       * Constructor
   99.28       */
   99.29 @@ -699,17 +687,9 @@
   99.30       * @return New property.
   99.31       */
   99.32      public final Property addOwnProperty(final String key, final int propertyFlags, final Object value) {
   99.33 -        final MethodHandle setter = addSpill(key, propertyFlags);
   99.34 -
   99.35 -        try {
   99.36 -            setter.invokeExact((Object)this, value);
   99.37 -        } catch (final Error|RuntimeException e) {
   99.38 -            throw e;
   99.39 -        } catch (final Throwable e) {
   99.40 -            throw new RuntimeException(e);
   99.41 -        }
   99.42 -
   99.43 -        return getMap().findProperty(key);
   99.44 +        final Property property = addSpillProperty(key, propertyFlags);
   99.45 +        property.setObjectValue(this, this, value, false);
   99.46 +        return property;
   99.47      }
   99.48  
   99.49      /**
   99.50 @@ -744,15 +724,7 @@
   99.51          // Erase the property field value with undefined. If the property is defined
   99.52          // by user-defined accessors, we don't want to call the setter!!
   99.53          if (!(property instanceof UserAccessorProperty)) {
   99.54 -            try {
   99.55 -                // make the property value to be undefined
   99.56 -                //TODO specproperties
   99.57 -                property.getSetter(Object.class, getMap()).invokeExact((Object)this, (Object)UNDEFINED);
   99.58 -            } catch (final RuntimeException | Error e) {
   99.59 -                throw e;
   99.60 -            } catch (final Throwable t) {
   99.61 -                throw new RuntimeException(t);
   99.62 -            }
   99.63 +            property.setObjectValue(this, this, UNDEFINED, false);
   99.64          }
   99.65      }
   99.66  
   99.67 @@ -948,18 +920,7 @@
   99.68        * @return the value of the property
   99.69        */
   99.70      protected static Object getObjectValue(final FindProperty find) {
   99.71 -        final MethodHandle getter = find.getGetter(Object.class);
   99.72 -        if (getter != null) {
   99.73 -            try {
   99.74 -                return getter.invokeExact((Object)find.getGetterReceiver());
   99.75 -            } catch (final Error|RuntimeException e) {
   99.76 -                throw e;
   99.77 -            } catch (final Throwable e) {
   99.78 -                throw new RuntimeException(e);
   99.79 -            }
   99.80 -        }
   99.81 -
   99.82 -        return UNDEFINED;
   99.83 +        return find.getObjectValue();
   99.84      }
   99.85  
   99.86      /**
   99.87 @@ -2087,11 +2048,7 @@
   99.88              property = addOwnProperty(property);
   99.89          } else {
   99.90              int i = getMap().getSpillLength();
   99.91 -            MethodHandle getter = MH.arrayElementGetter(Object[].class);
   99.92 -            MethodHandle setter = MH.arrayElementSetter(Object[].class);
   99.93 -            getter = MH.asType(MH.insertArguments(getter, 1, i), Lookup.GET_OBJECT_TYPE);
   99.94 -            setter = MH.asType(MH.insertArguments(setter, 1, i), Lookup.SET_OBJECT_TYPE);
   99.95 -            property = new AccessorProperty(key, propertyFlags | Property.IS_SPILL, i, getter, setter);
   99.96 +            property = new AccessorProperty(key, propertyFlags | Property.IS_SPILL, i);
   99.97              notifyPropertyAdded(this, property);
   99.98              property = addOwnProperty(property);
   99.99              i = property.getSlot();
  99.100 @@ -2115,20 +2072,15 @@
  99.101  
  99.102      /**
  99.103       * Add a spill entry for the given key.
  99.104 -     * @param key           Property key.
  99.105 -     * @param propertyFlags Property flags.
  99.106 +     * @param key Property key.
  99.107       * @return Setter method handle.
  99.108       */
  99.109 -    private MethodHandle addSpill(final String key, final int propertyFlags) {
  99.110 -        final Property spillProperty = addSpillProperty(key, propertyFlags);
  99.111 +    MethodHandle addSpill(final String key) {
  99.112 +        final Property spillProperty = addSpillProperty(key, 0);
  99.113          final Class<?> type = Object.class;
  99.114          return spillProperty.getSetter(type, getMap()); //TODO specfields
  99.115      }
  99.116  
  99.117 -    MethodHandle addSpill(final String key) {
  99.118 -        return addSpill(key, 0);
  99.119 -    }
  99.120 -
  99.121      /**
  99.122       * Make sure arguments are paired correctly, with respect to more parameters than declared,
  99.123       * fewer parameters than declared and other things that JavaScript allows. This might involve
  99.124 @@ -2659,14 +2611,8 @@
  99.125                  return;
  99.126              }
  99.127  
  99.128 -            try {
  99.129 -                final MethodHandle setter = f.getSetter(Object.class, strict); //TODO specfields
  99.130 -                setter.invokeExact((Object)f.getSetterReceiver(), value);
  99.131 -            } catch (final Error|RuntimeException e) {
  99.132 -                throw e;
  99.133 -            } catch (final Throwable e) {
  99.134 -                throw new RuntimeException(e);
  99.135 -            }
  99.136 +            f.setObjectValue(value, strict);
  99.137 +
  99.138          } else if (!isExtensible()) {
  99.139              if (strict) {
  99.140                  throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
  99.141 @@ -2677,13 +2623,7 @@
  99.142      }
  99.143  
  99.144      private void spill(final String key, final Object value) {
  99.145 -        try {
  99.146 -            addSpill(key).invokeExact((Object)this, value);
  99.147 -        } catch (final Error|RuntimeException e) {
  99.148 -            throw e;
  99.149 -        } catch (final Throwable e) {
  99.150 -            throw new RuntimeException(e);
  99.151 -        }
  99.152 +        addSpillProperty(key, 0).setObjectValue(this, this, value, false);
  99.153      }
  99.154  
  99.155  
  99.156 @@ -3217,46 +3157,6 @@
  99.157          return (index < 0 || (index >= spill.length)) ? null : spill[index];
  99.158      }
  99.159  
  99.160 -    // User defined getter and setter are always called by "dyn:call". Note that the user
  99.161 -    // getter/setter may be inherited. If so, proto is bound during lookup. In either
  99.162 -    // inherited or self case, slot is also bound during lookup. Actual ScriptFunction
  99.163 -    // to be called is retrieved everytime and applied.
  99.164 -    @SuppressWarnings("unused")
  99.165 -    private static Object userAccessorGetter(final ScriptObject proto, final int slot, final Object self) {
  99.166 -        final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
  99.167 -        final Object       func      = container.getSpill(slot);
  99.168 -
  99.169 -        if (func instanceof ScriptFunction) {
  99.170 -            try {
  99.171 -                return INVOKE_UA_GETTER.invokeExact(func, self);
  99.172 -            } catch(final Error|RuntimeException t) {
  99.173 -                throw t;
  99.174 -            } catch(final Throwable t) {
  99.175 -                throw new RuntimeException(t);
  99.176 -            }
  99.177 -        }
  99.178 -
  99.179 -        return UNDEFINED;
  99.180 -    }
  99.181 -
  99.182 -    @SuppressWarnings("unused")
  99.183 -    private static void userAccessorSetter(final ScriptObject proto, final int slot, final String name, final Object self, final Object value) {
  99.184 -        final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
  99.185 -        final Object       func      = container.getSpill(slot);
  99.186 -
  99.187 -        if (func instanceof ScriptFunction) {
  99.188 -            try {
  99.189 -                INVOKE_UA_SETTER.invokeExact(func, self, value);
  99.190 -            } catch(final Error|RuntimeException t) {
  99.191 -                throw t;
  99.192 -            } catch(final Throwable t) {
  99.193 -                throw new RuntimeException(t);
  99.194 -            }
  99.195 -        }  else if (name != null) {
  99.196 -            throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
  99.197 -        }
  99.198 -    }
  99.199 -
  99.200      private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
  99.201          final Class<?>   own = ScriptObject.class;
  99.202          final MethodType mt  = MH.type(rtype, types);
   100.1 --- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Thu May 30 10:58:35 2013 -0700
   100.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Mon Jun 03 23:24:36 2013 -0700
   100.3 @@ -36,6 +36,7 @@
   100.4  import java.lang.reflect.Array;
   100.5  import java.util.Collections;
   100.6  import java.util.Iterator;
   100.7 +import java.util.Locale;
   100.8  import java.util.NoSuchElementException;
   100.9  import java.util.Objects;
  100.10  import jdk.internal.dynalink.beans.StaticClass;
  100.11 @@ -788,7 +789,7 @@
  100.12              return false;
  100.13          }
  100.14  
  100.15 -        throw typeError("in.with.non.object", rvalType.toString().toLowerCase());
  100.16 +        throw typeError("in.with.non.object", rvalType.toString().toLowerCase(Locale.ENGLISH));
  100.17      }
  100.18  
  100.19      /**
   101.1 --- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Thu May 30 10:58:35 2013 -0700
   101.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Mon Jun 03 23:24:36 2013 -0700
   101.3 @@ -46,7 +46,7 @@
   101.4  public final class ScriptingFunctions {
   101.5  
   101.6      /** Handle to implementation of {@link ScriptingFunctions#readLine} - Nashorn extension */
   101.7 -    public static final MethodHandle READLINE = findOwnMH("readLine", Object.class, Object.class);
   101.8 +    public static final MethodHandle READLINE = findOwnMH("readLine", Object.class, Object.class, Object.class);
   101.9  
  101.10      /** Handle to implementation of {@link ScriptingFunctions#readFully} - Nashorn extension */
  101.11      public static final MethodHandle READFULLY = findOwnMH("readFully",     Object.class, Object.class, Object.class);
  101.12 @@ -78,13 +78,17 @@
  101.13       * Nashorn extension: global.readLine (scripting-mode-only)
  101.14       * Read one line of input from the standard input.
  101.15       *
  101.16 -     * @param self self reference
  101.17 +     * @param self   self reference
  101.18 +     * @param prompt String used as input prompt
  101.19       *
  101.20       * @return line that was read
  101.21       *
  101.22       * @throws IOException if an exception occurs
  101.23       */
  101.24 -    public static Object readLine(final Object self) throws IOException {
  101.25 +    public static Object readLine(final Object self, final Object prompt) throws IOException {
  101.26 +        if (prompt != UNDEFINED) {
  101.27 +            System.out.print(JSType.toString(prompt));
  101.28 +        }
  101.29          final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
  101.30          return reader.readLine();
  101.31      }
   102.1 --- a/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Thu May 30 10:58:35 2013 -0700
   102.2 +++ b/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Mon Jun 03 23:24:36 2013 -0700
   102.3 @@ -183,17 +183,10 @@
   102.4      private SetMethod createNewSpillPropertySetter() {
   102.5          final int nextSpill = getMap().getSpillLength();
   102.6  
   102.7 -        final Property property = createSpillProperty(nextSpill);
   102.8 +        final Property property = new AccessorProperty(getName(), Property.IS_SPILL, nextSpill);
   102.9          return new SetMethod(createSpillMethodHandle(nextSpill, property), property);
  102.10      }
  102.11  
  102.12 -    private Property createSpillProperty(final int nextSpill) {
  102.13 -        final MethodHandle getter = MH.asType(MH.insertArguments(MH.arrayElementGetter(Object[].class), 1, nextSpill), Lookup.GET_OBJECT_TYPE);
  102.14 -        final MethodHandle setter = MH.asType(MH.insertArguments(MH.arrayElementSetter(Object[].class), 1, nextSpill), Lookup.SET_OBJECT_TYPE);
  102.15 -
  102.16 -        return new AccessorProperty(getName(), Property.IS_SPILL, nextSpill, getter, setter);
  102.17 -    }
  102.18 -
  102.19      private MethodHandle createSpillMethodHandle(final int nextSpill, Property property) {
  102.20          final PropertyMap oldMap = getMap();
  102.21          final PropertyMap newMap = getNewMap(property);
   103.1 --- a/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Thu May 30 10:58:35 2013 -0700
   103.2 +++ b/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Mon Jun 03 23:24:36 2013 -0700
   103.3 @@ -26,7 +26,15 @@
   103.4  package jdk.nashorn.internal.runtime;
   103.5  
   103.6  import java.lang.invoke.MethodHandle;
   103.7 +import java.lang.invoke.MethodHandles;
   103.8 +
   103.9 +import jdk.nashorn.internal.codegen.CompilerConstants;
  103.10  import jdk.nashorn.internal.lookup.Lookup;
  103.11 +import jdk.nashorn.internal.runtime.linker.Bootstrap;
  103.12 +
  103.13 +import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
  103.14 +import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
  103.15 +import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
  103.16  
  103.17  /**
  103.18   * Property with user defined getters/setters. Actual getter and setter
  103.19 @@ -51,6 +59,22 @@
  103.20      /** User defined setter function slot. */
  103.21      private final int setterSlot;
  103.22  
  103.23 +    /** Getter method handle */
  103.24 +    private final static CompilerConstants.Call USER_ACCESSOR_GETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
  103.25 +            "userAccessorGetter", Object.class, ScriptObject.class, int.class, Object.class);
  103.26 +
  103.27 +    /** Setter method handle */
  103.28 +    private final static CompilerConstants.Call USER_ACCESSOR_SETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
  103.29 +            "userAccessorSetter", void.class, ScriptObject.class, int.class, String.class, Object.class, Object.class);
  103.30 +
  103.31 +    /** Dynamic invoker for getter */
  103.32 +    private static final MethodHandle INVOKE_UA_GETTER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
  103.33 +            Object.class, Object.class);
  103.34 +
  103.35 +    /** Dynamic invoker for setter */
  103.36 +    private static final MethodHandle INVOKE_UA_SETTER = Bootstrap.createDynamicInvoker("dyn:call", void.class,
  103.37 +            Object.class, Object.class, Object.class);
  103.38 +
  103.39      /**
  103.40       * Constructor
  103.41       *
  103.42 @@ -134,8 +158,18 @@
  103.43      }
  103.44  
  103.45      @Override
  103.46 +    protected Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
  103.47 +        return userAccessorGetter(owner, getGetterSlot(), self);
  103.48 +    }
  103.49 +
  103.50 +    @Override
  103.51 +    protected void setObjectValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
  103.52 +        userAccessorSetter(owner, getSetterSlot(), strict ? getKey() : null, self, value);
  103.53 +    }
  103.54 +
  103.55 +    @Override
  103.56      public MethodHandle getGetter(final Class<?> type) {
  103.57 -        return Lookup.filterReturnType(ScriptObject.USER_ACCESSOR_GETTER.methodHandle(), type);
  103.58 +        return Lookup.filterReturnType(USER_ACCESSOR_GETTER.methodHandle(), type);
  103.59      }
  103.60  
  103.61      @Override
  103.62 @@ -146,7 +180,7 @@
  103.63  
  103.64      @Override
  103.65      public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
  103.66 -        return ScriptObject.USER_ACCESSOR_SETTER.methodHandle();
  103.67 +        return USER_ACCESSOR_SETTER.methodHandle();
  103.68      }
  103.69  
  103.70      @Override
  103.71 @@ -155,4 +189,42 @@
  103.72          return (value instanceof ScriptFunction) ? (ScriptFunction) value : null;
  103.73      }
  103.74  
  103.75 +    // User defined getter and setter are always called by "dyn:call". Note that the user
  103.76 +    // getter/setter may be inherited. If so, proto is bound during lookup. In either
  103.77 +    // inherited or self case, slot is also bound during lookup. Actual ScriptFunction
  103.78 +    // to be called is retrieved everytime and applied.
  103.79 +    static Object userAccessorGetter(final ScriptObject proto, final int slot, final Object self) {
  103.80 +        final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
  103.81 +        final Object       func      = container.getSpill(slot);
  103.82 +
  103.83 +        if (func instanceof ScriptFunction) {
  103.84 +            try {
  103.85 +                return INVOKE_UA_GETTER.invokeExact(func, self);
  103.86 +            } catch(final Error|RuntimeException t) {
  103.87 +                throw t;
  103.88 +            } catch(final Throwable t) {
  103.89 +                throw new RuntimeException(t);
  103.90 +            }
  103.91 +        }
  103.92 +
  103.93 +        return UNDEFINED;
  103.94 +    }
  103.95 +
  103.96 +    static void userAccessorSetter(final ScriptObject proto, final int slot, final String name, final Object self, final Object value) {
  103.97 +        final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
  103.98 +        final Object       func      = container.getSpill(slot);
  103.99 +
 103.100 +        if (func instanceof ScriptFunction) {
 103.101 +            try {
 103.102 +                INVOKE_UA_SETTER.invokeExact(func, self, value);
 103.103 +            } catch(final Error|RuntimeException t) {
 103.104 +                throw t;
 103.105 +            } catch(final Throwable t) {
 103.106 +                throw new RuntimeException(t);
 103.107 +            }
 103.108 +        }  else if (name != null) {
 103.109 +            throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
 103.110 +        }
 103.111 +    }
 103.112 +
 103.113  }
   104.1 --- a/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java	Thu May 30 10:58:35 2013 -0700
   104.2 +++ b/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java	Mon Jun 03 23:24:36 2013 -0700
   104.3 @@ -40,7 +40,7 @@
   104.4   *     private static final InvokeByName TO_JSON = new InvokeByName("toJSON", Object.class, Object.class, Object.class);
   104.5   *     ...
   104.6   *     final Object toJSONFn = TO_JSON.getGetter().invokeExact(obj);
   104.7 - *     value = TO_JSON.getInvoker().invokeExact(toJSON, obj, key);
   104.8 + *     value = TO_JSON.getInvoker().invokeExact(toJSONFn, obj, key);
   104.9   * </pre>
  104.10   * In practice, you can have stronger type assumptions if it makes sense for your code, just remember that you must use
  104.11   * the same parameter types as the formal types of the arguments for {@code invokeExact} to work:
  104.12 @@ -50,7 +50,7 @@
  104.13   *     final ScriptObject sobj = (ScriptObject)obj;
  104.14   *     final Object toJSONFn = TO_JSON.getGetter().invokeExact(sobj);
  104.15   *     if(toJSONFn instanceof ScriptFunction) {
  104.16 - *         value = TO_JSON.getInvoker().invokeExact(toJSON, sobj, key);
  104.17 + *         value = TO_JSON.getInvoker().invokeExact(toJSONFn, sobj, key);
  104.18   *     }
  104.19   * </pre>
  104.20   * Note that in general you will not want to reuse a single instance of this class for implementing more than one call
  104.21 @@ -59,6 +59,7 @@
  104.22   * separate instance of this class for every place.
  104.23   */
  104.24  public class InvokeByName {
  104.25 +    private final String name;
  104.26      private final MethodHandle getter;
  104.27      private final MethodHandle invoker;
  104.28  
  104.29 @@ -81,6 +82,7 @@
  104.30       * @param ptypes the parameter types of the function.
  104.31       */
  104.32      public InvokeByName(final String name, final Class<?> targetClass, final Class<?> rtype, final Class<?>... ptypes) {
  104.33 +        this.name = name;
  104.34          getter  = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getItem:" + name, Object.class, targetClass);
  104.35  
  104.36          final Class<?>[] finalPtypes;
  104.37 @@ -97,6 +99,14 @@
  104.38      }
  104.39  
  104.40      /**
  104.41 +     * Returns the name of the function retrieved through this invoker.
  104.42 +     * @return the name of the function retrieved through this invoker.
  104.43 +     */
  104.44 +    public String getName() {
  104.45 +        return name;
  104.46 +    }
  104.47 +
  104.48 +    /**
  104.49       * Returns the property getter that can be invoked on an object to retrieve the function object that will be
  104.50       * subsequently invoked by the invoker returned by {@link #getInvoker()}.
  104.51       * @return the property getter method handle for the function.
   105.1 --- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Thu May 30 10:58:35 2013 -0700
   105.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Mon Jun 03 23:24:36 2013 -0700
   105.3 @@ -38,7 +38,7 @@
   105.4  import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
   105.5  import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
   105.6  import jdk.nashorn.internal.runtime.JSType;
   105.7 -import netscape.javascript.JSObject;
   105.8 +import jdk.nashorn.api.scripting.JSObject;
   105.9  
  105.10  /**
  105.11   * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well
   106.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Thu May 30 10:58:35 2013 -0700
   106.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Mon Jun 03 23:24:36 2013 -0700
   106.3 @@ -310,7 +310,34 @@
   106.4                  Type.getMethodDescriptor(Type.VOID_TYPE), null, null));
   106.5  
   106.6          mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getClassOverrides", GET_CLASS_INITIALIZER_DESCRIPTOR);
   106.7 -        // Assign MethodHandle fields through invoking getHandle()
   106.8 +        final Label initGlobal;
   106.9 +        if(samName != null) {
  106.10 +            // If the class is a SAM, allow having a ScriptFunction passed as class overrides
  106.11 +            final Label notAFunction = new Label();
  106.12 +            mv.dup();
  106.13 +            mv.instanceOf(SCRIPT_FUNCTION_TYPE);
  106.14 +            mv.ifeq(notAFunction);
  106.15 +            mv.checkcast(SCRIPT_FUNCTION_TYPE);
  106.16 +
  106.17 +            // Assign MethodHandle fields through invoking getHandle() for a ScriptFunction, only assigning the SAM
  106.18 +            // method(s).
  106.19 +            for (final MethodInfo mi : methodInfos) {
  106.20 +                if(mi.getName().equals(samName)) {
  106.21 +                    mv.dup();
  106.22 +                    mv.aconst(Type.getMethodType(mi.type.toMethodDescriptorString()));
  106.23 +                    mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", GET_HANDLE_FUNCTION_DESCRIPTOR);
  106.24 +                } else {
  106.25 +                    mv.visitInsn(ACONST_NULL);
  106.26 +                }
  106.27 +                mv.putstatic(generatedClassName, mi.methodHandleClassFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  106.28 +            }
  106.29 +            initGlobal = new Label();
  106.30 +            mv.goTo(initGlobal);
  106.31 +            mv.visitLabel(notAFunction);
  106.32 +        } else {
  106.33 +            initGlobal = null;
  106.34 +        }
  106.35 +        // Assign MethodHandle fields through invoking getHandle() for a ScriptObject
  106.36          for (final MethodInfo mi : methodInfos) {
  106.37              mv.dup();
  106.38              mv.aconst(mi.getName());
  106.39 @@ -319,6 +346,9 @@
  106.40              mv.putstatic(generatedClassName, mi.methodHandleClassFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  106.41          }
  106.42  
  106.43 +        if(initGlobal != null) {
  106.44 +            mv.visitLabel(initGlobal);
  106.45 +        }
  106.46          // Assign "staticGlobal = Context.getGlobal()"
  106.47          invokeGetGlobalWithNullCheck(mv);
  106.48          mv.putstatic(generatedClassName, STATIC_GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
   107.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Thu May 30 10:58:35 2013 -0700
   107.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Mon Jun 03 23:24:36 2013 -0700
   107.3 @@ -43,6 +43,7 @@
   107.4  import java.security.PrivilegedAction;
   107.5  import java.security.ProtectionDomain;
   107.6  import java.security.SecureClassLoader;
   107.7 +
   107.8  import jdk.internal.dynalink.beans.StaticClass;
   107.9  import jdk.internal.org.objectweb.asm.ClassWriter;
  107.10  import jdk.internal.org.objectweb.asm.Opcodes;
  107.11 @@ -58,6 +59,7 @@
  107.12   * "class loader", it does not, in fact, extend {@code ClassLoader}, but rather uses them internally. Instances of this
  107.13   * class are normally created by {@link JavaAdapterBytecodeGenerator}.
  107.14   */
  107.15 +@SuppressWarnings("javadoc")
  107.16  class JavaAdapterClassLoader extends JavaAdapterGeneratorBase {
  107.17      private static final Type PRIVILEGED_ACTION_TYPE = Type.getType(PrivilegedAction.class);
  107.18  
   108.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Thu May 30 10:58:35 2013 -0700
   108.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Mon Jun 03 23:24:36 2013 -0700
   108.3 @@ -39,6 +39,7 @@
   108.4  import java.util.HashMap;
   108.5  import java.util.List;
   108.6  import java.util.Map;
   108.7 +
   108.8  import jdk.internal.dynalink.beans.StaticClass;
   108.9  import jdk.internal.dynalink.support.LinkRequestImpl;
  108.10  import jdk.nashorn.internal.objects.NativeJava;
  108.11 @@ -66,6 +67,7 @@
  108.12   * </p>
  108.13   */
  108.14  
  108.15 +@SuppressWarnings("javadoc")
  108.16  public final class JavaAdapterFactory {
  108.17      /**
  108.18       * A mapping from an original Class object to AdapterInfo representing the adapter for the class it represents.
   109.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterGeneratorBase.java	Thu May 30 10:58:35 2013 -0700
   109.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterGeneratorBase.java	Mon Jun 03 23:24:36 2013 -0700
   109.3 @@ -33,6 +33,7 @@
   109.4   * Base class for both {@link JavaAdapterBytecodeGenerator} and {@link JavaAdapterClassLoader}, containing those
   109.5   * bytecode types, type names and method descriptor that are used by both.
   109.6   */
   109.7 +@SuppressWarnings("javadoc")
   109.8  abstract class JavaAdapterGeneratorBase {
   109.9      static final Type CONTEXT_TYPE       = Type.getType(Context.class);
  109.10      static final Type OBJECT_TYPE        = Type.getType(Object.class);
   110.1 --- a/src/jdk/nashorn/internal/runtime/options/Option.java	Thu May 30 10:58:35 2013 -0700
   110.2 +++ b/src/jdk/nashorn/internal/runtime/options/Option.java	Mon Jun 03 23:24:36 2013 -0700
   110.3 @@ -42,10 +42,6 @@
   110.4         this.value = value;
   110.5      }
   110.6  
   110.7 -    void setValue(final T value) {
   110.8 -        this.value = value;
   110.9 -    }
  110.10 -
  110.11      /**
  110.12       * Return the value of an option
  110.13       * @return the option value
   111.1 --- a/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java	Thu May 30 10:58:35 2013 -0700
   111.2 +++ b/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java	Mon Jun 03 23:24:36 2013 -0700
   111.3 @@ -25,6 +25,7 @@
   111.4  
   111.5  package jdk.nashorn.internal.runtime.options;
   111.6  
   111.7 +import java.util.Locale;
   111.8  import java.util.TimeZone;
   111.9  import jdk.nashorn.internal.runtime.QuotedStringTokenizer;
  111.10  
  111.11 @@ -151,6 +152,9 @@
  111.12          case "timezone":
  111.13              this.defaultValue = TimeZone.getDefault().getID();
  111.14              break;
  111.15 +        case "locale":
  111.16 +            this.defaultValue = Locale.getDefault().toLanguageTag();
  111.17 +            break;
  111.18          default:
  111.19              break;
  111.20          }
  111.21 @@ -263,7 +267,7 @@
  111.22                      this.params = arg;
  111.23                      break;
  111.24                  case "type":
  111.25 -                    this.type = arg.toLowerCase();
  111.26 +                    this.type = arg.toLowerCase(Locale.ENGLISH);
  111.27                      break;
  111.28                  case "default":
  111.29                      this.defaultValue = arg;
   112.1 --- a/src/jdk/nashorn/internal/runtime/options/Options.java	Thu May 30 10:58:35 2013 -0700
   112.2 +++ b/src/jdk/nashorn/internal/runtime/options/Options.java	Mon Jun 03 23:24:36 2013 -0700
   112.3 @@ -499,10 +499,10 @@
   112.4          case "timezone":
   112.5              // default value "TimeZone.getDefault()"
   112.6              return new Option<>(TimeZone.getTimeZone(value));
   112.7 +        case "locale":
   112.8 +            return new Option<>(Locale.forLanguageTag(value));
   112.9          case "keyvalues":
  112.10              return new KeyValueOption(value);
  112.11 -        case "values":
  112.12 -            return new ValueOption(value);
  112.13          case "log":
  112.14              final KeyValueOption kv = new KeyValueOption(value);
  112.15              Logging.initialize(kv.getValues());
   113.1 --- a/src/jdk/nashorn/internal/runtime/options/ValueOption.java	Thu May 30 10:58:35 2013 -0700
   113.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   113.3 @@ -1,59 +0,0 @@
   113.4 -/*
   113.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   113.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   113.7 - *
   113.8 - * This code is free software; you can redistribute it and/or modify it
   113.9 - * under the terms of the GNU General Public License version 2 only, as
  113.10 - * published by the Free Software Foundation.  Oracle designates this
  113.11 - * particular file as subject to the "Classpath" exception as provided
  113.12 - * by Oracle in the LICENSE file that accompanied this code.
  113.13 - *
  113.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
  113.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  113.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  113.17 - * version 2 for more details (a copy is included in the LICENSE file that
  113.18 - * accompanied this code).
  113.19 - *
  113.20 - * You should have received a copy of the GNU General Public License version
  113.21 - * 2 along with this work; if not, write to the Free Software Foundation,
  113.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  113.23 - *
  113.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  113.25 - * or visit www.oracle.com if you need additional information or have any
  113.26 - * questions.
  113.27 - */
  113.28 -
  113.29 -package jdk.nashorn.internal.runtime.options;
  113.30 -
  113.31 -import java.util.Collection;
  113.32 -import java.util.Collections;
  113.33 -import java.util.LinkedHashSet;
  113.34 -import java.util.StringTokenizer;
  113.35 -
  113.36 -/**
  113.37 - * This option represents a collection of comma separated values
  113.38 - */
  113.39 -public class ValueOption extends Option<String> {
  113.40 -
  113.41 -    private Collection<String> values;
  113.42 -
  113.43 -    ValueOption(final String value) {
  113.44 -        super(value);
  113.45 -        if (value != null) {
  113.46 -            values = new LinkedHashSet<>();
  113.47 -            final StringTokenizer st = new StringTokenizer(getValue(), ",");
  113.48 -            while (st.hasMoreElements()) {
  113.49 -                values.add(st.nextToken());
  113.50 -            }
  113.51 -        }
  113.52 -    }
  113.53 -
  113.54 -    /**
  113.55 -     * Get the values in the option
  113.56 -     * @return collection of strings
  113.57 -     */
  113.58 -    public Collection<String> getValues() {
  113.59 -        return Collections.unmodifiableCollection(values);
  113.60 -    }
  113.61 -
  113.62 -}
   114.1 --- a/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java	Thu May 30 10:58:35 2013 -0700
   114.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   114.3 @@ -1,163 +0,0 @@
   114.4 -/*
   114.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   114.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   114.7 - *
   114.8 - * This code is free software; you can redistribute it and/or modify it
   114.9 - * under the terms of the GNU General Public License version 2 only, as
  114.10 - * published by the Free Software Foundation.  Oracle designates this
  114.11 - * particular file as subject to the "Classpath" exception as provided
  114.12 - * by Oracle in the LICENSE file that accompanied this code.
  114.13 - *
  114.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
  114.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  114.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  114.17 - * version 2 for more details (a copy is included in the LICENSE file that
  114.18 - * accompanied this code).
  114.19 - *
  114.20 - * You should have received a copy of the GNU General Public License version
  114.21 - * 2 along with this work; if not, write to the Free Software Foundation,
  114.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  114.23 - *
  114.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  114.25 - * or visit www.oracle.com if you need additional information or have any
  114.26 - * questions.
  114.27 - */
  114.28 -
  114.29 -package jdk.nashorn.internal.runtime.regexp;
  114.30 -
  114.31 -import jdk.nashorn.internal.runtime.ParserException;
  114.32 -
  114.33 -import static java.util.regex.Pattern.CASE_INSENSITIVE;
  114.34 -import static java.util.regex.Pattern.MULTILINE;
  114.35 -import static java.util.regex.Pattern.UNICODE_CASE;
  114.36 -
  114.37 -import java.util.regex.Matcher;
  114.38 -import java.util.regex.Pattern;
  114.39 -import java.util.regex.PatternSyntaxException;
  114.40 -
  114.41 -/**
  114.42 - * Default regular expression implementation based on java.util.regex package.
  114.43 - *
  114.44 - * Note that this class is not thread-safe as it stores the current match result
  114.45 - * and the string being matched in instance fields.
  114.46 - */
  114.47 -public class DefaultRegExp extends RegExp {
  114.48 -
  114.49 -    /** Java regexp pattern to use for match. We compile to one of these */
  114.50 -    private Pattern pattern;
  114.51 -
  114.52 -    /** The matcher */
  114.53 -    private RegExpMatcher matcher;
  114.54 -
  114.55 -    /**
  114.56 -     * Construct a Regular expression from the given {@code source} and {@code flags} strings.
  114.57 -     *
  114.58 -     * @param source RegExp source string
  114.59 -     * @param flags RegExp flag string
  114.60 -     * @throws ParserException if flags is invalid or source string has syntax error.
  114.61 -     */
  114.62 -    public DefaultRegExp(final String source, final String flags) throws ParserException {
  114.63 -        super(source, flags);
  114.64 -
  114.65 -        int intFlags = 0;
  114.66 -
  114.67 -        if (isIgnoreCase()) {
  114.68 -            intFlags |= CASE_INSENSITIVE | UNICODE_CASE;
  114.69 -        }
  114.70 -        if (isMultiline()) {
  114.71 -            intFlags |= MULTILINE;
  114.72 -        }
  114.73 -
  114.74 -        try {
  114.75 -            RegExpScanner parsed;
  114.76 -
  114.77 -            try {
  114.78 -                parsed = RegExpScanner.scan(source);
  114.79 -            } catch (final PatternSyntaxException e) {
  114.80 -                // refine the exception with a better syntax error, if this
  114.81 -                // passes, just rethrow what we have
  114.82 -                Pattern.compile(source, intFlags);
  114.83 -                throw e;
  114.84 -            }
  114.85 -
  114.86 -            if (parsed != null) {
  114.87 -                this.pattern = Pattern.compile(parsed.getJavaPattern(), intFlags);
  114.88 -                this.groupsInNegativeLookahead = parsed.getGroupsInNegativeLookahead();
  114.89 -            }
  114.90 -        } catch (final PatternSyntaxException e2) {
  114.91 -            throwParserException("syntax", e2.getMessage());
  114.92 -        }
  114.93 -    }
  114.94 -
  114.95 -    @Override
  114.96 -    public RegExpMatcher match(final String str) {
  114.97 -        if (pattern == null) {
  114.98 -            return null; // never matches or similar, e.g. a[]
  114.99 -        }
 114.100 -
 114.101 -        RegExpMatcher currentMatcher = this.matcher;
 114.102 -
 114.103 -        if (currentMatcher == null || matcher.getInput() != str) {
 114.104 -            currentMatcher = new DefaultMatcher(str);
 114.105 -            this.matcher  = currentMatcher;
 114.106 -        }
 114.107 -
 114.108 -        return currentMatcher;
 114.109 -    }
 114.110 -
 114.111 -    class DefaultMatcher implements RegExpMatcher {
 114.112 -        final String input;
 114.113 -        final Matcher defaultMatcher;
 114.114 -
 114.115 -        DefaultMatcher(final String input) {
 114.116 -            this.input = input;
 114.117 -            this.defaultMatcher = pattern.matcher(input);
 114.118 -        }
 114.119 -
 114.120 -        @Override
 114.121 -        public boolean search(final int start) {
 114.122 -            return defaultMatcher.find(start);
 114.123 -        }
 114.124 -
 114.125 -        @Override
 114.126 -        public String getInput() {
 114.127 -            return input;
 114.128 -        }
 114.129 -
 114.130 -        @Override
 114.131 -        public int start() {
 114.132 -            return defaultMatcher.start();
 114.133 -        }
 114.134 -
 114.135 -        @Override
 114.136 -        public int start(final int group) {
 114.137 -            return defaultMatcher.start(group);
 114.138 -        }
 114.139 -
 114.140 -        @Override
 114.141 -        public int end() {
 114.142 -            return defaultMatcher.end();
 114.143 -        }
 114.144 -
 114.145 -        @Override
 114.146 -        public int end(final int group) {
 114.147 -            return defaultMatcher.end(group);
 114.148 -        }
 114.149 -
 114.150 -        @Override
 114.151 -        public String group() {
 114.152 -            return defaultMatcher.group();
 114.153 -        }
 114.154 -
 114.155 -        @Override
 114.156 -        public String group(final int group) {
 114.157 -            return defaultMatcher.group(group);
 114.158 -        }
 114.159 -
 114.160 -        @Override
 114.161 -        public int groupCount() {
 114.162 -            return defaultMatcher.groupCount();
 114.163 -        }
 114.164 -    }
 114.165 -
 114.166 -}
   115.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   115.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/JdkRegExp.java	Mon Jun 03 23:24:36 2013 -0700
   115.3 @@ -0,0 +1,163 @@
   115.4 +/*
   115.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   115.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   115.7 + *
   115.8 + * This code is free software; you can redistribute it and/or modify it
   115.9 + * under the terms of the GNU General Public License version 2 only, as
  115.10 + * published by the Free Software Foundation.  Oracle designates this
  115.11 + * particular file as subject to the "Classpath" exception as provided
  115.12 + * by Oracle in the LICENSE file that accompanied this code.
  115.13 + *
  115.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
  115.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  115.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  115.17 + * version 2 for more details (a copy is included in the LICENSE file that
  115.18 + * accompanied this code).
  115.19 + *
  115.20 + * You should have received a copy of the GNU General Public License version
  115.21 + * 2 along with this work; if not, write to the Free Software Foundation,
  115.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  115.23 + *
  115.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  115.25 + * or visit www.oracle.com if you need additional information or have any
  115.26 + * questions.
  115.27 + */
  115.28 +
  115.29 +package jdk.nashorn.internal.runtime.regexp;
  115.30 +
  115.31 +import jdk.nashorn.internal.runtime.ParserException;
  115.32 +
  115.33 +import static java.util.regex.Pattern.CASE_INSENSITIVE;
  115.34 +import static java.util.regex.Pattern.MULTILINE;
  115.35 +import static java.util.regex.Pattern.UNICODE_CASE;
  115.36 +
  115.37 +import java.util.regex.Matcher;
  115.38 +import java.util.regex.Pattern;
  115.39 +import java.util.regex.PatternSyntaxException;
  115.40 +
  115.41 +/**
  115.42 + * Default regular expression implementation based on java.util.regex package.
  115.43 + *
  115.44 + * Note that this class is not thread-safe as it stores the current match result
  115.45 + * and the string being matched in instance fields.
  115.46 + */
  115.47 +public class JdkRegExp extends RegExp {
  115.48 +
  115.49 +    /** Java regexp pattern to use for match. We compile to one of these */
  115.50 +    private Pattern pattern;
  115.51 +
  115.52 +    /** The matcher */
  115.53 +    private RegExpMatcher matcher;
  115.54 +
  115.55 +    /**
  115.56 +     * Construct a Regular expression from the given {@code source} and {@code flags} strings.
  115.57 +     *
  115.58 +     * @param source RegExp source string
  115.59 +     * @param flags RegExp flag string
  115.60 +     * @throws ParserException if flags is invalid or source string has syntax error.
  115.61 +     */
  115.62 +    public JdkRegExp(final String source, final String flags) throws ParserException {
  115.63 +        super(source, flags);
  115.64 +
  115.65 +        int intFlags = 0;
  115.66 +
  115.67 +        if (isIgnoreCase()) {
  115.68 +            intFlags |= CASE_INSENSITIVE | UNICODE_CASE;
  115.69 +        }
  115.70 +        if (isMultiline()) {
  115.71 +            intFlags |= MULTILINE;
  115.72 +        }
  115.73 +
  115.74 +        try {
  115.75 +            RegExpScanner parsed;
  115.76 +
  115.77 +            try {
  115.78 +                parsed = RegExpScanner.scan(source);
  115.79 +            } catch (final PatternSyntaxException e) {
  115.80 +                // refine the exception with a better syntax error, if this
  115.81 +                // passes, just rethrow what we have
  115.82 +                Pattern.compile(source, intFlags);
  115.83 +                throw e;
  115.84 +            }
  115.85 +
  115.86 +            if (parsed != null) {
  115.87 +                this.pattern = Pattern.compile(parsed.getJavaPattern(), intFlags);
  115.88 +                this.groupsInNegativeLookahead = parsed.getGroupsInNegativeLookahead();
  115.89 +            }
  115.90 +        } catch (final PatternSyntaxException e2) {
  115.91 +            throwParserException("syntax", e2.getMessage());
  115.92 +        }
  115.93 +    }
  115.94 +
  115.95 +    @Override
  115.96 +    public RegExpMatcher match(final String str) {
  115.97 +        if (pattern == null) {
  115.98 +            return null; // never matches or similar, e.g. a[]
  115.99 +        }
 115.100 +
 115.101 +        RegExpMatcher currentMatcher = this.matcher;
 115.102 +
 115.103 +        if (currentMatcher == null || matcher.getInput() != str) {
 115.104 +            currentMatcher = new DefaultMatcher(str);
 115.105 +            this.matcher  = currentMatcher;
 115.106 +        }
 115.107 +
 115.108 +        return currentMatcher;
 115.109 +    }
 115.110 +
 115.111 +    class DefaultMatcher implements RegExpMatcher {
 115.112 +        final String input;
 115.113 +        final Matcher defaultMatcher;
 115.114 +
 115.115 +        DefaultMatcher(final String input) {
 115.116 +            this.input = input;
 115.117 +            this.defaultMatcher = pattern.matcher(input);
 115.118 +        }
 115.119 +
 115.120 +        @Override
 115.121 +        public boolean search(final int start) {
 115.122 +            return defaultMatcher.find(start);
 115.123 +        }
 115.124 +
 115.125 +        @Override
 115.126 +        public String getInput() {
 115.127 +            return input;
 115.128 +        }
 115.129 +
 115.130 +        @Override
 115.131 +        public int start() {
 115.132 +            return defaultMatcher.start();
 115.133 +        }
 115.134 +
 115.135 +        @Override
 115.136 +        public int start(final int group) {
 115.137 +            return defaultMatcher.start(group);
 115.138 +        }
 115.139 +
 115.140 +        @Override
 115.141 +        public int end() {
 115.142 +            return defaultMatcher.end();
 115.143 +        }
 115.144 +
 115.145 +        @Override
 115.146 +        public int end(final int group) {
 115.147 +            return defaultMatcher.end(group);
 115.148 +        }
 115.149 +
 115.150 +        @Override
 115.151 +        public String group() {
 115.152 +            return defaultMatcher.group();
 115.153 +        }
 115.154 +
 115.155 +        @Override
 115.156 +        public String group(final int group) {
 115.157 +            return defaultMatcher.group(group);
 115.158 +        }
 115.159 +
 115.160 +        @Override
 115.161 +        public int groupCount() {
 115.162 +            return defaultMatcher.groupCount();
 115.163 +        }
 115.164 +    }
 115.165 +
 115.166 +}
   116.1 --- a/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java	Thu May 30 10:58:35 2013 -0700
   116.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java	Mon Jun 03 23:24:36 2013 -0700
   116.3 @@ -113,7 +113,7 @@
   116.4      public static class Factory extends RegExpFactory {
   116.5  
   116.6          @Override
   116.7 -        protected RegExp compile(final String pattern, final String flags) throws ParserException {
   116.8 +        public RegExp compile(final String pattern, final String flags) throws ParserException {
   116.9              return new JoniRegExp(pattern, flags);
  116.10          }
  116.11  
   117.1 --- a/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java	Thu May 30 10:58:35 2013 -0700
   117.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java	Mon Jun 03 23:24:36 2013 -0700
   117.3 @@ -29,7 +29,7 @@
   117.4  import jdk.nashorn.internal.runtime.options.Options;
   117.5  
   117.6  /**
   117.7 - * Factory class for regular expressions. This class creates instances of {@link DefaultRegExp}.
   117.8 + * Factory class for regular expressions. This class creates instances of {@link JdkRegExp}.
   117.9   * An alternative factory can be installed using the {@code nashorn.regexp.impl} system property.
  117.10   */
  117.11  public class RegExpFactory {
  117.12 @@ -62,8 +62,8 @@
  117.13       * @return new RegExp
  117.14       * @throws ParserException if flags is invalid or pattern string has syntax error.
  117.15       */
  117.16 -    protected RegExp compile(final String pattern, final String flags) throws ParserException {
  117.17 -        return new DefaultRegExp(pattern, flags);
  117.18 +    public RegExp compile(final String pattern, final String flags) throws ParserException {
  117.19 +        return new JdkRegExp(pattern, flags);
  117.20      }
  117.21  
  117.22      /**
   118.1 --- a/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java	Thu May 30 10:58:35 2013 -0700
   118.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java	Mon Jun 03 23:24:36 2013 -0700
   118.3 @@ -868,6 +868,9 @@
   118.4       *      \ ClassEscape
   118.5       */
   118.6      private boolean classAtomNoDash() {
   118.7 +        if (atEOF()) {
   118.8 +            return false;
   118.9 +        }
  118.10          final int startIn  = position;
  118.11          final int startOut = sb.length();
  118.12  
   119.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java	Thu May 30 10:58:35 2013 -0700
   119.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java	Mon Jun 03 23:24:36 2013 -0700
   119.3 @@ -21,10 +21,7 @@
   119.4  
   119.5  import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAll;
   119.6  import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
   119.7 -import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsClear;
   119.8  import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAt;
   119.9 -import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAtSimple;
  119.10 -import static jdk.nashorn.internal.runtime.regexp.joni.Option.isCaptureGroup;
  119.11  import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindCondition;
  119.12  import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase;
  119.13  import static jdk.nashorn.internal.runtime.regexp.joni.Option.isMultiline;
  119.14 @@ -36,8 +33,6 @@
  119.15  import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
  119.16  import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
  119.17  import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
  119.18 -import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
  119.19 -import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
  119.20  import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
  119.21  import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
  119.22  import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
  119.23 @@ -49,9 +44,7 @@
  119.24  import jdk.nashorn.internal.runtime.regexp.joni.constants.RegexState;
  119.25  import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
  119.26  import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
  119.27 -import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
  119.28  import jdk.nashorn.internal.runtime.regexp.joni.encoding.ObjPtr;
  119.29 -import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
  119.30  
  119.31  final class Analyser extends Parser {
  119.32  
  119.33 @@ -74,38 +67,9 @@
  119.34          //regex.repeatRangeAlloc = 0;
  119.35          regex.repeatRangeLo = null;
  119.36          regex.repeatRangeHi = null;
  119.37 -        regex.numCombExpCheck = 0;
  119.38 -
  119.39 -        if (Config.USE_COMBINATION_EXPLOSION_CHECK) regex.numCombExpCheck = 0;
  119.40  
  119.41          parse();
  119.42  
  119.43 -        if (Config.USE_NAMED_GROUP) {
  119.44 -            /* mixed use named group and no-named group */
  119.45 -            if (env.numNamed > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(regex.options)) {
  119.46 -                if (env.numNamed != env.numMem) {
  119.47 -                    root = disableNoNameGroupCapture(root);
  119.48 -                } else {
  119.49 -                    numberedRefCheck(root);
  119.50 -                }
  119.51 -            }
  119.52 -        } // USE_NAMED_GROUP
  119.53 -
  119.54 -        if (Config.USE_NAMED_GROUP) {
  119.55 -            if (env.numCall > 0) {
  119.56 -                env.unsetAddrList = new UnsetAddrList(env.numCall);
  119.57 -                setupSubExpCall(root);
  119.58 -                // r != 0 ???
  119.59 -                subexpRecursiveCheckTrav(root);
  119.60 -                // r < 0 -< err, FOUND_CALLED_NODE = 1
  119.61 -                subexpInfRecursiveCheckTrav(root);
  119.62 -                // r != 0  recursion infinite ???
  119.63 -                regex.numCall = env.numCall;
  119.64 -            } else {
  119.65 -                regex.numCall = 0;
  119.66 -            }
  119.67 -        } // USE_NAMED_GROUP
  119.68 -
  119.69          if (Config.DEBUG_PARSE_TREE_RAW && Config.DEBUG_PARSE_TREE) {
  119.70              Config.log.println("<RAW TREE>");
  119.71              Config.log.println(root + "\n");
  119.72 @@ -129,27 +93,6 @@
  119.73              regex.btMemEnd |= regex.captureHistory;
  119.74          }
  119.75  
  119.76 -        if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
  119.77 -            if (env.backrefedMem == 0 || (Config.USE_SUBEXP_CALL && env.numCall == 0)) {
  119.78 -                setupCombExpCheck(root, 0);
  119.79 -
  119.80 -                if (Config.USE_SUBEXP_CALL && env.hasRecursion) {
  119.81 -                    env.numCombExpCheck = 0;
  119.82 -                } else { // USE_SUBEXP_CALL
  119.83 -                    if (env.combExpMaxRegNum > 0) {
  119.84 -                        for (int i=1; i<env.combExpMaxRegNum; i++) {
  119.85 -                            if (bsAt(env.backrefedMem, i)) {
  119.86 -                                env.numCombExpCheck = 0;
  119.87 -                                break;
  119.88 -                            }
  119.89 -                        }
  119.90 -                    }
  119.91 -                }
  119.92 -
  119.93 -            } // USE_SUBEXP_CALL
  119.94 -            regex.numCombExpCheck = env.numCombExpCheck;
  119.95 -        } // USE_COMBINATION_EXPLOSION_CHECK
  119.96 -
  119.97          regex.clearOptimizeInfo();
  119.98  
  119.99          if (!Config.DONT_OPTIMIZE) setOptimizedInfoFromTree(root);
 119.100 @@ -167,7 +110,6 @@
 119.101          }
 119.102  
 119.103          if (Config.DEBUG_COMPILE) {
 119.104 -            if (Config.USE_NAMED_GROUP) Config.log.print(regex.nameTableToString());
 119.105              Config.log.println("stack used: " + regex.stackNeeded);
 119.106              if (Config.USE_STRING_TEMPLATES) Config.log.print("templates: " + regex.templateNum + "\n");
 119.107              Config.log.println(new ByteCodePrinter(regex).byteCodeListToString());
 119.108 @@ -177,157 +119,6 @@
 119.109          regex.state = RegexState.NORMAL;
 119.110      }
 119.111  
 119.112 -    private void noNameDisableMapFor_cosAlt(Node node, int[]map, Ptr counter) {
 119.113 -        ConsAltNode can = (ConsAltNode)node;
 119.114 -        do {
 119.115 -            can.setCar(noNameDisableMap(can.car, map, counter));
 119.116 -        } while ((can = can.cdr) != null);
 119.117 -    }
 119.118 -
 119.119 -    private void noNameDisableMapFor_quantifier(Node node, int[]map, Ptr counter) {
 119.120 -        QuantifierNode qn = (QuantifierNode)node;
 119.121 -        Node target = qn.target;
 119.122 -        Node old = target;
 119.123 -        target = noNameDisableMap(target, map, counter);
 119.124 -
 119.125 -        if (target != old) {
 119.126 -            qn.setTarget(target);
 119.127 -            if (target.getType() == NodeType.QTFR) qn.reduceNestedQuantifier((QuantifierNode)target);
 119.128 -        }
 119.129 -    }
 119.130 -
 119.131 -    private Node noNameDisableMapFor_enclose(Node node, int[]map, Ptr counter) {
 119.132 -        EncloseNode en = (EncloseNode)node;
 119.133 -        if (en.type == EncloseType.MEMORY) {
 119.134 -            if (en.isNamedGroup()) {
 119.135 -                counter.p++;
 119.136 -                map[en.regNum] = counter.p;
 119.137 -                en.regNum = counter.p;
 119.138 -                //en.target = noNameDisableMap(en.target, map, counter);
 119.139 -                en.setTarget(noNameDisableMap(en.target, map, counter)); // ???
 119.140 -            } else {
 119.141 -                node = en.target;
 119.142 -                en.target = null; // remove first enclose: /(a)(?<b>c)/
 119.143 -                node = noNameDisableMap(node, map, counter);
 119.144 -            }
 119.145 -        } else {
 119.146 -            //en.target = noNameDisableMap(en.target, map, counter);
 119.147 -            en.setTarget(noNameDisableMap(en.target, map, counter)); // ???
 119.148 -        }
 119.149 -        return node;
 119.150 -    }
 119.151 -
 119.152 -    private void noNameDisableMapFor_anchor(Node node, int[]map, Ptr counter) {
 119.153 -        AnchorNode an = (AnchorNode)node;
 119.154 -        switch (an.type) {
 119.155 -            case AnchorNode.PREC_READ:
 119.156 -            case AnchorNode.PREC_READ_NOT:
 119.157 -            case AnchorNode.LOOK_BEHIND:
 119.158 -            case AnchorNode.LOOK_BEHIND_NOT:
 119.159 -                an.setTarget(noNameDisableMap(an.target, map, counter));
 119.160 -        }
 119.161 -    }
 119.162 -
 119.163 -    private Node noNameDisableMap(Node node, int[]map, Ptr counter) {
 119.164 -        switch (node.getType()) {
 119.165 -        case NodeType.LIST:
 119.166 -        case NodeType.ALT:
 119.167 -            noNameDisableMapFor_cosAlt(node, map, counter);
 119.168 -            break;
 119.169 -        case NodeType.QTFR:
 119.170 -            noNameDisableMapFor_quantifier(node, map, counter);
 119.171 -            break;
 119.172 -        case NodeType.ENCLOSE:
 119.173 -            node = noNameDisableMapFor_enclose(node, map, counter);
 119.174 -            break;
 119.175 -        case NodeType.ANCHOR:
 119.176 -            noNameDisableMapFor_anchor(node, map, counter);
 119.177 -            break;
 119.178 -        } // switch
 119.179 -        return node;
 119.180 -    }
 119.181 -
 119.182 -    private void renumberByMap(Node node, int[]map) {
 119.183 -        switch (node.getType()) {
 119.184 -        case NodeType.LIST:
 119.185 -        case NodeType.ALT:
 119.186 -            ConsAltNode can = (ConsAltNode)node;
 119.187 -            do {
 119.188 -                renumberByMap(can.car, map);
 119.189 -            } while ((can = can.cdr) != null);
 119.190 -            break;
 119.191 -
 119.192 -        case NodeType.QTFR:
 119.193 -            renumberByMap(((QuantifierNode)node).target, map);
 119.194 -            break;
 119.195 -
 119.196 -        case NodeType.ENCLOSE:
 119.197 -            renumberByMap(((EncloseNode)node).target, map);
 119.198 -            break;
 119.199 -
 119.200 -        case NodeType.BREF:
 119.201 -            ((BackRefNode)node).renumber(map);
 119.202 -            break;
 119.203 -        } // switch
 119.204 -    }
 119.205 -
 119.206 -    protected final void numberedRefCheck(Node node) {
 119.207 -        switch (node.getType()) {
 119.208 -        case NodeType.LIST:
 119.209 -        case NodeType.ALT:
 119.210 -            ConsAltNode can = (ConsAltNode)node;
 119.211 -            do {
 119.212 -                numberedRefCheck(can.car);
 119.213 -            } while ((can = can.cdr) != null);
 119.214 -            break;
 119.215 -
 119.216 -        case NodeType.QTFR:
 119.217 -            numberedRefCheck(((QuantifierNode)node).target);
 119.218 -            break;
 119.219 -
 119.220 -        case NodeType.ENCLOSE:
 119.221 -            numberedRefCheck(((EncloseNode)node).target);
 119.222 -            break;
 119.223 -
 119.224 -        case NodeType.BREF:
 119.225 -            BackRefNode br = (BackRefNode)node;
 119.226 -            if (!br.isNameRef()) newValueException(ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
 119.227 -            break;
 119.228 -        } // switch
 119.229 -    }
 119.230 -
 119.231 -    protected final Node disableNoNameGroupCapture(Node root) {
 119.232 -        int[]map = new int[env.numMem + 1];
 119.233 -
 119.234 -        for (int i=1; i<=env.numMem; i++) map[i] = 0;
 119.235 -
 119.236 -        root = noNameDisableMap(root, map, new Ptr(0));
 119.237 -        renumberByMap(root, map);
 119.238 -
 119.239 -        for (int i=1, pos=1; i<=env.numMem; i++) {
 119.240 -            if (map[i] > 0) {
 119.241 -                env.memNodes[pos] = env.memNodes[i];
 119.242 -                pos++;
 119.243 -            }
 119.244 -        }
 119.245 -
 119.246 -        int loc = env.captureHistory;
 119.247 -        env.captureHistory = bsClear();
 119.248 -
 119.249 -        for (int i=1; i<=Config.MAX_CAPTURE_HISTORY_GROUP; i++) {
 119.250 -            if (bsAt(loc, i)) {
 119.251 -                env.captureHistory = bsOnAtSimple(env.captureHistory, map[i]);
 119.252 -            }
 119.253 -        }
 119.254 -
 119.255 -        env.numMem = env.numNamed;
 119.256 -        regex.numMem = env.numNamed;
 119.257 -
 119.258 -        regex.renumberNameTable(map);
 119.259 -
 119.260 -        return root;
 119.261 -    }
 119.262 -
 119.263      private void swap(Node a, Node b) {
 119.264          a.swap(b);
 119.265  
 119.266 @@ -352,17 +143,6 @@
 119.267              } while ((can = can.cdr) != null);
 119.268              break;
 119.269  
 119.270 -        case NodeType.CALL:
 119.271 -            if (Config.USE_SUBEXP_CALL) {
 119.272 -                CallNode cn = (CallNode)node;
 119.273 -                if (cn.isRecursion()) {
 119.274 -                    return TargetInfo.IS_EMPTY_REC; /* tiny version */
 119.275 -                } else {
 119.276 -                    info = quantifiersMemoryInfo(cn.target);
 119.277 -                }
 119.278 -            } // USE_SUBEXP_CALL
 119.279 -            break;
 119.280 -
 119.281          case NodeType.QTFR:
 119.282              QuantifierNode qn = (QuantifierNode)node;
 119.283              if (qn.upper != 0) {
 119.284 @@ -417,18 +197,6 @@
 119.285              }
 119.286              break;
 119.287  
 119.288 -        case NodeType.CALL:
 119.289 -            if (Config.USE_SUBEXP_CALL) {
 119.290 -                CallNode cn = (CallNode)node;
 119.291 -                if (cn.isRecursion()) {
 119.292 -                    EncloseNode en = (EncloseNode)cn.target;
 119.293 -                    if (en.isMinFixed()) min = en.minLength;
 119.294 -                } else {
 119.295 -                    min = getMinMatchLength(cn.target);
 119.296 -                }
 119.297 -            } // USE_SUBEXP_CALL
 119.298 -            break;
 119.299 -
 119.300          case NodeType.LIST:
 119.301              ConsAltNode can = (ConsAltNode)node;
 119.302              do {
 119.303 @@ -474,15 +242,13 @@
 119.304              EncloseNode en = (EncloseNode)node;
 119.305              switch (en.type) {
 119.306              case EncloseType.MEMORY:
 119.307 -                if (Config.USE_SUBEXP_CALL) {
 119.308 -                    if (en.isMinFixed()) {
 119.309 -                        min = en.minLength;
 119.310 -                    } else {
 119.311 -                        min = getMinMatchLength(en.target);
 119.312 -                        en.minLength = min;
 119.313 -                        en.setMinFixed();
 119.314 -                    }
 119.315 -                } // USE_SUBEXP_CALL
 119.316 +                if (en.isMinFixed()) {
 119.317 +                    min = en.minLength;
 119.318 +                } else {
 119.319 +                    min = getMinMatchLength(en.target);
 119.320 +                    en.minLength = min;
 119.321 +                    en.setMinFixed();
 119.322 +                }
 119.323                  break;
 119.324  
 119.325              case EncloseType.OPTION:
 119.326 @@ -547,17 +313,6 @@
 119.327              }
 119.328              break;
 119.329  
 119.330 -        case NodeType.CALL:
 119.331 -            if (Config.USE_SUBEXP_CALL) {
 119.332 -                CallNode cn = (CallNode)node;
 119.333 -                if (!cn.isRecursion()) {
 119.334 -                    max = getMaxMatchLength(cn.target);
 119.335 -                } else {
 119.336 -                    max = MinMaxLen.INFINITE_DISTANCE;
 119.337 -                }
 119.338 -            } // USE_SUBEXP_CALL
 119.339 -            break;
 119.340 -
 119.341          case NodeType.QTFR:
 119.342              QuantifierNode qn = (QuantifierNode)node;
 119.343              if (qn.upper != 0) {
 119.344 @@ -576,15 +331,13 @@
 119.345              EncloseNode en = (EncloseNode)node;
 119.346              switch (en.type) {
 119.347              case EncloseType.MEMORY:
 119.348 -                if (Config.USE_SUBEXP_CALL) {
 119.349 -                    if (en.isMaxFixed()) {
 119.350 -                        max = en.maxLength;
 119.351 -                    } else {
 119.352 -                        max = getMaxMatchLength(en.target);
 119.353 -                        en.maxLength = max;
 119.354 -                        en.setMaxFixed();
 119.355 -                    }
 119.356 -                } // USE_SUBEXP_CALL
 119.357 +                if (en.isMaxFixed()) {
 119.358 +                    max = en.maxLength;
 119.359 +                } else {
 119.360 +                    max = getMaxMatchLength(en.target);
 119.361 +                    en.maxLength = max;
 119.362 +                    en.setMaxFixed();
 119.363 +                }
 119.364                  break;
 119.365  
 119.366              case EncloseType.OPTION:
 119.367 @@ -663,17 +416,6 @@
 119.368              }
 119.369              break;
 119.370  
 119.371 -        case NodeType.CALL:
 119.372 -            if (Config.USE_SUBEXP_CALL) {
 119.373 -                CallNode cn = (CallNode)node;
 119.374 -                if (!cn.isRecursion()) {
 119.375 -                    len = getCharLengthTree(cn.target, level);
 119.376 -                } else {
 119.377 -                    returnCode = GET_CHAR_LEN_VARLEN;
 119.378 -                }
 119.379 -            } // USE_SUBEXP_CALL
 119.380 -            break;
 119.381 -
 119.382          case NodeType.CTYPE:
 119.383              len = 1;
 119.384  
 119.385 @@ -686,17 +428,15 @@
 119.386              EncloseNode en = (EncloseNode)node;
 119.387              switch(en.type) {
 119.388              case EncloseType.MEMORY:
 119.389 -                if (Config.USE_SUBEXP_CALL) {
 119.390 -                    if (en.isCLenFixed()) {
 119.391 -                        len = en.charLength;
 119.392 -                    } else {
 119.393 -                        len = getCharLengthTree(en.target, level);
 119.394 -                        if (returnCode == 0) {
 119.395 -                            en.charLength = len;
 119.396 -                            en.setCLenFixed();
 119.397 -                        }
 119.398 +                if (en.isCLenFixed()) {
 119.399 +                    len = en.charLength;
 119.400 +                } else {
 119.401 +                    len = getCharLengthTree(en.target, level);
 119.402 +                    if (returnCode == 0) {
 119.403 +                        en.charLength = len;
 119.404 +                        en.setCLenFixed();
 119.405                      }
 119.406 -                } // USE_SUBEXP_CALL
 119.407 +                }
 119.408                  break;
 119.409  
 119.410              case EncloseType.OPTION:
 119.411 @@ -727,10 +467,6 @@
 119.412          switch(x.getType()) {
 119.413          case NodeType.CTYPE:
 119.414              switch(yType) {
 119.415 -            case NodeType.CTYPE:
 119.416 -                CTypeNode cny = (CTypeNode)y;
 119.417 -                CTypeNode cnx = (CTypeNode)x;
 119.418 -                return cny.ctype == cnx.ctype && cny.not != cnx.not;
 119.419  
 119.420              case NodeType.CCLASS:
 119.421                  // !swap:!
 119.422 @@ -756,37 +492,6 @@
 119.423              CClassNode xc = (CClassNode)x;
 119.424  
 119.425              switch(yType) {
 119.426 -            case NodeType.CTYPE:
 119.427 -                switch(((CTypeNode)y).ctype) {
 119.428 -                case CharacterType.WORD:
 119.429 -                    if (!((CTypeNode)y).not) {
 119.430 -                        if (xc.mbuf == null && !xc.isNot()) {
 119.431 -                            for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
 119.432 -                                if (xc.bs.at(i)) {
 119.433 -                                    if (EncodingHelper.isWord(i)) return false;
 119.434 -                                }
 119.435 -                            }
 119.436 -                            return true;
 119.437 -                        }
 119.438 -                        return false;
 119.439 -                    } else {
 119.440 -                        for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
 119.441 -                            if (!EncodingHelper.isWord(i)) {
 119.442 -                                if (!xc.isNot()) {
 119.443 -                                    if (xc.bs.at(i)) return false;
 119.444 -                                } else {
 119.445 -                                    if (!xc.bs.at(i)) return false;
 119.446 -                                }
 119.447 -                            }
 119.448 -                        }
 119.449 -                        return true;
 119.450 -                    }
 119.451 -                    // break; not reached
 119.452 -
 119.453 -                default:
 119.454 -                    break;
 119.455 -                } // inner switch
 119.456 -                break;
 119.457  
 119.458              case NodeType.CCLASS:
 119.459                  CClassNode yc = (CClassNode)y;
 119.460 @@ -820,17 +525,6 @@
 119.461              if (xs.length() == 0) break;
 119.462  
 119.463              switch (yType) {
 119.464 -            case NodeType.CTYPE:
 119.465 -                CTypeNode cy = ((CTypeNode)y);
 119.466 -                switch (cy.ctype) {
 119.467 -                case CharacterType.WORD:
 119.468 -                    return !cy.not;
 119.469 -
 119.470 -                default:
 119.471 -                    break;
 119.472 -
 119.473 -                } // inner switch
 119.474 -                break;
 119.475  
 119.476              case NodeType.CCLASS:
 119.477                  CClassNode cc = (CClassNode)y;
 119.478 @@ -873,9 +567,6 @@
 119.479          case NodeType.CANY:
 119.480              break;
 119.481  
 119.482 -        case NodeType.CALL:
 119.483 -            break; // if (Config.USE_SUBEXP_CALL)
 119.484 -
 119.485          case NodeType.CTYPE:
 119.486          case NodeType.CCLASS:
 119.487              if (!exact) n = node;
 119.488 @@ -977,316 +668,6 @@
 119.489          return invalid;
 119.490      }
 119.491  
 119.492 -    private static final int RECURSION_EXIST       = 1;
 119.493 -    private static final int RECURSION_INFINITE    = 2;
 119.494 -    private int subexpInfRecursiveCheck(Node node, boolean head) {
 119.495 -        int r = 0;
 119.496 -
 119.497 -        switch (node.getType()) {
 119.498 -        case NodeType.LIST:
 119.499 -            int min;
 119.500 -            ConsAltNode x = (ConsAltNode)node;
 119.501 -            do {
 119.502 -                int ret = subexpInfRecursiveCheck(x.car, head);
 119.503 -                if (ret == RECURSION_INFINITE) return ret;
 119.504 -                r |= ret;
 119.505 -                if (head) {
 119.506 -                    min = getMinMatchLength(x.car);
 119.507 -                    if (min != 0) head = false;
 119.508 -                }
 119.509 -            } while ((x = x.cdr) != null);
 119.510 -            break;
 119.511 -
 119.512 -        case NodeType.ALT:
 119.513 -            ConsAltNode can = (ConsAltNode)node;
 119.514 -            r = RECURSION_EXIST;
 119.515 -            do {
 119.516 -                int ret = subexpInfRecursiveCheck(can.car, head);
 119.517 -                if (ret == RECURSION_INFINITE) return ret;
 119.518 -                r &= ret;
 119.519 -            } while ((can = can.cdr) != null);
 119.520 -            break;
 119.521 -
 119.522 -        case NodeType.QTFR:
 119.523 -            QuantifierNode qn = (QuantifierNode)node;
 119.524 -            r = subexpInfRecursiveCheck(qn.target, head);
 119.525 -            if (r == RECURSION_EXIST) {
 119.526 -                if (qn.lower == 0) r = 0;
 119.527 -            }
 119.528 -            break;
 119.529 -
 119.530 -        case NodeType.ANCHOR:
 119.531 -            AnchorNode an = (AnchorNode)node;
 119.532 -            switch (an.type) {
 119.533 -            case AnchorType.PREC_READ:
 119.534 -            case AnchorType.PREC_READ_NOT:
 119.535 -            case AnchorType.LOOK_BEHIND:
 119.536 -            case AnchorType.LOOK_BEHIND_NOT:
 119.537 -                r = subexpInfRecursiveCheck(an.target, head);
 119.538 -                break;
 119.539 -            } // inner switch
 119.540 -            break;
 119.541 -
 119.542 -        case NodeType.CALL:
 119.543 -            r = subexpInfRecursiveCheck(((CallNode)node).target, head);
 119.544 -            break;
 119.545 -
 119.546 -        case NodeType.ENCLOSE:
 119.547 -            EncloseNode en = (EncloseNode)node;
 119.548 -            if (en.isMark2()) {
 119.549 -                return 0;
 119.550 -            } else if (en.isMark1()) {
 119.551 -                return !head ? RECURSION_EXIST : RECURSION_INFINITE;
 119.552 -                // throw exception here ???
 119.553 -            } else {
 119.554 -                en.setMark2();
 119.555 -                r = subexpInfRecursiveCheck(en.target, head);
 119.556 -                en.clearMark2();
 119.557 -            }
 119.558 -            break;
 119.559 -
 119.560 -        default:
 119.561 -            break;
 119.562 -        } // switch
 119.563 -        return r;
 119.564 -    }
 119.565 -
 119.566 -    protected final int subexpInfRecursiveCheckTrav(Node node) {
 119.567 -        int r = 0;
 119.568 -
 119.569 -        switch (node.getType()) {
 119.570 -        case NodeType.LIST:
 119.571 -        case NodeType.ALT:
 119.572 -            ConsAltNode can = (ConsAltNode)node;
 119.573 -            do {
 119.574 -                r = subexpInfRecursiveCheckTrav(can.car);
 119.575 -            } while (r == 0 && (can = can.cdr) != null);
 119.576 -            break;
 119.577 -
 119.578 -        case NodeType.QTFR:
 119.579 -            r = subexpInfRecursiveCheckTrav(((QuantifierNode)node).target);
 119.580 -            break;
 119.581 -
 119.582 -        case NodeType.ANCHOR:
 119.583 -            AnchorNode an = (AnchorNode)node;
 119.584 -            switch (an.type) {
 119.585 -            case AnchorType.PREC_READ:
 119.586 -            case AnchorType.PREC_READ_NOT:
 119.587 -            case AnchorType.LOOK_BEHIND:
 119.588 -            case AnchorType.LOOK_BEHIND_NOT:
 119.589 -                r = subexpInfRecursiveCheckTrav(an.target);
 119.590 -                break;
 119.591 -            } // inner switch
 119.592 -            break;
 119.593 -
 119.594 -        case NodeType.ENCLOSE:
 119.595 -            EncloseNode en = (EncloseNode)node;
 119.596 -            if (en.isRecursion()) {
 119.597 -                en.setMark1();
 119.598 -                r = subexpInfRecursiveCheck(en.target, true);
 119.599 -                if (r > 0) newValueException(ERR_NEVER_ENDING_RECURSION);
 119.600 -                en.clearMark1();
 119.601 -            }
 119.602 -            r = subexpInfRecursiveCheckTrav(en.target);
 119.603 -            break;
 119.604 -
 119.605 -        default:
 119.606 -            break;
 119.607 -        } // switch
 119.608 -
 119.609 -        return r;
 119.610 -    }
 119.611 -
 119.612 -    private int subexpRecursiveCheck(Node node) {
 119.613 -        int r = 0;
 119.614 -
 119.615 -        switch (node.getType()) {
 119.616 -        case NodeType.LIST:
 119.617 -        case NodeType.ALT:
 119.618 -            ConsAltNode can = (ConsAltNode)node;
 119.619 -            do {
 119.620 -                r |= subexpRecursiveCheck(can.car);
 119.621 -            } while ((can = can.cdr) != null);
 119.622 -            break;
 119.623 -
 119.624 -        case NodeType.QTFR:
 119.625 -            r = subexpRecursiveCheck(((QuantifierNode)node).target);
 119.626 -            break;
 119.627 -
 119.628 -        case NodeType.ANCHOR:
 119.629 -            AnchorNode an = (AnchorNode)node;
 119.630 -            switch (an.type) {
 119.631 -            case AnchorType.PREC_READ:
 119.632 -            case AnchorType.PREC_READ_NOT:
 119.633 -            case AnchorType.LOOK_BEHIND:
 119.634 -            case AnchorType.LOOK_BEHIND_NOT:
 119.635 -                r = subexpRecursiveCheck(an.target);
 119.636 -                break;
 119.637 -            } // inner switch
 119.638 -            break;
 119.639 -
 119.640 -        case NodeType.CALL:
 119.641 -            CallNode cn = (CallNode)node;
 119.642 -            r = subexpRecursiveCheck(cn.target);
 119.643 -            if (r != 0) cn.setRecursion();
 119.644 -            break;
 119.645 -
 119.646 -        case NodeType.ENCLOSE:
 119.647 -            EncloseNode en = (EncloseNode)node;
 119.648 -            if (en.isMark2()) {
 119.649 -                return 0;
 119.650 -            } else if (en.isMark1()) {
 119.651 -                return 1; /* recursion */
 119.652 -            } else {
 119.653 -                en.setMark2();
 119.654 -                r = subexpRecursiveCheck(en.target);
 119.655 -                en.clearMark2();
 119.656 -            }
 119.657 -            break;
 119.658 -
 119.659 -        default:
 119.660 -            break;
 119.661 -        } // switch
 119.662 -
 119.663 -        return r;
 119.664 -    }
 119.665 -
 119.666 -    private static final int FOUND_CALLED_NODE  = 1;
 119.667 -    protected final int subexpRecursiveCheckTrav(Node node) {
 119.668 -        int r = 0;
 119.669 -
 119.670 -        switch (node.getType()) {
 119.671 -        case NodeType.LIST:
 119.672 -        case NodeType.ALT:
 119.673 -            ConsAltNode can = (ConsAltNode)node;
 119.674 -            do {
 119.675 -                int ret = subexpRecursiveCheckTrav(can.car);
 119.676 -                if (ret == FOUND_CALLED_NODE) {
 119.677 -                    r = FOUND_CALLED_NODE;
 119.678 -                }
 119.679 -                // else if (ret < 0) return ret; ???
 119.680 -            } while ((can = can.cdr) != null);
 119.681 -            break;
 119.682 -
 119.683 -        case NodeType.QTFR:
 119.684 -            QuantifierNode qn = (QuantifierNode)node;
 119.685 -            r = subexpRecursiveCheckTrav(qn.target);
 119.686 -            if (qn.upper == 0) {
 119.687 -                if (r == FOUND_CALLED_NODE) qn.isRefered = true;
 119.688 -            }
 119.689 -            break;
 119.690 -
 119.691 -        case NodeType.ANCHOR:
 119.692 -            AnchorNode an = (AnchorNode)node;
 119.693 -            switch (an.type) {
 119.694 -            case AnchorType.PREC_READ:
 119.695 -            case AnchorType.PREC_READ_NOT:
 119.696 -            case AnchorType.LOOK_BEHIND:
 119.697 -            case AnchorType.LOOK_BEHIND_NOT:
 119.698 -                r = subexpRecursiveCheckTrav(an.target);
 119.699 -                break;
 119.700 -            } // inner switch
 119.701 -            break;
 119.702 -
 119.703 -        case NodeType.ENCLOSE:
 119.704 -            EncloseNode en = (EncloseNode)node;
 119.705 -            if (!en.isRecursion()) {
 119.706 -                if (en.isCalled()) {
 119.707 -                    en.setMark1();
 119.708 -                    r = subexpRecursiveCheck(en.target);
 119.709 -                    if (r != 0) en.setRecursion();
 119.710 -                    en.clearMark1();
 119.711 -                }
 119.712 -            }
 119.713 -            r = subexpRecursiveCheckTrav(en.target);
 119.714 -            if (en.isCalled()) r |= FOUND_CALLED_NODE;
 119.715 -            break;
 119.716 -
 119.717 -        default:
 119.718 -            break;
 119.719 -        } // switch
 119.720 -
 119.721 -        return r;
 119.722 -    }
 119.723 -
 119.724 -    private void setCallAttr(CallNode cn) {
 119.725 -        cn.target = env.memNodes[cn.groupNum]; // no setTarget in call nodes!
 119.726 -        if (cn.target == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
 119.727 -
 119.728 -        ((EncloseNode)cn.target).setCalled();
 119.729 -        env.btMemStart = BitStatus.bsOnAt(env.btMemStart, cn.groupNum);
 119.730 -        cn.unsetAddrList = env.unsetAddrList;
 119.731 -    }
 119.732 -
 119.733 -    protected final void setupSubExpCall(Node node) {
 119.734 -
 119.735 -        switch(node.getType()) {
 119.736 -        case NodeType.LIST:
 119.737 -            ConsAltNode ln = (ConsAltNode)node;
 119.738 -            do {
 119.739 -                setupSubExpCall(ln.car);
 119.740 -            } while ((ln = ln.cdr) != null);
 119.741 -            break;
 119.742 -
 119.743 -        case NodeType.ALT:
 119.744 -            ConsAltNode can = (ConsAltNode)node;
 119.745 -            do {
 119.746 -                setupSubExpCall(can.car);
 119.747 -            } while ((can = can.cdr) != null);
 119.748 -            break;
 119.749 -
 119.750 -        case NodeType.QTFR:
 119.751 -            setupSubExpCall(((QuantifierNode)node).target);
 119.752 -            break;
 119.753 -
 119.754 -        case NodeType.ENCLOSE:
 119.755 -            setupSubExpCall(((EncloseNode)node).target);
 119.756 -            break;
 119.757 -
 119.758 -        case NodeType.CALL:
 119.759 -            CallNode cn = (CallNode)node;
 119.760 -
 119.761 -            if (cn.groupNum != 0) {
 119.762 -                int gNum = cn.groupNum;
 119.763 -
 119.764 -                if (Config.USE_NAMED_GROUP) {
 119.765 -                    if (env.numNamed > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(env.option)) {
 119.766 -                        newValueException(ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
 119.767 -                    }
 119.768 -                } // USE_NAMED_GROUP
 119.769 -                if (gNum > env.numMem) newValueException(ERR_UNDEFINED_GROUP_REFERENCE, cn.nameP, cn.nameEnd);
 119.770 -                setCallAttr(cn);
 119.771 -            } else {
 119.772 -                if (Config.USE_NAMED_GROUP) {
 119.773 -                    NameEntry ne = regex.nameToGroupNumbers(cn.name, cn.nameP, cn.nameEnd);
 119.774 -
 119.775 -                    if (ne == null) {
 119.776 -                        newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
 119.777 -                    } else if (ne.backNum > 1) {
 119.778 -                        newValueException(ERR_MULTIPLEX_DEFINITION_NAME_CALL, cn.nameP, cn.nameEnd);
 119.779 -                    } else {
 119.780 -                        cn.groupNum = ne.backRef1; // ne.backNum == 1 ? ne.backRef1 : ne.backRefs[0]; // ??? need to check ?
 119.781 -                        setCallAttr(cn);
 119.782 -                    }
 119.783 -                }
 119.784 -            }
 119.785 -            break;
 119.786 -
 119.787 -        case NodeType.ANCHOR:
 119.788 -            AnchorNode an = (AnchorNode)node;
 119.789 -            switch (an.type) {
 119.790 -            case AnchorType.PREC_READ:
 119.791 -            case AnchorType.PREC_READ_NOT:
 119.792 -            case AnchorType.LOOK_BEHIND:
 119.793 -            case AnchorType.LOOK_BEHIND_NOT:
 119.794 -                setupSubExpCall(an.target);
 119.795 -                break;
 119.796 -            }
 119.797 -            break;
 119.798 -
 119.799 -        } // switch
 119.800 -    }
 119.801 -
 119.802      /* divide different length alternatives in look-behind.
 119.803      (?<=A|B) ==> (?<=A)|(?<=B)
 119.804      (?<!A|B) ==> (?<!A)(?<!B)
 119.805 @@ -1523,125 +904,6 @@
 119.806          return xnode;
 119.807      }
 119.808  
 119.809 -    private static final int CEC_THRES_NUM_BIG_REPEAT       = 512;
 119.810 -    private static final int CEC_INFINITE_NUM               = 0x7fffffff;
 119.811 -
 119.812 -    private static final int CEC_IN_INFINITE_REPEAT         = (1<<0);
 119.813 -    private static final int CEC_IN_FINITE_REPEAT           = (1<<1);
 119.814 -    private static final int CEC_CONT_BIG_REPEAT            = (1<<2);
 119.815 -
 119.816 -    protected final int setupCombExpCheck(Node node, int state) {
 119.817 -        int r = state;
 119.818 -        int ret;
 119.819 -
 119.820 -        switch (node.getType()) {
 119.821 -        case NodeType.LIST:
 119.822 -            ConsAltNode ln = (ConsAltNode)node;
 119.823 -
 119.824 -            do {
 119.825 -                r = setupCombExpCheck(ln.car, r);
 119.826 -                //prev = ((ConsAltNode)node).car;
 119.827 -            } while (r >= 0 && (ln = ln.cdr) != null);
 119.828 -            break;
 119.829 -
 119.830 -        case NodeType.ALT:
 119.831 -            ConsAltNode an = (ConsAltNode)node;
 119.832 -            do {
 119.833 -                ret = setupCombExpCheck(an.car, state);
 119.834 -                r |= ret;
 119.835 -            } while (ret >= 0 && (an = an.cdr) != null);
 119.836 -            break;
 119.837 -
 119.838 -        case NodeType.QTFR:
 119.839 -            QuantifierNode qn = (QuantifierNode)node;
 119.840 -            int childState = state;
 119.841 -            int addState = 0;
 119.842 -            int varNum;
 119.843 -
 119.844 -            if (!isRepeatInfinite(qn.upper)) {
 119.845 -                if (qn.upper > 1) {
 119.846 -                    /* {0,1}, {1,1} are allowed */
 119.847 -                    childState |= CEC_IN_FINITE_REPEAT;
 119.848 -
 119.849 -                    /* check (a*){n,m}, (a+){n,m} => (a*){n,n}, (a+){n,n} */
 119.850 -                    if (env.backrefedMem == 0) {
 119.851 -                        if (qn.target.getType() == NodeType.ENCLOSE) {
 119.852 -                            EncloseNode en = (EncloseNode)qn.target;
 119.853 -                            if (en.type == EncloseType.MEMORY) {
 119.854 -                                if (en.target.getType() == NodeType.QTFR) {
 119.855 -                                    QuantifierNode q = (QuantifierNode)en.target;
 119.856 -                                    if (isRepeatInfinite(q.upper) && q.greedy == qn.greedy) {
 119.857 -                                        qn.upper = qn.lower == 0 ? 1 : qn.lower;
 119.858 -                                        if (qn.upper == 1) childState = state;
 119.859 -                                    }
 119.860 -                                }
 119.861 -                            }
 119.862 -                        }
 119.863 -                    }
 119.864 -                }
 119.865 -            }
 119.866 -
 119.867 -            if ((state & CEC_IN_FINITE_REPEAT) != 0) {
 119.868 -                qn.combExpCheckNum = -1;
 119.869 -            } else {
 119.870 -                if (isRepeatInfinite(qn.upper)) {
 119.871 -                    varNum = CEC_INFINITE_NUM;
 119.872 -                    childState |= CEC_IN_INFINITE_REPEAT;
 119.873 -                } else {
 119.874 -                    varNum = qn.upper - qn.lower;
 119.875 -                }
 119.876 -
 119.877 -                if (varNum >= CEC_THRES_NUM_BIG_REPEAT) addState |= CEC_CONT_BIG_REPEAT;
 119.878 -
 119.879 -                if (((state & CEC_IN_INFINITE_REPEAT) != 0 && varNum != 0) ||
 119.880 -                   ((state & CEC_CONT_BIG_REPEAT) != 0 && varNum >= CEC_THRES_NUM_BIG_REPEAT)) {
 119.881 -                    if (qn.combExpCheckNum == 0) {
 119.882 -                        env.numCombExpCheck++;
 119.883 -                        qn.combExpCheckNum = env.numCombExpCheck;
 119.884 -                        if (env.currMaxRegNum > env.combExpMaxRegNum) {
 119.885 -                            env.combExpMaxRegNum = env.currMaxRegNum;
 119.886 -                        }
 119.887 -                    }
 119.888 -                }
 119.889 -            }
 119.890 -            r = setupCombExpCheck(qn.target, childState);
 119.891 -            r |= addState;
 119.892 -            break;
 119.893 -
 119.894 -        case NodeType.ENCLOSE:
 119.895 -            EncloseNode en = (EncloseNode)node;
 119.896 -            switch( en.type) {
 119.897 -            case EncloseNode.MEMORY:
 119.898 -                if (env.currMaxRegNum < en.regNum) {
 119.899 -                    env.currMaxRegNum = en.regNum;
 119.900 -                }
 119.901 -                r = setupCombExpCheck(en.target, state);
 119.902 -                break;
 119.903 -
 119.904 -            default:
 119.905 -                r = setupCombExpCheck(en.target, state);
 119.906 -            } // inner switch
 119.907 -            break;
 119.908 -
 119.909 -        case NodeType.CALL:
 119.910 -            if (Config.USE_SUBEXP_CALL) {
 119.911 -                CallNode cn = (CallNode)node;
 119.912 -                if (cn.isRecursion()) {
 119.913 -                    env.hasRecursion = true;
 119.914 -                } else {
 119.915 -                    r = setupCombExpCheck(cn.target, state);
 119.916 -                }
 119.917 -            } // USE_SUBEXP_CALL
 119.918 -            break;
 119.919 -
 119.920 -        default:
 119.921 -            break;
 119.922 -
 119.923 -        } // switch
 119.924 -
 119.925 -        return r;
 119.926 -    }
 119.927 -
 119.928      private static final int IN_ALT                     = (1<<0);
 119.929      private static final int IN_NOT                     = (1<<1);
 119.930      private static final int IN_REPEAT                  = (1<<2);
 119.931 @@ -1691,20 +953,12 @@
 119.932          case NodeType.CANY:
 119.933              break;
 119.934  
 119.935 -        case NodeType.CALL: // if (Config.USE_SUBEXP_CALL) ?
 119.936 -            break;
 119.937 -
 119.938          case NodeType.BREF:
 119.939              BackRefNode br = (BackRefNode)node;
 119.940              for (int i=0; i<br.backNum; i++) {
 119.941                  if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF);
 119.942                  env.backrefedMem = bsOnAt(env.backrefedMem, br.back[i]);
 119.943                  env.btMemStart = bsOnAt(env.btMemStart, br.back[i]);
 119.944 -                if (Config.USE_BACKREF_WITH_LEVEL) {
 119.945 -                    if (br.isNestLevel()) {
 119.946 -                        env.btMemEnd = bsOnAt(env.btMemEnd, br.back[i]);
 119.947 -                    }
 119.948 -                } // USE_BACKREF_AT_LEVEL
 119.949                  ((EncloseNode)env.memNodes[br.back[i]]).setMemBackrefed();
 119.950              }
 119.951              break;
 119.952 @@ -1916,37 +1170,6 @@
 119.953              break;
 119.954          }
 119.955  
 119.956 -        case NodeType.CTYPE: {
 119.957 -            int min;
 119.958 -            int max = 1;
 119.959 -            if (max == 1) {
 119.960 -                min = 1;
 119.961 -                CTypeNode cn = (CTypeNode)node;
 119.962 -
 119.963 -                switch (cn.ctype) {
 119.964 -                case CharacterType.WORD:
 119.965 -                    if (cn.not) {
 119.966 -                        for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
 119.967 -                            if (!EncodingHelper.isWord(i)) {
 119.968 -                                opt.map.addChar(i);
 119.969 -                            }
 119.970 -                        }
 119.971 -                    } else {
 119.972 -                        for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
 119.973 -                            if (EncodingHelper.isWord(i)) {
 119.974 -                                opt.map.addChar(i);
 119.975 -                            }
 119.976 -                        }
 119.977 -                    }
 119.978 -                    break;
 119.979 -                } // inner switch
 119.980 -            } else {
 119.981 -                min = 1;
 119.982 -            }
 119.983 -            opt.length.set(min, max);
 119.984 -            break;
 119.985 -        }
 119.986 -
 119.987          case NodeType.CANY: {
 119.988              opt.length.set(1, 1);
 119.989              break;
 119.990 @@ -2008,20 +1231,6 @@
 119.991              break;
 119.992          }
 119.993  
 119.994 -        case NodeType.CALL: {
 119.995 -            if (Config.USE_SUBEXP_CALL) {
 119.996 -                CallNode cn = (CallNode)node;
 119.997 -                if (cn.isRecursion()) {
 119.998 -                    opt.length.set(0, MinMaxLen.INFINITE_DISTANCE);
 119.999 -                } else {
119.1000 -                    int safe = oenv.options;
119.1001 -                    oenv.options = ((EncloseNode)cn.target).option;
119.1002 -                    optimizeNodeLeft(cn.target, opt, oenv);
119.1003 -                    oenv.options = safe;
119.1004 -                }
119.1005 -            } // USE_SUBEXP_CALL
119.1006 -            break;
119.1007 -        }
119.1008  
119.1009          case NodeType.QTFR: {
119.1010              NodeOptInfo nopt = new NodeOptInfo();
119.1011 @@ -2081,7 +1290,7 @@
119.1012                  break;
119.1013  
119.1014              case EncloseType.MEMORY:
119.1015 -                if (Config.USE_SUBEXP_CALL && ++en.optCount > MAX_NODE_OPT_INFO_REF_COUNT) {
119.1016 +                if (++en.optCount > MAX_NODE_OPT_INFO_REF_COUNT) {
119.1017                      int min = 0;
119.1018                      int max = MinMaxLen.INFINITE_DISTANCE;
119.1019                      if (en.isMinFixed()) min = en.minLength;
   120.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java	Thu May 30 10:58:35 2013 -0700
   120.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java	Mon Jun 03 23:24:36 2013 -0700
   120.3 @@ -28,8 +28,6 @@
   120.4  import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
   120.5  import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
   120.6  import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
   120.7 -import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
   120.8 -import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
   120.9  import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
  120.10  import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
  120.11  import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
  120.12 @@ -71,11 +69,6 @@
  120.13          regex.templates = templates;
  120.14          regex.templateNum = templateNum;
  120.15          regex.factory = MatcherFactory.DEFAULT;
  120.16 -
  120.17 -        if (Config.USE_SUBEXP_CALL && analyser.env.unsetAddrList != null) {
  120.18 -            analyser.env.unsetAddrList.fix(regex);
  120.19 -            analyser.env.unsetAddrList = null;
  120.20 -        }
  120.21      }
  120.22  
  120.23      @Override
  120.24 @@ -119,7 +112,7 @@
  120.25          return isNeedStrLenOpExact(op);
  120.26      }
  120.27  
  120.28 -    private int selectStrOpcode(int mbLength, int strLength, boolean ignoreCase) {
  120.29 +    private int selectStrOpcode(int strLength, boolean ignoreCase) {
  120.30          int op;
  120.31  
  120.32          if (ignoreCase) {
  120.33 @@ -128,31 +121,14 @@
  120.34              default:op = OPCode.EXACTN_IC; break;
  120.35              } // switch
  120.36          } else {
  120.37 -            switch (mbLength) {
  120.38 -            case 1:
  120.39 -                switch (strLength) {
  120.40 -                case 1: op = OPCode.EXACT1; break;
  120.41 -                case 2: op = OPCode.EXACT2; break;
  120.42 -                case 3: op = OPCode.EXACT3; break;
  120.43 -                case 4: op = OPCode.EXACT4; break;
  120.44 -                case 5: op = OPCode.EXACT5; break;
  120.45 -                default:op = OPCode.EXACTN; break;
  120.46 -                } // inner switch
  120.47 -                break;
  120.48 -            case 2:
  120.49 -                switch (strLength) {
  120.50 -                case 1: op = OPCode.EXACTMB2N1; break;
  120.51 -                case 2: op = OPCode.EXACTMB2N2; break;
  120.52 -                case 3: op = OPCode.EXACTMB2N3; break;
  120.53 -                default:op = OPCode.EXACTMB2N;  break;
  120.54 -                } // inner switch
  120.55 -                break;
  120.56 -            case 3:
  120.57 -                op = OPCode.EXACTMB3N;
  120.58 -                break;
  120.59 -            default:
  120.60 -                op = OPCode.EXACTMBN;
  120.61 -            } // switch
  120.62 +            switch (strLength) {
  120.63 +            case 1: op = OPCode.EXACT1; break;
  120.64 +            case 2: op = OPCode.EXACT2; break;
  120.65 +            case 3: op = OPCode.EXACT3; break;
  120.66 +            case 4: op = OPCode.EXACT4; break;
  120.67 +            case 5: op = OPCode.EXACT5; break;
  120.68 +            default:op = OPCode.EXACTN; break;
  120.69 +            } // inner switch
  120.70          }
  120.71          return op;
  120.72      }
  120.73 @@ -185,8 +161,8 @@
  120.74          }
  120.75      }
  120.76  
  120.77 -    private int addCompileStringlength(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
  120.78 -        int op = selectStrOpcode(mbLength, strLength, ignoreCase);
  120.79 +    private int addCompileStringlength(char[] chars, int p, int strLength, boolean ignoreCase) {
  120.80 +        int op = selectStrOpcode(strLength, ignoreCase);
  120.81          int len = OPSize.OPCODE;
  120.82  
  120.83          if (Config.USE_STRING_TEMPLATES && opTemplated(op)) {
  120.84 @@ -194,25 +170,21 @@
  120.85              len += OPSize.LENGTH + OPSize.INDEX + OPSize.INDEX;
  120.86          } else {
  120.87              if (isNeedStrLenOpExact(op)) len += OPSize.LENGTH;
  120.88 -            len += mbLength * strLength;
  120.89 +            len += strLength;
  120.90          }
  120.91          if (op == OPCode.EXACTMBN) len += OPSize.LENGTH;
  120.92          return len;
  120.93      }
  120.94  
  120.95      @Override
  120.96 -    protected final void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
  120.97 -        int op = selectStrOpcode(mbLength, strLength, ignoreCase);
  120.98 +    protected final void addCompileString(char[] chars, int p, int strLength, boolean ignoreCase) {
  120.99 +        int op = selectStrOpcode(strLength, ignoreCase);
 120.100          addOpcode(op);
 120.101  
 120.102 -        if (op == OPCode.EXACTMBN) addLength(mbLength);
 120.103 +        if (op == OPCode.EXACTMBN) addLength(1);
 120.104  
 120.105          if (isNeedStrLenOpExact(op)) {
 120.106 -            if (op == OPCode.EXACTN_IC || op == OPCode.EXACTN_IC_SB) {
 120.107 -                addLength(mbLength * strLength);
 120.108 -            } else {
 120.109 -                addLength(strLength);
 120.110 -            }
 120.111 +            addLength(strLength);
 120.112          }
 120.113  
 120.114          if (Config.USE_STRING_TEMPLATES && opTemplated(op)) {
 120.115 @@ -220,7 +192,7 @@
 120.116              addInt(p);
 120.117              addTemplate(chars);
 120.118          } else {
 120.119 -            addChars(chars, p, mbLength * strLength);
 120.120 +            addChars(chars, p, strLength);
 120.121          }
 120.122      }
 120.123  
 120.124 @@ -242,14 +214,14 @@
 120.125              slen++;
 120.126              p++;
 120.127          }
 120.128 -        int r = addCompileStringlength(chars, prev, 1, slen, ambig);
 120.129 +        int r = addCompileStringlength(chars, prev, slen, ambig);
 120.130          rlen += r;
 120.131          return rlen;
 120.132      }
 120.133  
 120.134      private int compileLengthStringRawNode(StringNode sn) {
 120.135          if (sn.length() <= 0) return 0;
 120.136 -        return addCompileStringlength(sn.chars, sn.p, 1 /*sb*/, sn.length(), false);
 120.137 +        return addCompileStringlength(sn.chars, sn.p, sn.length(), false);
 120.138      }
 120.139  
 120.140      private void addMultiByteCClass(CodeRangeBuffer mbuf) {
 120.141 @@ -312,26 +284,6 @@
 120.142      }
 120.143  
 120.144      @Override
 120.145 -    protected void compileCTypeNode(CTypeNode node) {
 120.146 -        CTypeNode cn = node;
 120.147 -        int op;
 120.148 -        switch (cn.ctype) {
 120.149 -        case CharacterType.WORD:
 120.150 -            if (cn.not) {
 120.151 -                op = OPCode.NOT_WORD;
 120.152 -            } else {
 120.153 -                op = OPCode.WORD;
 120.154 -            }
 120.155 -            break;
 120.156 -
 120.157 -        default:
 120.158 -            newInternalException(ERR_PARSER_BUG);
 120.159 -            return; // not reached
 120.160 -        } // inner switch
 120.161 -        addOpcode(op);
 120.162 -    }
 120.163 -
 120.164 -    @Override
 120.165      protected void compileAnyCharNode() {
 120.166          if (isMultiline(regex.options)) {
 120.167              addOpcode(OPCode.ANYCHAR_ML);
 120.168 @@ -341,30 +293,15 @@
 120.169      }
 120.170  
 120.171      @Override
 120.172 -    protected void compileCallNode(CallNode node) {
 120.173 -        addOpcode(OPCode.CALL);
 120.174 -        node.unsetAddrList.add(codeLength, node.target);
 120.175 -        addAbsAddr(0); /*dummy addr.*/
 120.176 -    }
 120.177 -
 120.178 -    @Override
 120.179      protected void compileBackrefNode(BackRefNode node) {
 120.180          BackRefNode br = node;
 120.181 -        if (Config.USE_BACKREF_WITH_LEVEL && br.isNestLevel()) {
 120.182 -            addOpcode(OPCode.BACKREF_WITH_LEVEL);
 120.183 -            addOption(regex.options & Option.IGNORECASE);
 120.184 -            addLength(br.nestLevel);
 120.185 -            // !goto add_bacref_mems;!
 120.186 -            addLength(br.backNum);
 120.187 -            for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
 120.188 -            return;
 120.189 -        } else { // USE_BACKREF_AT_LEVEL
 120.190 -            if (br.backNum == 1) {
 120.191 -                if (isIgnoreCase(regex.options)) {
 120.192 -                    addOpcode(OPCode.BACKREFN_IC);
 120.193 -                    addMemNum(br.back[0]);
 120.194 -                } else {
 120.195 -                    switch (br.back[0]) {
 120.196 +        // USE_BACKREF_AT_LEVEL
 120.197 +        if (br.backNum == 1) {
 120.198 +            if (isIgnoreCase(regex.options)) {
 120.199 +                addOpcode(OPCode.BACKREFN_IC);
 120.200 +                addMemNum(br.back[0]);
 120.201 +            } else {
 120.202 +                switch (br.back[0]) {
 120.203                      case 1:
 120.204                          addOpcode(OPCode.BACKREF1);
 120.205                          break;
 120.206 @@ -375,18 +312,17 @@
 120.207                          addOpcode(OPCode.BACKREFN);
 120.208                          addOpcode(br.back[0]);
 120.209                          break;
 120.210 -                    } // switch
 120.211 -                }
 120.212 +                } // switch
 120.213 +            }
 120.214 +        } else {
 120.215 +            if (isIgnoreCase(regex.options)) {
 120.216 +                addOpcode(OPCode.BACKREF_MULTI_IC);
 120.217              } else {
 120.218 -                if (isIgnoreCase(regex.options)) {
 120.219 -                    addOpcode(OPCode.BACKREF_MULTI_IC);
 120.220 -                } else {
 120.221 -                    addOpcode(OPCode.BACKREF_MULTI);
 120.222 -                }
 120.223 -                // !add_bacref_mems:!
 120.224 -                addLength(br.backNum);
 120.225 -                for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
 120.226 +                addOpcode(OPCode.BACKREF_MULTI);
 120.227              }
 120.228 +            // !add_bacref_mems:!
 120.229 +            addLength(br.backNum);
 120.230 +            for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
 120.231          }
 120.232      }
 120.233  
 120.234 @@ -419,7 +355,7 @@
 120.235  
 120.236          compileTreeEmptyCheck(qn.target, emptyInfo);
 120.237  
 120.238 -        if ((Config.USE_SUBEXP_CALL && regex.numCall > 0) || qn.isInRepeat()) {
 120.239 +        if (qn.isInRepeat()) {
 120.240              addOpcode(qn.greedy ? OPCode.REPEAT_INC_SG : OPCode.REPEAT_INC_NG_SG);
 120.241          } else {
 120.242              addOpcode(qn.greedy ? OPCode.REPEAT_INC : OPCode.REPEAT_INC_NG);
 120.243 @@ -434,193 +370,6 @@
 120.244          return ckn > 0;
 120.245      }
 120.246  
 120.247 -    private int compileCECLengthQuantifierNode(QuantifierNode qn) {
 120.248 -        boolean infinite = isRepeatInfinite(qn.upper);
 120.249 -        int emptyInfo = qn.targetEmptyInfo;
 120.250 -
 120.251 -        int tlen = compileLengthTree(qn.target);
 120.252 -        int ckn = regex.numCombExpCheck > 0 ? qn.combExpCheckNum : 0;
 120.253 -        int cklen = cknOn(ckn) ? OPSize.STATE_CHECK_NUM : 0;
 120.254 -
 120.255 -        /* anychar repeat */
 120.256 -        if (qn.target.getType() == NodeType.CANY) {
 120.257 -            if (qn.greedy && infinite) {
 120.258 -                if (qn.nextHeadExact != null && !cknOn(ckn)) {
 120.259 -                    return OPSize.ANYCHAR_STAR_PEEK_NEXT + tlen * qn.lower + cklen;
 120.260 -                } else {
 120.261 -                    return OPSize.ANYCHAR_STAR + tlen * qn.lower + cklen;
 120.262 -                }
 120.263 -            }
 120.264 -        }
 120.265 -
 120.266 -        int modTLen;
 120.267 -        if (emptyInfo != 0) {
 120.268 -            modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
 120.269 -        } else {
 120.270 -            modTLen = tlen;
 120.271 -        }
 120.272 -
 120.273 -        int len;
 120.274 -        if (infinite && qn.lower <= 1) {
 120.275 -            if (qn.greedy) {
 120.276 -                if (qn.lower == 1) {
 120.277 -                    len = OPSize.JUMP;
 120.278 -                } else {
 120.279 -                    len = 0;
 120.280 -                }
 120.281 -                len += OPSize.PUSH + cklen + modTLen + OPSize.JUMP;
 120.282 -            } else {
 120.283 -                if (qn.lower == 0) {
 120.284 -                    len = OPSize.JUMP;
 120.285 -                } else {
 120.286 -                    len = 0;
 120.287 -                }
 120.288 -                len += modTLen + OPSize.PUSH + cklen;
 120.289 -            }
 120.290 -        } else if (qn.upper == 0) {
 120.291 -            if (qn.isRefered) { /* /(?<n>..){0}/ */
 120.292 -                len = OPSize.JUMP + tlen;
 120.293 -            } else {
 120.294 -                len = 0;
 120.295 -            }
 120.296 -        } else if (qn.upper == 1 && qn.greedy) {
 120.297 -            if (qn.lower == 0) {
 120.298 -                if (cknOn(ckn)) {
 120.299 -                    len = OPSize.STATE_CHECK_PUSH + tlen;
 120.300 -                } else {
 120.301 -                    len = OPSize.PUSH + tlen;
 120.302 -                }
 120.303 -            } else {
 120.304 -                len = tlen;
 120.305 -            }
 120.306 -        } else if (!qn.greedy && qn.upper == 1 && qn.lower == 0) { /* '??' */
 120.307 -            len = OPSize.PUSH + cklen + OPSize.JUMP + tlen;
 120.308 -        } else {
 120.309 -            len = OPSize.REPEAT_INC + modTLen + OPSize.OPCODE + OPSize.RELADDR + OPSize.MEMNUM;
 120.310 -
 120.311 -            if (cknOn(ckn)) {
 120.312 -                len += OPSize.STATE_CHECK;
 120.313 -            }
 120.314 -        }
 120.315 -        return len;
 120.316 -    }
 120.317 -
 120.318 -    @Override
 120.319 -    protected void compileCECQuantifierNode(QuantifierNode qn) {
 120.320 -        boolean infinite = isRepeatInfinite(qn.upper);
 120.321 -        int emptyInfo = qn.targetEmptyInfo;
 120.322 -
 120.323 -        int tlen = compileLengthTree(qn.target);
 120.324 -
 120.325 -        int ckn = regex.numCombExpCheck > 0 ? qn.combExpCheckNum : 0;
 120.326 -
 120.327 -        if (qn.isAnyCharStar()) {
 120.328 -            compileTreeNTimes(qn.target, qn.lower);
 120.329 -            if (qn.nextHeadExact != null && !cknOn(ckn)) {
 120.330 -                if (isMultiline(regex.options)) {
 120.331 -                    addOpcode(OPCode.ANYCHAR_ML_STAR_PEEK_NEXT);
 120.332 -                } else {
 120.333 -                    addOpcode(OPCode.ANYCHAR_STAR_PEEK_NEXT);
 120.334 -                }
 120.335 -                if (cknOn(ckn)) {
 120.336 -                    addStateCheckNum(ckn);
 120.337 -                }
 120.338 -                StringNode sn = (StringNode)qn.nextHeadExact;
 120.339 -                addChars(sn.chars, sn.p, 1);
 120.340 -                return;
 120.341 -            } else {
 120.342 -                if (isMultiline(regex.options)) {
 120.343 -                    if (cknOn(ckn)) {
 120.344 -                        addOpcode(OPCode.STATE_CHECK_ANYCHAR_ML_STAR);
 120.345 -                    } else {
 120.346 -                        addOpcode(OPCode.ANYCHAR_ML_STAR);
 120.347 -                    }
 120.348 -                } else {
 120.349 -                    if (cknOn(ckn)) {
 120.350 -                        addOpcode(OPCode.STATE_CHECK_ANYCHAR_STAR);
 120.351 -                    } else {
 120.352 -                        addOpcode(OPCode.ANYCHAR_STAR);
 120.353 -                    }
 120.354 -                }
 120.355 -                if (cknOn(ckn)) {
 120.356 -                    addStateCheckNum(ckn);
 120.357 -                }
 120.358 -                return;
 120.359 -            }
 120.360 -        }
 120.361 -
 120.362 -        int modTLen;
 120.363 -        if (emptyInfo != 0) {
 120.364 -            modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
 120.365 -        } else {
 120.366 -            modTLen = tlen;
 120.367 -        }
 120.368 -        if (infinite && qn.lower <= 1) {
 120.369 -            if (qn.greedy) {
 120.370 -                if (qn.lower == 1) {
 120.371 -                    addOpcodeRelAddr(OPCode.JUMP, cknOn(ckn) ? OPSize.STATE_CHECK_PUSH :
 120.372 -                                                                     OPSize.PUSH);
 120.373 -                }
 120.374 -                if (cknOn(ckn)) {
 120.375 -                    addOpcode(OPCode.STATE_CHECK_PUSH);
 120.376 -                    addStateCheckNum(ckn);
 120.377 -                    addRelAddr(modTLen + OPSize.JUMP);
 120.378 -                } else {
 120.379 -                    addOpcodeRelAddr(OPCode.PUSH, modTLen + OPSize.JUMP);
 120.380 -                }
 120.381 -                compileTreeEmptyCheck(qn.target, emptyInfo);
 120.382 -                addOpcodeRelAddr(OPCode.JUMP, -(modTLen + OPSize.JUMP + (cknOn(ckn) ?
 120.383 -                                                                               OPSize.STATE_CHECK_PUSH :
 120.384 -                                                                               OPSize.PUSH)));
 120.385 -            } else {
 120.386 -                if (qn.lower == 0) {
 120.387 -                    addOpcodeRelAddr(OPCode.JUMP, modTLen);
 120.388 -                }
 120.389 -                compileTreeEmptyCheck(qn.target, emptyInfo);
 120.390 -                if (cknOn(ckn)) {
 120.391 -                    addOpcode(OPCode.STATE_CHECK_PUSH_OR_JUMP);
 120.392 -                    addStateCheckNum(ckn);
 120.393 -                    addRelAddr(-(modTLen + OPSize.STATE_CHECK_PUSH_OR_JUMP));
 120.394 -                } else {
 120.395 -                    addOpcodeRelAddr(OPCode.PUSH, -(modTLen + OPSize.PUSH));
 120.396 -                }
 120.397 -            }
 120.398 -        } else if (qn.upper == 0) {
 120.399 -            if (qn.isRefered) { /* /(?<n>..){0}/ */
 120.400 -                addOpcodeRelAddr(OPCode.JUMP, tlen);
 120.401 -                compileTree(qn.target);
 120.402 -            } // else r=0 ???
 120.403 -        } else if (qn.upper == 1 && qn.greedy) {
 120.404 -            if (qn.lower == 0) {
 120.405 -                if (cknOn(ckn)) {
 120.406 -                    addOpcode(OPCode.STATE_CHECK_PUSH);
 120.407 -                    addStateCheckNum(ckn);
 120.408 -                    addRelAddr(tlen);
 120.409 -                } else {
 120.410 -                    addOpcodeRelAddr(OPCode.PUSH, tlen);
 120.411 -                }
 120.412 -            }
 120.413 -            compileTree(qn.target);
 120.414 -        } else if (!qn.greedy && qn.upper == 1 && qn.lower == 0){ /* '??' */
 120.415 -            if (cknOn(ckn)) {
 120.416 -                addOpcode(OPCode.STATE_CHECK_PUSH);
 120.417 -                addStateCheckNum(ckn);
 120.418 -                addRelAddr(OPSize.JUMP);
 120.419 -            } else {
 120.420 -                addOpcodeRelAddr(OPCode.PUSH, OPSize.JUMP);
 120.421 -            }
 120.422 -
 120.423 -            addOpcodeRelAddr(OPCode.JUMP, tlen);
 120.424 -            compileTree(qn.target);
 120.425 -        } else {
 120.426 -            compileRangeRepeatNode(qn, modTLen, emptyInfo);
 120.427 -            if (cknOn(ckn)) {
 120.428 -                addOpcode(OPCode.STATE_CHECK);
 120.429 -                addStateCheckNum(ckn);
 120.430 -            }
 120.431 -        }
 120.432 -    }
 120.433 -
 120.434      private int compileNonCECLengthQuantifierNode(QuantifierNode qn) {
 120.435          boolean infinite = isRepeatInfinite(qn.upper);
 120.436          int emptyInfo = qn.targetEmptyInfo;
 120.437 @@ -821,21 +570,12 @@
 120.438          int len;
 120.439          switch (node.type) {
 120.440          case EncloseType.MEMORY:
 120.441 -            if (Config.USE_SUBEXP_CALL && node.isCalled()) {
 120.442 -                len = OPSize.MEMORY_START_PUSH + tlen + OPSize.CALL + OPSize.JUMP + OPSize.RETURN;
 120.443 -                if (bsAt(regex.btMemEnd, node.regNum)) {
 120.444 -                    len += node.isRecursion() ? OPSize.MEMORY_END_PUSH_REC : OPSize.MEMORY_END_PUSH;
 120.445 -                } else {
 120.446 -                    len += node.isRecursion() ? OPSize.MEMORY_END_REC : OPSize.MEMORY_END;
 120.447 -                }
 120.448 -            } else { // USE_SUBEXP_CALL
 120.449 -                if (bsAt(regex.btMemStart, node.regNum)) {
 120.450 -                    len = OPSize.MEMORY_START_PUSH;
 120.451 -                } else {
 120.452 -                    len = OPSize.MEMORY_START;
 120.453 -                }
 120.454 -                len += tlen + (bsAt(regex.btMemEnd, node.regNum) ? OPSize.MEMORY_END_PUSH : OPSize.MEMORY_END);
 120.455 +            if (bsAt(regex.btMemStart, node.regNum)) {
 120.456 +                len = OPSize.MEMORY_START_PUSH;
 120.457 +            } else {
 120.458 +                len = OPSize.MEMORY_START;
 120.459              }
 120.460 +            len += tlen + (bsAt(regex.btMemEnd, node.regNum) ? OPSize.MEMORY_END_PUSH : OPSize.MEMORY_END);
 120.461              break;
 120.462  
 120.463          case EncloseType.STOP_BACKTRACK:
 120.464 @@ -860,23 +600,6 @@
 120.465          int len;
 120.466          switch (node.type) {
 120.467          case EncloseType.MEMORY:
 120.468 -            if (Config.USE_SUBEXP_CALL) {
 120.469 -                if (node.isCalled()) {
 120.470 -                    addOpcode(OPCode.CALL);
 120.471 -                    node.callAddr = codeLength + OPSize.ABSADDR + OPSize.JUMP;
 120.472 -                    node.setAddrFixed();
 120.473 -                    addAbsAddr(node.callAddr);
 120.474 -                    len = compileLengthTree(node.target);
 120.475 -                    len += OPSize.MEMORY_START_PUSH + OPSize.RETURN;
 120.476 -                    if (bsAt(regex.btMemEnd, node.regNum)) {
 120.477 -                        len += node.isRecursion() ? OPSize.MEMORY_END_PUSH_REC : OPSize.MEMORY_END_PUSH;
 120.478 -                    } else {
 120.479 -                        len += node.isRecursion() ? OPSize.MEMORY_END_REC : OPSize.MEMORY_END;
 120.480 -                    }
 120.481 -                    addOpcodeRelAddr(OPCode.JUMP, len);
 120.482 -                }
 120.483 -            } // USE_SUBEXP_CALL
 120.484 -
 120.485              if (bsAt(regex.btMemStart, node.regNum)) {
 120.486                  addOpcode(OPCode.MEMORY_START_PUSH);
 120.487              } else {
 120.488 @@ -886,22 +609,12 @@
 120.489              addMemNum(node.regNum);
 120.490              compileTree(node.target);
 120.491  
 120.492 -            if (Config.USE_SUBEXP_CALL && node.isCalled()) {
 120.493 -                if (bsAt(regex.btMemEnd, node.regNum)) {
 120.494 -                    addOpcode(node.isRecursion() ? OPCode.MEMORY_END_PUSH_REC : OPCode.MEMORY_END_PUSH);
 120.495 -                } else {
 120.496 -                    addOpcode(node.isRecursion() ? OPCode.MEMORY_END_REC : OPCode.MEMORY_END);
 120.497 -                }
 120.498 -                addMemNum(node.regNum);
 120.499 -                addOpcode(OPCode.RETURN);
 120.500 -            } else { // USE_SUBEXP_CALL
 120.501 -                if (bsAt(regex.btMemEnd, node.regNum)) {
 120.502 -                    addOpcode(OPCode.MEMORY_END_PUSH);
 120.503 -                } else {
 120.504 -                    addOpcode(OPCode.MEMORY_END);
 120.505 -                }
 120.506 -                addMemNum(node.regNum);
 120.507 +            if (bsAt(regex.btMemEnd, node.regNum)) {
 120.508 +                addOpcode(OPCode.MEMORY_END_PUSH);
 120.509 +            } else {
 120.510 +                addOpcode(OPCode.MEMORY_END);
 120.511              }
 120.512 +            addMemNum(node.regNum);
 120.513              break;
 120.514  
 120.515          case EncloseType.STOP_BACKTRACK:
 120.516 @@ -1078,32 +791,17 @@
 120.517          case NodeType.BREF:
 120.518              BackRefNode br = (BackRefNode)node;
 120.519  
 120.520 -            if (Config.USE_BACKREF_WITH_LEVEL && br.isNestLevel()) {
 120.521 -                len = OPSize.OPCODE + OPSize.OPTION + OPSize.LENGTH +
 120.522 -                      OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
 120.523 -            } else { // USE_BACKREF_AT_LEVEL
 120.524 -                if (br.backNum == 1) {
 120.525 -                    len = ((!isIgnoreCase(regex.options) && br.back[0] <= 2)
 120.526 -                            ? OPSize.OPCODE : (OPSize.OPCODE + OPSize.MEMNUM));
 120.527 -                } else {
 120.528 -                    len = OPSize.OPCODE + OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
 120.529 -                }
 120.530 +            // USE_BACKREF_AT_LEVEL
 120.531 +            if (br.backNum == 1) {
 120.532 +                len = ((!isIgnoreCase(regex.options) && br.back[0] <= 2)
 120.533 +                        ? OPSize.OPCODE : (OPSize.OPCODE + OPSize.MEMNUM));
 120.534 +            } else {
 120.535 +                len = OPSize.OPCODE + OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
 120.536              }
 120.537              break;
 120.538  
 120.539 -        case NodeType.CALL:
 120.540 -            if (Config.USE_SUBEXP_CALL) {
 120.541 -                len = OPSize.CALL;
 120.542 -                break;
 120.543 -            } // USE_SUBEXP_CALL
 120.544 -            break;
 120.545 -
 120.546          case NodeType.QTFR:
 120.547 -            if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
 120.548 -                len = compileCECLengthQuantifierNode((QuantifierNode)node);
 120.549 -            } else {
 120.550 -                len = compileNonCECLengthQuantifierNode((QuantifierNode)node);
 120.551 -            }
 120.552 +            len = compileNonCECLengthQuantifierNode((QuantifierNode)node);
 120.553              break;
 120.554  
 120.555          case NodeType.ENCLOSE:
   121.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompiler.java	Thu May 30 10:58:35 2013 -0700
   121.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   121.3 @@ -1,109 +0,0 @@
   121.4 -/*
   121.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   121.6 - * this software and associated documentation files (the "Software"), to deal in
   121.7 - * the Software without restriction, including without limitation the rights to
   121.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   121.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  121.10 - * so, subject to the following conditions:
  121.11 - *
  121.12 - * The above copyright notice and this permission notice shall be included in all
  121.13 - * copies or substantial portions of the Software.
  121.14 - *
  121.15 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  121.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  121.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  121.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  121.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  121.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  121.21 - * SOFTWARE.
  121.22 - */
  121.23 -package jdk.nashorn.internal.runtime.regexp.joni;
  121.24 -
  121.25 -import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
  121.26 -import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
  121.27 -import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
  121.28 -import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
  121.29 -import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
  121.30 -import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
  121.31 -import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
  121.32 -import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
  121.33 -
  121.34 -final class AsmCompiler extends AsmCompilerSupport {
  121.35 -
  121.36 -    public AsmCompiler(Analyser analyser) {
  121.37 -        super(analyser);
  121.38 -    }
  121.39 -
  121.40 -    @Override
  121.41 -    protected void prepare() {
  121.42 -        REG_NUM++;
  121.43 -        prepareMachine();
  121.44 -        prepareMachineInit();
  121.45 -        prepareMachineMatch();
  121.46 -
  121.47 -        prepareFactory();
  121.48 -        prepareFactoryInit();
  121.49 -    }
  121.50 -
  121.51 -    @Override
  121.52 -    protected void finish() {
  121.53 -        setupFactoryInit();
  121.54 -
  121.55 -        setupMachineInit();
  121.56 -        setupMachineMatch();
  121.57 -
  121.58 -        setupClasses();
  121.59 -    }
  121.60 -
  121.61 -    @Override
  121.62 -    protected void compileAltNode(ConsAltNode node) {
  121.63 -    }
  121.64 -
  121.65 -    @Override
  121.66 -    protected void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
  121.67 -        String template = installTemplate(chars, p, strLength);
  121.68 -    }
  121.69 -
  121.70 -    @Override
  121.71 -    protected void compileCClassNode(CClassNode node) {
  121.72 -        if (node.bs != null) {
  121.73 -            String bitsetName = installBitSet(node.bs.bits);
  121.74 -        }
  121.75 -    }
  121.76 -
  121.77 -    @Override
  121.78 -    protected void compileCTypeNode(CTypeNode node) {
  121.79 -    }
  121.80 -
  121.81 -    @Override
  121.82 -    protected void compileAnyCharNode() {
  121.83 -    }
  121.84 -
  121.85 -    @Override
  121.86 -    protected void compileBackrefNode(BackRefNode node) {
  121.87 -    }
  121.88 -
  121.89 -    @Override
  121.90 -    protected void compileCallNode(CallNode node) {
  121.91 -    }
  121.92 -
  121.93 -    @Override
  121.94 -    protected void compileCECQuantifierNode(QuantifierNode node) {
  121.95 -    }
  121.96 -
  121.97 -    @Override
  121.98 -    protected void compileNonCECQuantifierNode(QuantifierNode node) {
  121.99 -    }
 121.100 -
 121.101 -    @Override
 121.102 -    protected void compileOptionNode(EncloseNode node) {
 121.103 -    }
 121.104 -
 121.105 -    @Override
 121.106 -    protected void compileEncloseNode(EncloseNode node) {
 121.107 -    }
 121.108 -
 121.109 -    @Override
 121.110 -    protected void compileAnchorNode(AnchorNode node) {
 121.111 -    }
 121.112 -}
   122.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompilerSupport.java	Thu May 30 10:58:35 2013 -0700
   122.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   122.3 @@ -1,267 +0,0 @@
   122.4 -/*
   122.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   122.6 - * this software and associated documentation files (the "Software"), to deal in
   122.7 - * the Software without restriction, including without limitation the rights to
   122.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   122.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  122.10 - * so, subject to the following conditions:
  122.11 - *
  122.12 - * The above copyright notice and this permission notice shall be included in all
  122.13 - * copies or substantial portions of the Software.
  122.14 - *
  122.15 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  122.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  122.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  122.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  122.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  122.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  122.21 - * SOFTWARE.
  122.22 - */
  122.23 -package jdk.nashorn.internal.runtime.regexp.joni;
  122.24 -
  122.25 -import java.io.FileOutputStream;
  122.26 -import java.io.IOException;
  122.27 -
  122.28 -import jdk.nashorn.internal.runtime.regexp.joni.constants.AsmConstants;
  122.29 -import jdk.internal.org.objectweb.asm.ClassWriter;
  122.30 -import jdk.internal.org.objectweb.asm.MethodVisitor;
  122.31 -import jdk.internal.org.objectweb.asm.Opcodes;
  122.32 -
  122.33 -abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConstants {
  122.34 -    protected ClassWriter factory;      // matcher allocator, also bit set, code rage and string template container
  122.35 -    protected MethodVisitor factoryInit;// factory constructor
  122.36 -    protected String factoryName;
  122.37 -
  122.38 -    protected ClassWriter machine;      // matcher
  122.39 -    protected MethodVisitor machineInit;// matcher constructor
  122.40 -    protected MethodVisitor match;      // actual matcher implementation (the matchAt method)
  122.41 -    protected String machineName;
  122.42 -
  122.43 -    // we will? try to manage visitMaxs ourselves for efficiency
  122.44 -    protected int maxStack = 1;
  122.45 -    protected int maxVars = LAST_INDEX;
  122.46 -
  122.47 -    // for field generation
  122.48 -    protected int bitsets, ranges, templates;
  122.49 -
  122.50 -    // simple class name postfix scheme for now
  122.51 -    static int REG_NUM = 0;
  122.52 -
  122.53 -    // dummy class loader for now
  122.54 -    private static final class DummyClassLoader extends ClassLoader {
  122.55 -        public Class<?> defineClass(String name, byte[] bytes) {
  122.56 -            return super.defineClass(name, bytes, 0, bytes.length);
  122.57 -        }
  122.58 -    };
  122.59 -
  122.60 -    private static final DummyClassLoader loader = new DummyClassLoader();
  122.61 -
  122.62 -    AsmCompilerSupport(Analyser analyser) {
  122.63 -        super(analyser);
  122.64 -    }
  122.65 -
  122.66 -    protected final void prepareFactory() {
  122.67 -        factory = new ClassWriter(ClassWriter.COMPUTE_MAXS);
  122.68 -        factoryName = "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory" + REG_NUM;
  122.69 -
  122.70 -        factory.visit(V1_4, ACC_PUBLIC + ACC_FINAL, factoryName, null, "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory", null);
  122.71 -
  122.72 -        MethodVisitor create = factory.visitMethod(ACC_SYNTHETIC, "create", "(Lorg/joni/Regex;[BII)Lorg/joni/Matcher;", null, null);
  122.73 -        create.visitTypeInsn(NEW, machineName);
  122.74 -        create.visitInsn(DUP);          // instance
  122.75 -        create.visitVarInsn(ALOAD, 1);  // Regex
  122.76 -        create.visitVarInsn(ALOAD, 2);  // bytes[]
  122.77 -        create.visitVarInsn(ILOAD, 3);  // p
  122.78 -        create.visitVarInsn(ILOAD, 4);  // end
  122.79 -        create.visitMethodInsn(INVOKESPECIAL, machineName, "<init>", "(Lorg/joni/Regex;[BII)V");
  122.80 -        create.visitInsn(ARETURN);
  122.81 -        create.visitMaxs(0, 0);
  122.82 -        //create.visitMaxs(6, 5);
  122.83 -        create.visitEnd();
  122.84 -    }
  122.85 -
  122.86 -    protected final void prepareFactoryInit() {
  122.87 -        factoryInit = factory.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
  122.88 -        factoryInit.visitVarInsn(ALOAD, 0);
  122.89 -        factoryInit.visitMethodInsn(INVOKESPECIAL, "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory", "<init>", "()V");
  122.90 -    }
  122.91 -
  122.92 -    protected final void setupFactoryInit() {
  122.93 -        factoryInit.visitInsn(RETURN);
  122.94 -        factoryInit.visitMaxs(0, 0);
  122.95 -        //init.visitMaxs(1, 1);
  122.96 -        factoryInit.visitEnd();
  122.97 -    }
  122.98 -
  122.99 -    protected final void prepareMachine() {
 122.100 -        machine = new ClassWriter(ClassWriter.COMPUTE_MAXS);
 122.101 -        machineName = "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine" + REG_NUM;
 122.102 -    }
 122.103 -
 122.104 -    protected final void prepareMachineInit() {
 122.105 -        machine.visit(V1_4, ACC_PUBLIC + ACC_FINAL, machineName, null, "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine", null);
 122.106 -        machineInit = machine.visitMethod(ACC_PROTECTED, "<init>", "(Lorg/joni/Regex;[BII)V", null, null);
 122.107 -        machineInit.visitVarInsn(ALOAD, THIS);  // this
 122.108 -        machineInit.visitVarInsn(ALOAD, 1);     // Regex
 122.109 -        machineInit.visitVarInsn(ALOAD, 2);     // bytes[]
 122.110 -        machineInit.visitVarInsn(ILOAD, 3);     // p
 122.111 -        machineInit.visitVarInsn(ILOAD, 4);     // end
 122.112 -        machineInit.visitMethodInsn(INVOKESPECIAL, "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine", "<init>", "(Lorg/joni/Regex;[BII)V");
 122.113 -    }
 122.114 -
 122.115 -    protected final void setupMachineInit() {
 122.116 -        if (bitsets + ranges + templates > 0) { // ok, some of these are in use, we'd like to cache the factory
 122.117 -            machine.visitField(ACC_PRIVATE + ACC_FINAL, "factory", "L" + factoryName + ";", null, null);
 122.118 -            machineInit.visitVarInsn(ALOAD, THIS);  // this
 122.119 -            machineInit.visitVarInsn(ALOAD, 1);     // this, Regex
 122.120 -            machineInit.visitFieldInsn(GETFIELD, "jdk/nashorn/internal/runtime/regexp/joni/Regex", "factory", "Lorg/joni/MatcherFactory;"); // this, factory
 122.121 -            machineInit.visitTypeInsn(CHECKCAST, factoryName);
 122.122 -            machineInit.visitFieldInsn(PUTFIELD, machineName, "factory", "L" + factoryName + ";"); // []
 122.123 -        }
 122.124 -
 122.125 -        machineInit.visitInsn(RETURN);
 122.126 -        machineInit.visitMaxs(0, 0);
 122.127 -        //init.visitMaxs(5, 5);
 122.128 -        machineInit.visitEnd();
 122.129 -    }
 122.130 -
 122.131 -    protected final void prepareMachineMatch() {
 122.132 -        match = machine.visitMethod(ACC_SYNTHETIC, "matchAt", "(III)I", null, null);
 122.133 -        move(S, SSTART);        // s = sstart
 122.134 -        load("bytes", "[B");    //
 122.135 -        astore(BYTES);          // byte[]bytes = this.bytes
 122.136 -    }
 122.137 -
 122.138 -    protected final void setupMachineMatch() {
 122.139 -        match.visitInsn(ICONST_M1);
 122.140 -        match.visitInsn(IRETURN);
 122.141 -
 122.142 -        match.visitMaxs(maxStack, maxVars);
 122.143 -        match.visitEnd();
 122.144 -    }
 122.145 -
 122.146 -    protected final void setupClasses() {
 122.147 -        byte[]factoryCode = factory.toByteArray();
 122.148 -        byte[]machineCode = machine.toByteArray();
 122.149 -
 122.150 -        if (Config.DEBUG_ASM) {
 122.151 -            try {
 122.152 -                FileOutputStream fos;
 122.153 -                fos = new FileOutputStream(factoryName.substring(factoryName.lastIndexOf('/') + 1) + ".class");
 122.154 -                fos.write(factoryCode);
 122.155 -                fos.close();
 122.156 -                fos = new FileOutputStream(machineName.substring(machineName.lastIndexOf('/') + 1) + ".class");
 122.157 -                fos.write(machineCode);
 122.158 -                fos.close();
 122.159 -            } catch (IOException ioe) {
 122.160 -                ioe.printStackTrace(Config.err);
 122.161 -            }
 122.162 -        }
 122.163 -
 122.164 -        loader.defineClass(machineName.replace('/', '.'), machineCode);
 122.165 -        Class<?> cls = loader.defineClass(factoryName.replace('/', '.'), factoryCode);
 122.166 -        try {
 122.167 -            regex.factory = (MatcherFactory)cls.newInstance();
 122.168 -        } catch(Exception e) {
 122.169 -            e.printStackTrace(Config.err);
 122.170 -        }
 122.171 -    }
 122.172 -
 122.173 -    protected final void aload(int var) {
 122.174 -        match.visitVarInsn(ALOAD, var);
 122.175 -    }
 122.176 -
 122.177 -    protected final void astore(int var) {
 122.178 -        match.visitVarInsn(ASTORE, var);
 122.179 -    }
 122.180 -
 122.181 -    protected final void loadThis() {
 122.182 -        match.visitVarInsn(ALOAD, THIS);
 122.183 -    }
 122.184 -
 122.185 -    protected final void load(int var) {
 122.186 -        match.visitVarInsn(ILOAD, var);
 122.187 -    }
 122.188 -
 122.189 -    protected final void store(int var) {
 122.190 -        match.visitVarInsn(ISTORE, var);
 122.191 -    }
 122.192 -
 122.193 -    protected final void move(int to, int from) {
 122.194 -        load(from);
 122.195 -        store(to);
 122.196 -    }
 122.197 -
 122.198 -    protected final void load(String field, String singature) {
 122.199 -        loadThis();
 122.200 -        match.visitFieldInsn(GETFIELD, machineName, field, singature);
 122.201 -    }
 122.202 -
 122.203 -    protected final void load(String field) {
 122.204 -        load(field, "I");
 122.205 -    }
 122.206 -
 122.207 -    protected final void store(String field, String singature) {
 122.208 -        loadThis();
 122.209 -        match.visitFieldInsn(PUTFIELD, machineName, field, singature);
 122.210 -    }
 122.211 -
 122.212 -    protected final void store(String field) {
 122.213 -        store(field, "I");
 122.214 -    }
 122.215 -
 122.216 -    protected final String installTemplate(char[] arr, int p, int length) {
 122.217 -        String templateName = TEMPLATE + ++templates;
 122.218 -        installArray(templateName, arr, p, length);
 122.219 -        return templateName;
 122.220 -    }
 122.221 -
 122.222 -    protected final String installCodeRange(int[]arr) {
 122.223 -        String coreRangeName = CODERANGE + ++ranges;
 122.224 -        installArray(coreRangeName, arr);
 122.225 -        return coreRangeName;
 122.226 -    }
 122.227 -
 122.228 -    protected final String installBitSet(int[]arr) {
 122.229 -        String bitsetName = BITSET + ++bitsets;
 122.230 -        installArray(bitsetName, arr);
 122.231 -        return bitsetName;
 122.232 -    }
 122.233 -
 122.234 -    private void installArray(String name, int[]arr) {
 122.235 -        factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[I", null, null);
 122.236 -        factoryInit.visitVarInsn(ALOAD, THIS);          // this;
 122.237 -        loadInt(factoryInit, arr.length);               // this, length
 122.238 -        factoryInit.visitIntInsn(NEWARRAY, T_INT);      // this, arr
 122.239 -        for (int i=0;i < arr.length; i++) buildArray(i, arr[i], IASTORE);
 122.240 -        factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[I");
 122.241 -    }
 122.242 -
 122.243 -    private void installArray(String name, char[]arr, int p, int length) {
 122.244 -        factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[B", null, null);
 122.245 -        factoryInit.visitVarInsn(ALOAD, THIS);          // this;
 122.246 -        loadInt(factoryInit, arr.length);               // this, length
 122.247 -        factoryInit.visitIntInsn(NEWARRAY, T_BYTE);     // this, arr
 122.248 -        for (int i=p, j=0; i < p + length; i++, j++) buildArray(j, arr[i] & 0xff, BASTORE);
 122.249 -        factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[B");
 122.250 -    }
 122.251 -
 122.252 -    private void buildArray(int index, int value, int type) {
 122.253 -        factoryInit.visitInsn(DUP);     // ... arr, arr
 122.254 -        loadInt(factoryInit, index);    // ... arr, arr, index
 122.255 -        loadInt(factoryInit, value);    // ... arr, arr, index, value
 122.256 -        factoryInit.visitInsn(type);    // ... arr
 122.257 -    }
 122.258 -
 122.259 -    private void loadInt(MethodVisitor mv, int value) {
 122.260 -        if (value >= -1 && value <= 5) {
 122.261 -            mv.visitInsn(value + ICONST_0); // ICONST_0 == 3
 122.262 -        } else if (value >= 6 && value <= 127 || value >= -128 && value <= -2) {
 122.263 -            mv.visitIntInsn(BIPUSH, value);
 122.264 -        } else if (value >= 128 && value <= 32767 || value >= -32768 && value <= -129) {
 122.265 -            mv.visitIntInsn(SIPUSH, value);
 122.266 -        } else {
 122.267 -            mv.visitLdcInsn(new Integer(value));
 122.268 -        }
 122.269 -    }
 122.270 -}
   123.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java	Thu May 30 10:58:35 2013 -0700
   123.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java	Mon Jun 03 23:24:36 2013 -0700
   123.3 @@ -51,10 +51,6 @@
   123.4          bits[pos >>> ROOM_SHIFT] &= ~bit(pos);
   123.5      }
   123.6  
   123.7 -    public void invert(int pos) {
   123.8 -        bits[pos >>> ROOM_SHIFT] ^= bit(pos);
   123.9 -    }
  123.10 -
  123.11      public void clear() {
  123.12          for (int i=0; i<BITSET_SIZE; i++) bits[i]=0;
  123.13      }
  123.14 @@ -70,10 +66,6 @@
  123.15          for (int i=from; i<=to && i < SINGLE_BYTE_SIZE; i++) set(i);
  123.16      }
  123.17  
  123.18 -    public void setAll() {
  123.19 -        for (int i=0; i<BITSET_SIZE; i++) bits[i] = ~0;
  123.20 -    }
  123.21 -
  123.22      public void invert() {
  123.23          for (int i=0; i<BITSET_SIZE; i++) bits[i] = ~bits[i];
  123.24      }
   124.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/BitStatus.java	Thu May 30 10:58:35 2013 -0700
   124.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/BitStatus.java	Mon Jun 03 23:24:36 2013 -0700
   124.3 @@ -25,12 +25,15 @@
   124.4      public static int bsClear() {
   124.5          return 0;
   124.6      }
   124.7 +
   124.8      public static int bsAll() {
   124.9          return -1;
  124.10      }
  124.11 +
  124.12      public static boolean bsAt(int stats, int n) {
  124.13          return (n < BIT_STATUS_BITS_NUM ? stats & (1 << n) : (stats & 1)) != 0;
  124.14      }
  124.15 +
  124.16      public static int bsOnAt(int stats, int n) {
  124.17          if (n < BIT_STATUS_BITS_NUM) {
  124.18              stats |= (1 << n);
  124.19 @@ -39,10 +42,6 @@
  124.20          }
  124.21          return stats;
  124.22      }
  124.23 -    public static int bsOnAtSimple(int stats, int n) {
  124.24 -        if (n < BIT_STATUS_BITS_NUM) stats |= (1 << n);
  124.25 -        return stats;
  124.26 -    }
  124.27  
  124.28      public static int bsOnOff(int v, int f, boolean negative) {
  124.29          if (negative) {
   125.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java	Thu May 30 10:58:35 2013 -0700
   125.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java	Mon Jun 03 23:24:36 2013 -0700
   125.3 @@ -53,56 +53,6 @@
   125.4          this.code = regex.code;
   125.5      }
   125.6  
   125.7 -    protected int stkp; // a temporary
   125.8 -    private boolean makeCaptureHistoryTree(CaptureTreeNode node) {
   125.9 -        //CaptureTreeNode child;
  125.10 -        int k = stkp;
  125.11 -        //int k = kp;
  125.12 -
  125.13 -        while (k < stk) {
  125.14 -            StackEntry e = stack[k];
  125.15 -            if (e.type == MEM_START) {
  125.16 -                int n = e.getMemNum();
  125.17 -                if (n <= Config.MAX_CAPTURE_HISTORY_GROUP && bsAt(regex.captureHistory, n)) {
  125.18 -                    CaptureTreeNode child = new CaptureTreeNode();
  125.19 -                    child.group = n;
  125.20 -                    child.beg = e.getMemPStr() - str;
  125.21 -                    node.addChild(child);
  125.22 -                    stkp = k + 1;
  125.23 -                    if (makeCaptureHistoryTree(child)) return true;
  125.24 -
  125.25 -                    k = stkp;
  125.26 -                    child.end = e.getMemPStr() - str;
  125.27 -                }
  125.28 -            } else if (e.type == MEM_END) {
  125.29 -                if (e.getMemNum() == node.group) {
  125.30 -                    node.end = e.getMemPStr() - str;
  125.31 -                    stkp = k;
  125.32 -                    return false;
  125.33 -                }
  125.34 -            }
  125.35 -        }
  125.36 -        return true; /* 1: root node ending. */
  125.37 -    }
  125.38 -
  125.39 -    private void checkCaptureHistory(Region region) {
  125.40 -        CaptureTreeNode node;
  125.41 -        if (region.historyRoot == null) {
  125.42 -            node = region.historyRoot = new CaptureTreeNode();
  125.43 -        } else {
  125.44 -            node = region.historyRoot;
  125.45 -            node.clear();
  125.46 -        }
  125.47 -
  125.48 -        // was clear ???
  125.49 -        node.group = 0;
  125.50 -        node.beg = sstart - str;
  125.51 -        node.end = s      - str;
  125.52 -
  125.53 -        stkp = 0;
  125.54 -        makeCaptureHistoryTree(region.historyRoot);
  125.55 -    }
  125.56 -
  125.57      private boolean stringCmpIC(int caseFlodFlag, int s1, IntHolder ps2, int mbLen, int textEnd) {
  125.58  
  125.59          int s2 = ps2.value;
  125.60 @@ -175,13 +125,6 @@
  125.61                  case OPCode.EXACT5:                     opExact5();                continue;
  125.62                  case OPCode.EXACTN:                     opExactN();                continue;
  125.63  
  125.64 -                case OPCode.EXACTMB2N1:                 opExactMB2N1();            break;
  125.65 -                case OPCode.EXACTMB2N2:                 opExactMB2N2();            continue;
  125.66 -                case OPCode.EXACTMB2N3:                 opExactMB2N3();            continue;
  125.67 -                case OPCode.EXACTMB2N:                  opExactMB2N();             continue;
  125.68 -                case OPCode.EXACTMB3N:                  opExactMB3N();             continue;
  125.69 -                case OPCode.EXACTMBN:                   opExactMBN();              continue;
  125.70 -
  125.71                  case OPCode.EXACT1_IC:                  opExact1IC();              break;
  125.72                  case OPCode.EXACTN_IC:                  opExactNIC();              continue;
  125.73  
  125.74 @@ -199,8 +142,6 @@
  125.75                  case OPCode.ANYCHAR_ML_STAR:            opAnyCharMLStar();         break;
  125.76                  case OPCode.ANYCHAR_STAR_PEEK_NEXT:     opAnyCharStarPeekNext();   break;
  125.77                  case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT:  opAnyCharMLStarPeekNext(); break;
  125.78 -                case OPCode.STATE_CHECK_ANYCHAR_STAR:   opStateCheckAnyCharStar(); break;
  125.79 -                case OPCode.STATE_CHECK_ANYCHAR_ML_STAR:opStateCheckAnyCharMLStar();break;
  125.80  
  125.81                  case OPCode.WORD:                       opWord();                  break;
  125.82                  case OPCode.NOT_WORD:                   opNotWord();               break;
  125.83 @@ -239,11 +180,6 @@
  125.84                  case OPCode.JUMP:                       opJump();                  continue;
  125.85                  case OPCode.PUSH:                       opPush();                  continue;
  125.86  
  125.87 -                // CEC
  125.88 -                case OPCode.STATE_CHECK_PUSH:           opStateCheckPush();        continue;
  125.89 -                case OPCode.STATE_CHECK_PUSH_OR_JUMP:   opStateCheckPushOrJump();  continue;
  125.90 -                case OPCode.STATE_CHECK:                opStateCheck();            continue;
  125.91 -
  125.92                  case OPCode.POP:                        opPop();                   continue;
  125.93                  case OPCode.PUSH_OR_JUMP_EXACT1:        opPushOrJumpExact1();      continue;
  125.94                  case OPCode.PUSH_IF_PEEK_NEXT:          opPushIfPeekNext();        continue;
  125.95 @@ -266,10 +202,6 @@
  125.96                  case OPCode.PUSH_LOOK_BEHIND_NOT:       opPushLookBehindNot();     continue;
  125.97                  case OPCode.FAIL_LOOK_BEHIND_NOT:       opFailLookBehindNot();     continue;
  125.98  
  125.99 -                // USE_SUBEXP_CALL
 125.100 -                case OPCode.CALL:                       opCall();                  continue;
 125.101 -                case OPCode.RETURN:                     opReturn();                continue;
 125.102 -
 125.103                  case OPCode.FINISH:
 125.104                      return finish();
 125.105  
 125.106 @@ -322,9 +254,6 @@
 125.107  
 125.108                  }
 125.109  
 125.110 -                if (Config.USE_CAPTURE_HISTORY) {
 125.111 -                    if (regex.captureHistory != 0) checkCaptureHistory(region);
 125.112 -                }
 125.113              } else {
 125.114                  msaBegin = sstart - str;
 125.115                  msaEnd   = s      - str;
 125.116 @@ -437,125 +366,6 @@
 125.117          sprev = s - 1;
 125.118      }
 125.119  
 125.120 -    private void opExactMB2N1() {
 125.121 -        if (s + 2 > range) {opFail(); return;}
 125.122 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.123 -        ip++; s++;
 125.124 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.125 -        ip++; s++;
 125.126 -        sprev = sbegin; // break;
 125.127 -    }
 125.128 -
 125.129 -    private void opExactMB2N2() {
 125.130 -        if (s + 4 > range) {opFail(); return;}
 125.131 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.132 -        ip++; s++;
 125.133 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.134 -        ip++; s++;
 125.135 -        sprev = s;
 125.136 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.137 -        ip++; s++;
 125.138 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.139 -        ip++; s++;
 125.140 -   }
 125.141 -
 125.142 -    private void opExactMB2N3() {
 125.143 -        if (s + 6 > range) {opFail(); return;}
 125.144 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.145 -        ip++; s++;
 125.146 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.147 -        ip++; s++;
 125.148 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.149 -        ip++; s++;
 125.150 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.151 -        ip++; s++;
 125.152 -        sprev = s;
 125.153 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.154 -        ip++; s++;
 125.155 -        if (code[ip] != chars[s]) {opFail(); return;}
 125.156 -        ip++; s++;
 125.157 -    }
 125.158 -
 125.159 -    private void opExactMB2N() {
 125.160 -        int tlen = code[ip++];
 125.161 -        if (s + tlen * 2 > range) {opFail(); return;}
 125.162 -
 125.163 -        if (Config.USE_STRING_TEMPLATES) {
 125.164 -            char[] bs = regex.templates[code[ip++]];
 125.165 -            int ps = code[ip++];
 125.166 -
 125.167 -            while(tlen-- > 0) {
 125.168 -                if (bs[ps] != chars[s]) {opFail(); return;}
 125.169 -                ps++; s++;
 125.170 -                if (bs[ps] != chars[s]) {opFail(); return;}
 125.171 -                ps++; s++;
 125.172 -            }
 125.173 -        } else {
 125.174 -            while(tlen-- > 0) {
 125.175 -                if (code[ip] != chars[s]) {opFail(); return;}
 125.176 -                ip++; s++;
 125.177 -                if (code[ip] != chars[s]) {opFail(); return;}
 125.178 -                ip++; s++;
 125.179 -            }
 125.180 -        }
 125.181 -        sprev = s - 2;
 125.182 -    }
 125.183 -
 125.184 -    private void opExactMB3N() {
 125.185 -        int tlen = code[ip++];
 125.186 -        if (s + tlen * 3 > range) {opFail(); return;}
 125.187 -
 125.188 -        if (Config.USE_STRING_TEMPLATES) {
 125.189 -            char[] bs = regex.templates[code[ip++]];
 125.190 -            int ps = code[ip++];
 125.191 -
 125.192 -            while (tlen-- > 0) {
 125.193 -                if (bs[ps] != chars[s]) {opFail(); return;}
 125.194 -                ps++; s++;
 125.195 -                if (bs[ps] != chars[s]) {opFail(); return;}
 125.196 -                ps++; s++;
 125.197 -                if (bs[ps] != chars[s]) {opFail(); return;}
 125.198 -                ps++; s++;
 125.199 -            }
 125.200 -        } else {
 125.201 -            while (tlen-- > 0) {
 125.202 -                if (code[ip] != chars[s]) {opFail(); return;}
 125.203 -                ip++; s++;
 125.204 -                if (code[ip] != chars[s]) {opFail(); return;}
 125.205 -                ip++; s++;
 125.206 -                if (code[ip] != chars[s]) {opFail(); return;}
 125.207 -                ip++; s++;
 125.208 -            }
 125.209 -        }
 125.210 -
 125.211 -        sprev = s - 3;
 125.212 -    }
 125.213 -
 125.214 -    private void opExactMBN() {
 125.215 -        int tlen = code[ip++];   /* mb-len */
 125.216 -        int tlen2= code[ip++];   /* string len */
 125.217 -
 125.218 -        tlen2 *= tlen;
 125.219 -        if (s + tlen2 > range) {opFail(); return;}
 125.220 -
 125.221 -        if (Config.USE_STRING_TEMPLATES) {
 125.222 -            char[] bs = regex.templates[code[ip++]];
 125.223 -            int ps = code[ip++];
 125.224 -
 125.225 -            while (tlen2-- > 0) {
 125.226 -                if (bs[ps] != chars[s]) {opFail(); return;}
 125.227 -                ps++; s++;
 125.228 -            }
 125.229 -        } else {
 125.230 -            while (tlen2-- > 0) {
 125.231 -                if (code[ip] != chars[s]) {opFail(); return;}
 125.232 -                ip++; s++;
 125.233 -            }
 125.234 -        }
 125.235 -
 125.236 -        sprev = s - tlen;
 125.237 -    }
 125.238 -
 125.239      private void opExact1IC() {
 125.240          if (s >= range || code[ip] != Character.toLowerCase(chars[s++])) {opFail(); return;}
 125.241          ip++;
 125.242 @@ -748,34 +558,6 @@
 125.243          sprev = sbegin; // break;
 125.244      }
 125.245  
 125.246 -    // CEC
 125.247 -    private void opStateCheckAnyCharStar() {
 125.248 -        int mem = code[ip++];
 125.249 -        final char[] chars = this.chars;
 125.250 -
 125.251 -        while (s < range) {
 125.252 -            if (stateCheckVal(s, mem)) {opFail(); return;}
 125.253 -            pushAltWithStateCheck(ip, s, sprev, mem);
 125.254 -            if (chars[s] == EncodingHelper.NEW_LINE) {opFail(); return;}
 125.255 -            sprev = s;
 125.256 -            s++;
 125.257 -        }
 125.258 -        sprev = sbegin; // break;
 125.259 -    }
 125.260 -
 125.261 -    // CEC
 125.262 -    private void opStateCheckAnyCharMLStar() {
 125.263 -        int mem = code[ip++];
 125.264 -
 125.265 -        while (s < range) {
 125.266 -            if (stateCheckVal(s, mem)) {opFail(); return;}
 125.267 -            pushAltWithStateCheck(ip, s, sprev, mem);
 125.268 -            sprev = s;
 125.269 -            s++;
 125.270 -        }
 125.271 -        sprev = sbegin; // break;
 125.272 -    }
 125.273 -
 125.274      private void opWord() {
 125.275          if (s >= range || !EncodingHelper.isWord(chars[s])) {opFail(); return;}
 125.276          s++;
 125.277 @@ -1223,33 +1005,6 @@
 125.278          pushAlt(ip + addr, s, sprev);
 125.279      }
 125.280  
 125.281 -    // CEC
 125.282 -    private void opStateCheckPush() {
 125.283 -        int mem = code[ip++];
 125.284 -        if (stateCheckVal(s, mem)) {opFail(); return;}
 125.285 -        int addr = code[ip++];
 125.286 -        pushAltWithStateCheck(ip + addr, s, sprev, mem);
 125.287 -    }
 125.288 -
 125.289 -    // CEC
 125.290 -    private void opStateCheckPushOrJump() {
 125.291 -        int mem = code[ip++];
 125.292 -        int addr= code[ip++];
 125.293 -
 125.294 -        if (stateCheckVal(s, mem)) {
 125.295 -            ip += addr;
 125.296 -        } else {
 125.297 -            pushAltWithStateCheck(ip + addr, s, sprev, mem);
 125.298 -        }
 125.299 -    }
 125.300 -
 125.301 -    // CEC
 125.302 -    private void opStateCheck() {
 125.303 -        int mem = code[ip++];
 125.304 -        if (stateCheckVal(s, mem)) {opFail(); return;}
 125.305 -        pushStateCheck(s, mem);
 125.306 -    }
 125.307 -
 125.308      private void opPop() {
 125.309          popOne();
 125.310      }
 125.311 @@ -1425,17 +1180,6 @@
 125.312          opFail();
 125.313      }
 125.314  
 125.315 -    private void opCall() {
 125.316 -        int addr = code[ip++];
 125.317 -        pushCallFrame(ip);
 125.318 -        ip = addr; // absolute address
 125.319 -    }
 125.320 -
 125.321 -    private void opReturn() {
 125.322 -        ip = sreturn();
 125.323 -        pushReturn();
 125.324 -    }
 125.325 -
 125.326      private void opFail() {
 125.327          if (stack == null) {
 125.328              ip = regex.codeLength - 1;
 125.329 @@ -1447,13 +1191,6 @@
 125.330          ip    = e.getStatePCode();
 125.331          s     = e.getStatePStr();
 125.332          sprev = e.getStatePStrPrev();
 125.333 -
 125.334 -        if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
 125.335 -            if (e.getStateCheck() != 0) {
 125.336 -                e.type = STATE_CHECK_MARK;
 125.337 -                stk++;
 125.338 -            }
 125.339 -        }
 125.340      }
 125.341  
 125.342      private int finish() {
   126.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodePrinter.java	Thu May 30 10:58:35 2013 -0700
   126.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodePrinter.java	Mon Jun 03 23:24:36 2013 -0700
   126.3 @@ -34,6 +34,239 @@
   126.4      int operantCount;
   126.5      WarnCallback warnings;
   126.6  
   126.7 +    private final static String OpCodeNames[] = new String[] {
   126.8 +            "finish", /*OP_FINISH*/
   126.9 +            "end", /*OP_END*/
  126.10 +            "exact1", /*OP_EXACT1*/
  126.11 +            "exact2", /*OP_EXACT2*/
  126.12 +            "exact3", /*OP_EXACT3*/
  126.13 +            "exact4", /*OP_EXACT4*/
  126.14 +            "exact5", /*OP_EXACT5*/
  126.15 +            "exactn", /*OP_EXACTN*/
  126.16 +            "exactmb2-n1", /*OP_EXACTMB2N1*/
  126.17 +            "exactmb2-n2", /*OP_EXACTMB2N2*/
  126.18 +            "exactmb2-n3", /*OP_EXACTMB2N3*/
  126.19 +            "exactmb2-n", /*OP_EXACTMB2N*/
  126.20 +            "exactmb3n", /*OP_EXACTMB3N*/
  126.21 +            "exactmbn", /*OP_EXACTMBN*/
  126.22 +            "exact1-ic", /*OP_EXACT1_IC*/
  126.23 +            "exactn-ic", /*OP_EXACTN_IC*/
  126.24 +            "cclass", /*OP_CCLASS*/
  126.25 +            "cclass-mb", /*OP_CCLASS_MB*/
  126.26 +            "cclass-mix", /*OP_CCLASS_MIX*/
  126.27 +            "cclass-not", /*OP_CCLASS_NOT*/
  126.28 +            "cclass-mb-not", /*OP_CCLASS_MB_NOT*/
  126.29 +            "cclass-mix-not", /*OP_CCLASS_MIX_NOT*/
  126.30 +            "cclass-node", /*OP_CCLASS_NODE*/
  126.31 +            "anychar", /*OP_ANYCHAR*/
  126.32 +            "anychar-ml", /*OP_ANYCHAR_ML*/
  126.33 +            "anychar*", /*OP_ANYCHAR_STAR*/
  126.34 +            "anychar-ml*", /*OP_ANYCHAR_ML_STAR*/
  126.35 +            "anychar*-peek-next", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
  126.36 +            "anychar-ml*-peek-next", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
  126.37 +            "word", /*OP_WORD*/
  126.38 +            "not-word", /*OP_NOT_WORD*/
  126.39 +            "word-bound", /*OP_WORD_BOUND*/
  126.40 +            "not-word-bound", /*OP_NOT_WORD_BOUND*/
  126.41 +            "word-begin", /*OP_WORD_BEGIN*/
  126.42 +            "word-end", /*OP_WORD_END*/
  126.43 +            "begin-buf", /*OP_BEGIN_BUF*/
  126.44 +            "end-buf", /*OP_END_BUF*/
  126.45 +            "begin-line", /*OP_BEGIN_LINE*/
  126.46 +            "end-line", /*OP_END_LINE*/
  126.47 +            "semi-end-buf", /*OP_SEMI_END_BUF*/
  126.48 +            "begin-position", /*OP_BEGIN_POSITION*/
  126.49 +            "backref1", /*OP_BACKREF1*/
  126.50 +            "backref2", /*OP_BACKREF2*/
  126.51 +            "backrefn", /*OP_BACKREFN*/
  126.52 +            "backrefn-ic", /*OP_BACKREFN_IC*/
  126.53 +            "backref_multi", /*OP_BACKREF_MULTI*/
  126.54 +            "backref_multi-ic", /*OP_BACKREF_MULTI_IC*/
  126.55 +            "backref_at_level", /*OP_BACKREF_AT_LEVEL*/
  126.56 +            "mem-start", /*OP_MEMORY_START*/
  126.57 +            "mem-start-push", /*OP_MEMORY_START_PUSH*/
  126.58 +            "mem-end-push", /*OP_MEMORY_END_PUSH*/
  126.59 +            "mem-end-push-rec", /*OP_MEMORY_END_PUSH_REC*/
  126.60 +            "mem-end", /*OP_MEMORY_END*/
  126.61 +            "mem-end-rec", /*OP_MEMORY_END_REC*/
  126.62 +            "fail", /*OP_FAIL*/
  126.63 +            "jump", /*OP_JUMP*/
  126.64 +            "push", /*OP_PUSH*/
  126.65 +            "pop", /*OP_POP*/
  126.66 +            "push-or-jump-e1", /*OP_PUSH_OR_JUMP_EXACT1*/
  126.67 +            "push-if-peek-next", /*OP_PUSH_IF_PEEK_NEXT*/
  126.68 +            "repeat", /*OP_REPEAT*/
  126.69 +            "repeat-ng", /*OP_REPEAT_NG*/
  126.70 +            "repeat-inc", /*OP_REPEAT_INC*/
  126.71 +            "repeat-inc-ng", /*OP_REPEAT_INC_NG*/
  126.72 +            "repeat-inc-sg", /*OP_REPEAT_INC_SG*/
  126.73 +            "repeat-inc-ng-sg", /*OP_REPEAT_INC_NG_SG*/
  126.74 +            "null-check-start", /*OP_NULL_CHECK_START*/
  126.75 +            "null-check-end", /*OP_NULL_CHECK_END*/
  126.76 +            "null-check-end-memst", /*OP_NULL_CHECK_END_MEMST*/
  126.77 +            "null-check-end-memst-push", /*OP_NULL_CHECK_END_MEMST_PUSH*/
  126.78 +            "push-pos", /*OP_PUSH_POS*/
  126.79 +            "pop-pos", /*OP_POP_POS*/
  126.80 +            "push-pos-not", /*OP_PUSH_POS_NOT*/
  126.81 +            "fail-pos", /*OP_FAIL_POS*/
  126.82 +            "push-stop-bt", /*OP_PUSH_STOP_BT*/
  126.83 +            "pop-stop-bt", /*OP_POP_STOP_BT*/
  126.84 +            "look-behind", /*OP_LOOK_BEHIND*/
  126.85 +            "push-look-behind-not", /*OP_PUSH_LOOK_BEHIND_NOT*/
  126.86 +            "fail-look-behind-not", /*OP_FAIL_LOOK_BEHIND_NOT*/
  126.87 +            "call", /*OP_CALL*/
  126.88 +            "return", /*OP_RETURN*/
  126.89 +            "state-check-push", /*OP_STATE_CHECK_PUSH*/
  126.90 +            "state-check-push-or-jump", /*OP_STATE_CHECK_PUSH_OR_JUMP*/
  126.91 +            "state-check", /*OP_STATE_CHECK*/
  126.92 +            "state-check-anychar*", /*OP_STATE_CHECK_ANYCHAR_STAR*/
  126.93 +            "state-check-anychar-ml*", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
  126.94 +            "set-option-push", /*OP_SET_OPTION_PUSH*/
  126.95 +            "set-option", /*OP_SET_OPTION*/
  126.96 +
  126.97 +            // single byte versions
  126.98 +            "anychar-sb", /*OP_ANYCHAR*/
  126.99 +            "anychar-ml-sb", /*OP_ANYCHAR_ML*/
 126.100 +            "anychar*-sb", /*OP_ANYCHAR_STAR*/
 126.101 +            "anychar-ml*-sb", /*OP_ANYCHAR_ML_STAR*/
 126.102 +            "anychar*-peek-next-sb", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
 126.103 +            "anychar-ml*-peek-next-sb", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
 126.104 +            "state-check-anychar*-sb", /*OP_STATE_CHECK_ANYCHAR_STAR*/
 126.105 +            "state-check-anychar-ml*-sb", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
 126.106 +
 126.107 +            "cclass-sb", /*OP_CCLASS*/
 126.108 +            "cclass-not-sb", /*OP_CCLASS_NOT*/
 126.109 +
 126.110 +            "word-sb", /*OP_WORD*/
 126.111 +            "not-word-sb", /*OP_NOT_WORD*/
 126.112 +            "word-bound-sb", /*OP_WORD_BOUND*/
 126.113 +            "not-word-bound-sb", /*OP_NOT_WORD_BOUND*/
 126.114 +            "word-begin-sb", /*OP_WORD_BEGIN*/
 126.115 +            "word-end-sb", /*OP_WORD_END*/
 126.116 +
 126.117 +            "look-behind-sb", /*OP_LOOK_BEHIND*/
 126.118 +
 126.119 +            "exact1-ic-sb", /*OP_EXACT1_IC*/
 126.120 +            "exactn-ic-sb", /*OP_EXACTN_IC*/
 126.121 +
 126.122 +    };
 126.123 +
 126.124 +    private final static int OpCodeArgTypes[] = new int[] {
 126.125 +            Arguments.NON, /*OP_FINISH*/
 126.126 +            Arguments.NON, /*OP_END*/
 126.127 +            Arguments.SPECIAL, /*OP_EXACT1*/
 126.128 +            Arguments.SPECIAL, /*OP_EXACT2*/
 126.129 +            Arguments.SPECIAL, /*OP_EXACT3*/
 126.130 +            Arguments.SPECIAL, /*OP_EXACT4*/
 126.131 +            Arguments.SPECIAL, /*OP_EXACT5*/
 126.132 +            Arguments.SPECIAL, /*OP_EXACTN*/
 126.133 +            Arguments.SPECIAL, /*OP_EXACTMB2N1*/
 126.134 +            Arguments.SPECIAL, /*OP_EXACTMB2N2*/
 126.135 +            Arguments.SPECIAL, /*OP_EXACTMB2N3*/
 126.136 +            Arguments.SPECIAL, /*OP_EXACTMB2N*/
 126.137 +            Arguments.SPECIAL, /*OP_EXACTMB3N*/
 126.138 +            Arguments.SPECIAL, /*OP_EXACTMBN*/
 126.139 +            Arguments.SPECIAL, /*OP_EXACT1_IC*/
 126.140 +            Arguments.SPECIAL, /*OP_EXACTN_IC*/
 126.141 +            Arguments.SPECIAL, /*OP_CCLASS*/
 126.142 +            Arguments.SPECIAL, /*OP_CCLASS_MB*/
 126.143 +            Arguments.SPECIAL, /*OP_CCLASS_MIX*/
 126.144 +            Arguments.SPECIAL, /*OP_CCLASS_NOT*/
 126.145 +            Arguments.SPECIAL, /*OP_CCLASS_MB_NOT*/
 126.146 +            Arguments.SPECIAL, /*OP_CCLASS_MIX_NOT*/
 126.147 +            Arguments.SPECIAL, /*OP_CCLASS_NODE*/
 126.148 +            Arguments.NON, /*OP_ANYCHAR*/
 126.149 +            Arguments.NON, /*OP_ANYCHAR_ML*/
 126.150 +            Arguments.NON, /*OP_ANYCHAR_STAR*/
 126.151 +            Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
 126.152 +            Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
 126.153 +            Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
 126.154 +            Arguments.NON, /*OP_WORD*/
 126.155 +            Arguments.NON, /*OP_NOT_WORD*/
 126.156 +            Arguments.NON, /*OP_WORD_BOUND*/
 126.157 +            Arguments.NON, /*OP_NOT_WORD_BOUND*/
 126.158 +            Arguments.NON, /*OP_WORD_BEGIN*/
 126.159 +            Arguments.NON, /*OP_WORD_END*/
 126.160 +            Arguments.NON, /*OP_BEGIN_BUF*/
 126.161 +            Arguments.NON, /*OP_END_BUF*/
 126.162 +            Arguments.NON, /*OP_BEGIN_LINE*/
 126.163 +            Arguments.NON, /*OP_END_LINE*/
 126.164 +            Arguments.NON, /*OP_SEMI_END_BUF*/
 126.165 +            Arguments.NON, /*OP_BEGIN_POSITION*/
 126.166 +            Arguments.NON, /*OP_BACKREF1*/
 126.167 +            Arguments.NON, /*OP_BACKREF2*/
 126.168 +            Arguments.MEMNUM, /*OP_BACKREFN*/
 126.169 +            Arguments.SPECIAL, /*OP_BACKREFN_IC*/
 126.170 +            Arguments.SPECIAL, /*OP_BACKREF_MULTI*/
 126.171 +            Arguments.SPECIAL, /*OP_BACKREF_MULTI_IC*/
 126.172 +            Arguments.SPECIAL, /*OP_BACKREF_AT_LEVEL*/
 126.173 +            Arguments.MEMNUM, /*OP_MEMORY_START*/
 126.174 +            Arguments.MEMNUM, /*OP_MEMORY_START_PUSH*/
 126.175 +            Arguments.MEMNUM, /*OP_MEMORY_END_PUSH*/
 126.176 +            Arguments.MEMNUM, /*OP_MEMORY_END_PUSH_REC*/
 126.177 +            Arguments.MEMNUM, /*OP_MEMORY_END*/
 126.178 +            Arguments.MEMNUM, /*OP_MEMORY_END_REC*/
 126.179 +            Arguments.NON, /*OP_FAIL*/
 126.180 +            Arguments.RELADDR, /*OP_JUMP*/
 126.181 +            Arguments.RELADDR, /*OP_PUSH*/
 126.182 +            Arguments.NON, /*OP_POP*/
 126.183 +            Arguments.SPECIAL, /*OP_PUSH_OR_JUMP_EXACT1*/
 126.184 +            Arguments.SPECIAL, /*OP_PUSH_IF_PEEK_NEXT*/
 126.185 +            Arguments.SPECIAL, /*OP_REPEAT*/
 126.186 +            Arguments.SPECIAL, /*OP_REPEAT_NG*/
 126.187 +            Arguments.MEMNUM, /*OP_REPEAT_INC*/
 126.188 +            Arguments.MEMNUM, /*OP_REPEAT_INC_NG*/
 126.189 +            Arguments.MEMNUM, /*OP_REPEAT_INC_SG*/
 126.190 +            Arguments.MEMNUM, /*OP_REPEAT_INC_NG_SG*/
 126.191 +            Arguments.MEMNUM, /*OP_NULL_CHECK_START*/
 126.192 +            Arguments.MEMNUM, /*OP_NULL_CHECK_END*/
 126.193 +            Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST*/
 126.194 +            Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST_PUSH*/
 126.195 +            Arguments.NON, /*OP_PUSH_POS*/
 126.196 +            Arguments.NON, /*OP_POP_POS*/
 126.197 +            Arguments.RELADDR, /*OP_PUSH_POS_NOT*/
 126.198 +            Arguments.NON, /*OP_FAIL_POS*/
 126.199 +            Arguments.NON, /*OP_PUSH_STOP_BT*/
 126.200 +            Arguments.NON, /*OP_POP_STOP_BT*/
 126.201 +            Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
 126.202 +            Arguments.SPECIAL, /*OP_PUSH_LOOK_BEHIND_NOT*/
 126.203 +            Arguments.NON, /*OP_FAIL_LOOK_BEHIND_NOT*/
 126.204 +            Arguments.ABSADDR, /*OP_CALL*/
 126.205 +            Arguments.NON, /*OP_RETURN*/
 126.206 +            Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH*/
 126.207 +            Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH_OR_JUMP*/
 126.208 +            Arguments.STATE_CHECK, /*OP_STATE_CHECK*/
 126.209 +            Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
 126.210 +            Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
 126.211 +            Arguments.OPTION, /*OP_SET_OPTION_PUSH*/
 126.212 +            Arguments.OPTION, /*OP_SET_OPTION*/
 126.213 +
 126.214 +            // single byte versions
 126.215 +            Arguments.NON, /*OP_ANYCHAR*/
 126.216 +            Arguments.NON, /*OP_ANYCHAR_ML*/
 126.217 +            Arguments.NON, /*OP_ANYCHAR_STAR*/
 126.218 +            Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
 126.219 +            Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
 126.220 +            Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
 126.221 +            Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
 126.222 +            Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
 126.223 +
 126.224 +            Arguments.SPECIAL, /*OP_CCLASS*/
 126.225 +            Arguments.SPECIAL, /*OP_CCLASS_NOT*/
 126.226 +
 126.227 +            Arguments.NON, /*OP_WORD*/
 126.228 +            Arguments.NON, /*OP_NOT_WORD*/
 126.229 +            Arguments.NON, /*OP_WORD_BOUND*/
 126.230 +            Arguments.NON, /*OP_NOT_WORD_BOUND*/
 126.231 +            Arguments.NON, /*OP_WORD_BEGIN*/
 126.232 +            Arguments.NON, /*OP_WORD_END*/
 126.233 +
 126.234 +            Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
 126.235 +
 126.236 +            Arguments.SPECIAL, /*OP_EXACT1_IC*/
 126.237 +            Arguments.SPECIAL, /*OP_EXACTN_IC*/
 126.238 +    };
 126.239 +
 126.240      public ByteCodePrinter(Regex regex) {
 126.241          code = regex.code;
 126.242          codeLength = regex.codeLength;
 126.243 @@ -76,8 +309,8 @@
 126.244          CClassNode cc;
 126.245          int tm, idx;
 126.246  
 126.247 -        sb.append("[" + OPCode.OpCodeNames[code[bp]]);
 126.248 -        int argType = OPCode.OpCodeArgTypes[code[bp]];
 126.249 +        sb.append("[" + OpCodeNames[code[bp]]);
 126.250 +        int argType = OpCodeArgTypes[code[bp]];
 126.251          int ip = bp;
 126.252          if (argType != Arguments.SPECIAL) {
 126.253              bp++;
   127.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/CaptureTreeNode.java	Thu May 30 10:58:35 2013 -0700
   127.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   127.3 @@ -1,74 +0,0 @@
   127.4 -/*
   127.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   127.6 - * this software and associated documentation files (the "Software"), to deal in
   127.7 - * the Software without restriction, including without limitation the rights to
   127.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   127.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  127.10 - * so, subject to the following conditions:
  127.11 - *
  127.12 - * The above copyright notice and this permission notice shall be included in all
  127.13 - * copies or substantial portions of the Software.
  127.14 - *
  127.15 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  127.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  127.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  127.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  127.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  127.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  127.21 - * SOFTWARE.
  127.22 - */
  127.23 -package jdk.nashorn.internal.runtime.regexp.joni;
  127.24 -
  127.25 -public class CaptureTreeNode {
  127.26 -
  127.27 -
  127.28 -    int group;
  127.29 -    int beg;
  127.30 -    int end;
  127.31 -    // int allocated;
  127.32 -    int numChildren;
  127.33 -    CaptureTreeNode[]children;
  127.34 -
  127.35 -    CaptureTreeNode() {
  127.36 -        beg = Region.REGION_NOTPOS;
  127.37 -        end = Region.REGION_NOTPOS;
  127.38 -        group = -1;
  127.39 -    }
  127.40 -
  127.41 -    static final int HISTORY_TREE_INIT_ALLOC_SIZE = 8;
  127.42 -    void addChild(CaptureTreeNode child) {
  127.43 -        if (children == null) {
  127.44 -            children = new CaptureTreeNode[HISTORY_TREE_INIT_ALLOC_SIZE];
  127.45 -        } else if (numChildren >= children.length) {
  127.46 -            CaptureTreeNode[]tmp = new CaptureTreeNode[children.length << 1];
  127.47 -            System.arraycopy(children, 0, tmp, 0, children.length);
  127.48 -            children = tmp;
  127.49 -        }
  127.50 -
  127.51 -        children[numChildren] = child;
  127.52 -        numChildren++;
  127.53 -    }
  127.54 -
  127.55 -    void clear() {
  127.56 -        for (int i=0; i<numChildren; i++) {
  127.57 -            children[i] = null; // ???
  127.58 -        }
  127.59 -        numChildren = 0;
  127.60 -        beg = end = Region.REGION_NOTPOS;
  127.61 -        group = -1;
  127.62 -    }
  127.63 -
  127.64 -    CaptureTreeNode cloneTree() {
  127.65 -        CaptureTreeNode clone = new CaptureTreeNode();
  127.66 -        clone.beg = beg;
  127.67 -        clone.end = end;
  127.68 -
  127.69 -        for (int i=0; i<numChildren; i++) {
  127.70 -            CaptureTreeNode child = children[i].cloneTree();
  127.71 -            clone.addChild(child);
  127.72 -        }
  127.73 -        return clone;
  127.74 -    }
  127.75 -
  127.76 -
  127.77 -}
   128.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/Compiler.java	Thu May 30 10:58:35 2013 -0700
   128.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Compiler.java	Mon Jun 03 23:24:36 2013 -0700
   128.3 @@ -22,8 +22,6 @@
   128.4  import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
   128.5  import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
   128.6  import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
   128.7 -import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
   128.8 -import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
   128.9  import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
  128.10  import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
  128.11  import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
  128.12 @@ -56,7 +54,7 @@
  128.13  
  128.14      private void compileStringRawNode(StringNode sn) {
  128.15          if (sn.length() <= 0) return;
  128.16 -        addCompileString(sn.chars, sn.p, 1 /*sb*/, sn.length(), false);
  128.17 +        addCompileString(sn.chars, sn.p, sn.length(), false);
  128.18      }
  128.19  
  128.20      private void compileStringNode(StringNode node) {
  128.21 @@ -76,17 +74,14 @@
  128.22              slen++;
  128.23              p++;
  128.24          }
  128.25 -        addCompileString(chars, prev, 1, slen, ambig);
  128.26 +        addCompileString(chars, prev, slen, ambig);
  128.27      }
  128.28  
  128.29 -    protected abstract void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase);
  128.30 +    protected abstract void addCompileString(char[] chars, int p, int strLength, boolean ignoreCase);
  128.31  
  128.32      protected abstract void compileCClassNode(CClassNode node);
  128.33 -    protected abstract void compileCTypeNode(CTypeNode node);
  128.34      protected abstract void compileAnyCharNode();
  128.35 -    protected abstract void compileCallNode(CallNode node);
  128.36      protected abstract void compileBackrefNode(BackRefNode node);
  128.37 -    protected abstract void compileCECQuantifierNode(QuantifierNode node);
  128.38      protected abstract void compileNonCECQuantifierNode(QuantifierNode node);
  128.39      protected abstract void compileOptionNode(EncloseNode node);
  128.40      protected abstract void compileEncloseNode(EncloseNode node);
  128.41 @@ -118,10 +113,6 @@
  128.42              compileCClassNode((CClassNode)node);
  128.43              break;
  128.44  
  128.45 -        case NodeType.CTYPE:
  128.46 -            compileCTypeNode((CTypeNode)node);
  128.47 -            break;
  128.48 -
  128.49          case NodeType.CANY:
  128.50              compileAnyCharNode();
  128.51              break;
  128.52 @@ -130,19 +121,8 @@
  128.53              compileBackrefNode((BackRefNode)node);
  128.54              break;
  128.55  
  128.56 -        case NodeType.CALL:
  128.57 -            if (Config.USE_SUBEXP_CALL) {
  128.58 -                compileCallNode((CallNode)node);
  128.59 -                break;
  128.60 -            } // USE_SUBEXP_CALL
  128.61 -            break;
  128.62 -
  128.63          case NodeType.QTFR:
  128.64 -            if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
  128.65 -                compileCECQuantifierNode((QuantifierNode)node);
  128.66 -            } else {
  128.67 -                compileNonCECQuantifierNode((QuantifierNode)node);
  128.68 -            }
  128.69 +            compileNonCECQuantifierNode((QuantifierNode)node);
  128.70              break;
  128.71  
  128.72          case NodeType.ENCLOSE:
   129.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java	Thu May 30 10:58:35 2013 -0700
   129.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java	Mon Jun 03 23:24:36 2013 -0700
   129.3 @@ -31,10 +31,6 @@
   129.4      final int ENC_CASE_FOLD_DEFAULT = ENC_CASE_FOLD_MIN;
   129.5      final boolean USE_CRNL_AS_LINE_TERMINATOR = false;
   129.6  
   129.7 -    final boolean USE_NAMED_GROUP = true;
   129.8 -    final boolean USE_SUBEXP_CALL = true;
   129.9 -    final boolean USE_BACKREF_WITH_LEVEL = true;                            /* \k<name+n>, \k<name-n> */
  129.10 -
  129.11      final boolean USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT = true; /* /(?:()|())*\2/ */
  129.12      final boolean USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE = true;     /* /\n$/ =~ "\n" */
  129.13      final boolean USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR = false;
  129.14 @@ -42,12 +38,10 @@
  129.15      final boolean CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS = true;
  129.16  
  129.17      final boolean USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE = false;
  129.18 -    final boolean USE_CAPTURE_HISTORY = false;
  129.19      final boolean USE_VARIABLE_META_CHARS = true;
  129.20      final boolean USE_WORD_BEGIN_END = true;                                /* "\<": word-begin, "\>": word-end */
  129.21 -    final boolean USE_POSIX_API_REGION_OPTION = true;                           /* needed for POSIX API support */
  129.22 +    final boolean USE_POSIX_API_REGION_OPTION = false;                           /* needed for POSIX API support */
  129.23      final boolean USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE = true;
  129.24 -    final boolean USE_COMBINATION_EXPLOSION_CHECK = false;
  129.25  
  129.26      final int NREGION                   = 10;
  129.27      final int MAX_BACKREF_NUM           = 1000;
  129.28 @@ -73,13 +67,6 @@
  129.29  
  129.30      final boolean USE_STRING_TEMPLATES              = true; // use embeded string templates in Regex object as byte arrays instead of compiling them into int bytecode array
  129.31  
  129.32 -
  129.33 -    final int MAX_CAPTURE_HISTORY_GROUP             = 31;
  129.34 -
  129.35 -
  129.36 -    final int CHECK_STRING_THRESHOLD_LEN            = 7;
  129.37 -    final int CHECK_BUFF_MAX_SIZE                   = 0x4000;
  129.38 -
  129.39      final boolean NON_UNICODE_SDW                   = true;
  129.40  
  129.41  
  129.42 @@ -95,6 +82,4 @@
  129.43      final boolean DEBUG_COMPILE_BYTE_CODE_INFO      = DEBUG_ALL;
  129.44      final boolean DEBUG_SEARCH                      = DEBUG_ALL;
  129.45      final boolean DEBUG_MATCH                       = DEBUG_ALL;
  129.46 -    final boolean DEBUG_ASM                         = true;
  129.47 -    final boolean DEBUG_ASM_EXEC                    = true;
  129.48  }
   130.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java	Thu May 30 10:58:35 2013 -0700
   130.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java	Mon Jun 03 23:24:36 2013 -0700
   130.3 @@ -95,20 +95,6 @@
   130.4         return s;
   130.5      }
   130.6  
   130.7 -    /* onigenc_with_ascii_strncmp */
   130.8 -    public static int strNCmp(char[] chars1, int p1, int end, char[] chars2, int p2, int n) {
   130.9 -        while (n-- > 0) {
  130.10 -            if (p1 >= end) return chars2[p2];
  130.11 -            int c = chars1[p1];
  130.12 -            int x = chars2[p2] - c;
  130.13 -            if (x != 0) return x;
  130.14 -
  130.15 -            p2++;
  130.16 -            p1++;
  130.17 -        }
  130.18 -        return 0;
  130.19 -    }
  130.20 -
  130.21      public static int mbcToCode(byte[] bytes, int p, int end) {
  130.22          int code = 0;
  130.23          for (int i = p; i < end; i++) {
   131.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java	Thu May 30 10:58:35 2013 -0700
   131.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java	Mon Jun 03 23:24:36 2013 -0700
   131.3 @@ -27,10 +27,7 @@
   131.4  import jdk.nashorn.internal.runtime.regexp.joni.constants.MetaChar;
   131.5  import jdk.nashorn.internal.runtime.regexp.joni.constants.TokenType;
   131.6  import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
   131.7 -import jdk.nashorn.internal.runtime.regexp.joni.encoding.PosixBracket;
   131.8 -import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
   131.9  import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
  131.10 -import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
  131.11  
  131.12  class Lexer extends ScannerSupport {
  131.13      protected final ScanEnvironment env;
  131.14 @@ -215,198 +212,6 @@
  131.15          \k<-num+n>, \k<-num-n>
  131.16       */
  131.17  
  131.18 -    // value implicit (rnameEnd)
  131.19 -    private boolean fetchNameWithLevel(int startCode, Ptr rbackNum, Ptr rlevel) {
  131.20 -        int src = p;
  131.21 -        boolean existLevel = false;
  131.22 -        int isNum = 0;
  131.23 -        int sign = 1;
  131.24 -
  131.25 -        int endCode = nameEndCodePoint(startCode);
  131.26 -        int pnumHead = p;
  131.27 -        int nameEnd = stop;
  131.28 -
  131.29 -        String err = null;
  131.30 -        if (!left()) {
  131.31 -            newValueException(ERR_EMPTY_GROUP_NAME);
  131.32 -        } else {
  131.33 -            fetch();
  131.34 -            if (c == endCode) newValueException(ERR_EMPTY_GROUP_NAME);
  131.35 -            if (Character.isDigit(c)) {
  131.36 -                isNum = 1;
  131.37 -            } else if (c == '-') {
  131.38 -                isNum = 2;
  131.39 -                sign = -1;
  131.40 -                pnumHead = p;
  131.41 -            } else if (!EncodingHelper.isWord(c)) {
  131.42 -                err = ERR_INVALID_GROUP_NAME;
  131.43 -            }
  131.44 -        }
  131.45 -
  131.46 -        while (left()) {
  131.47 -            nameEnd = p;
  131.48 -            fetch();
  131.49 -            if (c == endCode || c == ')' || c == '+' || c == '-') {
  131.50 -                if (isNum == 2) err = ERR_INVALID_GROUP_NAME;
  131.51 -                break;
  131.52 -            }
  131.53 -
  131.54 -            if (isNum != 0) {
  131.55 -                if (EncodingHelper.isDigit(c)) {
  131.56 -                    isNum = 1;
  131.57 -                } else {
  131.58 -                    err = ERR_INVALID_GROUP_NAME;
  131.59 -                    // isNum = 0;
  131.60 -                }
  131.61 -            } else if (!EncodingHelper.isWord(c)) {
  131.62 -                err = ERR_INVALID_CHAR_IN_GROUP_NAME;
  131.63 -            }
  131.64 -        }
  131.65 -
  131.66 -        boolean isEndCode = false;
  131.67 -        if (err == null && c != endCode) {
  131.68 -            if (c == '+' || c == '-') {
  131.69 -                int flag = c == '-' ? -1 : 1;
  131.70 -
  131.71 -                fetch();
  131.72 -                if (!EncodingHelper.isDigit(c)) newValueException(ERR_INVALID_GROUP_NAME, src, stop);
  131.73 -                unfetch();
  131.74 -                int level = scanUnsignedNumber();
  131.75 -                if (level < 0) newValueException(ERR_TOO_BIG_NUMBER);
  131.76 -                rlevel.p = level * flag;
  131.77 -                existLevel = true;
  131.78 -
  131.79 -                fetch();
  131.80 -                isEndCode = c == endCode;
  131.81 -            }
  131.82 -
  131.83 -            if (!isEndCode) {
  131.84 -                err = ERR_INVALID_GROUP_NAME;
  131.85 -                nameEnd = stop;
  131.86 -            }
  131.87 -        }
  131.88 -
  131.89 -        if (err == null) {
  131.90 -            if (isNum != 0) {
  131.91 -                mark();
  131.92 -                p = pnumHead;
  131.93 -                int backNum = scanUnsignedNumber();
  131.94 -                restore();
  131.95 -                if (backNum < 0) {
  131.96 -                    newValueException(ERR_TOO_BIG_NUMBER);
  131.97 -                } else if (backNum == 0) {
  131.98 -                    newValueException(ERR_INVALID_GROUP_NAME, src, stop);
  131.99 -                }
 131.100 -                rbackNum.p = backNum * sign;
 131.101 -            }
 131.102 -            value = nameEnd;
 131.103 -            return existLevel;
 131.104 -        } else {
 131.105 -            newValueException(ERR_INVALID_GROUP_NAME, src, nameEnd);
 131.106 -            return false; // not reached
 131.107 -        }
 131.108 -    }
 131.109 -
 131.110 -    // USE_NAMED_GROUP
 131.111 -    // ref: 0 -> define name    (don't allow number name)
 131.112 -    //      1 -> reference name (allow number name)
 131.113 -    private int fetchNameForNamedGroup(int startCode, boolean ref) {
 131.114 -        int src = p;
 131.115 -        value = 0;
 131.116 -
 131.117 -        int isNum = 0;
 131.118 -        int sign = 1;
 131.119 -
 131.120 -        int endCode = nameEndCodePoint(startCode);
 131.121 -        int pnumHead = p;
 131.122 -        int nameEnd = stop;
 131.123 -
 131.124 -        String err = null;
 131.125 -        if (!left()) {
 131.126 -            newValueException(ERR_EMPTY_GROUP_NAME);
 131.127 -        } else {
 131.128 -            fetch();
 131.129 -            if (c == endCode) newValueException(ERR_EMPTY_GROUP_NAME);
 131.130 -            if (EncodingHelper.isDigit(c)) {
 131.131 -                if (ref) {
 131.132 -                    isNum = 1;
 131.133 -                } else {
 131.134 -                    err = ERR_INVALID_GROUP_NAME;
 131.135 -                    // isNum = 0;
 131.136 -                }
 131.137 -            } else if (c == '-') {
 131.138 -                if (ref) {
 131.139 -                    isNum = 2;
 131.140 -                    sign = -1;
 131.141 -                    pnumHead = p;
 131.142 -                } else {
 131.143 -                    err = ERR_INVALID_GROUP_NAME;
 131.144 -                    // isNum = 0;
 131.145 -                }
 131.146 -            } else if (!EncodingHelper.isWord(c)) {
 131.147 -                err = ERR_INVALID_CHAR_IN_GROUP_NAME;
 131.148 -            }
 131.149 -        }
 131.150 -
 131.151 -        if (err == null) {
 131.152 -            while (left()) {
 131.153 -                nameEnd = p;
 131.154 -                fetch();
 131.155 -                if (c == endCode || c == ')') {
 131.156 -                    if (isNum == 2) err = ERR_INVALID_GROUP_NAME;
 131.157 -                    break;
 131.158 -                }
 131.159 -
 131.160 -                if (isNum != 0) {
 131.161 -                    if (EncodingHelper.isDigit(c)) {
 131.162 -                        isNum = 1;
 131.163 -                    } else {
 131.164 -                        if (!EncodingHelper.isWord(c)) {
 131.165 -                            err = ERR_INVALID_CHAR_IN_GROUP_NAME;
 131.166 -                        } else {
 131.167 -                            err = ERR_INVALID_GROUP_NAME;
 131.168 -                        }
 131.169 -                        // isNum = 0;
 131.170 -                    }
 131.171 -                } else {
 131.172 -                    if (!EncodingHelper.isWord(c)) {
 131.173 -                        err = ERR_INVALID_CHAR_IN_GROUP_NAME;
 131.174 -                    }
 131.175 -                }
 131.176 -            }
 131.177 -
 131.178 -            if (c != endCode) {
 131.179 -                err = ERR_INVALID_GROUP_NAME;
 131.180 -                nameEnd = stop;
 131.181 -            }
 131.182 -
 131.183 -            int backNum = 0;
 131.184 -            if (isNum != 0) {
 131.185 -                mark();
 131.186 -                p = pnumHead;
 131.187 -                backNum = scanUnsignedNumber();
 131.188 -                restore();
 131.189 -                if (backNum < 0) {
 131.190 -                    newValueException(ERR_TOO_BIG_NUMBER);
 131.191 -                } else if (backNum == 0) {
 131.192 -                    newValueException(ERR_INVALID_GROUP_NAME, src, nameEnd);
 131.193 -                }
 131.194 -                backNum *= sign;
 131.195 -            }
 131.196 -            value = nameEnd;
 131.197 -            return backNum;
 131.198 -        } else {
 131.199 -            while (left()) {
 131.200 -                nameEnd = p;
 131.201 -                fetch();
 131.202 -                if (c == endCode || c == ')') break;
 131.203 -            }
 131.204 -            if (!left()) nameEnd = stop;
 131.205 -            newValueException(err, src, nameEnd);
 131.206 -            return 0; // not reached
 131.207 -        }
 131.208 -    }
 131.209 -
 131.210      // #else USE_NAMED_GROUP
 131.211      // make it return nameEnd!
 131.212      private final int fetchNameForNoNamedGroup(int startCode, boolean ref) {
 131.213 @@ -472,11 +277,7 @@
 131.214      }
 131.215  
 131.216      protected final int fetchName(int startCode, boolean ref) {
 131.217 -        if (Config.USE_NAMED_GROUP) {
 131.218 -            return fetchNameForNamedGroup(startCode, ref);
 131.219 -        } else {
 131.220 -            return fetchNameForNoNamedGroup(startCode, ref);
 131.221 -        }
 131.222 +        return fetchNameForNoNamedGroup(startCode, ref);
 131.223      }
 131.224  
 131.225      private boolean strExistCheckWithEsc(int[]s, int n, int bad) {
 131.226 @@ -519,26 +320,6 @@
 131.227          token.setPropNot(flag);
 131.228      }
 131.229  
 131.230 -    private void fetchTokenInCCFor_p() {
 131.231 -        int c2 = peek(); // !!! migrate to peekIs
 131.232 -        if (c2 == '{' && syntax.op2EscPBraceCharProperty()) {
 131.233 -            inc();
 131.234 -            token.type = TokenType.CHAR_PROPERTY;
 131.235 -            token.setPropNot(c == 'P');
 131.236 -
 131.237 -            if (syntax.op2EscPBraceCircumflexNot()) {
 131.238 -                c2 = fetchTo();
 131.239 -                if (c2 == '^') {
 131.240 -                    token.setPropNot(!token.getPropNot());
 131.241 -                } else {
 131.242 -                    unfetch();
 131.243 -                }
 131.244 -            }
 131.245 -        } else {
 131.246 -            syntaxWarn(Warnings.INVALID_UNICODE_PROPERTY, (char)c);
 131.247 -        }
 131.248 -    }
 131.249 -
 131.250      private void fetchTokenInCCFor_x() {
 131.251          if (!left()) return;
 131.252          int last = p;
 131.253 @@ -604,30 +385,6 @@
 131.254          }
 131.255      }
 131.256  
 131.257 -    private void fetchTokenInCCFor_posixBracket() {
 131.258 -        if (syntax.opPosixBracket() && peekIs(':')) {
 131.259 -            token.backP = p; /* point at '[' is readed */
 131.260 -            inc();
 131.261 -            if (strExistCheckWithEsc(send, send.length, ']')) {
 131.262 -                token.type = TokenType.POSIX_BRACKET_OPEN;
 131.263 -            } else {
 131.264 -                unfetch();
 131.265 -                // remove duplication, goto cc_in_cc;
 131.266 -                if (syntax.op2CClassSetOp()) {
 131.267 -                    token.type = TokenType.CC_CC_OPEN;
 131.268 -                } else {
 131.269 -                    env.ccEscWarn("[");
 131.270 -                }
 131.271 -            }
 131.272 -        } else { // cc_in_cc:
 131.273 -            if (syntax.op2CClassSetOp()) {
 131.274 -                token.type = TokenType.CC_CC_OPEN;
 131.275 -            } else {
 131.276 -                env.ccEscWarn("[");
 131.277 -            }
 131.278 -        }
 131.279 -    }
 131.280 -
 131.281      private void fetchTokenInCCFor_and() {
 131.282          if (syntax.op2CClassSetOp() && left() && peekIs('&')) {
 131.283              inc();
 131.284 @@ -683,10 +440,6 @@
 131.285              case 'H':
 131.286                  if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(true, CharacterType.XDIGIT);
 131.287                  break;
 131.288 -            case 'p':
 131.289 -            case 'P':
 131.290 -                fetchTokenInCCFor_p();
 131.291 -                break;
 131.292              case 'x':
 131.293                  fetchTokenInCCFor_x();
 131.294                  break;
 131.295 @@ -714,18 +467,12 @@
 131.296                  break;
 131.297              } // switch
 131.298  
 131.299 -        } else if (c == '[') {
 131.300 -            fetchTokenInCCFor_posixBracket();
 131.301          } else if (c == '&') {
 131.302              fetchTokenInCCFor_and();
 131.303          }
 131.304          return token.type;
 131.305      }
 131.306  
 131.307 -    protected final int backrefRelToAbs(int relNo) {
 131.308 -        return env.numMem + 1 + relNo;
 131.309 -    }
 131.310 -
 131.311      private void fetchTokenFor_repeat(int lower, int upper) {
 131.312          token.type = TokenType.OP_REPEAT;
 131.313          token.setRepeatLower(lower);
 131.314 @@ -815,7 +562,6 @@
 131.315              token.setBackrefNum(1);
 131.316              token.setBackrefRef1(num);
 131.317              token.setBackrefByName(false);
 131.318 -            if (Config.USE_BACKREF_WITH_LEVEL) token.setBackrefExistLevel(false);
 131.319              return;
 131.320          }
 131.321  
 131.322 @@ -845,76 +591,6 @@
 131.323          }
 131.324      }
 131.325  
 131.326 -    private void fetchTokenFor_namedBackref() {
 131.327 -        if (syntax.op2EscKNamedBackref()) {
 131.328 -            if (left()) {
 131.329 -                fetch();
 131.330 -                if (c =='<' || c == '\'') {
 131.331 -                    int last = p;
 131.332 -                    int backNum;
 131.333 -                    if (Config.USE_BACKREF_WITH_LEVEL) {
 131.334 -                        Ptr rbackNum = new Ptr();
 131.335 -                        Ptr rlevel = new Ptr();
 131.336 -                        token.setBackrefExistLevel(fetchNameWithLevel(c, rbackNum, rlevel));
 131.337 -                        token.setBackrefLevel(rlevel.p);
 131.338 -                        backNum = rbackNum.p;
 131.339 -                    } else {
 131.340 -                        backNum = fetchName(c, true);
 131.341 -                    } // USE_BACKREF_AT_LEVEL
 131.342 -                    int nameEnd = value; // set by fetchNameWithLevel/fetchName
 131.343 -
 131.344 -                    if (backNum != 0) {
 131.345 -                        if (backNum < 0) {
 131.346 -                            backNum = backrefRelToAbs(backNum);
 131.347 -                            if (backNum <= 0) newValueException(ERR_INVALID_BACKREF);
 131.348 -                        }
 131.349 -
 131.350 -                        if (syntax.strictCheckBackref() && (backNum > env.numMem || env.memNodes == null)) {
 131.351 -                            newValueException(ERR_INVALID_BACKREF);
 131.352 -                        }
 131.353 -                        token.type = TokenType.BACKREF;
 131.354 -                        token.setBackrefByName(false);
 131.355 -                        token.setBackrefNum(1);
 131.356 -                        token.setBackrefRef1(backNum);
 131.357 -                    } else {
 131.358 -                        NameEntry e = env.reg.nameToGroupNumbers(chars, last, nameEnd);
 131.359 -                        if (e == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, last, nameEnd);
 131.360 -
 131.361 -                        if (syntax.strictCheckBackref()) {
 131.362 -                            if (e.backNum == 1) {
 131.363 -                                if (e.backRef1 > env.numMem ||
 131.364 -                                    env.memNodes == null ||
 131.365 -                                    env.memNodes[e.backRef1] == null) newValueException(ERR_INVALID_BACKREF);
 131.366 -                            } else {
 131.367 -                                for (int i=0; i<e.backNum; i++) {
 131.368 -                                    if (e.backRefs[i] > env.numMem ||
 131.369 -                                        env.memNodes == null ||
 131.370 -                                        env.memNodes[e.backRefs[i]] == null) newValueException(ERR_INVALID_BACKREF);
 131.371 -                                }
 131.372 -                            }
 131.373 -                        }
 131.374 -
 131.375 -                        token.type = TokenType.BACKREF;
 131.376 -                        token.setBackrefByName(true);
 131.377 -
 131.378 -                        if (e.backNum == 1) {
 131.379 -                            token.setBackrefNum(1);
 131.380 -                            token.setBackrefRef1(e.backRef1);
 131.381 -                        } else {
 131.382 -                            token.setBackrefNum(e.backNum);
 131.383 -                            token.setBackrefRefs(e.backRefs);
 131.384 -                        }
 131.385 -                    }
 131.386 -                } else {
 131.387 -                    unfetch();
 131.388 -                    syntaxWarn(Warnings.INVALID_BACKREFERENCE);
 131.389 -                }
 131.390 -            } else {
 131.391 -                syntaxWarn(Warnings.INVALID_BACKREFERENCE);
 131.392 -            }
 131.393 -        }
 131.394 -    }
 131.395 -
 131.396      private void fetchTokenFor_subexpCall() {
 131.397          if (syntax.op2EscGSubexpCall()) {
 131.398              if (left()) {
 131.399 @@ -937,25 +613,6 @@
 131.400          }
 131.401      }
 131.402  
 131.403 -    private void fetchTokenFor_charProperty() {
 131.404 -        if (peekIs('{') && syntax.op2EscPBraceCharProperty()) {
 131.405 -            inc();
 131.406 -            token.type = TokenType.CHAR_PROPERTY;
 131.407 -            token.setPropNot(c == 'P');
 131.408 -
 131.409 -            if (syntax.op2EscPBraceCircumflexNot()) {
 131.410 -                fetch();
 131.411 -                if (c == '^') {
 131.412 -                    token.setPropNot(!token.getPropNot());
 131.413 -                } else {
 131.414 -                    unfetch();
 131.415 -                }
 131.416 -            }
 131.417 -        } else {
 131.418 -            syntaxWarn(Warnings.INVALID_UNICODE_PROPERTY, (char)c);
 131.419 -        }
 131.420 -    }
 131.421 -
 131.422      private void fetchTokenFor_metaChars() {
 131.423          if (c == syntax.metaCharTable.anyChar) {
 131.424              token.type = TokenType.ANYCHAR;
 131.425 @@ -1091,19 +748,6 @@
 131.426                  case '0':
 131.427                      fetchTokenFor_zero();
 131.428                      break;
 131.429 -                case 'k':
 131.430 -                    if (Config.USE_NAMED_GROUP) fetchTokenFor_namedBackref();
 131.431 -                    break;
 131.432 -                case 'g':
 131.433 -                    if (Config.USE_SUBEXP_CALL) fetchTokenFor_subexpCall();
 131.434 -                    break;
 131.435 -                case 'Q':
 131.436 -                    if (syntax.op2EscCapitalQQuote()) token.type = TokenType.QUOTE_OPEN;
 131.437 -                    break;
 131.438 -                case 'p':
 131.439 -                case 'P':
 131.440 -                    fetchTokenFor_charProperty();
 131.441 -                    break;
 131.442  
 131.443                  default:
 131.444                      unfetch();
 131.445 @@ -1244,24 +888,6 @@
 131.446          }
 131.447      }
 131.448  
 131.449 -    protected final int fetchCharPropertyToCType() {
 131.450 -        mark();
 131.451 -
 131.452 -        while (left()) {
 131.453 -            int last = p;
 131.454 -            fetch();
 131.455 -            if (c == '}') {
 131.456 -                String name = new String(chars, _p, last - _p);
 131.457 -                return PosixBracket.propertyNameToCType(name);
 131.458 -            } else if (c == '(' || c == ')' || c == '{' || c == '|') {
 131.459 -                String name = new String(chars, _p, last - _p);
 131.460 -                throw new JOniException(ERR_INVALID_CHAR_PROPERTY_NAME.replaceAll("%n", name));
 131.461 -            }
 131.462 -        }
 131.463 -        newInternalException(ERR_PARSER_BUG);
 131.464 -        return 0; // not reached
 131.465 -    }
 131.466 -
 131.467      protected final void syntaxWarn(String message, char c) {
 131.468          syntaxWarn(message.replace("<%n>", Character.toString(c)));
 131.469      }
   132.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java	Thu May 30 10:58:35 2013 -0700
   132.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java	Mon Jun 03 23:24:36 2013 -0700
   132.3 @@ -58,17 +58,10 @@
   132.4      // main matching method
   132.5      protected abstract int matchAt(int range, int sstart, int sprev);
   132.6  
   132.7 -    protected abstract void stateCheckBuffInit(int strLength, int offset, int stateNum);
   132.8 -    protected abstract void stateCheckBuffClear();
   132.9 -
  132.10      public final Region getRegion() {
  132.11          return msaRegion;
  132.12      }
  132.13  
  132.14 -    public final Region getEagerRegion() {
  132.15 -        return msaRegion != null ? msaRegion : new Region(msaBegin, msaEnd);
  132.16 -    }
  132.17 -
  132.18      public final int getBegin() {
  132.19          return msaBegin;
  132.20      }
  132.21 @@ -86,11 +79,6 @@
  132.22      public final int match(int at, int range, int option) {
  132.23          msaInit(option, at);
  132.24  
  132.25 -        if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
  132.26 -            int offset = at = str;
  132.27 -            stateCheckBuffInit(end - str, offset, regex.numCombExpCheck); // move it to construction?
  132.28 -        } // USE_COMBINATION_EXPLOSION_CHECK
  132.29 -
  132.30          int prev = EncodingHelper.prevCharHead(str, at);
  132.31  
  132.32          if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
  132.33 @@ -377,8 +365,6 @@
  132.34                  prev = -1;
  132.35                  msaInit(option, start);
  132.36  
  132.37 -                if (Config.USE_COMBINATION_EXPLOSION_CHECK) stateCheckBuffClear();
  132.38 -
  132.39                  if (matchCheck(end, s, prev)) return match(s);
  132.40                  return mismatch();
  132.41              }
  132.42 @@ -393,10 +379,6 @@
  132.43          }
  132.44  
  132.45          msaInit(option, origStart);
  132.46 -        if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
  132.47 -            int offset = Math.min(start, range) - str;
  132.48 -            stateCheckBuffInit(end - str, offset, regex.numCombExpCheck);
  132.49 -        }
  132.50  
  132.51          s = start;
  132.52          if (range > start) {    /* forward search */
   133.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/NameEntry.java	Thu May 30 10:58:35 2013 -0700
   133.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   133.3 @@ -1,97 +0,0 @@
   133.4 -/*
   133.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   133.6 - * this software and associated documentation files (the "Software"), to deal in
   133.7 - * the Software without restriction, including without limitation the rights to
   133.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   133.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  133.10 - * so, subject to the following conditions:
  133.11 - *
  133.12 - * The above copyright notice and this permission notice shall be included in all
  133.13 - * copies or substantial portions of the Software.
  133.14 - *
  133.15 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  133.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  133.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  133.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  133.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  133.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  133.21 - * SOFTWARE.
  133.22 - */
  133.23 -package jdk.nashorn.internal.runtime.regexp.joni;
  133.24 -
  133.25 -public final class NameEntry {
  133.26 -    static final int INIT_NAME_BACKREFS_ALLOC_NUM = 8;
  133.27 -
  133.28 -    public final char[] name;
  133.29 -    public final int nameP;
  133.30 -    public final int nameEnd;
  133.31 -
  133.32 -    int backNum;
  133.33 -    int backRef1;
  133.34 -    int backRefs[];
  133.35 -
  133.36 -    public NameEntry(char[] chars, int p, int end) {
  133.37 -        name = chars;
  133.38 -        nameP = p;
  133.39 -        nameEnd = end;
  133.40 -    }
  133.41 -
  133.42 -    public int[] getBackRefs() {
  133.43 -        switch (backNum) {
  133.44 -        case 0:
  133.45 -            return new int[]{};
  133.46 -        case 1:
  133.47 -            return new int[]{backRef1};
  133.48 -        default:
  133.49 -            int[]result = new int[backNum];
  133.50 -            System.arraycopy(backRefs, 0, result, 0, backNum);
  133.51 -            return result;
  133.52 -        }
  133.53 -    }
  133.54 -
  133.55 -    private void alloc() {
  133.56 -        backRefs = new int[INIT_NAME_BACKREFS_ALLOC_NUM];
  133.57 -    }
  133.58 -
  133.59 -    private void ensureSize() {
  133.60 -        if (backNum > backRefs.length) {
  133.61 -            int[]tmp = new int[backRefs.length << 1];
  133.62 -            System.arraycopy(backRefs, 0, tmp, 0, backRefs.length);
  133.63 -            backRefs = tmp;
  133.64 -        }
  133.65 -    }
  133.66 -
  133.67 -    public void addBackref(int backRef) {
  133.68 -        backNum++;
  133.69 -
  133.70 -        switch (backNum) {
  133.71 -            case 1:
  133.72 -                backRef1 = backRef;
  133.73 -                break;
  133.74 -            case 2:
  133.75 -                alloc();
  133.76 -                backRefs[0] = backRef1;
  133.77 -                backRefs[1] = backRef;
  133.78 -                break;
  133.79 -            default:
  133.80 -                ensureSize();
  133.81 -                backRefs[backNum - 1] = backRef;
  133.82 -        }
  133.83 -    }
  133.84 -
  133.85 -    public String toString() {
  133.86 -        StringBuilder buff = new StringBuilder(new String(name, nameP, nameEnd - nameP) + " ");
  133.87 -        if (backNum == 0) {
  133.88 -            buff.append("-");
  133.89 -        } else if (backNum == 1){
  133.90 -            buff.append(backRef1);
  133.91 -        } else {
  133.92 -            for (int i=0; i<backNum; i++){
  133.93 -                if (i > 0) buff.append(", ");
  133.94 -                buff.append(backRefs[i]);
  133.95 -            }
  133.96 -        }
  133.97 -        return buff.toString();
  133.98 -    }
  133.99 -
 133.100 -}
   134.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/NativeMachine.java	Thu May 30 10:58:35 2013 -0700
   134.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   134.3 @@ -1,27 +0,0 @@
   134.4 -/*
   134.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   134.6 - * this software and associated documentation files (the "Software"), to deal in
   134.7 - * the Software without restriction, including without limitation the rights to
   134.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   134.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  134.10 - * so, subject to the following conditions:
  134.11 - *
  134.12 - * The above copyright notice and this permission notice shall be included in all
  134.13 - * copies or substantial portions of the Software.
  134.14 - *
  134.15 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  134.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  134.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  134.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  134.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  134.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  134.21 - * SOFTWARE.
  134.22 - */
  134.23 -package jdk.nashorn.internal.runtime.regexp.joni;
  134.24 -
  134.25 -public abstract class NativeMachine extends Matcher {
  134.26 -
  134.27 -    protected NativeMachine(Regex regex, char[] chars, int p, int end) {
  134.28 -        super(regex, chars, p, end);
  134.29 -    }
  134.30 -}
   135.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java	Thu May 30 10:58:35 2013 -0700
   135.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java	Mon Jun 03 23:24:36 2013 -0700
   135.3 @@ -19,20 +19,15 @@
   135.4   */
   135.5  package jdk.nashorn.internal.runtime.regexp.joni;
   135.6  
   135.7 -import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAtSimple;
   135.8  import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnOff;
   135.9  import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup;
  135.10  import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase;
  135.11  
  135.12  import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
  135.13 -import jdk.nashorn.internal.runtime.regexp.joni.encoding.PosixBracket;
  135.14 -import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
  135.15  import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
  135.16  import jdk.nashorn.internal.runtime.regexp.joni.ast.AnyCharNode;
  135.17  import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
  135.18  import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
  135.19 -import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
  135.20 -import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
  135.21  import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
  135.22  import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
  135.23  import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
  135.24 @@ -66,65 +61,6 @@
  135.25          return root;
  135.26      }
  135.27  
  135.28 -    private static final int POSIX_BRACKET_NAME_MIN_LEN            = 4;
  135.29 -    private static final int POSIX_BRACKET_CHECK_LIMIT_LENGTH      = 20;
  135.30 -    private static final char BRACKET_END[]                        = ":]".toCharArray();
  135.31 -    private boolean parsePosixBracket(CClassNode cc) {
  135.32 -        mark();
  135.33 -
  135.34 -        boolean not;
  135.35 -        if (peekIs('^')) {
  135.36 -            inc();
  135.37 -            not = true;
  135.38 -        } else {
  135.39 -            not = false;
  135.40 -        }
  135.41 -        if (stop - p >= POSIX_BRACKET_NAME_MIN_LEN + 3) { // else goto not_posix_bracket
  135.42 -            char[][] pbs = PosixBracket.PBSNamesLower;
  135.43 -            for (int i=0; i<pbs.length; i++) {
  135.44 -                char[] name = pbs[i];
  135.45 -                // hash lookup here ?
  135.46 -                if (EncodingHelper.strNCmp(chars, p, stop, name, 0, name.length) == 0) {
  135.47 -                    p += name.length;
  135.48 -                    if (EncodingHelper.strNCmp(chars, p, stop, BRACKET_END, 0, BRACKET_END.length) != 0) {
  135.49 -                        newSyntaxException(ERR_INVALID_POSIX_BRACKET_TYPE);
  135.50 -                    }
  135.51 -                    cc.addCType(PosixBracket.PBSValues[i], not, env, this);
  135.52 -                    inc();
  135.53 -                    inc();
  135.54 -                    return false;
  135.55 -                }
  135.56 -            }
  135.57 -
  135.58 -        }
  135.59 -
  135.60 -        // not_posix_bracket:
  135.61 -        c = 0;
  135.62 -        int i= 0;
  135.63 -        while (left() && ((c=peek()) != ':') && c != ']') {
  135.64 -            inc();
  135.65 -            if (++i > POSIX_BRACKET_CHECK_LIMIT_LENGTH) break;
  135.66 -        }
  135.67 -
  135.68 -        if (c == ':' && left()) {
  135.69 -            inc();
  135.70 -            if (left()) {
  135.71 -                fetch();
  135.72 -                if (c == ']') newSyntaxException(ERR_INVALID_POSIX_BRACKET_TYPE);
  135.73 -            }
  135.74 -        }
  135.75 -        restore();
  135.76 -        return true; /* 1: is not POSIX bracket, but no error. */
  135.77 -    }
  135.78 -
  135.79 -    private CClassNode parseCharProperty() {
  135.80 -        int ctype = fetchCharPropertyToCType();
  135.81 -        CClassNode n = new CClassNode();
  135.82 -        n.addCType(ctype, false, env, this);
  135.83 -        if (token.getPropNot()) n.setNot();
  135.84 -        return n;
  135.85 -    }
  135.86 -
  135.87      private boolean codeExistCheck(int code, boolean ignoreEscaped) {
  135.88          mark();
  135.89  
  135.90 @@ -225,29 +161,11 @@
  135.91                  parseCharClassValEntry(cc, arg); // val_entry:, val_entry2
  135.92                  break;
  135.93  
  135.94 -            case POSIX_BRACKET_OPEN:
  135.95 -                if (parsePosixBracket(cc)) { /* true: is not POSIX bracket */
  135.96 -                    env.ccEscWarn("[");
  135.97 -                    p = token.backP;
  135.98 -                    arg.v = token.getC();
  135.99 -                    arg.vIsRaw = false;
 135.100 -                    parseCharClassValEntry(cc, arg); // goto val_entry
 135.101 -                    break;
 135.102 -                }
 135.103 -                cc.nextStateClass(arg, env); // goto next_class
 135.104 -                break;
 135.105 -
 135.106              case CHAR_TYPE:
 135.107                  cc.addCType(token.getPropCType(), token.getPropNot(), env, this);
 135.108                  cc.nextStateClass(arg, env); // next_class:
 135.109                  break;
 135.110  
 135.111 -            case CHAR_PROPERTY:
 135.112 -                int ctype = fetchCharPropertyToCType();
 135.113 -                cc.addCType(ctype, token.getPropNot(), env, this);
 135.114 -                cc.nextStateClass(arg, env); // goto next_class
 135.115 -                break;
 135.116 -
 135.117              case CC_RANGE:
 135.118                  if (arg.state == CCSTATE.VALUE) {
 135.119                      fetchTokenInCC();
 135.120 @@ -413,15 +331,6 @@
 135.121                  node = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
 135.122                  break;
 135.123              case '\'':
 135.124 -                if (Config.USE_NAMED_GROUP) {
 135.125 -                    if (syntax.op2QMarkLtNamedGroup()) {
 135.126 -                        listCapture = false; // goto named_group1
 135.127 -                        node = parseEncloseNamedGroup2(listCapture);
 135.128 -                        break;
 135.129 -                    } else {
 135.130 -                        newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
 135.131 -                    }
 135.132 -                } // USE_NAMED_GROUP
 135.133                  break;
 135.134              case '<':  /* look behind (?<=...), (?<!...) */
 135.135                  fetch();
 135.136 @@ -430,36 +339,12 @@
 135.137                  } else if (c == '!') {
 135.138                      node = new AnchorNode(AnchorType.LOOK_BEHIND_NOT);
 135.139                  } else {
 135.140 -                    if (Config.USE_NAMED_GROUP) {
 135.141 -                        if (syntax.op2QMarkLtNamedGroup()) {
 135.142 -                            unfetch();
 135.143 -                            c = '<';
 135.144 -
 135.145 -                            listCapture = false; // named_group1:
 135.146 -                            node = parseEncloseNamedGroup2(listCapture); // named_group2:
 135.147 -                            break;
 135.148 -                        } else {
 135.149 -                            newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
 135.150 -                        }
 135.151 -
 135.152 -                    } else { // USE_NAMED_GROUP
 135.153 -                        newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
 135.154 -                    } // USE_NAMED_GROUP
 135.155 +                    newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
 135.156                  }
 135.157                  break;
 135.158              case '@':
 135.159                  if (syntax.op2AtMarkCaptureHistory()) {
 135.160 -                    if (Config.USE_NAMED_GROUP) {
 135.161 -                        if (syntax.op2QMarkLtNamedGroup()) {
 135.162 -                            fetch();
 135.163 -                            if (c == '<' || c == '\'') {
 135.164 -                                listCapture = true;
 135.165 -                                node = parseEncloseNamedGroup2(listCapture); // goto named_group2 /* (?@<name>...) */
 135.166 -                            }
 135.167 -                            unfetch();
 135.168 -                        }
 135.169 -                    } // USE_NAMED_GROUP
 135.170 -                    EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
 135.171 +                    EncloseNode en = new EncloseNode(); // node_new_enclose_memory
 135.172                      int num = env.addMemEntry();
 135.173                      if (num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
 135.174                      en.regNum = num;
 135.175 @@ -546,7 +431,7 @@
 135.176                  returnCode = 1; /* group */
 135.177                  return node;
 135.178              }
 135.179 -            EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
 135.180 +            EncloseNode en = new EncloseNode(); // node_new_enclose_memory
 135.181              int num = env.addMemEntry();
 135.182              en.regNum = num;
 135.183              node = en;
 135.184 @@ -570,48 +455,6 @@
 135.185          return node; // ??
 135.186      }
 135.187  
 135.188 -    private Node parseEncloseNamedGroup2(boolean listCapture) {
 135.189 -        int nm = p;
 135.190 -        int num = fetchName(c, false);
 135.191 -        int nameEnd = value;
 135.192 -        num = env.addMemEntry();
 135.193 -        if (listCapture && num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
 135.194 -
 135.195 -        regex.nameAdd(chars, nm, nameEnd, num, syntax);
 135.196 -        EncloseNode en = new EncloseNode(env.option, true); // node_new_enclose_memory
 135.197 -        en.regNum = num;
 135.198 -
 135.199 -        Node node = en;
 135.200 -
 135.201 -        if (listCapture) env.captureHistory = bsOnAtSimple(env.captureHistory, num);
 135.202 -        env.numNamed++;
 135.203 -        return node;
 135.204 -    }
 135.205 -
 135.206 -    private int findStrPosition(int[]s, int n, int from, int to, Ptr nextChar) {
 135.207 -        int x;
 135.208 -        int q;
 135.209 -        int p = from;
 135.210 -        int i = 0;
 135.211 -        while (p < to) {
 135.212 -            x = chars[p];
 135.213 -            q = p + 1;
 135.214 -            if (x == s[0]) {
 135.215 -                for (i=1; i<n && q<to; i++) {
 135.216 -                    x = chars[q];
 135.217 -                    if (x != s[i]) break;
 135.218 -                    q++;
 135.219 -                }
 135.220 -                if (i >= n) {
 135.221 -                    if (chars[nextChar.p] != 0) nextChar.p = q; // we may need zero term semantics...
 135.222 -                    return p;
 135.223 -                }
 135.224 -            }
 135.225 -            p = q;
 135.226 -        }
 135.227 -        return -1;
 135.228 -    }
 135.229 -
 135.230      private Node parseExp(TokenType term) {
 135.231          if (token.type == term) return StringNode.EMPTY; // goto end_of_token
 135.232  
 135.233 @@ -656,16 +499,6 @@
 135.234              node = new StringNode(buf, 0, 1);
 135.235              break;
 135.236  
 135.237 -        case QUOTE_OPEN:
 135.238 -            int[] endOp = new int[] {syntax.metaCharTable.esc, 'E'};
 135.239 -            int qstart = p;
 135.240 -            Ptr nextChar = new Ptr();
 135.241 -            int qend = findStrPosition(endOp, endOp.length, qstart, stop, nextChar);
 135.242 -            if (qend == -1) nextChar.p = qend = stop;
 135.243 -            node = new StringNode(chars, qstart, qend);
 135.244 -            p = nextChar.p;
 135.245 -            break;
 135.246 -
 135.247          case CHAR_TYPE:
 135.248              switch(token.getPropCType()) {
 135.249              case CharacterType.D:
 135.250 @@ -679,10 +512,6 @@
 135.251                  }
 135.252                  break;
 135.253  
 135.254 -            case CharacterType.WORD:
 135.255 -                node = new CTypeNode(token.getPropCType(), token.getPropNot());
 135.256 -                break;
 135.257 -
 135.258              case CharacterType.SPACE:
 135.259              case CharacterType.DIGIT:
 135.260              case CharacterType.XDIGIT:
 135.261 @@ -699,10 +528,6 @@
 135.262              } // inner switch
 135.263              break;
 135.264  
 135.265 -        case CHAR_PROPERTY:
 135.266 -            node = parseCharProperty();
 135.267 -            break;
 135.268 -
 135.269          case CC_CC_OPEN:
 135.270              CClassNode cc = parseCharClass();
 135.271              node = cc;
 135.272 @@ -735,20 +560,6 @@
 135.273                              token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL
 135.274                              token.getBackrefLevel(),      // ...
 135.275                              env);
 135.276 -
 135.277 -            break;
 135.278 -
 135.279 -        case CALL:
 135.280 -            if (Config.USE_SUBEXP_CALL) {
 135.281 -                int gNum = token.getCallGNum();
 135.282 -
 135.283 -                if (gNum < 0) {
 135.284 -                    gNum = backrefRelToAbs(gNum);
 135.285 -                    if (gNum <= 0) newValueException(ERR_INVALID_BACKREF);
 135.286 -                }
 135.287 -                node = new CallNode(chars, token.getCallNameP(), token.getCallNameEnd(), gNum);
 135.288 -                env.numCall++;
 135.289 -            } // USE_SUBEXP_CALL
 135.290              break;
 135.291  
 135.292          case ANCHOR:
   136.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/Regex.java	Thu May 30 10:58:35 2013 -0700
   136.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Regex.java	Mon Jun 03 23:24:36 2013 -0700
   136.3 @@ -23,9 +23,11 @@
   136.4  import static jdk.nashorn.internal.runtime.regexp.joni.Option.isCaptureGroup;
   136.5  import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup;
   136.6  
   136.7 +import java.nio.file.Files;
   136.8  import java.util.HashMap;
   136.9  import java.util.Iterator;
  136.10  
  136.11 +import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
  136.12  import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
  136.13  import jdk.nashorn.internal.runtime.regexp.joni.constants.RegexState;
  136.14  import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
  136.15 @@ -44,7 +46,6 @@
  136.16      int numMem;             /* used memory(...) num counted from 1 */
  136.17      int numRepeat;          /* OP_REPEAT/OP_REPEAT_NG id-counter */
  136.18      int numNullCheck;       /* OP_NULL_CHECK_START/END id counter */
  136.19 -    int numCombExpCheck;    /* combination explosion check */
  136.20      int numCall;            /* number of subexp call */
  136.21      int captureHistory;     /* (?@...) flag (1-31) */
  136.22      int btMemStart;         /* need backtrack flag */
  136.23 @@ -57,7 +58,7 @@
  136.24  
  136.25      WarnCallback warnings;
  136.26      MatcherFactory factory;
  136.27 -    private Analyser analyser;
  136.28 +    protected Analyser analyser;
  136.29  
  136.30      int options;
  136.31      int userOptions;
  136.32 @@ -65,8 +66,6 @@
  136.33      //final Syntax syntax;
  136.34      final int caseFoldFlag;
  136.35  
  136.36 -    HashMap<String,NameEntry> nameTable;        // named entries
  136.37 -
  136.38      /* optimization info (string search, char-map and anchors) */
  136.39      SearchAlgorithm searchAlgorithm;        /* optimize flag */
  136.40      int thresholdLength;                    /* search str-length for apply optimize */
  136.41 @@ -172,112 +171,6 @@
  136.42          return numMem;
  136.43      }
  136.44  
  136.45 -    public int numberOfCaptureHistories() {
  136.46 -        if (Config.USE_CAPTURE_HISTORY) {
  136.47 -            int n = 0;
  136.48 -            for (int i=0; i<=Config.MAX_CAPTURE_HISTORY_GROUP; i++) {
  136.49 -                if (bsAt(captureHistory, i)) n++;
  136.50 -            }
  136.51 -            return n;
  136.52 -        } else {
  136.53 -            return 0;
  136.54 -        }
  136.55 -    }
  136.56 -
  136.57 -    String nameTableToString() {
  136.58 -        StringBuilder sb = new StringBuilder();
  136.59 -
  136.60 -        if (nameTable != null) {
  136.61 -            sb.append("name table\n");
  136.62 -            for (NameEntry ne : nameTable.values()) {
  136.63 -                sb.append("  " + ne + "\n");
  136.64 -            }
  136.65 -            sb.append("\n");
  136.66 -        }
  136.67 -        return sb.toString();
  136.68 -    }
  136.69 -
  136.70 -    NameEntry nameFind(char[] name, int nameP, int nameEnd) {
  136.71 -        if (nameTable != null) return nameTable.get(new String(name, nameP, nameEnd - nameP));
  136.72 -        return null;
  136.73 -    }
  136.74 -
  136.75 -    void renumberNameTable(int[]map) {
  136.76 -        if (nameTable != null) {
  136.77 -            for (NameEntry e : nameTable.values()) {
  136.78 -                if (e.backNum > 1) {
  136.79 -                    for (int i=0; i<e.backNum; i++) {
  136.80 -                        e.backRefs[i] = map[e.backRefs[i]];
  136.81 -                    }
  136.82 -                } else if (e.backNum == 1) {
  136.83 -                    e.backRef1 = map[e.backRef1];
  136.84 -                }
  136.85 -            }
  136.86 -        }
  136.87 -    }
  136.88 -
  136.89 -    public int numberOfNames() {
  136.90 -        return nameTable == null ? 0 : nameTable.size();
  136.91 -    }
  136.92 -
  136.93 -    void nameAdd(char[] name, int nameP, int nameEnd, int backRef, Syntax syntax) {
  136.94 -        if (nameEnd - nameP <= 0) throw new ValueException(ErrorMessages.ERR_EMPTY_GROUP_NAME);
  136.95 -
  136.96 -        NameEntry e = null;
  136.97 -        if (nameTable == null) {
  136.98 -            nameTable = new HashMap<String,NameEntry>(); // 13, oni defaults to 5
  136.99 -        } else {
 136.100 -            e = nameFind(name, nameP, nameEnd);
 136.101 -        }
 136.102 -
 136.103 -        if (e == null) {
 136.104 -            // dup the name here as oni does ?, what for ? (it has to manage it, we don't)
 136.105 -            e = new NameEntry(name, nameP, nameEnd);
 136.106 -            nameTable.put(new String(name, nameP, nameEnd - nameP), e);
 136.107 -        } else if (e.backNum >= 1 && !syntax.allowMultiplexDefinitionName()) {
 136.108 -            throw new ValueException(ErrorMessages.ERR_MULTIPLEX_DEFINED_NAME, new String(name, nameP, nameEnd - nameP));
 136.109 -        }
 136.110 -
 136.111 -        e.addBackref(backRef);
 136.112 -    }
 136.113 -
 136.114 -    NameEntry nameToGroupNumbers(char[] name, int nameP, int nameEnd) {
 136.115 -        return nameFind(name, nameP, nameEnd);
 136.116 -    }
 136.117 -
 136.118 -    public int nameToBackrefNumber(char[] name, int nameP, int nameEnd, Region region) {
 136.119 -        NameEntry e = nameToGroupNumbers(name, nameP, nameEnd);
 136.120 -        if (e == null) throw new ValueException(ErrorMessages.ERR_UNDEFINED_NAME_REFERENCE,
 136.121 -                                                new String(name, nameP, nameEnd - nameP));
 136.122 -
 136.123 -        switch(e.backNum) {
 136.124 -        case 0:
 136.125 -            throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
 136.126 -        case 1:
 136.127 -            return e.backRef1;
 136.128 -        default:
 136.129 -            if (region != null) {
 136.130 -                for (int i = e.backNum - 1; i >= 0; i--) {
 136.131 -                    if (region.beg[e.backRefs[i]] != Region.REGION_NOTPOS) return e.backRefs[i];
 136.132 -                }
 136.133 -            }
 136.134 -            return e.backRefs[e.backNum - 1];
 136.135 -        }
 136.136 -    }
 136.137 -
 136.138 -    public Iterator<NameEntry> namedBackrefIterator() {
 136.139 -        return nameTable.values().iterator();
 136.140 -    }
 136.141 -
 136.142 -    public boolean noNameGroupIsActive(Syntax syntax) {
 136.143 -        if (isDontCaptureGroup(options)) return false;
 136.144 -
 136.145 -        if (Config.USE_NAMED_GROUP) {
 136.146 -            if (numberOfNames() > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(options)) return false;
 136.147 -        }
 136.148 -        return true;
 136.149 -    }
 136.150 -
 136.151      /* set skip map for Boyer-Moor search */
 136.152      void setupBMSkipMap() {
 136.153          char[] chars = exact;
 136.154 @@ -353,16 +246,6 @@
 136.155          exactP = exactEnd = 0;
 136.156      }
 136.157  
 136.158 -    public String encStringToString(byte[]bytes, int p, int end) {
 136.159 -        StringBuilder sb = new StringBuilder("\nPATTERN: /");
 136.160 -
 136.161 -        while (p < end) {
 136.162 -            sb.append(new String(new byte[]{bytes[p]}));
 136.163 -            p++;
 136.164 -        }
 136.165 -        return sb.append("/").toString();
 136.166 -    }
 136.167 -
 136.168      public String optimizeInfoToString() {
 136.169          String s = "";
 136.170          s += "optimize: " + searchAlgorithm.getName() + "\n";
 136.171 @@ -410,19 +293,13 @@
 136.172          return options;
 136.173      }
 136.174  
 136.175 -    public void setUserOptions(int options) {
 136.176 -        this.userOptions = options;
 136.177 +    public String dumpTree() {
 136.178 +        return analyser == null ? null : analyser.root.toString();
 136.179      }
 136.180  
 136.181 -    public int getUserOptions() {
 136.182 -        return userOptions;
 136.183 +    public String dumpByteCode() {
 136.184 +        compile();
 136.185 +        return new ByteCodePrinter(this).byteCodeListToString();
 136.186      }
 136.187  
 136.188 -    public void setUserObject(Object object) {
 136.189 -        this.userObject = object;
 136.190 -    }
 136.191 -
 136.192 -    public Object getUserObject() {
 136.193 -        return userObject;
 136.194 -    }
 136.195  }
   137.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java	Thu May 30 10:58:35 2013 -0700
   137.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java	Mon Jun 03 23:24:36 2013 -0700
   137.3 @@ -25,7 +25,6 @@
   137.4      public final int numRegs;
   137.5      public final int[]beg;
   137.6      public final int[]end;
   137.7 -    public CaptureTreeNode historyRoot;
   137.8  
   137.9      public Region(int num) {
  137.10          this.numRegs = num;
  137.11 @@ -33,20 +32,6 @@
  137.12          this.end = new int[num];
  137.13      }
  137.14  
  137.15 -    public Region(int begin, int end) {
  137.16 -        this.numRegs = 1;
  137.17 -        this.beg = new int[]{begin};
  137.18 -        this.end = new int[]{end};
  137.19 -    }
  137.20 -
  137.21 -    public Region clone() {
  137.22 -        Region region = new Region(numRegs);
  137.23 -        System.arraycopy(beg, 0, region.beg, 0, beg.length);
  137.24 -        System.arraycopy(end, 0, region.end, 0, end.length);
  137.25 -        if (historyRoot != null) region.historyRoot = historyRoot.cloneTree();
  137.26 -        return region;
  137.27 -    }
  137.28 -
  137.29      public String toString() {
  137.30          StringBuilder sb = new StringBuilder();
  137.31          sb.append("Region: \n");
  137.32 @@ -54,10 +39,6 @@
  137.33          return sb.toString();
  137.34      }
  137.35  
  137.36 -    CaptureTreeNode getCaptureTree() {
  137.37 -        return historyRoot;
  137.38 -    }
  137.39 -
  137.40      void clear() {
  137.41          for (int i=0; i<beg.length; i++) {
  137.42              beg[i] = end[i] = REGION_NOTPOS;
   138.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/ScanEnvironment.java	Thu May 30 10:58:35 2013 -0700
   138.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/ScanEnvironment.java	Mon Jun 03 23:24:36 2013 -0700
   138.3 @@ -40,16 +40,10 @@
   138.4      final public Regex reg;
   138.5  
   138.6      int numCall;
   138.7 -    UnsetAddrList unsetAddrList; // USE_SUBEXP_CALL
   138.8      public int numMem;
   138.9  
  138.10 -    int numNamed; // USE_NAMED_GROUP
  138.11 -
  138.12      public Node memNodes[];
  138.13  
  138.14 -    // USE_COMBINATION_EXPLOSION_CHECK
  138.15 -    int numCombExpCheck;
  138.16 -    int combExpMaxRegNum;
  138.17      int currMaxRegNum;
  138.18      boolean hasRecursion;
  138.19  
  138.20 @@ -69,12 +63,8 @@
  138.21          numCall = 0;
  138.22          numMem = 0;
  138.23  
  138.24 -        numNamed = 0;
  138.25 -
  138.26          memNodes = null;
  138.27  
  138.28 -        numCombExpCheck = 0;
  138.29 -        combExpMaxRegNum = 0;
  138.30          currMaxRegNum = 0;
  138.31          hasRecursion = false;
  138.32      }
   139.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/ScannerSupport.java	Thu May 30 10:58:35 2013 -0700
   139.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/ScannerSupport.java	Mon Jun 03 23:24:36 2013 -0700
   139.3 @@ -37,6 +37,8 @@
   139.4      private final int end;              // pattern end position for reset() support
   139.5      protected int _p;                   // used by mark()/restore() to mark positions
   139.6  
   139.7 +    private final static int INT_SIGN_BIT = 1 << 31;
   139.8 +
   139.9      protected ScannerSupport(char[] chars, int p, int end) {
  139.10          this.chars = chars;
  139.11          this.begin = p;
  139.12 @@ -53,8 +55,6 @@
  139.13          return end;
  139.14      }
  139.15  
  139.16 -    private final int INT_SIGN_BIT = 1 << 31;
  139.17 -
  139.18      protected final int scanUnsignedNumber() {
  139.19          int last = c;
  139.20          int num = 0; // long ???
   140.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/StackMachine.java	Thu May 30 10:58:35 2013 -0700
   140.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/StackMachine.java	Mon Jun 03 23:24:36 2013 -0700
   140.3 @@ -22,7 +22,6 @@
   140.4  import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
   140.5  
   140.6  import java.lang.ref.WeakReference;
   140.7 -import java.util.Arrays;
   140.8  
   140.9  import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
  140.10  import jdk.nashorn.internal.runtime.regexp.joni.constants.StackType;
  140.11 @@ -36,10 +35,6 @@
  140.12      protected final int[]repeatStk;
  140.13      protected final int memStartStk, memEndStk;
  140.14  
  140.15 -    // CEC
  140.16 -    protected byte[] stateCheckBuff; // move to int[] ?
  140.17 -    int stateCheckBuffSize;
  140.18 -
  140.19      protected StackMachine(Regex regex, char[] chars, int p , int end) {
  140.20          super(regex, chars, p, end);
  140.21  
  140.22 @@ -104,67 +99,12 @@
  140.23          stk++;
  140.24      }
  140.25  
  140.26 -    // CEC
  140.27 -
  140.28 -    // STATE_CHECK_POS
  140.29 -    private int stateCheckPos(int s, int snum) {
  140.30 -        return (s - str) * regex.numCombExpCheck + (snum - 1);
  140.31 -    }
  140.32 -
  140.33 -    // STATE_CHECK_VAL
  140.34 -    protected final boolean stateCheckVal(int s, int snum) {
  140.35 -        if (stateCheckBuff != null) {
  140.36 -            int x = stateCheckPos(s, snum);
  140.37 -            return (stateCheckBuff[x / 8] & (1 << (x % 8))) != 0;
  140.38 -        }
  140.39 -        return false;
  140.40 -    }
  140.41 -
  140.42 -    // ELSE_IF_STATE_CHECK_MARK
  140.43 -    private void stateCheckMark() {
  140.44 -        StackEntry e = stack[stk];
  140.45 -        int x = stateCheckPos(e.getStatePStr(), e.getStateCheck());
  140.46 -        stateCheckBuff[x / 8] |= (1 << (x % 8));
  140.47 -    }
  140.48 -
  140.49 -    // STATE_CHECK_BUFF_INIT
  140.50 -    private static final int STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE = 16;
  140.51 -    protected final void stateCheckBuffInit(int strLength, int offset, int stateNum) {
  140.52 -        if (stateNum > 0 && strLength >= Config.CHECK_STRING_THRESHOLD_LEN) {
  140.53 -            int size = ((strLength + 1) * stateNum + 7) >>> 3;
  140.54 -            offset = (offset * stateNum) >>> 3;
  140.55 -
  140.56 -            if (size > 0 && offset < size && size < Config.CHECK_BUFF_MAX_SIZE) {
  140.57 -                if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) {
  140.58 -                    stateCheckBuff = new byte[size];
  140.59 -                } else {
  140.60 -                    // same impl, reduce...
  140.61 -                    stateCheckBuff = new byte[size];
  140.62 -                }
  140.63 -                Arrays.fill(stateCheckBuff, offset, (size - offset), (byte)0);
  140.64 -                stateCheckBuffSize = size;
  140.65 -            } else {
  140.66 -                stateCheckBuff = null; // reduce
  140.67 -                stateCheckBuffSize = 0;
  140.68 -            }
  140.69 -        } else {
  140.70 -            stateCheckBuff = null; // reduce
  140.71 -            stateCheckBuffSize = 0;
  140.72 -        }
  140.73 -    }
  140.74 -
  140.75 -    protected final void stateCheckBuffClear() {
  140.76 -        stateCheckBuff = null;
  140.77 -        stateCheckBuffSize = 0;
  140.78 -    }
  140.79 -
  140.80      private void push(int type, int pat, int s, int prev) {
  140.81          StackEntry e = ensure1();
  140.82          e.type = type;
  140.83          e.setStatePCode(pat);
  140.84          e.setStatePStr(s);
  140.85          e.setStatePStrPrev(prev);
  140.86 -        if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(0);
  140.87          stk++;
  140.88      }
  140.89  
  140.90 @@ -172,30 +112,9 @@
  140.91          StackEntry e = stack[stk];
  140.92          e.type = type;
  140.93          e.setStatePCode(pat);
  140.94 -        if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(0);
  140.95          stk++;
  140.96      }
  140.97  
  140.98 -    protected final void pushAltWithStateCheck(int pat, int s, int sprev, int snum) {
  140.99 -        StackEntry e = ensure1();
 140.100 -        e.type = ALT;
 140.101 -        e.setStatePCode(pat);
 140.102 -        e.setStatePStr(s);
 140.103 -        e.setStatePStrPrev(sprev);
 140.104 -        if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(stateCheckBuff != null ? snum : 0);
 140.105 -        stk++;
 140.106 -    }
 140.107 -
 140.108 -    protected final void pushStateCheck(int s, int snum) {
 140.109 -        if (stateCheckBuff != null) {
 140.110 -            StackEntry e = ensure1();
 140.111 -            e.type = STATE_CHECK_MARK;
 140.112 -            e.setStatePStr(s);
 140.113 -            e.setStateCheck(snum);
 140.114 -            stk++;
 140.115 -        }
 140.116 -    }
 140.117 -
 140.118      protected final void pushAlt(int pat, int s, int prev) {
 140.119          push(ALT, pat, s, prev);
 140.120      }
 140.121 @@ -294,19 +213,6 @@
 140.122          stk++;
 140.123      }
 140.124  
 140.125 -    protected final void pushCallFrame(int pat) {
 140.126 -        StackEntry e = ensure1();
 140.127 -        e.type = CALL_FRAME;
 140.128 -        e.setCallFrameRetAddr(pat);
 140.129 -        stk++;
 140.130 -    }
 140.131 -
 140.132 -    protected final void pushReturn() {
 140.133 -        StackEntry e = ensure1();
 140.134 -        e.type = RETURN;
 140.135 -        stk++;
 140.136 -    }
 140.137 -
 140.138      // stack debug routines here
 140.139      // ...
 140.140  
 140.141 @@ -331,8 +237,6 @@
 140.142  
 140.143              if ((e.type & MASK_POP_USED) != 0) {
 140.144                  return e;
 140.145 -            } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
 140.146 -                if (e.type == STATE_CHECK_MARK) stateCheckMark();
 140.147              }
 140.148          }
 140.149      }
 140.150 @@ -346,8 +250,6 @@
 140.151              } else if (e.type == MEM_START) {
 140.152                  repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
 140.153                  repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
 140.154 -            } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
 140.155 -                if (e.type == STATE_CHECK_MARK) stateCheckMark();
 140.156              }
 140.157          }
 140.158      }
 140.159 @@ -368,8 +270,6 @@
 140.160              } else if (e.type == MEM_END) {
 140.161                  repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
 140.162                  repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
 140.163 -            } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
 140.164 -                if (e.type == STATE_CHECK_MARK) stateCheckMark();
 140.165              }
 140.166          }
 140.167      }
 140.168 @@ -391,8 +291,6 @@
 140.169              } else if (e.type == MEM_END){
 140.170                  repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
 140.171                  repeatStk[memEndStk + e.getMemNum()] = e.getMemStart();
 140.172 -            } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
 140.173 -                if (e.type == STATE_CHECK_MARK) stateCheckMark();
 140.174              }
 140.175          }
 140.176      }
 140.177 @@ -414,8 +312,6 @@
 140.178              } else if (e.type == MEM_END) {
 140.179                  repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
 140.180                  repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
 140.181 -            } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
 140.182 -                if (e.type == STATE_CHECK_MARK) stateCheckMark();
 140.183              }
 140.184          }
 140.185      }
   141.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/Syntax.java	Thu May 30 10:58:35 2013 -0700
   141.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Syntax.java	Mon Jun 03 23:24:36 2013 -0700
   141.3 @@ -609,7 +609,7 @@
   141.4          OP_ESC_CONTROL_CHARS | OP_ESC_C_CONTROL | OP_ESC_X_HEX2)
   141.5          & ~OP_ESC_LTGT_WORD_BEGIN_END ),
   141.6  
   141.7 -        ( OP2_QMARK_GROUP_EFFECT | OP2_CCLASS_SET_OP |
   141.8 +        ( OP2_QMARK_GROUP_EFFECT |
   141.9          OP2_ESC_V_VTAB | OP2_ESC_U_HEX4 ),
  141.10  
  141.11          ( GNU_REGEX_BV | DIFFERENT_LEN_ALT_LOOK_BEHIND ),
   142.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/UnsetAddrList.java	Thu May 30 10:58:35 2013 -0700
   142.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   142.3 @@ -1,69 +0,0 @@
   142.4 -/*
   142.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   142.6 - * this software and associated documentation files (the "Software"), to deal in
   142.7 - * the Software without restriction, including without limitation the rights to
   142.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   142.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  142.10 - * so, subject to the following conditions:
  142.11 - *
  142.12 - * The above copyright notice and this permission notice shall be included in all
  142.13 - * copies or substantial portions of the Software.
  142.14 - *
  142.15 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  142.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  142.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  142.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  142.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  142.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  142.21 - * SOFTWARE.
  142.22 - */
  142.23 -package jdk.nashorn.internal.runtime.regexp.joni;
  142.24 -
  142.25 -import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
  142.26 -import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
  142.27 -import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
  142.28 -import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
  142.29 -
  142.30 -public final class UnsetAddrList {
  142.31 -    int num;
  142.32 -    Node[]targets;
  142.33 -    int[]offsets;
  142.34 -
  142.35 -    public UnsetAddrList(int size) {
  142.36 -        targets = new Node[size];
  142.37 -        offsets = new int[size];
  142.38 -    }
  142.39 -
  142.40 -    public void add(int offset, Node node) {
  142.41 -        if (num >= offsets.length) {
  142.42 -            Node []ttmp = new Node[targets.length << 1];
  142.43 -            System.arraycopy(targets, 0, ttmp, 0, num);
  142.44 -            targets = ttmp;
  142.45 -            int[]otmp = new int[offsets.length << 1];
  142.46 -            System.arraycopy(offsets, 0, otmp, 0, num);
  142.47 -            offsets = otmp;
  142.48 -        }
  142.49 -        targets[num] = node;
  142.50 -        offsets[num] = offset;
  142.51 -
  142.52 -        num++;
  142.53 -    }
  142.54 -
  142.55 -    public void fix(Regex regex) {
  142.56 -        for (int i=0; i<num; i++) {
  142.57 -            EncloseNode en = (EncloseNode)targets[i];
  142.58 -            if (!en.isAddrFixed()) new InternalException(ErrorMessages.ERR_PARSER_BUG);
  142.59 -            regex.code[offsets[i]] = en.callAddr; // is this safe ?
  142.60 -        }
  142.61 -    }
  142.62 -
  142.63 -    public String toString() {
  142.64 -        StringBuilder value = new StringBuilder();
  142.65 -        if (num > 0) {
  142.66 -            for (int i=0; i<num; i++) {
  142.67 -                value.append("offset + " + offsets[i] + " target: " + targets[i].getAddressName());
  142.68 -            }
  142.69 -        }
  142.70 -        return value.toString();
  142.71 -    }
  142.72 -}
   143.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CClassNode.java	Thu May 30 10:58:35 2013 -0700
   143.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CClassNode.java	Mon Jun 03 23:24:36 2013 -0700
   143.3 @@ -22,7 +22,6 @@
   143.4  import jdk.nashorn.internal.runtime.regexp.joni.*;
   143.5  import jdk.nashorn.internal.runtime.regexp.joni.constants.CCSTATE;
   143.6  import jdk.nashorn.internal.runtime.regexp.joni.constants.CCVALTYPE;
   143.7 -import jdk.nashorn.internal.runtime.regexp.joni.encoding.AsciiTables;
   143.8  import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
   143.9  import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
  143.10  import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
  143.11 @@ -40,6 +39,41 @@
  143.12  
  143.13      private int ctype;                      // for hashing purposes
  143.14  
  143.15 +    private final static short AsciiCtypeTable[] = {
  143.16 +            0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
  143.17 +            0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
  143.18 +            0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
  143.19 +            0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
  143.20 +            0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
  143.21 +            0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
  143.22 +            0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
  143.23 +            0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
  143.24 +            0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
  143.25 +            0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
  143.26 +            0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
  143.27 +            0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
  143.28 +            0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
  143.29 +            0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
  143.30 +            0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
  143.31 +            0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
  143.32 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.33 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.34 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.35 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.36 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.37 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.38 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.39 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.40 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.41 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.42 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.43 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.44 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.45 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.46 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  143.47 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  143.48 +    };
  143.49 +
  143.50      // node_new_cclass
  143.51      public CClassNode() {}
  143.52  
  143.53 @@ -330,13 +364,13 @@
  143.54                  if (not) {
  143.55                      for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
  143.56                          // if (!ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
  143.57 -                        if ((AsciiTables.AsciiCtypeTable[c] & (1 << ctype)) == 0) bs.set(c);
  143.58 +                        if ((AsciiCtypeTable[c] & (1 << ctype)) == 0) bs.set(c);
  143.59                      }
  143.60                      addAllMultiByteRange();
  143.61                  } else {
  143.62                      for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
  143.63                          // if (ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
  143.64 -                        if ((AsciiTables.AsciiCtypeTable[c] & (1 << ctype)) != 0) bs.set(c);
  143.65 +                        if ((AsciiCtypeTable[c] & (1 << ctype)) != 0) bs.set(c);
  143.66                      }
  143.67                  }
  143.68                  return;
   144.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CTypeNode.java	Thu May 30 10:58:35 2013 -0700
   144.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   144.3 @@ -1,50 +0,0 @@
   144.4 -/*
   144.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   144.6 - * this software and associated documentation files (the "Software"), to deal in
   144.7 - * the Software without restriction, including without limitation the rights to
   144.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   144.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  144.10 - * so, subject to the following conditions:
  144.11 - *
  144.12 - * The above copyright notice and this permission notice shall be included in all
  144.13 - * copies or substantial portions of the Software.
  144.14 - *
  144.15 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  144.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  144.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  144.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  144.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  144.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  144.21 - * SOFTWARE.
  144.22 - */
  144.23 -package jdk.nashorn.internal.runtime.regexp.joni.ast;
  144.24 -
  144.25 -public final class CTypeNode extends Node {
  144.26 -    public int ctype;
  144.27 -    public boolean not;
  144.28 -
  144.29 -    public CTypeNode(int type, boolean not) {
  144.30 -        this.ctype= type;
  144.31 -        this.not = not;
  144.32 -    }
  144.33 -
  144.34 -    @Override
  144.35 -    public int getType() {
  144.36 -        return CTYPE;
  144.37 -    }
  144.38 -
  144.39 -    @Override
  144.40 -    public String getName() {
  144.41 -        return "Character Type";
  144.42 -    }
  144.43 -
  144.44 -    @Override
  144.45 -    public String toString(int level) {
  144.46 -        StringBuilder value = new StringBuilder();
  144.47 -        value.append("\n  ctype: " + ctype);
  144.48 -        value.append("\n  not: " + not);
  144.49 -
  144.50 -        return value.toString();
  144.51 -    }
  144.52 -
  144.53 -}
   145.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CallNode.java	Thu May 30 10:58:35 2013 -0700
   145.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   145.3 @@ -1,86 +0,0 @@
   145.4 -/*
   145.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   145.6 - * this software and associated documentation files (the "Software"), to deal in
   145.7 - * the Software without restriction, including without limitation the rights to
   145.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   145.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  145.10 - * so, subject to the following conditions:
  145.11 - *
  145.12 - * The above copyright notice and this permission notice shall be included in all
  145.13 - * copies or substantial portions of the Software.
  145.14 - *
  145.15 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  145.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  145.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  145.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  145.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  145.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  145.21 - * SOFTWARE.
  145.22 - */
  145.23 -package jdk.nashorn.internal.runtime.regexp.joni.ast;
  145.24 -
  145.25 -import java.util.Set;
  145.26 -
  145.27 -import jdk.nashorn.internal.runtime.regexp.joni.UnsetAddrList;
  145.28 -import jdk.nashorn.internal.runtime.regexp.joni.WarnCallback;
  145.29 -
  145.30 -public final class CallNode extends StateNode {
  145.31 -    public char[] name;
  145.32 -    public int nameP;
  145.33 -    public int nameEnd;
  145.34 -
  145.35 -    public int groupNum;
  145.36 -    public Node target;             // is it an EncloseNode always ?
  145.37 -    public UnsetAddrList unsetAddrList;
  145.38 -
  145.39 -    public CallNode(char[] name, int nameP, int nameEnd, int gnum) {
  145.40 -        this.name = name;
  145.41 -        this.nameP = nameP;
  145.42 -        this.nameEnd = nameEnd;
  145.43 -        this.groupNum = gnum; /* call by number if gnum != 0 */
  145.44 -    }
  145.45 -
  145.46 -    @Override
  145.47 -    public int getType() {
  145.48 -        return CALL;
  145.49 -    }
  145.50 -
  145.51 -    @Override
  145.52 -    protected void setChild(Node newChild) {
  145.53 -        target = newChild;
  145.54 -    }
  145.55 -
  145.56 -    @Override
  145.57 -    protected Node getChild() {
  145.58 -        return target;
  145.59 -    }
  145.60 -
  145.61 -    public void setTarget(Node tgt) {
  145.62 -        target = tgt;
  145.63 -        tgt.parent = this;
  145.64 -    }
  145.65 -
  145.66 -    @Override
  145.67 -    public String getName() {
  145.68 -        return "Call";
  145.69 -    }
  145.70 -
  145.71 -    @Override
  145.72 -    public void verifyTree(Set<Node> set, WarnCallback warnings) {
  145.73 -        if (target == null || target.parent == this)
  145.74 -            warnings.warn(this.getAddressName() + " doesn't point to a target or the target has been stolen");
  145.75 -        // do not recurse here
  145.76 -    }
  145.77 -
  145.78 -    @Override
  145.79 -    public String toString(int level) {
  145.80 -        StringBuilder value = new StringBuilder(super.toString(level));
  145.81 -        value.append("\n  name: " + new String(name, nameP, nameEnd - nameP));
  145.82 -        value.append("\n  groupNum: " + groupNum);
  145.83 -        value.append("\n  target: " + pad(target.getAddressName(), level + 1));
  145.84 -        value.append("\n  unsetAddrList: " + pad(unsetAddrList, level + 1));
  145.85 -
  145.86 -        return value.toString();
  145.87 -    }
  145.88 -
  145.89 -}
   146.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java	Thu May 30 10:58:35 2013 -0700
   146.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java	Mon Jun 03 23:24:36 2013 -0700
   146.3 @@ -25,7 +25,7 @@
   146.4  
   146.5  public final class EncloseNode extends StateNode implements EncloseType {
   146.6  
   146.7 -    public int type;                // enclose type
   146.8 +    public final int type;                // enclose type
   146.9      public int regNum;
  146.10      public int option;
  146.11      public Node target;             /* EncloseNode : ENCLOSE_MEMORY */
  146.12 @@ -42,10 +42,8 @@
  146.13      }
  146.14  
  146.15      // node_new_enclose_memory
  146.16 -    public EncloseNode(int option, boolean isNamed) {
  146.17 +    public EncloseNode() {
  146.18          this(MEMORY);
  146.19 -        if (isNamed) setNamedGroup();
  146.20 -        if (Config.USE_SUBEXP_CALL) this.option = option;
  146.21      }
  146.22  
  146.23      // node_new_option
  146.24 @@ -104,46 +102,14 @@
  146.25          return types.toString();
  146.26      }
  146.27  
  146.28 -    public void setEncloseStatus(int flag) {
  146.29 -        state |= flag;
  146.30 -    }
  146.31 -
  146.32 -    public void clearEncloseStatus(int flag) {
  146.33 -        state &= ~flag;
  146.34 -    }
  146.35 -
  146.36 -    public void clearMemory() {
  146.37 -        type &= ~MEMORY;
  146.38 -    }
  146.39 -
  146.40 -    public void setMemory() {
  146.41 -        type |= MEMORY;
  146.42 -    }
  146.43 -
  146.44      public boolean isMemory() {
  146.45          return (type & MEMORY) != 0;
  146.46      }
  146.47  
  146.48 -    public void clearOption() {
  146.49 -        type &= ~OPTION;
  146.50 -    }
  146.51 -
  146.52 -    public void setOption() {
  146.53 -        type |= OPTION;
  146.54 -    }
  146.55 -
  146.56      public boolean isOption() {
  146.57          return (type & OPTION) != 0;
  146.58      }
  146.59  
  146.60 -    public void clearStopBacktrack() {
  146.61 -        type &= ~STOP_BACKTRACK;
  146.62 -    }
  146.63 -
  146.64 -    public void setStopBacktrack() {
  146.65 -        type |= STOP_BACKTRACK;
  146.66 -    }
  146.67 -
  146.68      public boolean isStopBacktrack() {
  146.69          return (type & STOP_BACKTRACK) != 0;
  146.70      }
   147.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java	Thu May 30 10:58:35 2013 -0700
   147.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java	Mon Jun 03 23:24:36 2013 -0700
   147.3 @@ -21,9 +21,10 @@
   147.4  
   147.5  import jdk.nashorn.internal.runtime.regexp.joni.Config;
   147.6  import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
   147.7 -import jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce;
   147.8  import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
   147.9  
  147.10 +import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.ReduceType.*;
  147.11 +
  147.12  public final class QuantifierNode extends StateNode {
  147.13  
  147.14      public Node target;
  147.15 @@ -37,8 +38,33 @@
  147.16      public Node nextHeadExact;
  147.17      public boolean isRefered;           /* include called node. don't eliminate even if {0} */
  147.18  
  147.19 -    // USE_COMBINATION_EXPLOSION_CHECK
  147.20 -    public int  combExpCheckNum;        /* 1,2,3...: check,  0: no check  */
  147.21 +    enum ReduceType {
  147.22 +        ASIS,       /* as is */
  147.23 +        DEL,        /* delete parent */
  147.24 +        A,          /* to '*'    */
  147.25 +        AQ,         /* to '*?'   */
  147.26 +        QQ,         /* to '??'   */
  147.27 +        P_QQ,       /* to '+)??' */
  147.28 +        PQ_Q,       /* to '+?)?' */
  147.29 +    }
  147.30 +
  147.31 +    private final static ReduceType[][] REDUCE_TABLE = {
  147.32 +            {DEL,     A,      A,      QQ,     AQ,     ASIS}, /* '?'  */
  147.33 +            {DEL,     DEL,    DEL,    P_QQ,   P_QQ,   DEL},  /* '*'  */
  147.34 +            {A,       A,      DEL,    ASIS,   P_QQ,   DEL},  /* '+'  */
  147.35 +            {DEL,     AQ,     AQ,     DEL,    AQ,     AQ},   /* '??' */
  147.36 +            {DEL,     DEL,    DEL,    DEL,    DEL,    DEL},  /* '*?' */
  147.37 +            {ASIS,    PQ_Q,   DEL,    AQ,     AQ,     DEL}   /* '+?' */
  147.38 +    };
  147.39 +
  147.40 +    private final static String PopularQStr[] = new String[] {
  147.41 +            "?", "*", "+", "??", "*?", "+?"
  147.42 +    };
  147.43 +
  147.44 +    private final static String ReduceQStr[]= new String[] {
  147.45 +            "", "", "*", "*?", "??", "+ and ??", "+? and ?"
  147.46 +    };
  147.47 +
  147.48  
  147.49      public QuantifierNode(int lower, int upper, boolean byNumber) {
  147.50          this.lower = lower;
  147.51 @@ -92,7 +118,6 @@
  147.52          value.append("\n  headExact: " + pad(headExact, level + 1));
  147.53          value.append("\n  nextHeadExact: " + pad(nextHeadExact, level + 1));
  147.54          value.append("\n  isRefered: " + isRefered);
  147.55 -        value.append("\n  combExpCheckNum: " + combExpCheckNum);
  147.56  
  147.57          return value.toString();
  147.58      }
  147.59 @@ -134,7 +159,6 @@
  147.60          headExact = other.headExact;
  147.61          nextHeadExact = other.nextHeadExact;
  147.62          isRefered = other.isRefered;
  147.63 -        combExpCheckNum = other.combExpCheckNum;
  147.64      }
  147.65  
  147.66      public void reduceNestedQuantifier(QuantifierNode other) {
  147.67 @@ -143,7 +167,7 @@
  147.68  
  147.69          if (pnum < 0 || cnum < 0) return;
  147.70  
  147.71 -        switch(Reduce.REDUCE_TABLE[cnum][pnum]) {
  147.72 +        switch(REDUCE_TABLE[cnum][pnum]) {
  147.73          case DEL:
  147.74              // no need to set the parent here...
  147.75              // swap ?
  147.76 @@ -226,7 +250,7 @@
  147.77  
  147.78              if (Config.USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR) {
  147.79                  if (!isByNumber() && !qnt.isByNumber() && env.syntax.warnReduntantNestedRepeat()) {
  147.80 -                    switch(Reduce.REDUCE_TABLE[targetQNum][nestQNum]) {
  147.81 +                    switch(REDUCE_TABLE[targetQNum][nestQNum]) {
  147.82                      case ASIS:
  147.83                          break;
  147.84  
  147.85 @@ -237,9 +261,9 @@
  147.86  
  147.87                      default:
  147.88                          env.reg.getWarnings().warn(new String(chars, p, end) +
  147.89 -                                " nested repeat operator " + Reduce.PopularQStr[targetQNum] +
  147.90 -                                " and " + Reduce.PopularQStr[nestQNum] + " was replaced with '" +
  147.91 -                                Reduce.ReduceQStr[Reduce.REDUCE_TABLE[targetQNum][nestQNum].ordinal()] + "'");
  147.92 +                                " nested repeat operator " + PopularQStr[targetQNum] +
  147.93 +                                " and " + PopularQStr[nestQNum] + " was replaced with '" +
  147.94 +                                ReduceQStr[REDUCE_TABLE[targetQNum][nestQNum].ordinal()] + "'");
  147.95                      }
  147.96                  }
  147.97              } // USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
   148.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StateNode.java	Thu May 30 10:58:35 2013 -0700
   148.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StateNode.java	Mon Jun 03 23:24:36 2013 -0700
   148.3 @@ -40,7 +40,6 @@
   148.4          if (isRecursion()) states.append("RECURSION ");
   148.5          if (isCalled()) states.append("CALLED ");
   148.6          if (isAddrFixed()) states.append("ADDR_FIXED ");
   148.7 -        if (isNamedGroup()) states.append("NAMED_GROUP ");
   148.8          if (isNameRef()) states.append("NAME_REF ");
   148.9          if (isInRepeat()) states.append("IN_REPEAT ");
  148.10          if (isNestLevel()) states.append("NEST_LEVEL ");
  148.11 @@ -57,10 +56,6 @@
  148.12          state |= NST_MIN_FIXED;
  148.13      }
  148.14  
  148.15 -    public void clearMinFixed() {
  148.16 -        state &= ~NST_MIN_FIXED;
  148.17 -    }
  148.18 -
  148.19      public boolean isMaxFixed() {
  148.20          return (state & NST_MAX_FIXED) != 0;
  148.21      }
  148.22 @@ -69,10 +64,6 @@
  148.23          state |= NST_MAX_FIXED;
  148.24      }
  148.25  
  148.26 -    public void clearMaxFixed() {
  148.27 -        state &= ~NST_MAX_FIXED;
  148.28 -    }
  148.29 -
  148.30      public boolean isCLenFixed() {
  148.31          return (state & NST_CLEN_FIXED) != 0;
  148.32      }
  148.33 @@ -81,10 +72,6 @@
  148.34          state |= NST_CLEN_FIXED;
  148.35      }
  148.36  
  148.37 -    public void clearCLenFixed() {
  148.38 -        state &= ~NST_CLEN_FIXED;
  148.39 -    }
  148.40 -
  148.41      public boolean isMark1() {
  148.42          return (state & NST_MARK1) != 0;
  148.43      }
  148.44 @@ -93,10 +80,6 @@
  148.45          state |= NST_MARK1;
  148.46      }
  148.47  
  148.48 -    public void clearMark1() {
  148.49 -        state &= ~NST_MARK1;
  148.50 -    }
  148.51 -
  148.52      public boolean isMark2() {
  148.53          return (state & NST_MARK2) != 0;
  148.54      }
  148.55 @@ -117,10 +100,6 @@
  148.56          state |= NST_MEM_BACKREFED;
  148.57      }
  148.58  
  148.59 -    public void clearMemBackrefed() {
  148.60 -        state &= ~NST_MEM_BACKREFED;
  148.61 -    }
  148.62 -
  148.63      public boolean isStopBtSimpleRepeat() {
  148.64          return (state & NST_STOP_BT_SIMPLE_REPEAT) != 0;
  148.65      }
  148.66 @@ -129,10 +108,6 @@
  148.67          state |= NST_STOP_BT_SIMPLE_REPEAT;
  148.68      }
  148.69  
  148.70 -    public void clearStopBtSimpleRepeat() {
  148.71 -        state &= ~NST_STOP_BT_SIMPLE_REPEAT;
  148.72 -    }
  148.73 -
  148.74      public boolean isRecursion() {
  148.75          return (state & NST_RECURSION) != 0;
  148.76      }
  148.77 @@ -141,10 +116,6 @@
  148.78          state |= NST_RECURSION;
  148.79      }
  148.80  
  148.81 -    public void clearRecursion() {
  148.82 -        state &= ~NST_RECURSION;
  148.83 -    }
  148.84 -
  148.85      public boolean isCalled() {
  148.86          return (state & NST_CALLED) != 0;
  148.87      }
  148.88 @@ -153,10 +124,6 @@
  148.89          state |= NST_CALLED;
  148.90      }
  148.91  
  148.92 -    public void clearCAlled() {
  148.93 -        state &= ~NST_CALLED;
  148.94 -    }
  148.95 -
  148.96      public boolean isAddrFixed() {
  148.97          return (state & NST_ADDR_FIXED) != 0;
  148.98      }
  148.99 @@ -165,22 +132,6 @@
 148.100          state |= NST_ADDR_FIXED;
 148.101      }
 148.102  
 148.103 -    public void clearAddrFixed() {
 148.104 -        state &= ~NST_ADDR_FIXED;
 148.105 -    }
 148.106 -
 148.107 -    public boolean isNamedGroup() {
 148.108 -        return (state & NST_NAMED_GROUP) != 0;
 148.109 -    }
 148.110 -
 148.111 -    public void setNamedGroup() {
 148.112 -        state |= NST_NAMED_GROUP;
 148.113 -    }
 148.114 -
 148.115 -    public void clearNamedGroup() {
 148.116 -        state &= ~NST_NAMED_GROUP;
 148.117 -    }
 148.118 -
 148.119      public boolean isNameRef() {
 148.120          return (state & NST_NAME_REF) != 0;
 148.121      }
 148.122 @@ -189,10 +140,6 @@
 148.123          state |= NST_NAME_REF;
 148.124      }
 148.125  
 148.126 -    public void clearNameRef() {
 148.127 -        state &= ~NST_NAME_REF;
 148.128 -    }
 148.129 -
 148.130      public boolean isInRepeat() {
 148.131          return (state & NST_IN_REPEAT) != 0;
 148.132      }
 148.133 @@ -201,10 +148,6 @@
 148.134          state |= NST_IN_REPEAT;
 148.135      }
 148.136  
 148.137 -    public void clearInRepeat() {
 148.138 -        state &= ~NST_IN_REPEAT;
 148.139 -    }
 148.140 -
 148.141      public boolean isNestLevel() {
 148.142          return (state & NST_NEST_LEVEL) != 0;
 148.143      }
 148.144 @@ -213,10 +156,6 @@
 148.145          state |= NST_NEST_LEVEL;
 148.146      }
 148.147  
 148.148 -    public void clearNestLevel() {
 148.149 -        state &= ~NST_NEST_LEVEL;
 148.150 -    }
 148.151 -
 148.152      public boolean isByNumber() {
 148.153          return (state & NST_BY_NUMBER) != 0;
 148.154      }
 148.155 @@ -225,8 +164,4 @@
 148.156          state |= NST_BY_NUMBER;
 148.157      }
 148.158  
 148.159 -    public void clearByNumber() {
 148.160 -        state &= ~NST_BY_NUMBER;
 148.161 -    }
 148.162 -
 148.163  }
   149.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/bench/AbstractBench.java	Thu May 30 10:58:35 2013 -0700
   149.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   149.3 @@ -1,49 +0,0 @@
   149.4 -package jdk.nashorn.internal.runtime.regexp.joni.bench;
   149.5 -
   149.6 -import jdk.nashorn.internal.runtime.regexp.joni.Option;
   149.7 -import jdk.nashorn.internal.runtime.regexp.joni.Regex;
   149.8 -import jdk.nashorn.internal.runtime.regexp.joni.Syntax;
   149.9 -
  149.10 -public abstract class AbstractBench {
  149.11 -    protected void bench(String _reg, String _str, int warmup, int times) throws Exception {
  149.12 -        char[] reg = _reg.toCharArray();
  149.13 -        char[] str = _str.toCharArray();
  149.14 -
  149.15 -        Regex p = new Regex(reg,0,reg.length,Option.DEFAULT,Syntax.DEFAULT);
  149.16 -
  149.17 -        System.err.println("::: /" + _reg + "/ =~ \"" + _str + "\", " + warmup + " * " + times + " times");
  149.18 -
  149.19 -        for(int j=0;j<warmup;j++) {
  149.20 -            long before = System.currentTimeMillis();
  149.21 -            for(int i = 0; i < times; i++) {
  149.22 -                p.matcher(str, 0, str.length).search(0, str.length, Option.NONE);
  149.23 -            }
  149.24 -            long time = System.currentTimeMillis() - before;
  149.25 -            System.err.println(":  " + time + "ms");
  149.26 -        }
  149.27 -    }
  149.28 -
  149.29 -    protected void benchBestOf(String _reg, String _str, int warmup, int times) throws Exception {
  149.30 -        char[] reg = _reg.toCharArray();
  149.31 -        char[] str = _str.toCharArray();
  149.32 -
  149.33 -        Regex p = new Regex(reg,0,reg.length,Option.DEFAULT,Syntax.DEFAULT);
  149.34 -
  149.35 -        System.err.println("::: /" + _reg + "/ =~ \"" + _str + "\", " + warmup + " * " + times + " times");
  149.36 -
  149.37 -        long best = Long.MAX_VALUE;
  149.38 -
  149.39 -        for(int j=0;j<warmup;j++) {
  149.40 -            long before = System.currentTimeMillis();
  149.41 -            for(int i = 0; i < times; i++) {
  149.42 -                p.matcher(str, 0, str.length).search(0, str.length, Option.NONE);
  149.43 -            }
  149.44 -            long time = System.currentTimeMillis() - before;
  149.45 -            if(time < best) {
  149.46 -                best = time;
  149.47 -            }
  149.48 -            System.err.print(".");
  149.49 -        }
  149.50 -        System.err.println(":  " + best + "ms");
  149.51 -    }
  149.52 -}
   150.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchGreedyBacktrack.java	Thu May 30 10:58:35 2013 -0700
   150.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   150.3 @@ -1,7 +0,0 @@
   150.4 -package jdk.nashorn.internal.runtime.regexp.joni.bench;
   150.5 -
   150.6 -public class BenchGreedyBacktrack extends AbstractBench {
   150.7 -    public static void main(String[] args) throws Exception {
   150.8 -        new BenchGreedyBacktrack().bench(".*_p","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,1000000);
   150.9 -    }
  150.10 -}
   151.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchRailsRegs.java	Thu May 30 10:58:35 2013 -0700
   151.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   151.3 @@ -1,31 +0,0 @@
   151.4 -package jdk.nashorn.internal.runtime.regexp.joni.bench;
   151.5 -
   151.6 -public class BenchRailsRegs extends AbstractBench {
   151.7 -    public static void main(String[] args) throws Exception {
   151.8 -        final String[][] regexps = {{"a.*?[b-z]{2,4}aaaaaa","afdgdsgderaabxxaaaaaaaaaaaaaaaaaaaaaaaa"},
   151.9 -                                    {"://","/shop/viewCategory.shtml?category=DOGS"},
  151.10 -                                    {"^\\w+\\://[^/]+(/.*|$)$","/shop/viewCategory.shtml?category=DOGS"},
  151.11 -                                    {"\\A/?\\Z","/shop/viewCategory.shtml"},
  151.12 -                                    {"\\A/shop/signonForm\\.shtml/?\\Z","/shop/viewCategory.shtml"},
  151.13 -                                    {"\\A/shop/newAccountForm\\.shtml/?\\Z","/shop/viewCategory.shtml"},
  151.14 -                                    {"\\A/shop/newAccount\\.shtml/?\\Z","/shop/viewCategory.shtml"},
  151.15 -                                    {"\\A/shop/viewCart\\.shtml/?\\Z","/shop/viewCategory.shtml"},
  151.16 -                                    {"\\A/shop/index\\.shtml/?\\Z","/shop/viewCategory.shtml"},
  151.17 -                                    {"\\A/shop/viewCategory\\.shtml/?\\Z","/shop/viewCategory.shtml"},
  151.18 -                                    {"\\A(?:::)?([A-Z]\\w*(?:::[A-Z]\\w*)*)\\z","CategoriesController"},
  151.19 -                                    {"\\Ainsert","SELECT * FROM sessions WHERE (session_id = '1b341ffe23b5298676d535fcabd3d0d7')  LIMIT 1"},
  151.20 -                                    {"\\A\\(?\\s*(select|show)","SELECT * FROM sessions WHERE (session_id = '1b341ffe23b5298676d535fcabd3d0d7')  LIMIT 1"},
  151.21 -                                    {".*?\n","1b341ffe23b5298676d535fcabd3d0d7"},
  151.22 -                                    {"^find_(all_by|by)_([_a-zA-Z]\\w*)$","find_by_string_id"},
  151.23 -                                    {"\\.rjs$","categories/show.rhtml"},
  151.24 -                                    {"^[-a-z]+://","petstore.css"},
  151.25 -                                    {"^get$",""},
  151.26 -                                    {"^post$",""},
  151.27 -                                    {"^[^:]+","www.example.com"},
  151.28 -                                    {"(=|\\?|_before_type_cast)$", "updated_on"},
  151.29 -                                    {"^(.*?)=(.*?);","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/"}};
  151.30 -        for(String[] reg : regexps) {
  151.31 -            new BenchRailsRegs().benchBestOf(reg[0],reg[1],10,1000000);
  151.32 -        }
  151.33 -    }
  151.34 -}
   152.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchSeveralRegexps.java	Thu May 30 10:58:35 2013 -0700
   152.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   152.3 @@ -1,17 +0,0 @@
   152.4 -package jdk.nashorn.internal.runtime.regexp.joni.bench;
   152.5 -
   152.6 -public class BenchSeveralRegexps extends AbstractBench {
   152.7 -    public static void main(String[] args) throws Exception {
   152.8 -        int BASE = 1000000;
   152.9 -
  152.10 -        new BenchSeveralRegexps().benchBestOf("a"," a",10,4*BASE);
  152.11 -
  152.12 -        new BenchSeveralRegexps().benchBestOf(".*?=","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,BASE);
  152.13 -
  152.14 -        new BenchSeveralRegexps().benchBestOf("^(.*?)=(.*?);","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,BASE);
  152.15 -
  152.16 -        new BenchSeveralRegexps().benchBestOf(".*_p","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,4*BASE);
  152.17 -
  152.18 -        new BenchSeveralRegexps().benchBestOf(".*=","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,4*BASE);
  152.19 -    }
  152.20 -}
   153.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPCode.java	Thu May 30 10:58:35 2013 -0700
   153.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPCode.java	Mon Jun 03 23:24:36 2013 -0700
   153.3 @@ -19,8 +19,6 @@
   153.4   */
   153.5  package jdk.nashorn.internal.runtime.regexp.joni.constants;
   153.6  
   153.7 -import jdk.nashorn.internal.runtime.regexp.joni.Config;
   153.8 -
   153.9  public interface OPCode {
  153.10      final int FINISH                        = 0;            /* matching process terminator (no more alternative) */
  153.11      final int END                           = 1;            /* pattern code terminator (success end) */
  153.12 @@ -151,237 +149,4 @@
  153.13      final int EXACT1_IC_SB                  = 105;           /* single byte, N = 1, ignore case */
  153.14      final int EXACTN_IC_SB                  = 106;           /* single byte,        ignore case */
  153.15  
  153.16 -
  153.17 -    public final String OpCodeNames[] = Config.DEBUG_COMPILE ? new String[] {
  153.18 -        "finish", /*OP_FINISH*/
  153.19 -        "end", /*OP_END*/
  153.20 -        "exact1", /*OP_EXACT1*/
  153.21 -        "exact2", /*OP_EXACT2*/
  153.22 -        "exact3", /*OP_EXACT3*/
  153.23 -        "exact4", /*OP_EXACT4*/
  153.24 -        "exact5", /*OP_EXACT5*/
  153.25 -        "exactn", /*OP_EXACTN*/
  153.26 -        "exactmb2-n1", /*OP_EXACTMB2N1*/
  153.27 -        "exactmb2-n2", /*OP_EXACTMB2N2*/
  153.28 -        "exactmb2-n3", /*OP_EXACTMB2N3*/
  153.29 -        "exactmb2-n", /*OP_EXACTMB2N*/
  153.30 -        "exactmb3n", /*OP_EXACTMB3N*/
  153.31 -        "exactmbn", /*OP_EXACTMBN*/
  153.32 -        "exact1-ic", /*OP_EXACT1_IC*/
  153.33 -        "exactn-ic", /*OP_EXACTN_IC*/
  153.34 -        "cclass", /*OP_CCLASS*/
  153.35 -        "cclass-mb", /*OP_CCLASS_MB*/
  153.36 -        "cclass-mix", /*OP_CCLASS_MIX*/
  153.37 -        "cclass-not", /*OP_CCLASS_NOT*/
  153.38 -        "cclass-mb-not", /*OP_CCLASS_MB_NOT*/
  153.39 -        "cclass-mix-not", /*OP_CCLASS_MIX_NOT*/
  153.40 -        "cclass-node", /*OP_CCLASS_NODE*/
  153.41 -        "anychar", /*OP_ANYCHAR*/
  153.42 -        "anychar-ml", /*OP_ANYCHAR_ML*/
  153.43 -        "anychar*", /*OP_ANYCHAR_STAR*/
  153.44 -        "anychar-ml*", /*OP_ANYCHAR_ML_STAR*/
  153.45 -        "anychar*-peek-next", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
  153.46 -        "anychar-ml*-peek-next", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
  153.47 -        "word", /*OP_WORD*/
  153.48 -        "not-word", /*OP_NOT_WORD*/
  153.49 -        "word-bound", /*OP_WORD_BOUND*/
  153.50 -        "not-word-bound", /*OP_NOT_WORD_BOUND*/
  153.51 -        "word-begin", /*OP_WORD_BEGIN*/
  153.52 -        "word-end", /*OP_WORD_END*/
  153.53 -        "begin-buf", /*OP_BEGIN_BUF*/
  153.54 -        "end-buf", /*OP_END_BUF*/
  153.55 -        "begin-line", /*OP_BEGIN_LINE*/
  153.56 -        "end-line", /*OP_END_LINE*/
  153.57 -        "semi-end-buf", /*OP_SEMI_END_BUF*/
  153.58 -        "begin-position", /*OP_BEGIN_POSITION*/
  153.59 -        "backref1", /*OP_BACKREF1*/
  153.60 -        "backref2", /*OP_BACKREF2*/
  153.61 -        "backrefn", /*OP_BACKREFN*/
  153.62 -        "backrefn-ic", /*OP_BACKREFN_IC*/
  153.63 -        "backref_multi", /*OP_BACKREF_MULTI*/
  153.64 -        "backref_multi-ic", /*OP_BACKREF_MULTI_IC*/
  153.65 -        "backref_at_level", /*OP_BACKREF_AT_LEVEL*/
  153.66 -        "mem-start", /*OP_MEMORY_START*/
  153.67 -        "mem-start-push", /*OP_MEMORY_START_PUSH*/
  153.68 -        "mem-end-push", /*OP_MEMORY_END_PUSH*/
  153.69 -        "mem-end-push-rec", /*OP_MEMORY_END_PUSH_REC*/
  153.70 -        "mem-end", /*OP_MEMORY_END*/
  153.71 -        "mem-end-rec", /*OP_MEMORY_END_REC*/
  153.72 -        "fail", /*OP_FAIL*/
  153.73 -        "jump", /*OP_JUMP*/
  153.74 -        "push", /*OP_PUSH*/
  153.75 -        "pop", /*OP_POP*/
  153.76 -        "push-or-jump-e1", /*OP_PUSH_OR_JUMP_EXACT1*/
  153.77 -        "push-if-peek-next", /*OP_PUSH_IF_PEEK_NEXT*/
  153.78 -        "repeat", /*OP_REPEAT*/
  153.79 -        "repeat-ng", /*OP_REPEAT_NG*/
  153.80 -        "repeat-inc", /*OP_REPEAT_INC*/
  153.81 -        "repeat-inc-ng", /*OP_REPEAT_INC_NG*/
  153.82 -        "repeat-inc-sg", /*OP_REPEAT_INC_SG*/
  153.83 -        "repeat-inc-ng-sg", /*OP_REPEAT_INC_NG_SG*/
  153.84 -        "null-check-start", /*OP_NULL_CHECK_START*/
  153.85 -        "null-check-end", /*OP_NULL_CHECK_END*/
  153.86 -        "null-check-end-memst", /*OP_NULL_CHECK_END_MEMST*/
  153.87 -        "null-check-end-memst-push", /*OP_NULL_CHECK_END_MEMST_PUSH*/
  153.88 -        "push-pos", /*OP_PUSH_POS*/
  153.89 -        "pop-pos", /*OP_POP_POS*/
  153.90 -        "push-pos-not", /*OP_PUSH_POS_NOT*/
  153.91 -        "fail-pos", /*OP_FAIL_POS*/
  153.92 -        "push-stop-bt", /*OP_PUSH_STOP_BT*/
  153.93 -        "pop-stop-bt", /*OP_POP_STOP_BT*/
  153.94 -        "look-behind", /*OP_LOOK_BEHIND*/
  153.95 -        "push-look-behind-not", /*OP_PUSH_LOOK_BEHIND_NOT*/
  153.96 -        "fail-look-behind-not", /*OP_FAIL_LOOK_BEHIND_NOT*/
  153.97 -        "call", /*OP_CALL*/
  153.98 -        "return", /*OP_RETURN*/
  153.99 -        "state-check-push", /*OP_STATE_CHECK_PUSH*/
 153.100 -        "state-check-push-or-jump", /*OP_STATE_CHECK_PUSH_OR_JUMP*/
 153.101 -        "state-check", /*OP_STATE_CHECK*/
 153.102 -        "state-check-anychar*", /*OP_STATE_CHECK_ANYCHAR_STAR*/
 153.103 -        "state-check-anychar-ml*", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
 153.104 -        "set-option-push", /*OP_SET_OPTION_PUSH*/
 153.105 -        "set-option", /*OP_SET_OPTION*/
 153.106 -
 153.107 -        // single byte versions
 153.108 -        "anychar-sb", /*OP_ANYCHAR*/
 153.109 -        "anychar-ml-sb", /*OP_ANYCHAR_ML*/
 153.110 -        "anychar*-sb", /*OP_ANYCHAR_STAR*/
 153.111 -        "anychar-ml*-sb", /*OP_ANYCHAR_ML_STAR*/
 153.112 -        "anychar*-peek-next-sb", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
 153.113 -        "anychar-ml*-peek-next-sb", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
 153.114 -        "state-check-anychar*-sb", /*OP_STATE_CHECK_ANYCHAR_STAR*/
 153.115 -        "state-check-anychar-ml*-sb", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
 153.116 -
 153.117 -        "cclass-sb", /*OP_CCLASS*/
 153.118 -        "cclass-not-sb", /*OP_CCLASS_NOT*/
 153.119 -
 153.120 -        "word-sb", /*OP_WORD*/
 153.121 -        "not-word-sb", /*OP_NOT_WORD*/
 153.122 -        "word-bound-sb", /*OP_WORD_BOUND*/
 153.123 -        "not-word-bound-sb", /*OP_NOT_WORD_BOUND*/
 153.124 -        "word-begin-sb", /*OP_WORD_BEGIN*/
 153.125 -        "word-end-sb", /*OP_WORD_END*/
 153.126 -
 153.127 -        "look-behind-sb", /*OP_LOOK_BEHIND*/
 153.128 -
 153.129 -        "exact1-ic-sb", /*OP_EXACT1_IC*/
 153.130 -        "exactn-ic-sb", /*OP_EXACTN_IC*/
 153.131 -
 153.132 -    } : null;
 153.133 -
 153.134 -    public final int OpCodeArgTypes[] = Config.DEBUG_COMPILE ? new int[] {
 153.135 -        Arguments.NON, /*OP_FINISH*/
 153.136 -        Arguments.NON, /*OP_END*/
 153.137 -        Arguments.SPECIAL, /*OP_EXACT1*/
 153.138 -        Arguments.SPECIAL, /*OP_EXACT2*/
 153.139 -        Arguments.SPECIAL, /*OP_EXACT3*/
 153.140 -        Arguments.SPECIAL, /*OP_EXACT4*/
 153.141 -        Arguments.SPECIAL, /*OP_EXACT5*/
 153.142 -        Arguments.SPECIAL, /*OP_EXACTN*/
 153.143 -        Arguments.SPECIAL, /*OP_EXACTMB2N1*/
 153.144 -        Arguments.SPECIAL, /*OP_EXACTMB2N2*/
 153.145 -        Arguments.SPECIAL, /*OP_EXACTMB2N3*/
 153.146 -        Arguments.SPECIAL, /*OP_EXACTMB2N*/
 153.147 -        Arguments.SPECIAL, /*OP_EXACTMB3N*/
 153.148 -        Arguments.SPECIAL, /*OP_EXACTMBN*/
 153.149 -        Arguments.SPECIAL, /*OP_EXACT1_IC*/
 153.150 -        Arguments.SPECIAL, /*OP_EXACTN_IC*/
 153.151 -        Arguments.SPECIAL, /*OP_CCLASS*/
 153.152 -        Arguments.SPECIAL, /*OP_CCLASS_MB*/
 153.153 -        Arguments.SPECIAL, /*OP_CCLASS_MIX*/
 153.154 -        Arguments.SPECIAL, /*OP_CCLASS_NOT*/
 153.155 -        Arguments.SPECIAL, /*OP_CCLASS_MB_NOT*/
 153.156 -        Arguments.SPECIAL, /*OP_CCLASS_MIX_NOT*/
 153.157 -        Arguments.SPECIAL, /*OP_CCLASS_NODE*/
 153.158 -        Arguments.NON, /*OP_ANYCHAR*/
 153.159 -        Arguments.NON, /*OP_ANYCHAR_ML*/
 153.160 -        Arguments.NON, /*OP_ANYCHAR_STAR*/
 153.161 -        Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
 153.162 -        Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
 153.163 -        Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
 153.164 -        Arguments.NON, /*OP_WORD*/
 153.165 -        Arguments.NON, /*OP_NOT_WORD*/
 153.166 -        Arguments.NON, /*OP_WORD_BOUND*/
 153.167 -        Arguments.NON, /*OP_NOT_WORD_BOUND*/
 153.168 -        Arguments.NON, /*OP_WORD_BEGIN*/
 153.169 -        Arguments.NON, /*OP_WORD_END*/
 153.170 -        Arguments.NON, /*OP_BEGIN_BUF*/
 153.171 -        Arguments.NON, /*OP_END_BUF*/
 153.172 -        Arguments.NON, /*OP_BEGIN_LINE*/
 153.173 -        Arguments.NON, /*OP_END_LINE*/
 153.174 -        Arguments.NON, /*OP_SEMI_END_BUF*/
 153.175 -        Arguments.NON, /*OP_BEGIN_POSITION*/
 153.176 -        Arguments.NON, /*OP_BACKREF1*/
 153.177 -        Arguments.NON, /*OP_BACKREF2*/
 153.178 -        Arguments.MEMNUM, /*OP_BACKREFN*/
 153.179 -        Arguments.SPECIAL, /*OP_BACKREFN_IC*/
 153.180 -        Arguments.SPECIAL, /*OP_BACKREF_MULTI*/
 153.181 -        Arguments.SPECIAL, /*OP_BACKREF_MULTI_IC*/
 153.182 -        Arguments.SPECIAL, /*OP_BACKREF_AT_LEVEL*/
 153.183 -        Arguments.MEMNUM, /*OP_MEMORY_START*/
 153.184 -        Arguments.MEMNUM, /*OP_MEMORY_START_PUSH*/
 153.185 -        Arguments.MEMNUM, /*OP_MEMORY_END_PUSH*/
 153.186 -        Arguments.MEMNUM, /*OP_MEMORY_END_PUSH_REC*/
 153.187 -        Arguments.MEMNUM, /*OP_MEMORY_END*/
 153.188 -        Arguments.MEMNUM, /*OP_MEMORY_END_REC*/
 153.189 -        Arguments.NON, /*OP_FAIL*/
 153.190 -        Arguments.RELADDR, /*OP_JUMP*/
 153.191 -        Arguments.RELADDR, /*OP_PUSH*/
 153.192 -        Arguments.NON, /*OP_POP*/
 153.193 -        Arguments.SPECIAL, /*OP_PUSH_OR_JUMP_EXACT1*/
 153.194 -        Arguments.SPECIAL, /*OP_PUSH_IF_PEEK_NEXT*/
 153.195 -        Arguments.SPECIAL, /*OP_REPEAT*/
 153.196 -        Arguments.SPECIAL, /*OP_REPEAT_NG*/
 153.197 -        Arguments.MEMNUM, /*OP_REPEAT_INC*/
 153.198 -        Arguments.MEMNUM, /*OP_REPEAT_INC_NG*/
 153.199 -        Arguments.MEMNUM, /*OP_REPEAT_INC_SG*/
 153.200 -        Arguments.MEMNUM, /*OP_REPEAT_INC_NG_SG*/
 153.201 -        Arguments.MEMNUM, /*OP_NULL_CHECK_START*/
 153.202 -        Arguments.MEMNUM, /*OP_NULL_CHECK_END*/
 153.203 -        Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST*/
 153.204 -        Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST_PUSH*/
 153.205 -        Arguments.NON, /*OP_PUSH_POS*/
 153.206 -        Arguments.NON, /*OP_POP_POS*/
 153.207 -        Arguments.RELADDR, /*OP_PUSH_POS_NOT*/
 153.208 -        Arguments.NON, /*OP_FAIL_POS*/
 153.209 -        Arguments.NON, /*OP_PUSH_STOP_BT*/
 153.210 -        Arguments.NON, /*OP_POP_STOP_BT*/
 153.211 -        Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
 153.212 -        Arguments.SPECIAL, /*OP_PUSH_LOOK_BEHIND_NOT*/
 153.213 -        Arguments.NON, /*OP_FAIL_LOOK_BEHIND_NOT*/
 153.214 -        Arguments.ABSADDR, /*OP_CALL*/
 153.215 -        Arguments.NON, /*OP_RETURN*/
 153.216 -        Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH*/
 153.217 -        Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH_OR_JUMP*/
 153.218 -        Arguments.STATE_CHECK, /*OP_STATE_CHECK*/
 153.219 -        Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
 153.220 -        Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
 153.221 -        Arguments.OPTION, /*OP_SET_OPTION_PUSH*/
 153.222 -        Arguments.OPTION, /*OP_SET_OPTION*/
 153.223 -
 153.224 -        // single byte versions
 153.225 -        Arguments.NON, /*OP_ANYCHAR*/
 153.226 -        Arguments.NON, /*OP_ANYCHAR_ML*/
 153.227 -        Arguments.NON, /*OP_ANYCHAR_STAR*/
 153.228 -        Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
 153.229 -        Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
 153.230 -        Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
 153.231 -        Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
 153.232 -        Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
 153.233 -
 153.234 -        Arguments.SPECIAL, /*OP_CCLASS*/
 153.235 -        Arguments.SPECIAL, /*OP_CCLASS_NOT*/
 153.236 -
 153.237 -        Arguments.NON, /*OP_WORD*/
 153.238 -        Arguments.NON, /*OP_NOT_WORD*/
 153.239 -        Arguments.NON, /*OP_WORD_BOUND*/
 153.240 -        Arguments.NON, /*OP_NOT_WORD_BOUND*/
 153.241 -        Arguments.NON, /*OP_WORD_BEGIN*/
 153.242 -        Arguments.NON, /*OP_WORD_END*/
 153.243 -
 153.244 -        Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
 153.245 -
 153.246 -        Arguments.SPECIAL, /*OP_EXACT1_IC*/
 153.247 -        Arguments.SPECIAL, /*OP_EXACTN_IC*/
 153.248 -    } : null;
 153.249  }
   154.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Reduce.java	Thu May 30 10:58:35 2013 -0700
   154.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   154.3 @@ -1,61 +0,0 @@
   154.4 -/*
   154.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   154.6 - * this software and associated documentation files (the "Software"), to deal in
   154.7 - * the Software without restriction, including without limitation the rights to
   154.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   154.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  154.10 - * so, subject to the following conditions:
  154.11 - *
  154.12 - * The above copyright notice and this permission notice shall be included in all
  154.13 - * copies or substantial portions of the Software.
  154.14 - *
  154.15 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  154.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  154.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  154.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  154.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  154.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  154.21 - * SOFTWARE.
  154.22 - */
  154.23 -package jdk.nashorn.internal.runtime.regexp.joni.constants;
  154.24 -
  154.25 -import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.A;
  154.26 -import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.AQ;
  154.27 -import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.ASIS;
  154.28 -import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.DEL;
  154.29 -import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.PQ_Q;
  154.30 -import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.P_QQ;
  154.31 -import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.QQ;
  154.32 -
  154.33 -public interface Reduce {
  154.34 -
  154.35 -    enum ReduceType {
  154.36 -        ASIS,       /* as is */
  154.37 -        DEL,        /* delete parent */
  154.38 -        A,          /* to '*'    */
  154.39 -        AQ,         /* to '*?'   */
  154.40 -        QQ,         /* to '??'   */
  154.41 -        P_QQ,       /* to '+)??' */
  154.42 -        PQ_Q,       /* to '+?)?' */
  154.43 -    }
  154.44 -
  154.45 -    final ReduceType[][]REDUCE_TABLE = {
  154.46 -      {DEL,     A,      A,      QQ,     AQ,     ASIS}, /* '?'  */
  154.47 -      {DEL,     DEL,    DEL,    P_QQ,   P_QQ,   DEL},  /* '*'  */
  154.48 -      {A,       A,      DEL,    ASIS,   P_QQ,   DEL},  /* '+'  */
  154.49 -      {DEL,     AQ,     AQ,     DEL,    AQ,     AQ},   /* '??' */
  154.50 -      {DEL,     DEL,    DEL,    DEL,    DEL,    DEL},  /* '*?' */
  154.51 -      {ASIS,    PQ_Q,   DEL,    AQ,     AQ,     DEL}   /* '+?' */
  154.52 -    };
  154.53 -
  154.54 -
  154.55 -    final String PopularQStr[] = new String[] {
  154.56 -        "?", "*", "+", "??", "*?", "+?"
  154.57 -    };
  154.58 -
  154.59 -    String ReduceQStr[]= new String[] {
  154.60 -        "", "", "*", "*?", "??", "+ and ??", "+? and ?"
  154.61 -    };
  154.62 -
  154.63 -}
  154.64 -
   155.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/AsciiTables.java	Thu May 30 10:58:35 2013 -0700
   155.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   155.3 @@ -1,157 +0,0 @@
   155.4 -/*
   155.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   155.6 - * this software and associated documentation files (the "Software"), to deal in
   155.7 - * the Software without restriction, including without limitation the rights to
   155.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   155.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  155.10 - * so, subject to the following conditions:
  155.11 - *
  155.12 - * The above copyright notice and this permission notice shall be included in all
  155.13 - * copies or substantial portions of the Software.
  155.14 - *
  155.15 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  155.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  155.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  155.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  155.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  155.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  155.21 - * SOFTWARE.
  155.22 - */
  155.23 -package jdk.nashorn.internal.runtime.regexp.joni.encoding;
  155.24 -
  155.25 -public class AsciiTables {
  155.26 -
  155.27 -    public static final short AsciiCtypeTable[] = {
  155.28 -            0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
  155.29 -            0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
  155.30 -            0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
  155.31 -            0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
  155.32 -            0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
  155.33 -            0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
  155.34 -            0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
  155.35 -            0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
  155.36 -            0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
  155.37 -            0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
  155.38 -            0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
  155.39 -            0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
  155.40 -            0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
  155.41 -            0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
  155.42 -            0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
  155.43 -            0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
  155.44 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.45 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.46 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.47 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.48 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.49 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.50 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.51 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.52 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.53 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.54 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.55 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.56 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.57 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.58 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155.59 -            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  155.60 -    };
  155.61 -
  155.62 -    public static final byte ToLowerCaseTable[] = {
  155.63 -            (byte)'\000', (byte)'\001', (byte)'\002', (byte)'\003', (byte)'\004', (byte)'\005', (byte)'\006', (byte)'\007',
  155.64 -            (byte)'\010', (byte)'\011', (byte)'\012', (byte)'\013', (byte)'\014', (byte)'\015', (byte)'\016', (byte)'\017',
  155.65 -            (byte)'\020', (byte)'\021', (byte)'\022', (byte)'\023', (byte)'\024', (byte)'\025', (byte)'\026', (byte)'\027',
  155.66 -            (byte)'\030', (byte)'\031', (byte)'\032', (byte)'\033', (byte)'\034', (byte)'\035', (byte)'\036', (byte)'\037',
  155.67 -            (byte)'\040', (byte)'\041', (byte)'\042', (byte)'\043', (byte)'\044', (byte)'\045', (byte)'\046', (byte)'\047',
  155.68 -            (byte)'\050', (byte)'\051', (byte)'\052', (byte)'\053', (byte)'\054', (byte)'\055', (byte)'\056', (byte)'\057',
  155.69 -            (byte)'\060', (byte)'\061', (byte)'\062', (byte)'\063', (byte)'\064', (byte)'\065', (byte)'\066', (byte)'\067',
  155.70 -            (byte)'\070', (byte)'\071', (byte)'\072', (byte)'\073', (byte)'\074', (byte)'\075', (byte)'\076', (byte)'\077',
  155.71 -            (byte)'\100', (byte)'\141', (byte)'\142', (byte)'\143', (byte)'\144', (byte)'\145', (byte)'\146', (byte)'\147',
  155.72 -            (byte)'\150', (byte)'\151', (byte)'\152', (byte)'\153', (byte)'\154', (byte)'\155', (byte)'\156', (byte)'\157',
  155.73 -            (byte)'\160', (byte)'\161', (byte)'\162', (byte)'\163', (byte)'\164', (byte)'\165', (byte)'\166', (byte)'\167',
  155.74 -            (byte)'\170', (byte)'\171', (byte)'\172', (byte)'\133', (byte)'\134', (byte)'\135', (byte)'\136', (byte)'\137',
  155.75 -            (byte)'\140', (byte)'\141', (byte)'\142', (byte)'\143', (byte)'\144', (byte)'\145', (byte)'\146', (byte)'\147',
  155.76 -            (byte)'\150', (byte)'\151', (byte)'\152', (byte)'\153', (byte)'\154', (byte)'\155', (byte)'\156', (byte)'\157',
  155.77 -            (byte)'\160', (byte)'\161', (byte)'\162', (byte)'\163', (byte)'\164', (byte)'\165', (byte)'\166', (byte)'\167',
  155.78 -            (byte)'\170', (byte)'\171', (byte)'\172', (byte)'\173', (byte)'\174', (byte)'\175', (byte)'\176', (byte)'\177',
  155.79 -            (byte)'\200', (byte)'\201', (byte)'\202', (byte)'\203', (byte)'\204', (byte)'\205', (byte)'\206', (byte)'\207',
  155.80 -            (byte)'\210', (byte)'\211', (byte)'\212', (byte)'\213', (byte)'\214', (byte)'\215', (byte)'\216', (byte)'\217',
  155.81 -            (byte)'\220', (byte)'\221', (byte)'\222', (byte)'\223', (byte)'\224', (byte)'\225', (byte)'\226', (byte)'\227',
  155.82 -            (byte)'\230', (byte)'\231', (byte)'\232', (byte)'\233', (byte)'\234', (byte)'\235', (byte)'\236', (byte)'\237',
  155.83 -            (byte)'\240', (byte)'\241', (byte)'\242', (byte)'\243', (byte)'\244', (byte)'\245', (byte)'\246', (byte)'\247',
  155.84 -            (byte)'\250', (byte)'\251', (byte)'\252', (byte)'\253', (byte)'\254', (byte)'\255', (byte)'\256', (byte)'\257',
  155.85 -            (byte)'\260', (byte)'\261', (byte)'\262', (byte)'\263', (byte)'\264', (byte)'\265', (byte)'\266', (byte)'\267',
  155.86 -            (byte)'\270', (byte)'\271', (byte)'\272', (byte)'\273', (byte)'\274', (byte)'\275', (byte)'\276', (byte)'\277',
  155.87 -            (byte)'\300', (byte)'\301', (byte)'\302', (byte)'\303', (byte)'\304', (byte)'\305', (byte)'\306', (byte)'\307',
  155.88 -            (byte)'\310', (byte)'\311', (byte)'\312', (byte)'\313', (byte)'\314', (byte)'\315', (byte)'\316', (byte)'\317',
  155.89 -            (byte)'\320', (byte)'\321', (byte)'\322', (byte)'\323', (byte)'\324', (byte)'\325', (byte)'\326', (byte)'\327',
  155.90 -            (byte)'\330', (byte)'\331', (byte)'\332', (byte)'\333', (byte)'\334', (byte)'\335', (byte)'\336', (byte)'\337',
  155.91 -            (byte)'\340', (byte)'\341', (byte)'\342', (byte)'\343', (byte)'\344', (byte)'\345', (byte)'\346', (byte)'\347',
  155.92 -            (byte)'\350', (byte)'\351', (byte)'\352', (byte)'\353', (byte)'\354', (byte)'\355', (byte)'\356', (byte)'\357',
  155.93 -            (byte)'\360', (byte)'\361', (byte)'\362', (byte)'\363', (byte)'\364', (byte)'\365', (byte)'\366', (byte)'\367',
  155.94 -            (byte)'\370', (byte)'\371', (byte)'\372', (byte)'\373', (byte)'\374', (byte)'\375', (byte)'\376', (byte)'\377',
  155.95 -    };
  155.96 -
  155.97 -    public static final byte ToUpperCaseTable[] = {
  155.98 -            (byte)'\000', (byte)'\001', (byte)'\002', (byte)'\003', (byte)'\004', (byte)'\005', (byte)'\006', (byte)'\007',
  155.99 -            (byte)'\010', (byte)'\011', (byte)'\012', (byte)'\013', (byte)'\014', (byte)'\015', (byte)'\016', (byte)'\017',
 155.100 -            (byte)'\020', (byte)'\021', (byte)'\022', (byte)'\023', (byte)'\024', (byte)'\025', (byte)'\026', (byte)'\027',
 155.101 -            (byte)'\030', (byte)'\031', (byte)'\032', (byte)'\033', (byte)'\034', (byte)'\035', (byte)'\036', (byte)'\037',
 155.102 -            (byte)'\040', (byte)'\041', (byte)'\042', (byte)'\043', (byte)'\044', (byte)'\045', (byte)'\046', (byte)'\047',
 155.103 -            (byte)'\050', (byte)'\051', (byte)'\052', (byte)'\053', (byte)'\054', (byte)'\055', (byte)'\056', (byte)'\057',
 155.104 -            (byte)'\060', (byte)'\061', (byte)'\062', (byte)'\063', (byte)'\064', (byte)'\065', (byte)'\066', (byte)'\067',
 155.105 -            (byte)'\070', (byte)'\071', (byte)'\072', (byte)'\073', (byte)'\074', (byte)'\075', (byte)'\076', (byte)'\077',
 155.106 -            (byte)'\100', (byte)'\101', (byte)'\102', (byte)'\103', (byte)'\104', (byte)'\105', (byte)'\106', (byte)'\107',
 155.107 -            (byte)'\110', (byte)'\111', (byte)'\112', (byte)'\113', (byte)'\114', (byte)'\115', (byte)'\116', (byte)'\117',
 155.108 -            (byte)'\120', (byte)'\121', (byte)'\122', (byte)'\123', (byte)'\124', (byte)'\125', (byte)'\126', (byte)'\127',
 155.109 -            (byte)'\130', (byte)'\131', (byte)'\132', (byte)'\133', (byte)'\134', (byte)'\135', (byte)'\136', (byte)'\137',
 155.110 -            (byte)'\140', (byte)'\101', (byte)'\102', (byte)'\103', (byte)'\104', (byte)'\105', (byte)'\106', (byte)'\107',
 155.111 -            (byte)'\110', (byte)'\111', (byte)'\112', (byte)'\113', (byte)'\114', (byte)'\115', (byte)'\116', (byte)'\117',
 155.112 -            (byte)'\120', (byte)'\121', (byte)'\122', (byte)'\123', (byte)'\124', (byte)'\125', (byte)'\126', (byte)'\127',
 155.113 -            (byte)'\130', (byte)'\131', (byte)'\132', (byte)'\173', (byte)'\174', (byte)'\175', (byte)'\176', (byte)'\177',
 155.114 -            (byte)'\200', (byte)'\201', (byte)'\202', (byte)'\203', (byte)'\204', (byte)'\205', (byte)'\206', (byte)'\207',
 155.115 -            (byte)'\210', (byte)'\211', (byte)'\212', (byte)'\213', (byte)'\214', (byte)'\215', (byte)'\216', (byte)'\217',
 155.116 -            (byte)'\220', (byte)'\221', (byte)'\222', (byte)'\223', (byte)'\224', (byte)'\225', (byte)'\226', (byte)'\227',
 155.117 -            (byte)'\230', (byte)'\231', (byte)'\232', (byte)'\233', (byte)'\234', (byte)'\235', (byte)'\236', (byte)'\237',
 155.118 -            (byte)'\240', (byte)'\241', (byte)'\242', (byte)'\243', (byte)'\244', (byte)'\245', (byte)'\246', (byte)'\247',
 155.119 -            (byte)'\250', (byte)'\251', (byte)'\252', (byte)'\253', (byte)'\254', (byte)'\255', (byte)'\256', (byte)'\257',
 155.120 -            (byte)'\260', (byte)'\261', (byte)'\262', (byte)'\263', (byte)'\264', (byte)'\265', (byte)'\266', (byte)'\267',
 155.121 -            (byte)'\270', (byte)'\271', (byte)'\272', (byte)'\273', (byte)'\274', (byte)'\275', (byte)'\276', (byte)'\277',
 155.122 -            (byte)'\300', (byte)'\301', (byte)'\302', (byte)'\303', (byte)'\304', (byte)'\305', (byte)'\306', (byte)'\307',
 155.123 -            (byte)'\310', (byte)'\311', (byte)'\312', (byte)'\313', (byte)'\314', (byte)'\315', (byte)'\316', (byte)'\317',
 155.124 -            (byte)'\320', (byte)'\321', (byte)'\322', (byte)'\323', (byte)'\324', (byte)'\325', (byte)'\326', (byte)'\327',
 155.125 -            (byte)'\330', (byte)'\331', (byte)'\332', (byte)'\333', (byte)'\334', (byte)'\335', (byte)'\336', (byte)'\337',
 155.126 -            (byte)'\340', (byte)'\341', (byte)'\342', (byte)'\343', (byte)'\344', (byte)'\345', (byte)'\346', (byte)'\347',
 155.127 -            (byte)'\350', (byte)'\351', (byte)'\352', (byte)'\353', (byte)'\354', (byte)'\355', (byte)'\356', (byte)'\357',
 155.128 -            (byte)'\360', (byte)'\361', (byte)'\362', (byte)'\363', (byte)'\364', (byte)'\365', (byte)'\366', (byte)'\367',
 155.129 -            (byte)'\370', (byte)'\371', (byte)'\372', (byte)'\373', (byte)'\374', (byte)'\375', (byte)'\376', (byte)'\377',
 155.130 -    };
 155.131 -
 155.132 -    public static final int LowerMap[][] = {
 155.133 -            {0x41, 0x61},
 155.134 -            {0x42, 0x62},
 155.135 -            {0x43, 0x63},
 155.136 -            {0x44, 0x64},
 155.137 -            {0x45, 0x65},
 155.138 -            {0x46, 0x66},
 155.139 -            {0x47, 0x67},
 155.140 -            {0x48, 0x68},
 155.141 -            {0x49, 0x69},
 155.142 -            {0x4a, 0x6a},
 155.143 -            {0x4b, 0x6b},
 155.144 -            {0x4c, 0x6c},
 155.145 -            {0x4d, 0x6d},
 155.146 -            {0x4e, 0x6e},
 155.147 -            {0x4f, 0x6f},
 155.148 -            {0x50, 0x70},
 155.149 -            {0x51, 0x71},
 155.150 -            {0x52, 0x72},
 155.151 -            {0x53, 0x73},
 155.152 -            {0x54, 0x74},
 155.153 -            {0x55, 0x75},
 155.154 -            {0x56, 0x76},
 155.155 -            {0x57, 0x77},
 155.156 -            {0x58, 0x78},
 155.157 -            {0x59, 0x79},
 155.158 -            {0x5a, 0x7a}
 155.159 -    };
 155.160 -}
   156.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/ObjPtr.java	Thu May 30 10:58:35 2013 -0700
   156.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/ObjPtr.java	Mon Jun 03 23:24:36 2013 -0700
   156.3 @@ -30,6 +30,5 @@
   156.4  
   156.5      public T p;
   156.6  
   156.7 -    static final ObjPtr<Void> NULL = new ObjPtr<Void>();
   156.8  }
   156.9  
   157.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/PosixBracket.java	Thu May 30 10:58:35 2013 -0700
   157.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   157.3 @@ -1,77 +0,0 @@
   157.4 -/*
   157.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   157.6 - * this software and associated documentation files (the "Software"), to deal in
   157.7 - * the Software without restriction, including without limitation the rights to
   157.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   157.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  157.10 - * so, subject to the following conditions:
  157.11 - *
  157.12 - * The above copyright notice and this permission notice shall be included in all
  157.13 - * copies or substantial portions of the Software.
  157.14 - *
  157.15 - * THE SOFTWARE IS PROVIDED "AS IS".toCharArray(), WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  157.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  157.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  157.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  157.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  157.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  157.21 - * SOFTWARE.
  157.22 - */
  157.23 -package jdk.nashorn.internal.runtime.regexp.joni.encoding;
  157.24 -
  157.25 -import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
  157.26 -import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
  157.27 -
  157.28 -import java.util.HashMap;
  157.29 -
  157.30 -public class PosixBracket {
  157.31 -
  157.32 -    public static final char[][] PBSNamesLower = {
  157.33 -            "alnum".toCharArray(),
  157.34 -            "alpha".toCharArray(),
  157.35 -            "blank".toCharArray(),
  157.36 -            "cntrl".toCharArray(),
  157.37 -            "digit".toCharArray(),
  157.38 -            "graph".toCharArray(),
  157.39 -            "lower".toCharArray(),
  157.40 -            "print".toCharArray(),
  157.41 -            "punct".toCharArray(),
  157.42 -            "space".toCharArray(),
  157.43 -            "upper".toCharArray(),
  157.44 -            "xdigit".toCharArray(),
  157.45 -            "ascii".toCharArray(),
  157.46 -            "word".toCharArray()
  157.47 -    };
  157.48 -
  157.49 -    public static final int PBSValues[] = {
  157.50 -            CharacterType.ALNUM,
  157.51 -            CharacterType.ALPHA,
  157.52 -            CharacterType.BLANK,
  157.53 -            CharacterType.CNTRL,
  157.54 -            CharacterType.DIGIT,
  157.55 -            CharacterType.GRAPH,
  157.56 -            CharacterType.LOWER,
  157.57 -            CharacterType.PRINT,
  157.58 -            CharacterType.PUNCT,
  157.59 -            CharacterType.SPACE,
  157.60 -            CharacterType.UPPER,
  157.61 -            CharacterType.XDIGIT,
  157.62 -            CharacterType.ASCII,
  157.63 -            CharacterType.WORD,
  157.64 -    };
  157.65 -
  157.66 -    public static int propertyNameToCType(String name) {
  157.67 -        name = name.toLowerCase();
  157.68 -        if (!PBSTableUpper.containsKey(name)) {
  157.69 -            throw new JOniException(ErrorMessages.ERR_INVALID_CHAR_PROPERTY_NAME.replaceAll("%n", name));
  157.70 -        }
  157.71 -        return PBSTableUpper.get(name);
  157.72 -    }
  157.73 -
  157.74 -    private static final HashMap<String,Integer> PBSTableUpper = new HashMap<String,Integer>();
  157.75 -
  157.76 -    static {
  157.77 -        for (int i=0; i<PBSValues.length; i++) PBSTableUpper.put(new String(PBSNamesLower[i]), PBSValues[i]);
  157.78 -    }
  157.79 -
  157.80 -}
   158.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/Ptr.java	Thu May 30 10:58:35 2013 -0700
   158.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   158.3 @@ -1,35 +0,0 @@
   158.4 -/*
   158.5 - * Permission is hereby granted, free of charge, to any person obtaining a copy of
   158.6 - * this software and associated documentation files (the "Software"), to deal in
   158.7 - * the Software without restriction, including without limitation the rights to
   158.8 - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   158.9 - * of the Software, and to permit persons to whom the Software is furnished to do
  158.10 - * so, subject to the following conditions:
  158.11 - *
  158.12 - * The above copyright notice and this permission notice shall be included in all
  158.13 - * copies or substantial portions of the Software.
  158.14 - *
  158.15 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  158.16 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  158.17 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  158.18 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  158.19 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  158.20 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  158.21 - * SOFTWARE.
  158.22 - */
  158.23 -package jdk.nashorn.internal.runtime.regexp.joni.encoding;
  158.24 -
  158.25 -public final class Ptr {
  158.26 -    public Ptr() {
  158.27 -        this(0);
  158.28 -    }
  158.29 -
  158.30 -    public Ptr(int p) {
  158.31 -        this.p = p;
  158.32 -    }
  158.33 -
  158.34 -    public int p;
  158.35 -
  158.36 -    public static final Ptr NULL = new Ptr(0);
  158.37 -}
  158.38 -
   159.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java	Thu May 30 10:58:35 2013 -0700
   159.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java	Mon Jun 03 23:24:36 2013 -0700
   159.3 @@ -22,28 +22,16 @@
   159.4  import jdk.nashorn.internal.runtime.regexp.joni.Config;
   159.5  
   159.6  public interface ErrorMessages {
   159.7 -    final String MISMATCH = "mismatch";
   159.8 -    final String NO_SUPPORT_CONFIG = "no support in this configuration";
   159.9  
  159.10      /* from jcodings */
  159.11 -    final String ERR_INVALID_CHAR_PROPERTY_NAME = "invalid character property name <%n>";
  159.12      final String ERR_INVALID_CODE_POINT_VALUE = "invalid code point value";
  159.13      final String ERR_TOO_BIG_WIDE_CHAR_VALUE = "too big wide-char value";
  159.14      final String ERR_TOO_LONG_WIDE_CHAR_VALUE = "too long wide-char value";
  159.15  
  159.16      /* internal error */
  159.17 -    final String ERR_MEMORY = "fail to memory allocation";
  159.18 -    final String ERR_MATCH_STACK_LIMIT_OVER = "match-stack limit over";
  159.19 -    final String ERR_TYPE_BUG = "undefined type (bug)";
  159.20      final String ERR_PARSER_BUG = "internal parser error (bug)";
  159.21 -    final String ERR_STACK_BUG = "stack error (bug)";
  159.22      final String ERR_UNDEFINED_BYTECODE = "undefined bytecode (bug)";
  159.23      final String ERR_UNEXPECTED_BYTECODE = "unexpected bytecode (bug)";
  159.24 -    final String ERR_DEFAULT_ENCODING_IS_NOT_SETTED = "default multibyte-encoding is not setted";
  159.25 -    final String ERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR = "can't convert to wide-char on specified multibyte-encoding";
  159.26 -
  159.27 -    /* general error */
  159.28 -    final String ERR_INVALID_ARGUMENT = "invalid argument";
  159.29  
  159.30      /* syntax error */
  159.31      final String ERR_END_PATTERN_AT_LEFT_BRACE = "end pattern at left brace";
  159.32 @@ -56,11 +44,9 @@
  159.33      final String ERR_META_CODE_SYNTAX = "invalid meta-code syntax";
  159.34      final String ERR_CONTROL_CODE_SYNTAX = "invalid control-code syntax";
  159.35      final String ERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE = "char-class value at end of range";
  159.36 -    final String ERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE = "char-class value at start of range";
  159.37      final String ERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS = "unmatched range specifier in char-class";
  159.38      final String ERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED = "target of repeat operator is not specified";
  159.39      final String ERR_TARGET_OF_REPEAT_OPERATOR_INVALID = "target of repeat operator is invalid";
  159.40 -    final String ERR_NESTED_REPEAT_OPERATOR = "nested repeat operator";
  159.41      final String ERR_UNMATCHED_CLOSE_PARENTHESIS = "unmatched close parenthesis";
  159.42      final String ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS = "end pattern with unmatched parenthesis";
  159.43      final String ERR_END_PATTERN_IN_GROUP = "end pattern in group";
  159.44 @@ -74,25 +60,14 @@
  159.45      final String ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE = "too big number for repeat range";
  159.46      final String ERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE = "upper is smaller than lower in repeat range";
  159.47      final String ERR_EMPTY_RANGE_IN_CHAR_CLASS = "empty range in char class";
  159.48 -    final String ERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE = "mismatch multibyte code length in char-class range";
  159.49      final String ERR_TOO_MANY_MULTI_BYTE_RANGES = "too many multibyte code ranges are specified";
  159.50      final String ERR_TOO_SHORT_MULTI_BYTE_STRING = "too short multibyte code string";
  159.51 -    final String ERR_TOO_BIG_BACKREF_NUMBER = "too big backref number";
  159.52 -    final String ERR_INVALID_BACKREF = Config.USE_NAMED_GROUP ? "invalid backref number/name" : "invalid backref number";
  159.53 +    final String ERR_INVALID_BACKREF = "invalid backref number";
  159.54      final String ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED = "numbered backref/call is not allowed. (use name)";
  159.55 -    final String ERR_INVALID_WIDE_CHAR_VALUE = "invalid wide-char value";
  159.56      final String ERR_EMPTY_GROUP_NAME = "group name is empty";
  159.57      final String ERR_INVALID_GROUP_NAME = "invalid group name <%n>";
  159.58 -    final String ERR_INVALID_CHAR_IN_GROUP_NAME = Config.USE_NAMED_GROUP ? "invalid char in group name <%n>" : "invalid char in group number <%n>";
  159.59 -    final String ERR_UNDEFINED_NAME_REFERENCE = "undefined name <%n> reference";
  159.60 -    final String ERR_UNDEFINED_GROUP_REFERENCE = "undefined group <%n> reference";
  159.61 -    final String ERR_MULTIPLEX_DEFINED_NAME = "multiplex defined name <%n>";
  159.62 -    final String ERR_MULTIPLEX_DEFINITION_NAME_CALL = "multiplex definition name <%n> call";
  159.63 -    final String ERR_NEVER_ENDING_RECURSION = "never ending recursion";
  159.64 +    final String ERR_INVALID_CHAR_IN_GROUP_NAME = "invalid char in group number <%n>";
  159.65      final String ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY = "group number is too big for capture history";
  159.66 -    final String ERR_NOT_SUPPORTED_ENCODING_COMBINATION = "not supported encoding combination";
  159.67      final String ERR_INVALID_COMBINATION_OF_OPTIONS = "invalid combination of options";
  159.68 -    final String ERR_OVER_THREAD_PASS_LIMIT_COUNT = "over thread pass limit count";
  159.69 -    final String ERR_TOO_BIG_SB_CHAR_VALUE = "too big singlebyte char value";
  159.70  
  159.71  }
   160.1 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ValueException.java	Thu May 30 10:58:35 2013 -0700
   160.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ValueException.java	Mon Jun 03 23:24:36 2013 -0700
   160.3 @@ -30,8 +30,4 @@
   160.4          super(message.replaceAll("%n", str));
   160.5      }
   160.6  
   160.7 -    public ValueException(String message, byte[]bytes, int p, int end) {
   160.8 -        this(message, new String(bytes, p, end - p));
   160.9 -    }
  160.10 -
  160.11  }
   161.1 --- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Thu May 30 10:58:35 2013 -0700
   161.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Mon Jun 03 23:24:36 2013 -0700
   161.3 @@ -125,6 +125,7 @@
   161.4  type.error.no.method.matches.args=Can not invoke method {0} with the passed arguments; they do not match any of its method signatures.
   161.5  type.error.method.not.constructor=Java method {0} can't be used as a constructor.
   161.6  type.error.env.not.object=$ENV must be an Object.
   161.7 +type.error.unsupported.java.to.type=Unsupported Java.to target type {0}.
   161.8  range.error.inappropriate.array.length=inappropriate array length: {0}
   161.9  range.error.invalid.fraction.digits=fractionDigits argument to {0} must be in [0, 20]
  161.10  range.error.invalid.precision=precision argument toPrecision() must be in [1, 21]
   162.1 --- a/src/jdk/nashorn/internal/runtime/resources/Options.properties	Thu May 30 10:58:35 2013 -0700
   162.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Options.properties	Mon Jun 03 23:24:36 2013 -0700
   162.3 @@ -277,6 +277,12 @@
   162.4      desc="Print the symbol table." \
   162.5  }
   162.6  
   162.7 +nashorn.option.range.analysis = { \
   162.8 +    name="--range-analysis",      \
   162.9 +    is_undocumented=true,         \
  162.10 +    desc="Do range analysis using known compile time types, and try to narrow number types" \
  162.11 +}    
  162.12 +
  162.13  nashorn.option.D = {                                                          \
  162.14      name="-D",                                                                \
  162.15      desc="-Dname=value. Set a system property. This option can be repeated.", \
  162.16 @@ -326,6 +332,15 @@
  162.17      type=TimeZone                              \
  162.18  }
  162.19  
  162.20 +nashorn.option.locale = {                    \
  162.21 +    name="--locale",                         \
  162.22 +    short_name="-l",                         \
  162.23 +    is_undocumented=true,                    \
  162.24 +    params="<locale>",                       \
  162.25 +    desc="Set Locale for script execution.", \
  162.26 +    type=Locale                              \
  162.27 +}
  162.28 +
  162.29  nashorn.option.trace.callsites = {                                              \
  162.30      name="--trace-callsites",                                                   \
  162.31      short_name="-tcs",                                                          \
   163.1 --- a/src/netscape/javascript/JSObject.java	Thu May 30 10:58:35 2013 -0700
   163.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   163.3 @@ -1,101 +0,0 @@
   163.4 -/*
   163.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   163.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   163.7 - *
   163.8 - * This code is free software; you can redistribute it and/or modify it
   163.9 - * under the terms of the GNU General Public License version 2 only, as
  163.10 - * published by the Free Software Foundation.  Oracle designates this
  163.11 - * particular file as subject to the "Classpath" exception as provided
  163.12 - * by Oracle in the LICENSE file that accompanied this code.
  163.13 - *
  163.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
  163.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  163.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  163.17 - * version 2 for more details (a copy is included in the LICENSE file that
  163.18 - * accompanied this code).
  163.19 - *
  163.20 - * You should have received a copy of the GNU General Public License version
  163.21 - * 2 along with this work; if not, write to the Free Software Foundation,
  163.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  163.23 - *
  163.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  163.25 - * or visit www.oracle.com if you need additional information or have any
  163.26 - * questions.
  163.27 - */
  163.28 -
  163.29 -package netscape.javascript;
  163.30 -
  163.31 -import java.applet.Applet;
  163.32 -
  163.33 -/**
  163.34 - * Stub for JSObject to get compilation going.
  163.35 - */
  163.36 -public abstract class JSObject {
  163.37 -
  163.38 -    /**
  163.39 -     * Get the window for an {@link Applet}. Not supported
  163.40 -     * by Nashorn
  163.41 -     *
  163.42 -     * @param a applet
  163.43 -     * @return the window instance
  163.44 -     */
  163.45 -    public static JSObject getWindow(final Applet a) {
  163.46 -        throw new UnsupportedOperationException("getWindow");
  163.47 -    }
  163.48 -
  163.49 -    /**
  163.50 -     * Call a JavaScript method
  163.51 -     *
  163.52 -     * @param methodName name of method
  163.53 -     * @param args arguments to method
  163.54 -     * @return result of call
  163.55 -     */
  163.56 -    public abstract Object call(String methodName, Object args[]);
  163.57 -
  163.58 -    /**
  163.59 -     * Evaluate a JavaScript expression
  163.60 -     *
  163.61 -     * @param s JavaScript expression to evaluate
  163.62 -     * @return evaluation result
  163.63 -     */
  163.64 -    public abstract Object eval(String s);
  163.65 -
  163.66 -    /**
  163.67 -     * Retrieves a named member of a JavaScript object.
  163.68 -     *
  163.69 -     * @param name of member
  163.70 -     * @return member
  163.71 -     */
  163.72 -    public abstract Object getMember(String name);
  163.73 -
  163.74 -    /**
  163.75 -     * Retrieves an indexed member of a JavaScript object.
  163.76 -     *
  163.77 -     * @param index index of member slot
  163.78 -     * @return member
  163.79 -     */
  163.80 -    public abstract Object getSlot(int index);
  163.81 -
  163.82 -    /**
  163.83 -     * Remove a named member from a JavaScript object
  163.84 -     *
  163.85 -     * @param name name of member
  163.86 -     */
  163.87 -    public abstract void removeMember(String name);
  163.88 -
  163.89 -    /**
  163.90 -     * Set a named member in a JavaScript object
  163.91 -     *
  163.92 -     * @param name  name of member
  163.93 -     * @param value value of member
  163.94 -     */
  163.95 -    public abstract void setMember(String name, Object value);
  163.96 -
  163.97 -    /**
  163.98 -     * Set an indexed member in a JavaScript object
  163.99 -     *
 163.100 -     * @param index index of member slot
 163.101 -     * @param value value of member
 163.102 -     */
 163.103 -    public abstract void setSlot(int index, Object value);
 163.104 -}
   164.1 --- a/test/script/basic/JDK-8008554.js	Thu May 30 10:58:35 2013 -0700
   164.2 +++ b/test/script/basic/JDK-8008554.js	Mon Jun 03 23:24:36 2013 -0700
   164.3 @@ -32,5 +32,5 @@
   164.4  var dir = __DIR__;
   164.5  var file = __FILE__.replace("JDK-8008554", "NASHORN-99");
   164.6  load(file);
   164.7 -file = "file://" + __DIR__ + "NASHORN-99.js";
   164.8 +file = "file:///" + __DIR__ + "NASHORN-99.js";
   164.9  load(file);
   165.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   165.2 +++ b/test/script/basic/JDK-8010804.js	Mon Jun 03 23:24:36 2013 -0700
   165.3 @@ -0,0 +1,86 @@
   165.4 +/*
   165.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   165.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   165.7 + * 
   165.8 + * This code is free software; you can redistribute it and/or modify it
   165.9 + * under the terms of the GNU General Public License version 2 only, as
  165.10 + * published by the Free Software Foundation.
  165.11 + * 
  165.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  165.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  165.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  165.15 + * version 2 for more details (a copy is included in the LICENSE file that
  165.16 + * accompanied this code).
  165.17 + * 
  165.18 + * You should have received a copy of the GNU General Public License version
  165.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  165.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  165.21 + * 
  165.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  165.23 + * or visit www.oracle.com if you need additional information or have any
  165.24 + * questions.
  165.25 + */
  165.26 +
  165.27 +/**
  165.28 + * JDK-8010804: Review long and integer usage conventions
  165.29 + *
  165.30 + * @test
  165.31 + * @run
  165.32 + */
  165.33 +
  165.34 +var x = [];
  165.35 +print(x.length);
  165.36 +x[4294967294] = 1;
  165.37 +print(x.length);
  165.38 +x[4294967295] = 1;
  165.39 +print(x.length);
  165.40 +print(x.slice(4294967293).length);
  165.41 +print(x.slice(4294967294).length);
  165.42 +print(x.slice(4294967295).length);
  165.43 +print(x.slice(4294967296).length);
  165.44 +
  165.45 +print(x.slice(-4294967293).length);
  165.46 +print(x.slice(-4294967294).length);
  165.47 +print(x.slice(-4294967295).length);
  165.48 +print(x.slice(-4294967296).length);
  165.49 +
  165.50 +print(x.slice(0, 4294967293).length);
  165.51 +print(x.slice(0, 4294967294).length);
  165.52 +print(x.slice(0, 4294967295).length);
  165.53 +print(x.slice(0, 4294967296).length);
  165.54 +
  165.55 +print(x.slice(0, -4294967293).length);
  165.56 +print(x.slice(0, -4294967294).length);
  165.57 +print(x.slice(0, -4294967295).length);
  165.58 +print(x.slice(0, -4294967296).length);
  165.59 +
  165.60 +print(x.slice(9223371036854775807).length);
  165.61 +print(x.slice(9223372036854775807).length);
  165.62 +print(x.slice(9223373036854775807).length);
  165.63 +print(x.slice(9223374036854775807).length);
  165.64 +
  165.65 +print(x.slice(-9223371036854775807).length);
  165.66 +print(x.slice(-9223372036854775807).length);
  165.67 +print(x.slice(-9223373036854775807).length);
  165.68 +print(x.slice(-9223374036854775807).length);
  165.69 +
  165.70 +print(x.slice(-9223371036854775807, 1).length);
  165.71 +print(x.slice(-9223372036854775807, 1).length);
  165.72 +print(x.slice(-9223373036854775807, 1).length);
  165.73 +print(x.slice(-9223374036854775807, 1).length);
  165.74 +
  165.75 +print(x.slice(-9223371036854775807, -1).length);
  165.76 +print(x.slice(-9223372036854775807, -1).length);
  165.77 +print(x.slice(-9223373036854775807, -1).length);
  165.78 +print(x.slice(-9223374036854775807, -1).length);
  165.79 +
  165.80 +print(x.slice(Infinity).length);
  165.81 +print(x.slice(Infinity, Infinity).length);
  165.82 +print(x.slice(Infinity, -Infinity).length);
  165.83 +print(x.slice(-Infinity).length);
  165.84 +print(x.slice(-Infinity, Infinity).length);
  165.85 +print(x.slice(-Infinity, -Infinity).length);
  165.86 +
  165.87 +var d = new Date();
  165.88 +d.setYear(Infinity);
  165.89 +print(d);
  165.90 \ No newline at end of file
   166.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   166.2 +++ b/test/script/basic/JDK-8010804.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   166.3 @@ -0,0 +1,42 @@
   166.4 +0
   166.5 +4294967295
   166.6 +4294967295
   166.7 +2
   166.8 +1
   166.9 +0
  166.10 +0
  166.11 +4294967293
  166.12 +4294967294
  166.13 +4294967295
  166.14 +4294967295
  166.15 +4294967293
  166.16 +4294967294
  166.17 +4294967295
  166.18 +4294967295
  166.19 +2
  166.20 +1
  166.21 +0
  166.22 +0
  166.23 +0
  166.24 +0
  166.25 +0
  166.26 +0
  166.27 +4294967295
  166.28 +4294967295
  166.29 +4294967295
  166.30 +4294967295
  166.31 +1
  166.32 +1
  166.33 +1
  166.34 +1
  166.35 +4294967294
  166.36 +4294967294
  166.37 +4294967294
  166.38 +4294967294
  166.39 +0
  166.40 +0
  166.41 +0
  166.42 +4294967295
  166.43 +4294967295
  166.44 +0
  166.45 +Invalid Date
   167.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   167.2 +++ b/test/script/basic/JDK-8011023.js	Mon Jun 03 23:24:36 2013 -0700
   167.3 @@ -0,0 +1,34 @@
   167.4 +/*
   167.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   167.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   167.7 + * 
   167.8 + * This code is free software; you can redistribute it and/or modify it
   167.9 + * under the terms of the GNU General Public License version 2 only, as
  167.10 + * published by the Free Software Foundation.
  167.11 + * 
  167.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  167.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  167.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  167.15 + * version 2 for more details (a copy is included in the LICENSE file that
  167.16 + * accompanied this code).
  167.17 + * 
  167.18 + * You should have received a copy of the GNU General Public License version
  167.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  167.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  167.21 + * 
  167.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  167.23 + * or visit www.oracle.com if you need additional information or have any
  167.24 + * questions.
  167.25 + */
  167.26 +
  167.27 +/**
  167.28 + * Round should be ecma compliant
  167.29 + *
  167.30 + * @test
  167.31 + * @run 
  167.32 + */
  167.33 +
  167.34 +print(1/Math.round(-0.5));
  167.35 +print(Math.round(9007199254740991));
  167.36 +print(Math.round(9223372036854775807*2));
  167.37 +
   168.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   168.2 +++ b/test/script/basic/JDK-8011023.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   168.3 @@ -0,0 +1,3 @@
   168.4 +-Infinity
   168.5 +9007199254740991
   168.6 +18446744073709552000
   169.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   169.2 +++ b/test/script/basic/JDK-8011718.js	Mon Jun 03 23:24:36 2013 -0700
   169.3 @@ -0,0 +1,46 @@
   169.4 +/*
   169.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   169.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   169.7 + *
   169.8 + * This code is free software; you can redistribute it and/or modify it
   169.9 + * under the terms of the GNU General Public License version 2 only, as
  169.10 + * published by the Free Software Foundation.
  169.11 + *
  169.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  169.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  169.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  169.15 + * version 2 for more details (a copy is included in the LICENSE file that
  169.16 + * accompanied this code).
  169.17 + *
  169.18 + * You should have received a copy of the GNU General Public License version
  169.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  169.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  169.21 + *
  169.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  169.23 + * or visit www.oracle.com if you need additional information or have any
  169.24 + * questions.
  169.25 + */
  169.26 +
  169.27 +/**
  169.28 + * JDK-8011718: binding already bound function with extra arguments fails.
  169.29 + *
  169.30 + * @test
  169.31 + * @run
  169.32 + */
  169.33 +
  169.34 +var obj = { 
  169.35 +    hello:"From obj", 
  169.36 +}; 
  169.37 +var obj2 = { 
  169.38 +    hello:"From obj2", 
  169.39 +}; 
  169.40 +
  169.41 +function doit(cb){ 
  169.42 +    cb(); 
  169.43 +    var cb2 = cb.bind(obj2, "This one is not acccepted"); 
  169.44 +    cb2(); 
  169.45 +} 
  169.46 +
  169.47 +doit(function(){ 
  169.48 +        print(this.hello); 
  169.49 +    }.bind(obj));
   170.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   170.2 +++ b/test/script/basic/JDK-8011718.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   170.3 @@ -0,0 +1,2 @@
   170.4 +From obj
   170.5 +From obj
   171.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   171.2 +++ b/test/script/basic/JDK-8012083.js	Mon Jun 03 23:24:36 2013 -0700
   171.3 @@ -0,0 +1,70 @@
   171.4 +/*
   171.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   171.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   171.7 + * 
   171.8 + * This code is free software; you can redistribute it and/or modify it
   171.9 + * under the terms of the GNU General Public License version 2 only, as
  171.10 + * published by the Free Software Foundation.
  171.11 + * 
  171.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  171.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  171.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  171.15 + * version 2 for more details (a copy is included in the LICENSE file that
  171.16 + * accompanied this code).
  171.17 + * 
  171.18 + * You should have received a copy of the GNU General Public License version
  171.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  171.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  171.21 + * 
  171.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  171.23 + * or visit www.oracle.com if you need additional information or have any
  171.24 + * questions.
  171.25 + */
  171.26 +
  171.27 +/**
  171.28 + * JDK-8012093 - array literals can only be subject to constant evaluation under very special
  171.29 + * circumstances.
  171.30 + *
  171.31 + * @test
  171.32 + * @run
  171.33 + */
  171.34 +
  171.35 +
  171.36 +var w00t = 17;
  171.37 +print(+[w00t]);
  171.38 +
  171.39 +var empty = [];
  171.40 +print(empty == false);
  171.41 +
  171.42 +print([] == false);
  171.43 +print([] === false);
  171.44 +print(!![]);
  171.45 +
  171.46 +print(~[]);
  171.47 +print(![]);
  171.48 +print(![17]);
  171.49 +print(![17,1,2]);
  171.50 +
  171.51 +var one = 1;
  171.52 +var two = 2;
  171.53 +var a1 = [one];
  171.54 +var a2 = [two];
  171.55 +print(+a1 + +a2); //3
  171.56 +
  171.57 +var x = 1;
  171.58 +print(+["apa"]);
  171.59 +print(+[]);  //0
  171.60 +print(+[1]); //1
  171.61 +print(+[x]); //1
  171.62 +print(+[1,2,3]); //NaN
  171.63 +var a = [];
  171.64 +var b = [1];
  171.65 +print(a/b);
  171.66 +print(++[[]][+[]]+[+[]]); //10
  171.67 +print(+[] == 0);
  171.68 +
  171.69 +var first = [![]+[]][+[]][+[]]+[![]+[]][+[]][+!+[]]+[!+[]+[]][+![]][+![]]+[![]+[]][+[]][+!+[]]+[![]+[]][+[]][+!+[]+!+[]];
  171.70 +var second =(![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]];
  171.71 +
  171.72 +print(first + " " + second);
  171.73 +
   172.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   172.2 +++ b/test/script/basic/JDK-8012083.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   172.3 @@ -0,0 +1,19 @@
   172.4 +17
   172.5 +true
   172.6 +true
   172.7 +false
   172.8 +true
   172.9 +-1
  172.10 +false
  172.11 +false
  172.12 +false
  172.13 +3
  172.14 +NaN
  172.15 +0
  172.16 +1
  172.17 +1
  172.18 +NaN
  172.19 +0
  172.20 +10
  172.21 +true
  172.22 +fatal fail
   173.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   173.2 +++ b/test/script/basic/JDK-8012305.js	Mon Jun 03 23:24:36 2013 -0700
   173.3 @@ -0,0 +1,39 @@
   173.4 +/*
   173.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   173.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   173.7 + *
   173.8 + * This code is free software; you can redistribute it and/or modify it
   173.9 + * under the terms of the GNU General Public License version 2 only, as
  173.10 + * published by the Free Software Foundation.
  173.11 + *
  173.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  173.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  173.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  173.15 + * version 2 for more details (a copy is included in the LICENSE file that
  173.16 + * accompanied this code).
  173.17 + *
  173.18 + * You should have received a copy of the GNU General Public License version
  173.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  173.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  173.21 + *
  173.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  173.23 + * or visit www.oracle.com if you need additional information or have any
  173.24 + * questions.
  173.25 + */
  173.26 +
  173.27 +/**
  173.28 + * JDK-8012305: Function.bind can't be called on prototype function inside constructor 
  173.29 + *
  173.30 + * @test
  173.31 + * @run
  173.32 + */
  173.33 +
  173.34 +function MyObject() {
  173.35 +    // If the call to bind is removed, then the function is properly printed.
  173.36 +    print("function " + this._process);
  173.37 +    this._process = this._process.bind(this);
  173.38 +}
  173.39 +
  173.40 +MyObject.prototype._process = function() { print("Message "); }
  173.41 +
  173.42 +var s = new MyObject(); 
   174.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   174.2 +++ b/test/script/basic/JDK-8012305.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   174.3 @@ -0,0 +1,1 @@
   174.4 +function function() { print("Message "); }
   175.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   175.2 +++ b/test/script/basic/JDK-8013919.js	Mon Jun 03 23:24:36 2013 -0700
   175.3 @@ -0,0 +1,39 @@
   175.4 +/*
   175.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   175.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   175.7 + * 
   175.8 + * This code is free software; you can redistribute it and/or modify it
   175.9 + * under the terms of the GNU General Public License version 2 only, as
  175.10 + * published by the Free Software Foundation.
  175.11 + * 
  175.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  175.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  175.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  175.15 + * version 2 for more details (a copy is included in the LICENSE file that
  175.16 + * accompanied this code).
  175.17 + * 
  175.18 + * You should have received a copy of the GNU General Public License version
  175.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  175.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  175.21 + * 
  175.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  175.23 + * or visit www.oracle.com if you need additional information or have any
  175.24 + * questions.
  175.25 + */
  175.26 +
  175.27 +/**
  175.28 + * JDK-8013913: finally cloning of function node declarations caused
  175.29 + * method collissions
  175.30 + *
  175.31 + * @test
  175.32 + * @run
  175.33 + */
  175.34 +
  175.35 +try {
  175.36 +    print("a");
  175.37 +} finally {
  175.38 +    var b = function() {
  175.39 +	print("b");
  175.40 +    }
  175.41 +    b();
  175.42 +}
   176.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   176.2 +++ b/test/script/basic/JDK-8013919.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   176.3 @@ -0,0 +1,2 @@
   176.4 +a
   176.5 +b
   177.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   177.2 +++ b/test/script/basic/JDK-8014426.js	Mon Jun 03 23:24:36 2013 -0700
   177.3 @@ -0,0 +1,49 @@
   177.4 +/*
   177.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   177.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   177.7 + * 
   177.8 + * This code is free software; you can redistribute it and/or modify it
   177.9 + * under the terms of the GNU General Public License version 2 only, as
  177.10 + * published by the Free Software Foundation.
  177.11 + * 
  177.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  177.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  177.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  177.15 + * version 2 for more details (a copy is included in the LICENSE file that
  177.16 + * accompanied this code).
  177.17 + * 
  177.18 + * You should have received a copy of the GNU General Public License version
  177.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  177.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  177.21 + * 
  177.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  177.23 + * or visit www.oracle.com if you need additional information or have any
  177.24 + * questions.
  177.25 + */
  177.26 +
  177.27 +/**
  177.28 + * Ensure catchall exceptions from finally inlining are rethrown as is
  177.29 + *
  177.30 + * @test
  177.31 + * @run
  177.32 + */
  177.33 +
  177.34 +function runScriptEngine() {
  177.35 +    var fac    = new Packages.jdk.nashorn.api.scripting.NashornScriptEngineFactory();
  177.36 +    var engine = fac.getScriptEngine();
  177.37 +    engine.eval(
  177.38 +"try {\n\
  177.39 +  doIt();\n\
  177.40 +} finally { \n\
  177.41 +  var x = 17;\n\
  177.42 +}\n\
  177.43 +function doIt() {\n\
  177.44 +  throw new TypeError('en stor graa noshoerning!');\n\
  177.45 +}\n");
  177.46 +}
  177.47 +
  177.48 +try {
  177.49 +    runScriptEngine();
  177.50 +} catch(e) {
  177.51 +    print(e);
  177.52 +}
   178.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   178.2 +++ b/test/script/basic/JDK-8014426.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   178.3 @@ -0,0 +1,1 @@
   178.4 +javax.script.ScriptException: TypeError: en stor graa noshoerning! in <eval> at line number 7 at column number 2
   179.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   179.2 +++ b/test/script/basic/JDK-8014647.js	Mon Jun 03 23:24:36 2013 -0700
   179.3 @@ -0,0 +1,40 @@
   179.4 +/*
   179.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   179.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   179.7 + * 
   179.8 + * This code is free software; you can redistribute it and/or modify it
   179.9 + * under the terms of the GNU General Public License version 2 only, as
  179.10 + * published by the Free Software Foundation.
  179.11 + * 
  179.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  179.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  179.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  179.15 + * version 2 for more details (a copy is included in the LICENSE file that
  179.16 + * accompanied this code).
  179.17 + * 
  179.18 + * You should have received a copy of the GNU General Public License version
  179.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  179.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  179.21 + * 
  179.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  179.23 + * or visit www.oracle.com if you need additional information or have any
  179.24 + * questions.
  179.25 + */
  179.26 +
  179.27 +/**
  179.28 + * JDK-8014647: Allow class-based overrides to be initialized with a ScriptFunction
  179.29 + *
  179.30 + * @test
  179.31 + * @run
  179.32 + */
  179.33 +
  179.34 +var RunnableImpl1 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
  179.35 +var RunnableImpl2 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 2!") })
  179.36 +var r1 = new RunnableImpl1()
  179.37 +var r2 = new RunnableImpl2()
  179.38 +var r3 = new RunnableImpl2(function() { print("I'm runnable 3!") })
  179.39 +r1.run()
  179.40 +r2.run()
  179.41 +r3.run()
  179.42 +print("r1.class === r2.class: " + (r1.class === r2.class))
  179.43 +print("r2.class === r3.class: " + (r2.class === r3.class))
   180.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   180.2 +++ b/test/script/basic/JDK-8014647.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   180.3 @@ -0,0 +1,5 @@
   180.4 +I'm runnable 1!
   180.5 +I'm runnable 2!
   180.6 +I'm runnable 3!
   180.7 +r1.class === r2.class: false
   180.8 +r2.class === r3.class: true
   181.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   181.2 +++ b/test/script/basic/JDK-8014735.js	Mon Jun 03 23:24:36 2013 -0700
   181.3 @@ -0,0 +1,43 @@
   181.4 +/*
   181.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   181.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   181.7 + *
   181.8 + * This code is free software; you can redistribute it and/or modify it
   181.9 + * under the terms of the GNU General Public License version 2 only, as
  181.10 + * published by the Free Software Foundation.
  181.11 + *
  181.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  181.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  181.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  181.15 + * version 2 for more details (a copy is included in the LICENSE file that
  181.16 + * accompanied this code).
  181.17 + *
  181.18 + * You should have received a copy of the GNU General Public License version
  181.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  181.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  181.21 + *
  181.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  181.23 + * or visit www.oracle.com if you need additional information or have any
  181.24 + * questions.
  181.25 + */
  181.26 +
  181.27 +/**
  181.28 + * JDK-8014735: Typed Array, BYTES_PER_ELEMENT should be a class property
  181.29 + *
  181.30 + * @test
  181.31 + * @run
  181.32 + */
  181.33 +
  181.34 +function bytesPerElement(func) {
  181.35 +    print(func.name + ".BYTES_PER_ELEMENT = " + func.BYTES_PER_ELEMENT);
  181.36 +}
  181.37 +
  181.38 +bytesPerElement(Int8Array);
  181.39 +bytesPerElement(Int16Array);
  181.40 +bytesPerElement(Int32Array);
  181.41 +bytesPerElement(Uint8Array);
  181.42 +bytesPerElement(Uint8ClampedArray);
  181.43 +bytesPerElement(Uint16Array);
  181.44 +bytesPerElement(Uint32Array);
  181.45 +bytesPerElement(Float32Array);
  181.46 +bytesPerElement(Float64Array);
   182.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   182.2 +++ b/test/script/basic/JDK-8014735.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   182.3 @@ -0,0 +1,9 @@
   182.4 +Int8Array.BYTES_PER_ELEMENT = 1
   182.5 +Int16Array.BYTES_PER_ELEMENT = 2
   182.6 +Int32Array.BYTES_PER_ELEMENT = 4
   182.7 +Uint8Array.BYTES_PER_ELEMENT = 1
   182.8 +Uint8ClampedArray.BYTES_PER_ELEMENT = 1
   182.9 +Uint16Array.BYTES_PER_ELEMENT = 2
  182.10 +Uint32Array.BYTES_PER_ELEMENT = 4
  182.11 +Float32Array.BYTES_PER_ELEMENT = 4
  182.12 +Float64Array.BYTES_PER_ELEMENT = 8
   183.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   183.2 +++ b/test/script/basic/JDK-8014953.js	Mon Jun 03 23:24:36 2013 -0700
   183.3 @@ -0,0 +1,45 @@
   183.4 +/*
   183.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   183.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   183.7 + * 
   183.8 + * This code is free software; you can redistribute it and/or modify it
   183.9 + * under the terms of the GNU General Public License version 2 only, as
  183.10 + * published by the Free Software Foundation.
  183.11 + * 
  183.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  183.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  183.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  183.15 + * version 2 for more details (a copy is included in the LICENSE file that
  183.16 + * accompanied this code).
  183.17 + * 
  183.18 + * You should have received a copy of the GNU General Public License version
  183.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  183.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  183.21 + * 
  183.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  183.23 + * or visit www.oracle.com if you need additional information or have any
  183.24 + * questions.
  183.25 + */
  183.26 +
  183.27 +/**
  183.28 + * JDK-8014953: Have NativeJavaPackage throw a ClassNotFoundException when invoked with "new"
  183.29 + *
  183.30 + * @test
  183.31 + * @run
  183.32 + */
  183.33 + 
  183.34 +try {
  183.35 +    new java.util.ArrrayList(16)
  183.36 +} catch(e) {
  183.37 +   print("Invoked as constructor");
  183.38 +   print("e.class=" + e.class)
  183.39 +   print("e.message=" + e.message);
  183.40 +}
  183.41 +
  183.42 +try {
  183.43 +    java.util.ArrrayList(16)
  183.44 +} catch(e) {
  183.45 +   print("Invoked as method");
  183.46 +   print("e.class=" + e.class)
  183.47 +   print("e.message=" + e.message);
  183.48 +}
   184.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   184.2 +++ b/test/script/basic/JDK-8014953.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   184.3 @@ -0,0 +1,6 @@
   184.4 +Invoked as constructor
   184.5 +e.class=class java.lang.ClassNotFoundException
   184.6 +e.message=java.util.ArrrayList
   184.7 +Invoked as method
   184.8 +e.class=class java.lang.ClassNotFoundException
   184.9 +e.message=java.util.ArrrayList
   185.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   185.2 +++ b/test/script/basic/JDK-8015267.js	Mon Jun 03 23:24:36 2013 -0700
   185.3 @@ -0,0 +1,109 @@
   185.4 +/*
   185.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   185.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   185.7 + * 
   185.8 + * This code is free software; you can redistribute it and/or modify it
   185.9 + * under the terms of the GNU General Public License version 2 only, as
  185.10 + * published by the Free Software Foundation.
  185.11 + * 
  185.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  185.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  185.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  185.15 + * version 2 for more details (a copy is included in the LICENSE file that
  185.16 + * accompanied this code).
  185.17 + * 
  185.18 + * You should have received a copy of the GNU General Public License version
  185.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  185.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  185.21 + * 
  185.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  185.23 + * or visit www.oracle.com if you need additional information or have any
  185.24 + * questions.
  185.25 + */
  185.26 +
  185.27 +/**
  185.28 + * JDK-8015267: have a List/Deque adapter for JS array-like objects
  185.29 + *
  185.30 + * @test
  185.31 + * @run
  185.32 + */
  185.33 + 
  185.34 +var a = ['a', 'b', 'c', 'd']
  185.35 +
  185.36 +var l = Java.to(a, java.util.List)
  185.37 +print(l instanceof java.util.List)
  185.38 +print(l instanceof java.util.Deque)
  185.39 +
  185.40 +print(l[0])
  185.41 +print(l[1])
  185.42 +print(l[2])
  185.43 +print(l[3])
  185.44 +
  185.45 +print(l.size())
  185.46 +
  185.47 +l.push('x')
  185.48 +print(a)
  185.49 +
  185.50 +l.addLast('y')
  185.51 +print(a)
  185.52 +
  185.53 +print(l.pop())
  185.54 +print(l.removeLast())
  185.55 +print(a)
  185.56 +
  185.57 +l.add('e')
  185.58 +l.add(5, 'f')
  185.59 +print(a)
  185.60 +
  185.61 +l.add(0, 'z')
  185.62 +print(a)
  185.63 +
  185.64 +l.add(2, 'x')
  185.65 +print(a)
  185.66 +
  185.67 +l[7] = 'g'
  185.68 +print(a)
  185.69 +
  185.70 +try { l.add(15, '') } catch(e) { print(e.class) } 
  185.71 +try { l.remove(15) } catch(e) { print(e.class) } 
  185.72 +try { l.add(-1, '') } catch(e) { print(e.class) } 
  185.73 +try { l.remove(-1) } catch(e) { print(e.class) } 
  185.74 +
  185.75 +l.remove(7)
  185.76 +l.remove(2)
  185.77 +l.remove(0)
  185.78 +print(a)
  185.79 +
  185.80 +print(l.peek())
  185.81 +print(l.peekFirst())
  185.82 +print(l.peekLast())
  185.83 +
  185.84 +print(l.element())
  185.85 +print(l.getFirst())
  185.86 +print(l.getLast())
  185.87 +
  185.88 +l.offer('1')
  185.89 +l.offerFirst('2')
  185.90 +l.offerLast('3')
  185.91 +print(a)
  185.92 +
  185.93 +a = ['1', '2', 'x', '3', '4', 'x', '5', '6', 'x', '7', '8']
  185.94 +print(a)
  185.95 +var l = Java.to(a, java.util.List)
  185.96 +l.removeFirstOccurrence('x')
  185.97 +print(a)
  185.98 +l.removeLastOccurrence('x')
  185.99 +print(a)
 185.100 +
 185.101 +var empty = Java.to([], java.util.List)
 185.102 +try { empty.pop() } catch(e) { print(e.class) }
 185.103 +try { empty.removeFirst() } catch(e) { print(e.class) }
 185.104 +try { empty.removeLast() } catch(e) { print(e.class) }
 185.105 +
 185.106 +try { empty.element() } catch(e) { print(e.class) }
 185.107 +try { empty.getFirst() } catch(e) { print(e.class) }
 185.108 +try { empty.getLast() } catch(e) { print(e.class) }
 185.109 +
 185.110 +print(empty.peek())
 185.111 +print(empty.peekFirst())
 185.112 +print(empty.peekLast())
   186.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   186.2 +++ b/test/script/basic/JDK-8015267.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   186.3 @@ -0,0 +1,40 @@
   186.4 +true
   186.5 +true
   186.6 +a
   186.7 +b
   186.8 +c
   186.9 +d
  186.10 +4
  186.11 +x,a,b,c,d
  186.12 +x,a,b,c,d,y
  186.13 +x
  186.14 +y
  186.15 +a,b,c,d
  186.16 +a,b,c,d,e,f
  186.17 +z,a,b,c,d,e,f
  186.18 +z,a,x,b,c,d,e,f
  186.19 +z,a,x,b,c,d,e,g
  186.20 +class java.lang.IndexOutOfBoundsException
  186.21 +class java.lang.IndexOutOfBoundsException
  186.22 +class java.lang.IndexOutOfBoundsException
  186.23 +class java.lang.IndexOutOfBoundsException
  186.24 +a,b,c,d,e
  186.25 +a
  186.26 +a
  186.27 +e
  186.28 +a
  186.29 +a
  186.30 +e
  186.31 +2,a,b,c,d,e,1,3
  186.32 +1,2,x,3,4,x,5,6,x,7,8
  186.33 +1,2,3,4,x,5,6,x,7,8
  186.34 +1,2,3,4,x,5,6,7,8
  186.35 +class java.util.NoSuchElementException
  186.36 +class java.util.NoSuchElementException
  186.37 +class java.util.NoSuchElementException
  186.38 +class java.util.NoSuchElementException
  186.39 +class java.util.NoSuchElementException
  186.40 +class java.util.NoSuchElementException
  186.41 +null
  186.42 +null
  186.43 +null
   187.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   187.2 +++ b/test/script/basic/JDK-8015348.js	Mon Jun 03 23:24:36 2013 -0700
   187.3 @@ -0,0 +1,35 @@
   187.4 +/*
   187.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   187.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   187.7 + * 
   187.8 + * This code is free software; you can redistribute it and/or modify it
   187.9 + * under the terms of the GNU General Public License version 2 only, as
  187.10 + * published by the Free Software Foundation.
  187.11 + * 
  187.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  187.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  187.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  187.15 + * version 2 for more details (a copy is included in the LICENSE file that
  187.16 + * accompanied this code).
  187.17 + * 
  187.18 + * You should have received a copy of the GNU General Public License version
  187.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  187.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  187.21 + * 
  187.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  187.23 + * or visit www.oracle.com if you need additional information or have any
  187.24 + * questions.
  187.25 + */
  187.26 +
  187.27 +/**
  187.28 + * JDK-8015348: RegExp("[") results in StackOverflowError
  187.29 + *
  187.30 + * @test
  187.31 + * @run
  187.32 + */
  187.33 +
  187.34 +try {
  187.35 +    new RegExp('[');
  187.36 +} catch (error) {
  187.37 +    print(error.name);
  187.38 +}
   188.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   188.2 +++ b/test/script/basic/JDK-8015348.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   188.3 @@ -0,0 +1,1 @@
   188.4 +SyntaxError
   189.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   189.2 +++ b/test/script/basic/JDK-8015349.js	Mon Jun 03 23:24:36 2013 -0700
   189.3 @@ -0,0 +1,43 @@
   189.4 +/*
   189.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   189.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   189.7 + * 
   189.8 + * This code is free software; you can redistribute it and/or modify it
   189.9 + * under the terms of the GNU General Public License version 2 only, as
  189.10 + * published by the Free Software Foundation.
  189.11 + * 
  189.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  189.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  189.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  189.15 + * version 2 for more details (a copy is included in the LICENSE file that
  189.16 + * accompanied this code).
  189.17 + * 
  189.18 + * You should have received a copy of the GNU General Public License version
  189.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  189.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  189.21 + * 
  189.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  189.23 + * or visit www.oracle.com if you need additional information or have any
  189.24 + * questions.
  189.25 + */
  189.26 +
  189.27 +/**
  189.28 + * JDK-8015349: "abc".lastIndexOf("a",-1) should evaluate to 0 and not -1
  189.29 + *
  189.30 + * @test
  189.31 + * @run
  189.32 + */
  189.33 +
  189.34 +function printEval(code) {
  189.35 +    print(code + " = " + eval(code));
  189.36 +}
  189.37 +
  189.38 +printEval("'abc'.lastIndexOf('a', 4)"); 
  189.39 +printEval("'abc'.lastIndexOf('b', Infinity)");
  189.40 +printEval("'abc'.lastIndexOf('a', -1)");
  189.41 +printEval("'abc'.lastIndexOf('a', -Infinity)");
  189.42 +printEval("'oracle'.lastIndexOf('u')");
  189.43 +printEval("'hello'.lastIndexOf('l')");
  189.44 +printEval("'hello'.lastIndexOf('l', 2)");
  189.45 +printEval("'hello'.lastIndexOf('l', 3)");
  189.46 +printEval("'hello'.lastIndexOf('l', 1)");
   190.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   190.2 +++ b/test/script/basic/JDK-8015349.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   190.3 @@ -0,0 +1,9 @@
   190.4 +'abc'.lastIndexOf('a', 4) = 0
   190.5 +'abc'.lastIndexOf('b', Infinity) = 1
   190.6 +'abc'.lastIndexOf('a', -1) = 0
   190.7 +'abc'.lastIndexOf('a', -Infinity) = 0
   190.8 +'oracle'.lastIndexOf('u') = -1
   190.9 +'hello'.lastIndexOf('l') = 3
  190.10 +'hello'.lastIndexOf('l', 2) = 2
  190.11 +'hello'.lastIndexOf('l', 3) = 3
  190.12 +'hello'.lastIndexOf('l', 1) = -1
   191.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   191.2 +++ b/test/script/basic/JDK-8015352.js	Mon Jun 03 23:24:36 2013 -0700
   191.3 @@ -0,0 +1,46 @@
   191.4 +/*
   191.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   191.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   191.7 + * 
   191.8 + * This code is free software; you can redistribute it and/or modify it
   191.9 + * under the terms of the GNU General Public License version 2 only, as
  191.10 + * published by the Free Software Foundation.
  191.11 + * 
  191.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  191.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  191.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  191.15 + * version 2 for more details (a copy is included in the LICENSE file that
  191.16 + * accompanied this code).
  191.17 + * 
  191.18 + * You should have received a copy of the GNU General Public License version
  191.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  191.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  191.21 + * 
  191.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  191.23 + * or visit www.oracle.com if you need additional information or have any
  191.24 + * questions.
  191.25 + */
  191.26 +
  191.27 +/**
  191.28 + * JDK-8015352: "i".toUpperCase() => currently returns "Ä°", but should be "I" (with Turkish locale)
  191.29 + *
  191.30 + * @test
  191.31 + * @option --locale=tr-TR
  191.32 + * @run
  191.33 + */
  191.34 +
  191.35 +if ("i".toUpperCase() != "I") {
  191.36 +    fail("'i'.toUpperCase() is not 'I'");
  191.37 +}
  191.38 +
  191.39 +if ("i".toUpperCase() == "i".toLocaleUpperCase()) {
  191.40 +    fail("'i'.toUpperCase() == 'i'.toLocaleUpperCase()");
  191.41 +}
  191.42 +
  191.43 +if ("I".toLowerCase() != "i") {
  191.44 +    fail("'I'.toLowerCase() is not 'i'");
  191.45 +}
  191.46 +
  191.47 +if ("I".toLowerCase() == "I".toLocaleLowerCase()) {
  191.48 +    fail("'i'.toLowerCase() == 'i'.toLocaleLowerCase()");
  191.49 +}
   192.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   192.2 +++ b/test/script/basic/JDK-8015354.js	Mon Jun 03 23:24:36 2013 -0700
   192.3 @@ -0,0 +1,46 @@
   192.4 +/*
   192.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   192.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   192.7 + *
   192.8 + * This code is free software; you can redistribute it and/or modify it
   192.9 + * under the terms of the GNU General Public License version 2 only, as
  192.10 + * published by the Free Software Foundation.
  192.11 + *
  192.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  192.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  192.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  192.15 + * version 2 for more details (a copy is included in the LICENSE file that
  192.16 + * accompanied this code).
  192.17 + *
  192.18 + * You should have received a copy of the GNU General Public License version
  192.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  192.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  192.21 + *
  192.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  192.23 + * or visit www.oracle.com if you need additional information or have any
  192.24 + * questions.
  192.25 + */
  192.26 +
  192.27 +/**
  192.28 + * JDK-8015354: JSON.parse should not use [[Put]] but use [[DefineOwnProperty]] instead 
  192.29 + *
  192.30 + * @test
  192.31 + * @run
  192.32 + */
  192.33 +
  192.34 +Object.defineProperty(Object.prototype,
  192.35 +    "", {
  192.36 +    set: function(v) {
  192.37 +        throw "set called";
  192.38 +    }
  192.39 +});
  192.40 +
  192.41 +JSON.parse('{}',function(){});
  192.42 +
  192.43 +Object.defineProperty(Object.prototype,
  192.44 +    "foo",{
  192.45 +    set: function(v) {
  192.46 +        throw "set called";
  192.47 +    }
  192.48 +});
  192.49 +JSON.parse('{"foo": 1}');
   193.1 --- a/test/script/basic/NASHORN-377.js	Thu May 30 10:58:35 2013 -0700
   193.2 +++ b/test/script/basic/NASHORN-377.js	Mon Jun 03 23:24:36 2013 -0700
   193.3 @@ -43,7 +43,7 @@
   193.4  function arrstr(a, n, w) {
   193.5    var s = "";
   193.6    if (typeof n == "undefined") n = a.length;
   193.7 -  if (typeof w == "undefined") w = a.BYTES_PER_ELEMENT * 2;
   193.8 +  if (typeof w == "undefined") w = a.constructor.BYTES_PER_ELEMENT * 2;
   193.9    for (var i = 0; i < n; i++) {
  193.10      s += tohex(a[i], w);
  193.11    }
  193.12 @@ -96,7 +96,7 @@
  193.13    var b = new ArrayBuffer(8);
  193.14    for (var i in types) {
  193.15      var x = new types[i](b);
  193.16 -    print(x.byteOffset, x.byteLength, x.length, x.BYTES_PER_ELEMENT);
  193.17 +    print(x.byteOffset, x.byteLength, x.length, x.constructor.BYTES_PER_ELEMENT);
  193.18      assertTrue(function(){ return x.constructor === types[i] });
  193.19    }
  193.20  })();
   194.1 --- a/test/script/basic/NASHORN-556.js	Thu May 30 10:58:35 2013 -0700
   194.2 +++ b/test/script/basic/NASHORN-556.js	Mon Jun 03 23:24:36 2013 -0700
   194.3 @@ -47,7 +47,7 @@
   194.4    // (NoTypeArrayData)
   194.5    var empty = {};
   194.6    empty.length = 10;
   194.7 -  Java.toJavaArray(empty);
   194.8 +  Java.to(empty);
   194.9    delete empty[0];
  194.10    Array.prototype.slice.call(empty, 0, 1);
  194.11    Array.prototype.pop.call(empty);
  194.12 @@ -63,7 +63,7 @@
  194.13  function f2() {
  194.14    // DeletedArrayFilter
  194.15    var deleted = [,1,,2,,3,,4,,];
  194.16 -  assertEq(2, Java.toJavaArray(deleted)[3]);
  194.17 +  assertEq(2, Java.to(deleted)[3]);
  194.18    assertEq(undefined, deleted.pop());
  194.19    assertEq(4, deleted.pop());
  194.20    deleted.unshift(5);
  194.21 @@ -78,7 +78,7 @@
  194.22  function f3() {
  194.23    // DeletedRangeArrayFilter
  194.24    var delrange = [1,2,3,,,,,,,,,,];
  194.25 -  Java.toJavaArray(delrange);
  194.26 +  Java.to(delrange);
  194.27    delrange.unshift(4);
  194.28    p.apply(null, delrange);
  194.29    print(delrange.slice(1,3), delrange.slice(2,6));
  194.30 @@ -88,7 +88,7 @@
  194.31  function f4() {
  194.32    // NumberArrayData
  194.33    var num = [1.1,2.2,3.3,4.4,5.5];
  194.34 -  Java.toJavaArray(num);
  194.35 +  Java.to(num);
  194.36    assertEq(2, num[3] >>> 1);
  194.37    assertEq(5, num[4] | 0);
  194.38    assertEq(5.5, num.pop());
  194.39 @@ -104,7 +104,7 @@
  194.40  function f5() {
  194.41    // ObjectArrayData
  194.42    var obj = [2,"two",3.14,"pi",14,"fourteen"];
  194.43 -  Java.toJavaArray(obj);
  194.44 +  Java.to(obj);
  194.45    assertEq(-12.86, obj[2] - 16);
  194.46    assertEq(7, obj[4] >>> 1);
  194.47    obj.unshift("one");
  194.48 @@ -131,14 +131,14 @@
  194.49    sparse.length = 1024*1024;
  194.50    sparse.push(sparse.length);
  194.51    delete sparse[sparse.length-1];
  194.52 -  //print(Java.toJavaArray(sparse).length);
  194.53 +  //print(Java.to(sparse).length);
  194.54    (function(){}).apply(null, sparse);
  194.55  }
  194.56  
  194.57  function f7() {
  194.58    // UndefinedArrayFilter
  194.59    var undef = [1,2,3,4,5,undefined,7,8,9,19];
  194.60 -  Java.toJavaArray(undef);
  194.61 +  Java.to(undef);
  194.62    assertEq(4, undef[8] >>> 1);
  194.63    var tmp = undef[9] >>> 1;
  194.64    undef[8] = tmp;
  194.65 @@ -154,8 +154,8 @@
  194.66  
  194.67  function f8() {
  194.68    // LongArrayData
  194.69 -  var j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
  194.70 -  Java.toJavaArray(j);
  194.71 +  var j = Java.from(Java.to([23,37,42,86,47], "long[]"));
  194.72 +  Java.to(j);
  194.73    p.apply(null, j);
  194.74    assertEq(43, j[3] >>> 1);
  194.75    assertEq(36, j[4] - 11);
  194.76 @@ -164,12 +164,12 @@
  194.77    assertEq(7, j.shift());
  194.78    assertEq(47, j.pop());
  194.79    j.push("asdf");
  194.80 -  j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
  194.81 +  j = Java.from(Java.to([23,37,42,86,47], "long[]"));
  194.82    j.length = 3;
  194.83    j[0] = 13;
  194.84 -  j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
  194.85 +  j = Java.from(Java.to([23,37,42,86,47], "long[]"));
  194.86    delete j[0];
  194.87 -  j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
  194.88 +  j = Java.from(Java.to([23,37,42,86,47], "long[]"));
  194.89    j.length = 20;
  194.90    j[0] = 13.37;
  194.91  }
   195.1 --- a/test/script/basic/allgettersetters.js	Thu May 30 10:58:35 2013 -0700
   195.2 +++ b/test/script/basic/allgettersetters.js	Mon Jun 03 23:24:36 2013 -0700
   195.3 @@ -34,6 +34,9 @@
   195.4          for (var i in properties) {
   195.5              var prop = properties[i];
   195.6              try {
   195.7 +                if (!/\d.*/.test(prop)) {
   195.8 +                    eval("obj." + prop + " = " + "obj." + prop + ";");
   195.9 +                }
  195.10                  obj[prop] = obj[prop];
  195.11              } catch (e) {
  195.12                  if (!expectError || !(e instanceof TypeError)) {
   196.1 --- a/test/script/basic/compile-octane.js.EXPECTED	Thu May 30 10:58:35 2013 -0700
   196.2 +++ b/test/script/basic/compile-octane.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   196.3 @@ -1,39 +1,13 @@
   196.4 -Compiling... box2d.js
   196.5 -Compiled OK: box2d.js
   196.6 -
   196.7 -Compiling... code-load.js
   196.8 -Compiled OK: code-load.js
   196.9 -
  196.10 -Compiling... crypto.js
  196.11 -Compiled OK: crypto.js
  196.12 -
  196.13 -Compiling... deltablue.js
  196.14 -Compiled OK: deltablue.js
  196.15 -
  196.16 -Compiling... earley-boyer.js
  196.17 -Compiled OK: earley-boyer.js
  196.18 -
  196.19 -Compiling... gbemu.js
  196.20 -Compiled OK: gbemu.js
  196.21 -
  196.22 -Compiling... mandreel.js
  196.23 -Compiled OK: mandreel.js
  196.24 -
  196.25 -Compiling... navier-stokes.js
  196.26 -Compiled OK: navier-stokes.js
  196.27 -
  196.28 -Compiling... pdfjs.js
  196.29 -Compiled OK: pdfjs.js
  196.30 -
  196.31 -Compiling... raytrace.js
  196.32 -Compiled OK: raytrace.js
  196.33 -
  196.34 -Compiling... regexp.js
  196.35 -Compiled OK: regexp.js
  196.36 -
  196.37 -Compiling... richards.js
  196.38 -Compiled OK: richards.js
  196.39 -
  196.40 -Compiling... splay.js
  196.41 -Compiled OK: splay.js
  196.42 -
  196.43 +Compiled OK: box2d
  196.44 +Compiled OK: code-load
  196.45 +Compiled OK: crypto
  196.46 +Compiled OK: deltablue
  196.47 +Compiled OK: earley-boyer
  196.48 +Compiled OK: gbemu
  196.49 +Compiled OK: mandreel
  196.50 +Compiled OK: navier-stokes
  196.51 +Compiled OK: pdfjs
  196.52 +Compiled OK: raytrace
  196.53 +Compiled OK: regexp
  196.54 +Compiled OK: richards
  196.55 +Compiled OK: splay
   197.1 --- a/test/script/basic/javaarrayconversion.js	Thu May 30 10:58:35 2013 -0700
   197.2 +++ b/test/script/basic/javaarrayconversion.js	Mon Jun 03 23:24:36 2013 -0700
   197.3 @@ -34,7 +34,7 @@
   197.4  var testCount = 0;
   197.5  
   197.6  function testF(inputValue, type, testFn) {
   197.7 -  var x = Java.toJavaArray([inputValue], type)[0];
   197.8 +  var x = Java.to([inputValue], type + "[]")[0];
   197.9    if(!testFn(x)) {
  197.10      throw ("unexpected value: " + x)
  197.11    }
  197.12 @@ -130,7 +130,7 @@
  197.13  
  197.14  function assertCantConvert(sourceType, targetType) {
  197.15    try {
  197.16 -    Java.toJavaArray([new Java.type(sourceType)()], targetType)
  197.17 +    Java.to([new Java.type(sourceType)()], targetType + "[]")
  197.18      throw "no TypeError encountered"
  197.19    } catch(e) {
  197.20        if(!(e instanceof TypeError)) {
  197.21 @@ -164,7 +164,7 @@
  197.22  intArray[0] = 1234;
  197.23  intArray[1] = 42;
  197.24  intArray[2] = 5;
  197.25 -var jsIntArray = Java.toJavaScriptArray(intArray)
  197.26 +var jsIntArray = Java.from(intArray)
  197.27  assert(jsIntArray instanceof Array);
  197.28  assert(jsIntArray[0] === 1234);
  197.29  assert(jsIntArray[1] === 42);
  197.30 @@ -179,7 +179,7 @@
  197.31  var byteArray = new (Java.type("byte[]"))(2)
  197.32  byteArray[0] = -128;
  197.33  byteArray[1] = 127;
  197.34 -var jsByteArray = Java.toJavaScriptArray(byteArray)
  197.35 +var jsByteArray = Java.from(byteArray)
  197.36  assert(jsByteArray instanceof Array);
  197.37  assert(jsByteArray[0] === -128);
  197.38  assert(jsByteArray[1] === 127);
  197.39 @@ -187,7 +187,7 @@
  197.40  var shortArray = new (Java.type("short[]"))(2)
  197.41  shortArray[0] = -32768;
  197.42  shortArray[1] = 32767;
  197.43 -var jsShortArray = Java.toJavaScriptArray(shortArray)
  197.44 +var jsShortArray = Java.from(shortArray)
  197.45  assert(jsShortArray instanceof Array);
  197.46  assert(jsShortArray[0] === -32768);
  197.47  assert(jsShortArray[1] === 32767);
  197.48 @@ -195,7 +195,7 @@
  197.49  var floatArray = new (Java.type("float[]"))(2)
  197.50  floatArray[0] = java.lang.Float.MIN_VALUE;
  197.51  floatArray[1] = java.lang.Float.MAX_VALUE;
  197.52 -var jsFloatArray = Java.toJavaScriptArray(floatArray)
  197.53 +var jsFloatArray = Java.from(floatArray)
  197.54  assert(jsFloatArray instanceof Array);
  197.55  assert(jsFloatArray[0] == java.lang.Float.MIN_VALUE);
  197.56  assert(jsFloatArray[1] == java.lang.Float.MAX_VALUE);
  197.57 @@ -204,7 +204,7 @@
  197.58  charArray[0] = "a";
  197.59  charArray[1] = "b";
  197.60  charArray[2] = "1";
  197.61 -var jsCharArray = Java.toJavaScriptArray(charArray)
  197.62 +var jsCharArray = Java.from(charArray)
  197.63  assert(jsCharArray instanceof Array);
  197.64  assert(jsCharArray[0] === 97);
  197.65  assert(jsCharArray[1] === 98);
  197.66 @@ -213,7 +213,7 @@
  197.67  var booleanArray = new (Java.type("boolean[]"))(2)
  197.68  booleanArray[0] = true;
  197.69  booleanArray[1] = false;
  197.70 -var jsBooleanArray = Java.toJavaScriptArray(booleanArray)
  197.71 +var jsBooleanArray = Java.from(booleanArray)
  197.72  assert(jsBooleanArray instanceof Array);
  197.73  assert(jsBooleanArray[0] === true);
  197.74  assert(jsBooleanArray[1] === false);
   198.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   198.2 +++ b/test/script/basic/ranges_disabled.js	Mon Jun 03 23:24:36 2013 -0700
   198.3 @@ -0,0 +1,32 @@
   198.4 +/*
   198.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   198.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   198.7 + * 
   198.8 + * This code is free software; you can redistribute it and/or modify it
   198.9 + * under the terms of the GNU General Public License version 2 only, as
  198.10 + * published by the Free Software Foundation.
  198.11 + * 
  198.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  198.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  198.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  198.15 + * version 2 for more details (a copy is included in the LICENSE file that
  198.16 + * accompanied this code).
  198.17 + * 
  198.18 + * You should have received a copy of the GNU General Public License version
  198.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  198.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  198.21 + * 
  198.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  198.23 + * or visit www.oracle.com if you need additional information or have any
  198.24 + * questions.
  198.25 + */
  198.26 +
  198.27 +/**
  198.28 + * range analysis test. check that computation return values are correct
  198.29 + * both with and without range analysis
  198.30 + *
  198.31 + * @test 
  198.32 + * @run 
  198.33 + */
  198.34 +
  198.35 +load(__DIR__ + "ranges_payload.js");
   199.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   199.2 +++ b/test/script/basic/ranges_disabled.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   199.3 @@ -0,0 +1,4 @@
   199.4 +289
   199.5 +11094405
   199.6 +4294967293
   199.7 +-4722
   200.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   200.2 +++ b/test/script/basic/ranges_enabled.js	Mon Jun 03 23:24:36 2013 -0700
   200.3 @@ -0,0 +1,33 @@
   200.4 +/*
   200.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   200.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   200.7 + * 
   200.8 + * This code is free software; you can redistribute it and/or modify it
   200.9 + * under the terms of the GNU General Public License version 2 only, as
  200.10 + * published by the Free Software Foundation.
  200.11 + * 
  200.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  200.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  200.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  200.15 + * version 2 for more details (a copy is included in the LICENSE file that
  200.16 + * accompanied this code).
  200.17 + * 
  200.18 + * You should have received a copy of the GNU General Public License version
  200.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  200.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  200.21 + * 
  200.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  200.23 + * or visit www.oracle.com if you need additional information or have any
  200.24 + * questions.
  200.25 + */
  200.26 +
  200.27 +/**
  200.28 + * range analysis test. check that computation return values are correct
  200.29 + * both with and without range analysis
  200.30 + *
  200.31 + * @test
  200.32 + * @option --range-analysis
  200.33 + * @run 
  200.34 + */
  200.35 +
  200.36 +load(__DIR__ + "ranges_payload.js");
   201.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   201.2 +++ b/test/script/basic/ranges_enabled.js.EXPECTED	Mon Jun 03 23:24:36 2013 -0700
   201.3 @@ -0,0 +1,4 @@
   201.4 +289
   201.5 +11094405
   201.6 +4294967293
   201.7 +-4722
   202.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   202.2 +++ b/test/script/basic/ranges_payload.js	Mon Jun 03 23:24:36 2013 -0700
   202.3 @@ -0,0 +1,74 @@
   202.4 +/*
   202.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   202.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   202.7 + * 
   202.8 + * This code is free software; you can redistribute it and/or modify it
   202.9 + * under the terms of the GNU General Public License version 2 only, as
  202.10 + * published by the Free Software Foundation.
  202.11 + * 
  202.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  202.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  202.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  202.15 + * version 2 for more details (a copy is included in the LICENSE file that
  202.16 + * accompanied this code).
  202.17 + * 
  202.18 + * You should have received a copy of the GNU General Public License version
  202.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  202.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  202.21 + * 
  202.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  202.23 + * or visit www.oracle.com if you need additional information or have any
  202.24 + * questions.
  202.25 + */
  202.26 +
  202.27 +/**
  202.28 + * range analysis test. check that computation return values are correct
  202.29 + * both with and without range analysis
  202.30 + *
  202.31 + * @subtest
  202.32 + */
  202.33 +
  202.34 +function f(c) {
  202.35 +    var v = c & 0xffff;
  202.36 +    var w = v & 0xfff;
  202.37 +    var x = v * w;
  202.38 +    return x;
  202.39 +}
  202.40 +
  202.41 +function g() {
  202.42 +    var sum = 0;
  202.43 +    for (var x = 0; x < 4711; x++) {
  202.44 +	sum += x;
  202.45 +    }
  202.46 +    return sum;
  202.47 +}
  202.48 +
  202.49 +function g2() {
  202.50 +    var sum = 0;
  202.51 +    //make sure we overflow
  202.52 +    var displacement = 0x7ffffffe;
  202.53 +    for (var x = displacement; x < (displacement + 2); x++) {
  202.54 +	sum += x;
  202.55 +    }
  202.56 +    return sum;
  202.57 +}
  202.58 +
  202.59 +//mostly provide code coverage for all the range operations    
  202.60 +function h() {
  202.61 +    var sum = 0;
  202.62 +    sum += 4711;
  202.63 +    sum &= 0xffff;
  202.64 +    sum /= 2;
  202.65 +    sum *= 2;
  202.66 +    sum -= 4;
  202.67 +    sum |= 2;
  202.68 +    sum ^= 17;
  202.69 +    sum = sum % 10000;
  202.70 +    sum = -sum;
  202.71 +    return sum
  202.72 +}
  202.73 +
  202.74 +print(f(17));
  202.75 +print(g());
  202.76 +print(g2());
  202.77 +print(h());
   203.1 --- a/test/script/basic/run-octane.js	Thu May 30 10:58:35 2013 -0700
   203.2 +++ b/test/script/basic/run-octane.js	Mon Jun 03 23:24:36 2013 -0700
   203.3 @@ -26,36 +26,20 @@
   203.4   */
   203.5  
   203.6  var tests = [
   203.7 -    "box2d.js",
   203.8 -    "code-load.js",
   203.9 -    "crypto.js", 
  203.10 -    "deltablue.js", 
  203.11 -    "earley-boyer.js", 
  203.12 -    "gbemu.js",
  203.13 -    "mandreel.js",
  203.14 -    "navier-stokes.js", 
  203.15 -    "pdfjs.js",
  203.16 -    "raytrace.js",
  203.17 -    "regexp.js", 
  203.18 -    "richards.js", 
  203.19 -    "splay.js" 
  203.20 +    {file:"box2d",suite:"Box2DBenchmark"},
  203.21 +    {file:"code-load",suite:"CodeLoad"},
  203.22 +    {file:"crypto",suite:"Crypto"},
  203.23 +    {file:"deltablue",suite:"DeltaBlue"},
  203.24 +    {file:"earley-boyer", suite:"EarleyBoyer"},
  203.25 +    {file:"gbemu", suite:"GameboyBenchmark"},
  203.26 +    {file:"mandreel", suite:"MandreelBenchmark"},
  203.27 +    {file:"navier-stokes", suite:"NavierStokes"},
  203.28 +    {file:"pdfjs", suite:"PdfJS"},
  203.29 +    {file:"raytrace", suite:"RayTrace"},
  203.30 +    {file:"regexp", suite:"RegExpSuite"},
  203.31 +    {file:"richards", suite:"Richards"},
  203.32 +    {file:"splay", suite:"Splay"}
  203.33  ];
  203.34 -
  203.35 -// hack, teardown breaks things defined in the global space, making it impossible
  203.36 -// to do multiple consecutive benchmark runs with the same harness. I think it's a bug
  203.37 -// that the setup and teardown aren't each others constructor and destructor but rather
  203.38 -// that the benchmarks rely on partial global state. For shame, Octane! 
  203.39 -var ignoreTeardown = [
  203.40 -    { name: "box2d.js" },
  203.41 -    { name: "gbemu.js" },
  203.42 -];
  203.43 -
  203.44 -
  203.45 -//TODO mandreel can be compiled as a test, but not run multiple times unless modified to not have global state
  203.46 -var compileOnly = {
  203.47 -    "mandreel.js" : true
  203.48 -};
  203.49 -
  203.50  var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
  203.51  
  203.52  // TODO: why is this path hard coded when it's defined in project properties?
  203.53 @@ -71,110 +55,106 @@
  203.54  }
  203.55  
  203.56  function should_compile_only(name) {
  203.57 -    return (typeof compile_only !== 'undefined') || compileOnly[name] === true;
  203.58 +    return (typeof compile_only !== 'undefined')
  203.59  }
  203.60  
  203.61  function run_one_benchmark(arg, iters) {
  203.62 -
  203.63      var file_name;
  203.64 -    var file = arg.split('/');
  203.65 -    if (file.length == 1) {
  203.66 -        file = arg.split('\\');
  203.67 -    }    
  203.68 -
  203.69 -    //trim off trailing path separators
  203.70 -    while (file[file.length - 1].indexOf(".js") == -1) {
  203.71 -	file.pop();
  203.72 -    }
  203.73 -    file_name = file[file.length - 1];
  203.74 -
  203.75 +    var file = (arg.file + ".js").split('/');
  203.76 +    
  203.77 +    file_name = path + file[file.length - 1];
  203.78 +    
  203.79      var compile_and_return = should_compile_only(file_name);
  203.80      if (compile_and_return) {
  203.81  	if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
  203.82  	    return;
  203.83  	}
  203.84 -	print("Compiling... " + file_name);
  203.85      }
  203.86 -
  203.87 -    load(path + 'base.js');
  203.88 -    load(arg);
  203.89 +    
  203.90 +    print_verbose("Loading... " + file_name);
  203.91 +    load(file_name);
  203.92      
  203.93      if (compile_and_return) {
  203.94 -	print("Compiled OK: " + file_name);
  203.95 -	print("");
  203.96 +	print_always("Compiled OK: " + arg.file);
  203.97  	return;
  203.98      }
  203.99      
 203.100      var success = true;
 203.101 -    var hiscore = 0;
 203.102 -    var loscore = 10e8;
 203.103      var current_name;
 203.104      
 203.105 -    function PrintResult(name, result) {
 203.106 -	current_name = name;
 203.107 -    }
 203.108 -        
 203.109 -    function PrintError(name, error) {
 203.110 -	current_name = name;
 203.111 -	PrintResult(name, error);
 203.112 -	success = false;
 203.113 -    }
 203.114 -        
 203.115 -    function PrintScore(score) {
 203.116 -	if (success) {
 203.117 -	    if (+score >= hiscore) {
 203.118 -		hiscore = +score;
 203.119 -	    }
 203.120 -	    if (+score <= loscore) {
 203.121 -		loscore = +score;
 203.122 -	    }
 203.123 -	}
 203.124 -
 203.125 -	if (verbose) {
 203.126 -	    print("Score: " + score);
 203.127 -	}
 203.128 -    }
 203.129 -    
 203.130      if (iters == undefined) {
 203.131  	iters = numberOfIterations;
 203.132      } else {
 203.133  	numberOfIterations = iters;
 203.134      }
 203.135 +    
 203.136 +    var benchmarks = eval(arg.suite + ".benchmarks");
 203.137 +    var min_score  = 1e9;
 203.138 +    var max_score  = 0;
 203.139 +    var mean_score = 0;
 203.140  
 203.141 -    print(runtime + ": running " + file_name + "...");
 203.142 +    try {
 203.143 +	for (var x = 0; x < benchmarks.length ; x++) { 
 203.144 +	    benchmarks[x].Setup();
 203.145 +	}
 203.146 +	print_verbose("Running '" + arg.file + "' for " + iters + " iterations of no less than " + min_time + " seconds (" + runtime + ")");
 203.147 +	
 203.148 +	var scores = [];
 203.149 +	
 203.150 +	var min_time_ms = min_time * 1000;
 203.151 +	var len = benchmarks.length;    
 203.152 +	
 203.153 +	for (var it = 0; it < iters + 1; it++) {
 203.154 +	    //every iteration must take a minimum of 10 secs
 203.155 +	    var ops = 0;
 203.156 +	    var elapsed = 0;
 203.157 +	    var start = new Date;
 203.158 +	    do {
 203.159 +		for (var i = 0; i < len; i++) {
 203.160 +		    benchmarks[i].run();
 203.161 +		}	    
 203.162 +		ops += len;
 203.163 +		elapsed = new Date - start;
 203.164 +	    } while (elapsed < min_time * 1000);
 203.165 +	    
 203.166 +	    var score = ops / elapsed * 1000 * 60;
 203.167 +	    scores.push(score);
 203.168 +	    var name = it == 0 ? "warmup" : "iteration " + it;   
 203.169 +	    print_verbose("[" + arg.file + "] " + name + " finished " + score.toFixed(0) + " ops/minute");
 203.170 +	}
 203.171  
 203.172 -    for (var i = 0; i < numberOfIterations; i++) {
 203.173 -	var callbacks =
 203.174 -	    { NotifyResult: PrintResult,
 203.175 -	      NotifyError: PrintError,
 203.176 -	      NotifyScore: PrintScore };	
 203.177 +	for (var x = 0; x < benchmarks.length ; x++) { 
 203.178 +	    benchmarks[x].TearDown();
 203.179 +	}
 203.180  
 203.181 -	for (j in ignoreTeardown) {
 203.182 -	    var ignore = ignoreTeardown[j];
 203.183 -	    if (endsWith(arg, ignore.name)) {
 203.184 -		var teardownOverride = ignore.teardown;
 203.185 -		if (!teardownOverride) {
 203.186 -		    teardownOverride = function() {};
 203.187 -		}
 203.188 +	for (var x = 1; x < iters + 1 ; x++) {
 203.189 +	    mean_score += scores[x];
 203.190 +	    min_score = Math.min(min_score, scores[x]);
 203.191 +	    max_score = Math.max(max_score, scores[x]);
 203.192 +	}
 203.193 +	mean_score /= iters;    
 203.194  
 203.195 -		for (k in BenchmarkSuite.suites) {
 203.196 -		    var benchmarks = BenchmarkSuite.suites[k].benchmarks;
 203.197 -		    for (l in benchmarks) {
 203.198 -			benchmarks[l].TearDown = teardownOverride;
 203.199 -		    }
 203.200 -                }
 203.201 -		break;
 203.202 -	    }
 203.203 -	}
 203.204 -	
 203.205 -	BenchmarkSuite.RunSuites(callbacks);
 203.206 +    } catch (e) {
 203.207 +	print_always("*** Aborted and setting score to zero. Reason: " + e);
 203.208 +	mean_score = min_score = max_score = 0;
 203.209 +	scores = [0];
 203.210      }
 203.211 -    
 203.212 -    var start = "Score: ";
 203.213 -    if (runtime != "") {
 203.214 -	start = runtime + ": ";
 203.215 -    } 
 203.216 -    print(start + current_name + ' (version ' + BenchmarkSuite.version + '): ' + loscore + '-' + hiscore);
 203.217 +
 203.218 +    var res = "[" + arg.file + "] " + mean_score.toFixed(0);
 203.219 +    if (verbose) {
 203.220 +	res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0);
 203.221 +    }
 203.222 +    print_always(res);
 203.223 +}
 203.224 +
 203.225 +function print_always(x) {
 203.226 +    print(x);
 203.227 +}
 203.228 +
 203.229 +function print_verbose(x) {
 203.230 +    if (verbose) {
 203.231 +	print(x);
 203.232 +    }
 203.233  }
 203.234  
 203.235  function run_suite(tests, iters) {
 203.236 @@ -186,6 +166,7 @@
 203.237  runtime = "command line";
 203.238  
 203.239  var args = [];
 203.240 +
 203.241  if (typeof $ARGS !== 'undefined') {
 203.242      args = $ARGS;
 203.243  } else if (typeof arguments !== 'undefined' && arguments.length != 0) {
 203.244 @@ -211,6 +192,7 @@
 203.245  
 203.246  var tests_found = [];
 203.247  var iters = undefined;
 203.248 +var min_time = 5;
 203.249  
 203.250  for (var i = 0; i < args.length; i++) { 
 203.251      arg = args[i];
 203.252 @@ -220,21 +202,41 @@
 203.253  	runtime = args[++i];
 203.254      } else if (arg == "--verbose") {
 203.255  	verbose = true;
 203.256 +    } else if (arg == "--min-time") {
 203.257 +	min_time = +args[++i];
 203.258      } else if (arg == "") {
 203.259  	continue; //skip
 203.260      } else {
 203.261 -	tests_found.push(arg);
 203.262 +	var found = false;
 203.263 +	for (j in tests) {
 203.264 +	    if (tests[j].file === arg) {
 203.265 +		tests_found.push(tests[j]);
 203.266 +		found = true;
 203.267 +		break;
 203.268 +	    }
 203.269 +	}
 203.270 +	if (!found) {
 203.271 +	    var str = "unknown test name: '" + arg + "' -- valid names are: ";
 203.272 +	    for (j in tests) {
 203.273 +		if (j != 0) {
 203.274 +		    str += ", ";
 203.275 +		}
 203.276 +		str += "'" + tests[j].file + "'";
 203.277 +	    }
 203.278 +	    throw str;
 203.279 +	}
 203.280      }
 203.281  }
 203.282  
 203.283  if (tests_found.length == 0) {    
 203.284      for (i in tests) {
 203.285 -	tests_found.push(path + tests[i]);
 203.286 +	tests_found.push(tests[i]);
 203.287      }
 203.288  } 
 203.289  
 203.290  tests_found.sort();
 203.291  
 203.292 +load(path + 'base.js');
 203.293  run_suite(tests_found, iters);
 203.294  
 203.295  
   204.1 --- a/test/script/currently-failing/logcoverage.js	Thu May 30 10:58:35 2013 -0700
   204.2 +++ b/test/script/currently-failing/logcoverage.js	Mon Jun 03 23:24:36 2013 -0700
   204.3 @@ -53,8 +53,7 @@
   204.4              // set new standard err
   204.5              System.setErr(newErr);
   204.6              System.setOut(newOut);
   204.7 -            var strType = Java.type("java.lang.String");
   204.8 -            var engine = fac.getScriptEngine(Java.toJavaArray(opts, strType));
   204.9 +            var engine = fac.getScriptEngine(Java.to(opts, "java.lang.String[]"));
  204.10  	    var reader = new java.io.FileReader(name);
  204.11              engine.eval(reader);
  204.12              newErr.flush();
   205.1 --- a/test/script/trusted/NASHORN-638.js	Thu May 30 10:58:35 2013 -0700
   205.2 +++ b/test/script/trusted/NASHORN-638.js	Mon Jun 03 23:24:36 2013 -0700
   205.3 @@ -47,8 +47,7 @@
   205.4          try {
   205.5              // set new standard err
   205.6              System.setErr(newErr);
   205.7 -            var strType = Java.type("java.lang.String");
   205.8 -            var engine = fac.getScriptEngine(Java.toJavaArray(opts, strType));
   205.9 +            var engine = fac.getScriptEngine(Java.to(opts, "java.lang.String[]"));
  205.10              engine.eval(code);
  205.11              newErr.flush();
  205.12              return new java.lang.String(baos.toByteArray());
   206.1 --- a/test/script/trusted/NASHORN-653.js	Thu May 30 10:58:35 2013 -0700
   206.2 +++ b/test/script/trusted/NASHORN-653.js	Mon Jun 03 23:24:36 2013 -0700
   206.3 @@ -85,8 +85,7 @@
   206.4          try {
   206.5              // set new standard err
   206.6              System.setErr(newErr);
   206.7 -            var strType = Java.type("java.lang.String");
   206.8 -            var engine = fac.getScriptEngine(Java.toJavaArray(opts, strType));
   206.9 +            var engine = fac.getScriptEngine(Java.to(opts, "java.lang.String[]"));
  206.10              engine.eval(code);
  206.11              newErr.flush();
  206.12              return new java.lang.String(baos.toByteArray());
   207.1 --- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java	Thu May 30 10:58:35 2013 -0700
   207.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java	Mon Jun 03 23:24:36 2013 -0700
   207.3 @@ -47,7 +47,6 @@
   207.4  import javax.script.ScriptEngineManager;
   207.5  import javax.script.ScriptException;
   207.6  import javax.script.SimpleScriptContext;
   207.7 -import netscape.javascript.JSObject;
   207.8  import org.testng.Assert;
   207.9  import org.testng.annotations.Test;
  207.10  
   208.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   208.2 +++ b/test/src/jdk/nashorn/internal/runtime/regexp/JdkRegExpTest.java	Mon Jun 03 23:24:36 2013 -0700
   208.3 @@ -0,0 +1,61 @@
   208.4 +/*
   208.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   208.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   208.7 + *
   208.8 + * This code is free software; you can redistribute it and/or modify it
   208.9 + * under the terms of the GNU General Public License version 2 only, as
  208.10 + * published by the Free Software Foundation.  Oracle designates this
  208.11 + * particular file as subject to the "Classpath" exception as provided
  208.12 + * by Oracle in the LICENSE file that accompanied this code.
  208.13 + *
  208.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
  208.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  208.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  208.17 + * version 2 for more details (a copy is included in the LICENSE file that
  208.18 + * accompanied this code).
  208.19 + *
  208.20 + * You should have received a copy of the GNU General Public License version
  208.21 + * 2 along with this work; if not, write to the Free Software Foundation,
  208.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  208.23 + *
  208.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  208.25 + * or visit www.oracle.com if you need additional information or have any
  208.26 + * questions.
  208.27 + */
  208.28 +
  208.29 +package jdk.nashorn.internal.runtime.regexp;
  208.30 +
  208.31 +import static org.testng.Assert.assertEquals;
  208.32 +import static org.testng.Assert.assertNotNull;
  208.33 +import static org.testng.Assert.assertTrue;
  208.34 +
  208.35 +import jdk.nashorn.internal.runtime.ParserException;
  208.36 +import org.testng.annotations.Test;
  208.37 +
  208.38 +/**
  208.39 + * Basic tests for the JDK based RegExp implementation.
  208.40 + *
  208.41 + * @test
  208.42 + * @run testng jdk.nashorn.internal.runtime.regexp.JdkRegExpTest
  208.43 + */
  208.44 +public class JdkRegExpTest {
  208.45 +
  208.46 +    /**
  208.47 +     * Compile a regular expression using the JDK implementation
  208.48 +     */
  208.49 +    @Test
  208.50 +    public void testMatcher() {
  208.51 +        RegExp regexp = new RegExpFactory().compile("f(o)o", "");
  208.52 +        RegExpMatcher matcher = regexp.match("foo");
  208.53 +        assertNotNull(matcher);
  208.54 +        assertTrue(matcher.search(0));
  208.55 +        assertEquals(matcher.getInput(), "foo");
  208.56 +        assertEquals(matcher.groupCount(), 1);
  208.57 +        assertEquals(matcher.group(), "foo");
  208.58 +        assertEquals(matcher.start(), 0);
  208.59 +        assertEquals(matcher.end(), 3);
  208.60 +        assertEquals(matcher.group(1), "o");
  208.61 +        assertEquals(matcher.start(1), 1);
  208.62 +        assertEquals(matcher.end(1), 2);
  208.63 +    }
  208.64 +}
   209.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   209.2 +++ b/test/src/jdk/nashorn/internal/runtime/regexp/joni/JoniTest.java	Mon Jun 03 23:24:36 2013 -0700
   209.3 @@ -0,0 +1,52 @@
   209.4 +/*
   209.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   209.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   209.7 + *
   209.8 + * This code is free software; you can redistribute it and/or modify it
   209.9 + * under the terms of the GNU General Public License version 2 only, as
  209.10 + * published by the Free Software Foundation.  Oracle designates this
  209.11 + * particular file as subject to the "Classpath" exception as provided
  209.12 + * by Oracle in the LICENSE file that accompanied this code.
  209.13 + *
  209.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
  209.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  209.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  209.17 + * version 2 for more details (a copy is included in the LICENSE file that
  209.18 + * accompanied this code).
  209.19 + *
  209.20 + * You should have received a copy of the GNU General Public License version
  209.21 + * 2 along with this work; if not, write to the Free Software Foundation,
  209.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  209.23 + *
  209.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  209.25 + * or visit www.oracle.com if you need additional information or have any
  209.26 + * questions.
  209.27 + */
  209.28 +
  209.29 +package jdk.nashorn.internal.runtime.regexp.joni;
  209.30 +
  209.31 +import static org.testng.Assert.assertEquals;
  209.32 +import static org.testng.Assert.assertTrue;
  209.33 +
  209.34 +import org.testng.annotations.Test;
  209.35 +
  209.36 +/**
  209.37 + * Joni coverage tests
  209.38 + *
  209.39 + * @test
  209.40 + * @run testng jdk.nashorn.internal.runtime.regexp.joni.JoniTest
  209.41 + */
  209.42 +public class JoniTest {
  209.43 +
  209.44 +    @Test
  209.45 +    public void testDump() {
  209.46 +        new Regex("^a{3,}(.*)[z]++\\s\\1x$").dumpTree();
  209.47 +        new Regex("^a{3,}(.*)[z]++\\s\\1x$").dumpByteCode();
  209.48 +        new Regex("(abc){4,}{2,5}").dumpTree();
  209.49 +        new Regex("(abc){4,}{2,5}").dumpByteCode();
  209.50 +        new Regex("aaa|aa|bbbb|ccc").dumpTree();
  209.51 +        new Regex("aaa|aa|bbbb|ccc").dumpByteCode();
  209.52 +        new Regex("(?:ZFVR.(\\d+\\.\\d+))|(?:(?:Sversbk|TenaCnenqvfb|Vprjrnfry).(\\d+\\.\\d+))|(?:Bcren.(\\d+\\.\\d+))|(?:NccyrJroXvg.(\\d+(?:\\.\\d+)?))").dumpTree();
  209.53 +        new Regex("(?:ZFVR.(\\d+\\.\\d+))|(?:(?:Sversbk|TenaCnenqvfb|Vprjrnfry).(\\d+\\.\\d+))|(?:Bcren.(\\d+\\.\\d+))|(?:NccyrJroXvg.(\\d+(?:\\.\\d+)?))").dumpByteCode();
  209.54 +    }
  209.55 +}

mercurial