diff --git a/nashorn/.hgignore b/nashorn/.hgignore
index 02ec40d7e8d..7ee241994a9 100644
--- a/nashorn/.hgignore
+++ b/nashorn/.hgignore
@@ -26,3 +26,5 @@ jcov2/*
test/lib/testng.jar
test/script/external/*
.project
+.externalToolBuilders/*
+.settings/*
diff --git a/nashorn/bin/runopt.sh b/nashorn/bin/runopt.sh
new file mode 100644
index 00000000000..0a61491e624
--- /dev/null
+++ b/nashorn/bin/runopt.sh
@@ -0,0 +1,137 @@
+#!/bin/sh
+#
+# Copyright (c) 2010, 2014, 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.
+#
+
+###########################################################################################
+# This is a helper script to evaluate nashorn with optimistic types
+# it produces a flight recording for every run, and uses the best
+# known flags for performance for the current configration
+###########################################################################################
+
+# Flags to enable assertions, we need the system assertions too, since
+# this script runs Nashorn in the BCP to override any nashorn.jar that might
+# reside in your $JAVA_HOME/jre/lib/ext/nashorn.jar
+#
+ENABLE_ASSERTIONS_FLAGS="-ea -esa"
+
+# Flags to instrument lambdaform computation, caching, interpretation and compilation
+# Default compile threshold for lambdaforms is 30
+#
+#LAMBDAFORM_FLAGS="\
+# -Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=3 \
+# -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true \
+# -Djava.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE=true \
+# -Djava.lang.invoke.MethodHandle.TRACE_INTERPRETER=true"
+
+# Flags to run trusted tests from the Nashorn test suite
+#
+#TRUSTED_TEST_FLAGS="\
+#-Djava.security.manager \
+#-Djava.security.policy=../build/nashorn.policy -Dnashorn.debug"
+
+# Testing out new code optimizations using the generic hotspot "new code" parameter
+#
+#USE_NEW_CODE_FLAGS=-XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode
+
+#
+#-Dnashorn.typeInfo.disabled=false \
+# and for Nashorn options:
+# --class-cache-size=0 --persistent-code-cache=false
+
+# Unique timestamped file name for JFR recordings. For JFR, we also have to
+# crank up the stack cutoff depth to 1024, because of ridiculously long lambda form
+# stack traces.
+#
+# It is also recommended that you go into $JAVA_HOME/jre/lib/jfr/default.jfc and
+# set the "method-sampling-interval" Normal and Maximum sample time as low as you
+# can go (10 ms on most platforms). The default is normally higher. The increased
+# sampling overhead is usually negligible for Nashorn runs, but the data is better
+
+if [ -z $JFR_FILENAME ]; then
+ JFR_FILENAME="./nashorn_$(date|sed "s/ /_/g"|sed "s/:/_/g").jfr"
+ echo "Using default JFR filename: ${JFR_FILENAME}..."
+fi
+
+# Flight recorder
+#
+# see above - already in place, copy the flags down here to disable
+ENABLE_FLIGHT_RECORDER_FLAGS="\
+ -XX:+UnlockCommercialFeatures \
+ -XX:+FlightRecorder \
+ -XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=$JFR_FILENAME,stackdepth=1024"
+
+# Type specialization and math intrinsic replacement should be enabled by default in 8u20 and nine,
+# keeping this flag around for experimental reasons. Replace + with - to switch it off
+#
+#ENABLE_TYPE_SPECIALIZATION_FLAGS=-XX:+UseTypeSpeculation
+
+# Same with math intrinsics. They should be enabled by default in 8u20 and 9, so
+# this disables them if needed
+#
+#DISABLE_MATH_INTRINSICS_FLAGS=-XX:-UseMathExactIntrinsics
+
+# Add timing to time the compilation phases.
+#ENABLE_TIME_FLAGS=--log=time
+
+# Add ShowHiddenFrames to get lambda form internals on the stack traces
+#ENABLE_SHOW_HIDDEN_FRAMES_FLAGS=-XX:+ShowHiddenFrames
+
+# Add print optoassembly to get an asm dump. This requires 1) a debug build, not product,
+# That tired compilation is switched off, for C2 only output and that the number of
+# compiler threads is set to 1 for determinsm.
+#
+#PRINT_ASM_FLAGS=-XX:+PrintOptoAssembly -XX:-TieredCompilation -XX:CICompilerCount=1 \
+
+# Tier compile threasholds. Default value is 10. (1-100 is useful for experiments)
+#TIER_COMPILATION_THRESHOLD_FLAGS=-XX:IncreaseFirstTierCompileThresholdAt=10
+
+# Directory where to look for nashorn.jar in a dist folder. The default is "..", assuming
+# that we run the script from the make dir
+DIR=..
+NASHORN_JAR=$DIR/dist/nashorn.jar
+
+
+# The built Nashorn jar is placed first in the bootclasspath to override the JDK
+# nashorn.jar in $JAVA_HOME/jre/lib/ext. Thus, we also need -esa, as assertions in
+# nashorn count as system assertions in this configuration
+
+# Type profiling default level is 111, 222 adds some compile time, but is faster
+
+$JAVA_HOME/bin/java \
+$ENABLE_ASSERTIONS_FLAGS \
+$LAMBDAFORM_FLAGS \
+$TRUSTED_FLAGS \
+$USE_NEW_CODE_FLAGS \
+$ENABLE_SHOW_HIDDEN_FRAMES_FLAGS \
+$ENABLE_FLIGHT_RECORDER_FLAGS \
+$ENABLE_TYPE_SPECIALIZATION_FLAGS \
+$TIERED_COMPILATION_THRESOLD_FLAGS \
+$DISABLE_MATH_INTRINSICS_FLAGS \
+$PRINT_ASM_FLAGS \
+-Xbootclasspath/p:$NASHORN_JAR \
+-Xms2G -Xmx2G \
+-XX:TypeProfileLevel=222 \
+-cp $CLASSPATH:../build/test/classes/ \
+jdk.nashorn.tools.Shell $ENABLE_TIME_FLAGS ${@}
+
+
diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml
index 27ae1b319fc..9e6f5b5558e 100644
--- a/nashorn/make/build.xml
+++ b/nashorn/make/build.xml
@@ -408,7 +408,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
-
@@ -431,7 +431,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
-
@@ -457,9 +457,11 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
+
+
@@ -467,9 +469,11 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
+
+
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngine.java
index bbf1eecfb49..2f000954815 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngine.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngine.java
@@ -229,6 +229,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
private T getInterfaceInner(final Object thiz, final Class clazz) {
+ assert !(thiz instanceof ScriptObject) : "raw ScriptObject not expected here";
+
if (clazz == null || !clazz.isInterface()) {
throw new IllegalArgumentException(getMessage("interface.class.expected"));
}
@@ -251,17 +253,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
final ScriptObjectMirror mirror = (ScriptObjectMirror)thiz;
realSelf = mirror.getScriptObject();
realGlobal = mirror.getHomeGlobal();
- if (! isOfContext(realGlobal, nashornContext)) {
- throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
- }
- } else if (thiz instanceof ScriptObject) {
- // called from script code.
- realSelf = (ScriptObject)thiz;
- realGlobal = Context.getGlobal();
- if (realGlobal == null) {
- throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
- }
-
if (! isOfContext(realGlobal, nashornContext)) {
throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
}
@@ -368,6 +359,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
name.getClass(); // null check
+ assert !(selfObject instanceof ScriptObject) : "raw ScriptObject not expected here";
Global invokeGlobal = null;
ScriptObjectMirror selfMirror = null;
@@ -377,20 +369,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
}
invokeGlobal = selfMirror.getHomeGlobal();
- } else if (selfObject instanceof ScriptObject) {
- // invokeMethod called from script code - in which case we may get 'naked' ScriptObject
- // Wrap it with oldGlobal to make a ScriptObjectMirror for the same.
- final Global oldGlobal = Context.getGlobal();
- invokeGlobal = oldGlobal;
- if (oldGlobal == null) {
- throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
- }
-
- if (! isOfContext(oldGlobal, nashornContext)) {
- throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
- }
-
- selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
} else if (selfObject == null) {
// selfObject is null => global function call
final Global ctxtGlobal = getNashornGlobalFrom(context);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java
index 4de2cbf5516..e6e3915ab29 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java
@@ -25,8 +25,6 @@
package jdk.nashorn.api.scripting;
-import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
-
import java.lang.invoke.MethodHandle;
import jdk.internal.dynalink.beans.StaticClass;
import jdk.internal.dynalink.linker.LinkerServices;
@@ -75,11 +73,8 @@ public final class ScriptUtils {
* @param sync the object to synchronize on
* @return a synchronizing wrapper function
*/
- public static Object makeSynchronizedFunction(final Object func, final Object sync) {
- if (func instanceof ScriptFunction) {
- return ((ScriptFunction)func).makeSynchronizedFunction(sync);
- }
- throw typeError("not.a.function", ScriptRuntime.safeToString(func));
+ public static Object makeSynchronizedFunction(final ScriptFunction func, final Object sync) {
+ return func.makeSynchronizedFunction(unwrap(sync));
}
/**
@@ -88,12 +83,8 @@ public final class ScriptUtils {
* @param obj object to be wrapped
* @return wrapped object
*/
- public static Object wrap(final Object obj) {
- if (obj instanceof ScriptObject) {
- return ScriptObjectMirror.wrap(obj, Context.getGlobal());
- }
-
- return obj;
+ public static ScriptObjectMirror wrap(final ScriptObject obj) {
+ return (ScriptObjectMirror) ScriptObjectMirror.wrap(obj, Context.getGlobal());
}
/**
@@ -160,14 +151,15 @@ public final class ScriptUtils {
}
final LinkerServices linker = Bootstrap.getLinkerServices();
- final MethodHandle converter = linker.getTypeConverter(obj.getClass(), clazz);
+ final Object objToConvert = unwrap(obj);
+ final MethodHandle converter = linker.getTypeConverter(objToConvert.getClass(), clazz);
if (converter == null) {
// no supported conversion!
throw new UnsupportedOperationException("conversion not supported");
}
try {
- return converter.invoke(obj);
+ return converter.invoke(objToConvert);
} catch (final RuntimeException | Error e) {
throw e;
} catch (final Throwable t) {
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java
index fa2b8a198bd..f83dc9ccdd1 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java
@@ -511,16 +511,6 @@ final class AssignSymbols extends NodeVisitor implements Loggabl
thisProperties.push(new HashSet());
- if (functionNode.isDeclared()) {
- // Can't use lc.getCurrentBlock() as we can have an outermost function in our lexical context that
- // is not a program - it is a function being compiled on-demand.
- final Iterator blocks = lc.getBlocks();
- if (blocks.hasNext()) {
- final IdentNode ident = functionNode.getIdent();
- defineSymbol(blocks.next(), ident.getName(), ident, IS_VAR | (functionNode.isAnonymous()? IS_INTERNAL : 0));
- }
- }
-
// Every function has a body, even the ones skipped on reparse (they have an empty one). We're
// asserting this as even for those, enterBlock() must be invoked to correctly process symbols that
// are used in them.
@@ -532,16 +522,36 @@ final class AssignSymbols extends NodeVisitor implements Loggabl
@Override
public boolean enterVarNode(final VarNode varNode) {
start(varNode);
+ // Normally, a symbol assigned in a var statement is not live for its RHS. Since we also represent function
+ // declarations as VarNodes, they are exception to the rule, as they need to have the symbol visible to the
+ // body of the declared function for self-reference.
+ if (varNode.isFunctionDeclaration()) {
+ defineVarIdent(varNode);
+ }
return true;
}
@Override
public Node leaveVarNode(final VarNode varNode) {
- final IdentNode ident = varNode.getName();
- defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0));
+ if (!varNode.isFunctionDeclaration()) {
+ defineVarIdent(varNode);
+ }
return super.leaveVarNode(varNode);
}
+ private void defineVarIdent(final VarNode varNode) {
+ final IdentNode ident = varNode.getName();
+ final int flags;
+ if (varNode.isAnonymousFunctionDeclaration()) {
+ flags = IS_INTERNAL;
+ } else if (lc.getCurrentFunction().isProgram()) {
+ flags = IS_SCOPE;
+ } else {
+ flags = 0;
+ }
+ defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | flags);
+ }
+
private Symbol exceptionSymbol() {
return newObjectInternal(EXCEPTION_PREFIX);
}
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java
index 3a0cc6bfb4b..80846e139dd 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java
@@ -410,10 +410,29 @@ public final class Compiler implements Loggable {
baseName = baseName + installer.getUniqueScriptId();
}
- final String mangled = NameCodec.encode(baseName);
+ // ASM's bytecode verifier does not allow JVM allowed safe escapes using '\' as escape char.
+ // While ASM accepts such escapes for method names, field names, it enforces Java identifier
+ // for class names. Workaround that ASM bug here by replacing JVM 'dangerous' chars with '_'
+ // rather than safe encoding using '\'.
+ final String mangled = env._verify_code? replaceDangerChars(baseName) : NameCodec.encode(baseName);
return mangled != null ? mangled : baseName;
}
+ private static final String DANGEROUS_CHARS = "\\/.;:$[]<>";
+ private static String replaceDangerChars(final String name) {
+ final int len = name.length();
+ final StringBuilder buf = new StringBuilder();
+ for (int i = 0; i < len; i++) {
+ final char ch = name.charAt(i);
+ if (DANGEROUS_CHARS.indexOf(ch) != -1) {
+ buf.append('_');
+ } else {
+ buf.append(ch);
+ }
+ }
+ return buf.toString();
+ }
+
private String firstCompileUnitName() {
final StringBuilder sb = new StringBuilder(SCRIPTS_PACKAGE).
append('/').
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java
index 20914472ce6..2df1ae90b88 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java
@@ -98,6 +98,7 @@ import jdk.nashorn.internal.ir.LocalVariableConversion;
import jdk.nashorn.internal.ir.RuntimeNode;
import jdk.nashorn.internal.ir.Symbol;
import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.objects.NativeArray;
import jdk.nashorn.internal.runtime.ArgumentSetter;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.Debug;
@@ -2125,7 +2126,14 @@ public class MethodEmitter implements Emitter {
int pos = 0;
for (int i = argCount - 1; i >= 0; i--) {
- paramTypes[i] = stack.peek(pos++);
+ Type pt = stack.peek(pos++);
+ // "erase" specific ScriptObject subtype info - except for NativeArray.
+ // NativeArray is used for array/List/Deque conversion for Java calls.
+ if (ScriptObject.class.isAssignableFrom(pt.getTypeClass()) &&
+ !NativeArray.class.isAssignableFrom(pt.getTypeClass())) {
+ pt = Type.SCRIPT_OBJECT;
+ }
+ paramTypes[i] = pt;
}
final String descriptor = Type.getMethodDescriptor(returnType, paramTypes);
for (int i = 0; i < argCount; i++) {
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java
index 11a23ecd3a1..4f3bc07f1db 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java
@@ -29,16 +29,22 @@ import static jdk.nashorn.internal.runtime.Property.NOT_CONFIGURABLE;
import static jdk.nashorn.internal.runtime.Property.NOT_ENUMERABLE;
import static jdk.nashorn.internal.runtime.Property.NOT_WRITABLE;
+import java.lang.invoke.MethodType;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.AccessNode;
+import jdk.nashorn.internal.ir.CallNode;
import jdk.nashorn.internal.ir.Expression;
+import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.IdentNode;
import jdk.nashorn.internal.ir.IndexNode;
import jdk.nashorn.internal.ir.Optimistic;
+import jdk.nashorn.internal.objects.ArrayBufferView;
import jdk.nashorn.internal.objects.NativeArray;
import jdk.nashorn.internal.runtime.FindProperty;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
+import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
@@ -47,6 +53,13 @@ import jdk.nashorn.internal.runtime.ScriptRuntime;
* Used during recompilation.
*/
final class TypeEvaluator {
+ /**
+ * Type signature for invocation of functions without parameters: we must pass (callee, this) of type
+ * (ScriptFunction, Object) respectively. We also use Object as the return type (we must pass something,
+ * but it'll be ignored; it can't be void, though).
+ */
+ private static final MethodType EMPTY_INVOCATION_TYPE = MethodType.methodType(Object.class, ScriptFunction.class, Object.class);
+
private final Compiler compiler;
private final ScriptObject runtimeScope;
@@ -190,30 +203,46 @@ final class TypeEvaluator {
return null;
}
return getPropertyType(runtimeScope, ((IdentNode)expr).getName());
- }
-
- if (expr instanceof AccessNode) {
+ } else if (expr instanceof AccessNode) {
final AccessNode accessNode = (AccessNode)expr;
final Object base = evaluateSafely(accessNode.getBase());
if (!(base instanceof ScriptObject)) {
return null;
}
return getPropertyType((ScriptObject)base, accessNode.getProperty());
- }
-
- if (expr instanceof IndexNode) {
+ } else if (expr instanceof IndexNode) {
final IndexNode indexNode = (IndexNode)expr;
final Object base = evaluateSafely(indexNode.getBase());
- if(!(base instanceof NativeArray)) {
- // We only know how to deal with NativeArray. TODO: maybe manage buffers too
- return null;
+ if(base instanceof NativeArray || base instanceof ArrayBufferView) {
+ // NOTE: optimistic array getters throw UnwarrantedOptimismException based on the type of their
+ // underlying array storage, not based on values of individual elements. Thus, a LongArrayData will
+ // throw UOE for every optimistic int linkage attempt, even if the long value being returned in the
+ // first invocation would be representable as int. That way, we can presume that the array's optimistic
+ // type is the most optimistic type for which an element getter has a chance of executing successfully.
+ return ((ScriptObject)base).getArray().getOptimisticType();
+ }
+ } else if (expr instanceof CallNode) {
+ // Currently, we'll only try to guess the return type of immediately invoked function expressions with no
+ // parameters, that is (function() { ... })(). We could do better, but these are all heuristics and we can
+ // gradually introduce them as needed. An easy one would be to do the same for .call(this) idiom.
+ final CallNode callExpr = (CallNode)expr;
+ final Expression fnExpr = callExpr.getFunction();
+ if (fnExpr instanceof FunctionNode) {
+ final FunctionNode fn = (FunctionNode)fnExpr;
+ if (callExpr.getArgs().isEmpty()) {
+ final RecompilableScriptFunctionData data = compiler.getScriptFunctionData(fn.getId());
+ if (data != null) {
+ final Type returnType = Type.typeFor(data.getReturnType(EMPTY_INVOCATION_TYPE, runtimeScope));
+ if (returnType == Type.BOOLEAN) {
+ // We don't have optimistic booleans. In fact, optimistic call sites getting back boolean
+ // currently deoptimize all the way to Object.
+ return Type.OBJECT;
+ }
+ assert returnType == Type.INT || returnType == Type.LONG || returnType == Type.NUMBER || returnType == Type.OBJECT;
+ return returnType;
+ }
+ }
}
- // NOTE: optimistic array getters throw UnwarrantedOptimismException based on the type of their underlying
- // array storage, not based on values of individual elements. Thus, a LongArrayData will throw UOE for every
- // optimistic int linkage attempt, even if the long value being returned in the first invocation would be
- // representable as int. That way, we can presume that the array's optimistic type is the most optimistic
- // type for which an element getter has a chance of executing successfully.
- return ((NativeArray)base).getArray().getOptimisticType();
}
return null;
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java
index 86a84ca6de8..e3a26893cb5 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java
@@ -80,11 +80,12 @@ public class Block extends Node implements BreakableNode, Terminal, Flags
/**
* Constructor
*
- * @param token token
- * @param finish finish
- * @param statements statements
+ * @param token The first token of the block
+ * @param finish The index of the last character
+ * @param flags The flags of the block
+ * @param statements All statements in the block
*/
- public Block(final long token, final int finish, final Statement... statements) {
+ public Block(final long token, final int finish, final int flags, final Statement... statements) {
super(token, finish);
this.statements = Arrays.asList(statements);
@@ -92,29 +93,52 @@ public class Block extends Node implements BreakableNode, Terminal, Flags
this.entryLabel = new Label("block_entry");
this.breakLabel = new Label("block_break");
final int len = statements.length;
- this.flags = len > 0 && statements[len - 1].hasTerminalFlags() ? IS_TERMINAL : 0;
+ final int terminalFlags = len > 0 && statements[len - 1].hasTerminalFlags() ? IS_TERMINAL : 0;
+ this.flags = terminalFlags | flags;
this.conversion = null;
}
+ /**
+ * Constructs a new block
+ *
+ * @param token The first token of the block
+ * @param finish The index of the last character
+ * @param statements All statements in the block
+ */
+ public Block(final long token, final int finish, final Statement...statements){
+ this(token, finish, 0, statements);
+ }
+
+ /**
+ * Constructs a new block
+ *
+ * @param token The first token of the block
+ * @param finish The index of the last character
+ * @param statements All statements in the block
+ */
+ public Block(final long token, final int finish, final List statements){
+ this(token, finish, 0, statements);
+ }
+
/**
* Constructor
*
- * @param token token
- * @param finish finish
- * @param statements statements
+ * @param token The first token of the block
+ * @param finish The index of the last character
+ * @param flags The flags of the block
+ * @param statements All statements in the block
*/
- public Block(final long token, final int finish, final List statements) {
- this(token, finish, statements.toArray(new Statement[statements.size()]));
+ public Block(final long token, final int finish, final int flags, final List statements) {
+ this(token, finish, flags, statements.toArray(new Statement[statements.size()]));
}
private Block(final Block block, final int finish, final List statements, final int flags, final Map symbols, final LocalVariableConversion conversion) {
- super(block);
+ super(block, finish);
this.statements = statements;
this.flags = flags;
this.symbols = new LinkedHashMap<>(symbols); //todo - symbols have no dependencies on any IR node and can as far as we understand it be shallow copied now
this.entryLabel = new Label(block.entryLabel);
this.breakLabel = new Label(block.breakLabel);
- this.finish = finish;
this.conversion = conversion;
}
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ForNode.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ForNode.java
index 9b4cb6d6e1c..bc864eb68bb 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ForNode.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ForNode.java
@@ -54,20 +54,37 @@ public final class ForNode extends LoopNode {
private final int flags;
+ /**
+ * Constructs a ForNode
+ *
+ * @param lineNumber The line number of header
+ * @param token The for token
+ * @param finish The last character of the for node
+ * @param body The body of the for node
+ * @param flags The flags
+ */
+ public ForNode(final int lineNumber, final long token, final int finish, final Block body, final int flags){
+ this(lineNumber, token, finish, body, flags, null, null, null);
+ }
+
/**
* Constructor
*
- * @param lineNumber line number
- * @param token token
- * @param finish finish
- * @param body body
- * @param flags flags
+ * @param lineNumber The line number of header
+ * @param token The for token
+ * @param finish The last character of the for node
+ * @param body The body of the for node
+ * @param flags The flags
+ * @param init The initial expression
+ * @param test The test expression
+ * @param modify The modify expression
*/
- public ForNode(final int lineNumber, final long token, final int finish, final Block body, final int flags) {
- super(lineNumber, token, finish, body, false);
+ public ForNode(final int lineNumber, final long token, final int finish, final Block body, final int flags, final Expression init, final JoinPredecessorExpression test, final JoinPredecessorExpression modify) {
+ super(lineNumber, token, finish, body, test, false);
this.flags = flags;
- this.init = null;
- this.modify = null;
+ this.init = init;
+ this.modify = modify;
+
}
private ForNode(final ForNode forNode, final Expression init, final JoinPredecessorExpression test,
@@ -166,16 +183,6 @@ public final class ForNode extends LoopNode {
public boolean isForIn() {
return (flags & IS_FOR_IN) != 0;
}
-
- /**
- * Flag this to be a for in construct
- * @param lc lexical context
- * @return new for node if changed or existing if not
- */
- public ForNode setIsForIn(final LexicalContext lc) {
- return setFlags(lc, flags | IS_FOR_IN);
- }
-
/**
* Is this a for each construct, known from e.g. Rhino. This will be a for of construct
* in ECMAScript 6
@@ -185,15 +192,6 @@ public final class ForNode extends LoopNode {
return (flags & IS_FOR_EACH) != 0;
}
- /**
- * Flag this to be a for each construct
- * @param lc lexical context
- * @return new for node if changed or existing if not
- */
- public ForNode setIsForEach(final LexicalContext lc) {
- return setFlags(lc, flags | IS_FOR_EACH);
- }
-
/**
* If this is a for in or for each construct, there is an iterator symbol
* @return the symbol for the iterator to be used, or null if none exists
@@ -260,13 +258,6 @@ public final class ForNode extends LoopNode {
return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
}
- private ForNode setFlags(final LexicalContext lc, final int flags) {
- if (this.flags == flags) {
- return this;
- }
- return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
- }
-
@Override
JoinPredecessor setLocalVariableConversionChanged(final LexicalContext lc, final LocalVariableConversion conversion) {
return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java
index 1bbc7ab0834..ad19f8d53a8 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java
@@ -31,7 +31,6 @@ import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALL
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_ENTEREXIT;
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES;
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES;
-
import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
@@ -46,6 +45,7 @@ import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.annotations.Ignore;
import jdk.nashorn.internal.ir.annotations.Immutable;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.Token;
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.Source;
@@ -299,12 +299,16 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
* @param token token
* @param finish finish
* @param firstToken first token of the function node (including the function declaration)
+ * @param lastToken lastToken
* @param namespace the namespace
* @param ident the identifier
* @param name the name of the function
* @param parameters parameter list
* @param kind kind of function as in {@link FunctionNode.Kind}
* @param flags initial flags
+ * @param body body of the function
+ * @param state The initial state from the parser. Must be one of {@link CompilationState#PARSED} and {@link CompilationState#PARSE_ERROR}
+ * @param endParserState The parser state at the end of the parsing.
*/
public FunctionNode(
final Source source,
@@ -312,12 +316,16 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
final long token,
final int finish,
final long firstToken,
+ final long lastToken,
final Namespace namespace,
final IdentNode ident,
final String name,
final List parameters,
final FunctionNode.Kind kind,
- final int flags) {
+ final int flags,
+ final Block body,
+ final CompilationState state,
+ final Object endParserState) {
super(token, finish);
this.source = source;
@@ -327,15 +335,15 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
this.kind = kind;
this.parameters = parameters;
this.firstToken = firstToken;
- this.lastToken = token;
+ this.lastToken = lastToken;
this.namespace = namespace;
- this.compilationState = EnumSet.of(CompilationState.INITIALIZED);
+ this.compilationState = EnumSet.of(CompilationState.INITIALIZED, state);
this.flags = flags;
this.compileUnit = null;
- this.body = null;
+ this.body = body;
this.thisProperties = 0;
this.rootClass = null;
- this.endParserState = null;
+ this.endParserState = endParserState;
}
private FunctionNode(
@@ -439,7 +447,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
* @return the id
*/
public int getId() {
- return position();
+ return isProgram() ? -1: Token.descPosition(firstToken);
}
/**
@@ -902,34 +910,6 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
return lastToken;
}
- /**
- * Set the last token for this function's code
- * @param lc lexical context
- * @param lastToken the last token
- * @return function node or a new one if state was changed
- */
- public FunctionNode setLastToken(final LexicalContext lc, final long lastToken) {
- if (this.lastToken == lastToken) {
- return this;
- }
- return Node.replaceInLexicalContext(
- lc,
- this,
- new FunctionNode(
- this,
- lastToken,
- endParserState,
- flags,
- name,
- returnType,
- compileUnit,
- compilationState,
- body,
- parameters,
- thisProperties,
- rootClass));
- }
-
/**
* Returns the end parser state for this function.
* @return the end parser state for this function.
@@ -938,33 +918,6 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
return endParserState;
}
- /**
- * Set the end parser state for this function.
- * @param lc lexical context
- * @param endParserState the parser state to set
- * @return function node or a new one if state was changed
- */
- public FunctionNode setEndParserState(final LexicalContext lc, final Object endParserState) {
- if (this.endParserState == endParserState) {
- return this;
- }
- return Node.replaceInLexicalContext(
- lc,
- this,
- new FunctionNode(
- this,
- lastToken,
- endParserState,
- flags,
- name,
- returnType,
- compileUnit,
- compilationState,
- body,
- parameters,
- thisProperties, rootClass));
- }
-
/**
* Get the name of this function
* @return the name
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LoopNode.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LoopNode.java
index 86ef3cdad49..bfc86a69a43 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LoopNode.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LoopNode.java
@@ -53,14 +53,15 @@ public abstract class LoopNode extends BreakableStatement {
* @param token token
* @param finish finish
* @param body loop body
+ * @param test test
* @param controlFlowEscapes controlFlowEscapes
*/
- protected LoopNode(final int lineNumber, final long token, final int finish, final Block body, final boolean controlFlowEscapes) {
+ protected LoopNode(final int lineNumber, final long token, final int finish, final Block body, final JoinPredecessorExpression test, final boolean controlFlowEscapes) {
super(lineNumber, token, finish, new Label("while_break"));
this.continueLabel = new Label("while_continue");
- this.test = null;
this.body = body;
this.controlFlowEscapes = controlFlowEscapes;
+ this.test = test;
}
/**
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Node.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Node.java
index 37ec4b96a39..861f12a05ff 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Node.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Node.java
@@ -39,7 +39,7 @@ public abstract class Node implements Cloneable {
protected final int start;
/** End of source range. */
- protected int finish;
+ protected final int finish;
/** Token descriptor. */
private final long token;
@@ -80,6 +80,18 @@ public abstract class Node implements Cloneable {
this.finish = node.finish;
}
+ /**
+ * Copy constructor that overrides finish
+ *
+ * @param node source node
+ * @param finish Last character
+ */
+ protected Node(final Node node, final int finish) {
+ this.token = node.token;
+ this.start = node.start;
+ this.finish = finish;
+ }
+
/**
* Is this a loop node?
*
@@ -151,14 +163,6 @@ public abstract class Node implements Cloneable {
return finish;
}
- /**
- * Set finish position for this node in the source string
- * @param finish finish
- */
- public void setFinish(final int finish) {
- this.finish = finish;
- }
-
/**
* Get start position for node
* @return start position
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/VarNode.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/VarNode.java
index f9aef826fe6..a8db410042e 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/VarNode.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/VarNode.java
@@ -272,4 +272,12 @@ public final class VarNode extends Statement implements Assignment {
public boolean isFunctionDeclaration() {
return init instanceof FunctionNode && ((FunctionNode)init).isDeclared();
}
+
+ /**
+ * Returns true if this is an anonymous function declaration.
+ * @return true if this is an anonymous function declaration.
+ */
+ public boolean isAnonymousFunctionDeclaration() {
+ return isFunctionDeclaration() && ((FunctionNode)init).isAnonymous();
+ }
}
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WhileNode.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WhileNode.java
index 0cced567fbc..99bdce87c19 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WhileNode.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WhileNode.java
@@ -45,9 +45,11 @@ public final class WhileNode extends LoopNode {
* @param token token
* @param finish finish
* @param isDoWhile is this a do while loop?
+ * @param test test expression
+ * @param body body of the while loop
*/
- public WhileNode(final int lineNumber, final long token, final int finish, final boolean isDoWhile) {
- super(lineNumber, token, finish, null, false);
+ public WhileNode(final int lineNumber, final long token, final int finish, final boolean isDoWhile, final JoinPredecessorExpression test, final Block body) {
+ super(lineNumber, token, finish, body, test, false);
this.isDoWhile = isDoWhile;
}
@@ -55,10 +57,10 @@ public final class WhileNode extends LoopNode {
* Internal copy constructor
*
* @param whileNode while node
- * @param test test
- * @param body body
+ * @param test Test expression
+ * @param body body of the while loop
* @param controlFlowEscapes control flow escapes?
- * @param conversion TODO
+ * @param conversion local variable conversion info
*/
private WhileNode(final WhileNode whileNode, final JoinPredecessorExpression test, final Block body, final boolean controlFlowEscapes, final LocalVariableConversion conversion) {
super(whileNode, test, body, controlFlowEscapes, conversion);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WithNode.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WithNode.java
index 0ea52c98bb4..20e319294d2 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WithNode.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WithNode.java
@@ -42,14 +42,16 @@ public final class WithNode extends LexicalContextStatement {
/**
* Constructor
*
- * @param lineNumber line number
- * @param token token
- * @param finish finish
+ * @param lineNumber Line number of the header
+ * @param token First token
+ * @param finish Character index of the last token
+ * @param expression With expression
+ * @param body Body of with node
*/
- public WithNode(final int lineNumber, final long token, final int finish) {
+ public WithNode(final int lineNumber, final long token, final int finish, final Expression expression, final Block body) {
super(lineNumber, token, finish);
- this.expression = null;
- this.body = null;
+ this.expression = expression;
+ this.body = body;
}
private WithNode(final WithNode node, final Expression expression, final Block body) {
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayBufferView.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayBufferView.java
index efcc3ddcf60..e33fac3bb11 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayBufferView.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayBufferView.java
@@ -31,7 +31,6 @@ import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
@@ -46,7 +45,7 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
@ScriptClass("ArrayBufferView")
-abstract class ArrayBufferView extends ScriptObject {
+public abstract class ArrayBufferView extends ScriptObject {
private final NativeArrayBuffer buffer;
private final int byteOffset;
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java
index eb56de0e18f..61d7948f621 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java
@@ -561,7 +561,6 @@ public final class Global extends ScriptObject implements Scope {
*
* @param engine ScriptEngine to initialize
*/
- @SuppressWarnings("hiding")
public void initBuiltinObjects(final ScriptEngine engine) {
if (this.builtinObject != null) {
// already initialized, just return
@@ -1718,7 +1717,6 @@ public final class Global extends ScriptObject implements Scope {
return func;
}
- @SuppressWarnings("hiding")
private void init(final ScriptEngine engine) {
assert Context.getGlobal() == this : "this global is not set as current";
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeError.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeError.java
index e1d95ce097f..41ea9a5f4e2 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeError.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeError.java
@@ -27,7 +27,6 @@ package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import jdk.nashorn.api.scripting.NashornException;
@@ -131,7 +130,6 @@ public final class NativeError extends ScriptObject {
// This is called NativeError, NativeTypeError etc. to
// associate a ECMAException with the ECMA Error object.
- @SuppressWarnings("unused")
static void initException(final ScriptObject self) {
// ECMAException constructor has side effects
new ECMAException(self, null);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java
index 049d8fa8142..e5ef0b5a5fd 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
@@ -140,6 +141,11 @@ public final class NativeFloat32Array extends ArrayBufferView {
return getElem(index);
}
+ @Override
+ public double getDoubleOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public Object getObject(final int index) {
return getDouble(index);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java
index 79268cc51a9..1ad61b277c2 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
@@ -140,6 +141,11 @@ public final class NativeFloat64Array extends ArrayBufferView {
return getElem(index);
}
+ @Override
+ public double getDoubleOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public Object getObject(final int index) {
return getDouble(index);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java
index 72e24a20418..061488487f7 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
@@ -123,16 +124,31 @@ public final class NativeInt16Array extends ArrayBufferView {
return getElem(index);
}
+ @Override
+ public int getIntOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public long getLong(final int index) {
return getInt(index);
}
+ @Override
+ public long getLongOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public double getDouble(final int index) {
return getInt(index);
}
+ @Override
+ public double getDoubleOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public Object getObject(final int index) {
return getInt(index);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java
index 56b3106fb44..5074dc68539 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
@@ -121,16 +122,31 @@ public final class NativeInt32Array extends ArrayBufferView {
return getElem(index);
}
+ @Override
+ public int getIntOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public long getLong(final int index) {
return getInt(index);
}
+ @Override
+ public long getLongOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public double getDouble(final int index) {
return getInt(index);
}
+ @Override
+ public double getDoubleOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public Object getObject(final int index) {
return getInt(index);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java
index 68e6b0bc1ca..319168c0522 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
@@ -121,16 +122,31 @@ public final class NativeInt8Array extends ArrayBufferView {
return getElem(index);
}
+ @Override
+ public int getIntOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public long getLong(final int index) {
return getInt(index);
}
+ @Override
+ public long getLongOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public double getDouble(final int index) {
return getInt(index);
}
+ @Override
+ public double getDoubleOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public Object getObject(final int index) {
return getInt(index);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java
index 4395e081e70..e9a4380dadc 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java
@@ -27,7 +27,6 @@ package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Array;
import java.util.Collection;
@@ -36,7 +35,6 @@ import java.util.List;
import jdk.internal.dynalink.beans.StaticClass;
import jdk.internal.dynalink.support.TypeUtilities;
import jdk.nashorn.api.scripting.JSObject;
-import jdk.nashorn.api.scripting.ScriptUtils;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
@@ -90,7 +88,11 @@ public final class NativeJava {
*/
@Function(name="synchronized", attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object synchronizedFunc(final Object self, final Object func, final Object obj) {
- return ScriptUtils.makeSynchronizedFunction(func, obj);
+ if (func instanceof ScriptFunction) {
+ return ((ScriptFunction)func).makeSynchronizedFunction(obj);
+ }
+
+ throw typeError("not.a.function", ScriptRuntime.safeToString(func));
}
/**
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJavaImporter.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJavaImporter.java
index d1aa8cb1653..498c263cba6 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJavaImporter.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJavaImporter.java
@@ -25,6 +25,7 @@
package jdk.nashorn.internal.objects;
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
import jdk.internal.dynalink.CallSiteDescriptor;
@@ -36,9 +37,11 @@ import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.NativeJavaPackage;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
/**
@@ -94,33 +97,30 @@ public final class NativeJavaImporter extends ScriptObject {
}
/**
- * "No such property" call placeholder.
- *
- * This can never be called as we override {@link ScriptObject#noSuchProperty}. We do declare it here as it's a signal
- * to {@link jdk.nashorn.internal.runtime.WithObject} that it's worth trying doing a {@code noSuchProperty} on this object.
+ * "No such property" handler.
*
* @param self self reference
* @param name property name
- * @return never returns
+ * @return value of the missing property
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object __noSuchProperty__(final Object self, final Object name) {
- throw new AssertionError("__noSuchProperty__ placeholder called");
+ if (! (self instanceof NativeJavaImporter)) {
+ throw typeError("not.a.java.importer", ScriptRuntime.safeToString(self));
+ }
+ return ((NativeJavaImporter)self).createProperty(JSType.toString(name));
}
/**
- * "No such method call" placeholder
- *
- * This can never be called as we override {@link ScriptObject#noSuchMethod}. We do declare it here as it's a signal
- * to {@link jdk.nashorn.internal.runtime.WithObject} that it's worth trying doing a noSuchProperty on this object.
+ * "No such method call" handler
*
* @param self self reference
* @param args arguments to method
- * @return never returns
+ * @return never returns always throw TypeError
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object __noSuchMethod__(final Object self, final Object... args) {
- throw new AssertionError("__noSuchMethod__ placeholder called");
+ throw typeError("not.a.function", ScriptRuntime.safeToString(args[0]));
}
@Override
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java
index d049c9331f3..7f8a192399a 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
@@ -127,16 +128,31 @@ public final class NativeUint16Array extends ArrayBufferView {
return getElem(index);
}
+ @Override
+ public int getIntOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public long getLong(final int index) {
return getInt(index);
}
+ @Override
+ public long getLongOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public double getDouble(final int index) {
return getInt(index);
}
+ @Override
+ public double getDoubleOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public Object getObject(final int index) {
return getInt(index);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java
index 2ae2be056ae..4772b977dd8 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
@@ -128,7 +129,7 @@ public final class NativeUint32Array extends ArrayBufferView {
@Override
public Class> getElementType() {
- return int.class;
+ return long.class;
}
@Override
@@ -141,11 +142,21 @@ public final class NativeUint32Array extends ArrayBufferView {
return getElem(index);
}
+ @Override
+ public long getLongOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public double getDouble(final int index) {
return getLong(index);
}
+ @Override
+ public double getDoubleOptimistic(final int index, final int programPoint) {
+ return getLong(index);
+ }
+
@Override
public Object getObject(final int index) {
return getLong(index);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java
index 1067baa58d4..be7eb368b49 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
@@ -127,16 +128,31 @@ public final class NativeUint8Array extends ArrayBufferView {
return getElem(index);
}
+ @Override
+ public int getIntOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public long getLong(final int index) {
return getInt(index);
}
+ @Override
+ public long getLongOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public double getDouble(final int index) {
return getInt(index);
}
+ @Override
+ public double getDoubleOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public Object getObject(final int index) {
return getInt(index);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
index ffd0f14cfec..125ac0a2128 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
@@ -28,6 +28,7 @@ package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
import static jdk.nashorn.internal.lookup.Lookup.MH;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
@@ -157,16 +158,31 @@ public final class NativeUint8ClampedArray extends ArrayBufferView {
return getElem(index);
}
+ @Override
+ public int getIntOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public long getLong(final int index) {
return getInt(index);
}
+ @Override
+ public long getLongOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public double getDouble(final int index) {
return getInt(index);
}
+ @Override
+ public double getDoubleOptimistic(final int index, final int programPoint) {
+ return getElem(index);
+ }
+
@Override
public Object getObject(final int index) {
return getInt(index);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
index 3162e184468..32f1df63895 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
@@ -53,7 +53,6 @@ import static jdk.nashorn.internal.parser.TokenType.RPAREN;
import static jdk.nashorn.internal.parser.TokenType.SEMICOLON;
import static jdk.nashorn.internal.parser.TokenType.TERNARY;
import static jdk.nashorn.internal.parser.TokenType.WHILE;
-
import java.io.Serializable;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -71,10 +70,8 @@ import jdk.nashorn.internal.ir.AccessNode;
import jdk.nashorn.internal.ir.BaseNode;
import jdk.nashorn.internal.ir.BinaryNode;
import jdk.nashorn.internal.ir.Block;
-import jdk.nashorn.internal.ir.BlockLexicalContext;
import jdk.nashorn.internal.ir.BlockStatement;
import jdk.nashorn.internal.ir.BreakNode;
-import jdk.nashorn.internal.ir.BreakableNode;
import jdk.nashorn.internal.ir.CallNode;
import jdk.nashorn.internal.ir.CaseNode;
import jdk.nashorn.internal.ir.CatchNode;
@@ -90,9 +87,7 @@ import jdk.nashorn.internal.ir.IfNode;
import jdk.nashorn.internal.ir.IndexNode;
import jdk.nashorn.internal.ir.JoinPredecessorExpression;
import jdk.nashorn.internal.ir.LabelNode;
-import jdk.nashorn.internal.ir.LexicalContext;
import jdk.nashorn.internal.ir.LiteralNode;
-import jdk.nashorn.internal.ir.LoopNode;
import jdk.nashorn.internal.ir.Node;
import jdk.nashorn.internal.ir.ObjectNode;
import jdk.nashorn.internal.ir.PropertyKey;
@@ -138,8 +133,8 @@ public class Parser extends AbstractParser implements Loggable {
private List functionDeclarations;
- private final BlockLexicalContext lc = new BlockLexicalContext();
- private final Deque