8066407: Function with same body not reparsed after SyntaxError
authorhannesw
Mon, 27 Apr 2015 12:27:33 +0200
changeset 30055 32ec71b01637
parent 30019 e7dbbef69d12
child 30056 06d201382b55
8066407: Function with same body not reparsed after SyntaxError Reviewed-by: attila, lagergren
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java
nashorn/test/script/basic/JDK-8066407.js
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java	Wed Jul 05 20:30:11 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java	Mon Apr 27 12:27:33 2015 +0200
@@ -26,7 +26,7 @@
 package jdk.nashorn.internal.runtime.regexp;
 
 import java.util.Collections;
-import java.util.Set;
+import java.util.Map;
 import java.util.WeakHashMap;
 import jdk.nashorn.internal.runtime.ParserException;
 import jdk.nashorn.internal.runtime.options.Options;
@@ -45,11 +45,10 @@
     /** Weak cache of already validated regexps - when reparsing, we don't, for example
      *  need to recompile (reverify) all regexps that have previously been parsed by this
      *  RegExpFactory in a previous compilation. This saves significant time in e.g. avatar
-     *  startup */
-    private static final Set<String> VALID_CACHE_SET =
-            Collections.newSetFromMap(
-                    Collections.synchronizedMap(
-                            new WeakHashMap<String, Boolean>()));
+     *  startup
+     */
+    private static final Map<String, RegExp> REGEXP_CACHE =
+            Collections.synchronizedMap(new WeakHashMap<String, RegExp>());
 
     static {
         final String impl = Options.getStringProperty("nashorn.regexp.impl", JONI);
@@ -87,7 +86,13 @@
      * @throws ParserException if invalid source or flags
      */
     public static RegExp create(final String pattern, final String flags) {
-        return instance.compile(pattern,  flags);
+        final String key = pattern + "/" + flags;
+        RegExp regexp = REGEXP_CACHE.get(key);
+        if (regexp == null) {
+            regexp = instance.compile(pattern,  flags);
+            REGEXP_CACHE.put(key, regexp);
+        }
+        return regexp;
     }
 
     /**
@@ -98,11 +103,8 @@
      *
      * @throws ParserException if invalid source or flags
      */
-    // @SuppressWarnings({"unused"})
     public static void validate(final String pattern, final String flags) throws ParserException {
-        if (VALID_CACHE_SET.add(pattern + flags)) {
-            instance.compile(pattern, flags);
-        }
+        create(pattern, flags);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8066407.js	Mon Apr 27 12:27:33 2015 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8066407: Function with same body not reparsed after SyntaxError
+ *
+ * @test
+ * @run
+ */
+
+function testFunction(body) {
+    try {
+        Function(body);
+        Assert.fail("Should have thrown");
+    } catch (e) {
+        Assert.assertEquals(e.name, "SyntaxError");
+        count++;
+    }
+
+}
+
+var count = 0;
+
+testFunction("/a/r");
+testFunction("/a/r");
+testFunction("/a/r");
+
+Assert.assertTrue(count === 3);