Mon, 03 Jun 2013 23:24:36 -0700
Merge
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 – passing an implementation JavaScript object 2.174 +or function to a constructor, or using <code>Java.extend</code> with <code>new</code> – 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> – aside from being able to take any number of type parameters 2.204 +denoting a class to extend and interfaces to implement – 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 – 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 – 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 – 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 – 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. – 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 """/> 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 +}