Merge
This commit is contained in:
commit
fef5b70b3f
nashorn
buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen
make
samples
EvalWithArbitraryThis.javaEvalWithArbitraryThis.java.origLambdaAsFunc.javaMain.asmMain.classPrintToString.javaarray_removeif.jsbind_on_java.jscall_bind_java.jscheck_nashorn.jsdatetime.jsdefaults.jsfind_max_lines.jsfixed_point.jsimportstatic.jsjava_completion.jsjrtlist.jsmothers_day.jspasswordgen.jsprint_symlinks.jssort_by_java8.jsthis_for_eval.js
src
jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs
jdk.scripting.nashorn/share/classes/jdk
internal/dynalink
nashorn
api
internal
codegen
ApplySpecialization.javaAssignSymbols.javaCodeGenerator.javaCompilationPhase.javaCompiler.javaCompilerConstants.javaLabel.javaLower.javaMethodEmitter.javaObjectClassGenerator.java
types
ir
objects
ArrayBufferView.javaBoundScriptFunctionImpl.javaGlobal.javaNativeDebug.javaNativeError.javaNativeJSAdapter.javaNativeJava.javaNativeNumber.javaNativeRegExp.javaScriptFunctionImpl.java
parser
runtime
CodeInstaller.javaCompiledFunction.javaContext.javaFindProperty.javaGlobalConstants.javaJSONFunctions.javaJSType.javaParserException.javaPropertyListeners.javaPropertyMap.javaPrototypeObject.javaRecompilableScriptFunctionData.javaScope.javaScriptFunction.javaScriptFunctionData.javaScriptObject.javaStoredScript.javaWithObject.java
arrays
linker
regexp/joni
resources
tools
test/script
@ -54,10 +54,9 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIEL
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_TYPE;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE;
|
||||
@ -282,9 +281,9 @@ public class ClassGenerator {
|
||||
assert specs != null;
|
||||
if (!specs.isEmpty()) {
|
||||
mi.memberInfoArray(className, specs);
|
||||
mi.invokeStatic(SCRIPTFUNCTIONIMPL_TYPE, SCRIPTFUNCTIONIMPL_MAKEFUNCTION, SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC);
|
||||
mi.invokeStatic(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_CREATEBUILTIN, SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC);
|
||||
} else {
|
||||
mi.invokeStatic(SCRIPTFUNCTIONIMPL_TYPE, SCRIPTFUNCTIONIMPL_MAKEFUNCTION, SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC);
|
||||
mi.invokeStatic(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_CREATEBUILTIN, SCRIPTFUNCTION_CREATEBUILTIN_DESC);
|
||||
}
|
||||
|
||||
if (arityFound) {
|
||||
|
@ -38,9 +38,8 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIEL
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_INIT_DESC3;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_INIT_DESC4;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_TYPE;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_INIT_DESC3;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_INIT_DESC4;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE;
|
||||
@ -76,7 +75,7 @@ public class ConstructorGenerator extends ClassGenerator {
|
||||
|
||||
byte[] getClassBytes() {
|
||||
// new class extending from ScriptObject
|
||||
final String superClass = (constructor != null)? SCRIPTFUNCTIONIMPL_TYPE : SCRIPTOBJECT_TYPE;
|
||||
final String superClass = (constructor != null)? SCRIPTFUNCTION_TYPE : SCRIPTOBJECT_TYPE;
|
||||
cw.visit(V1_7, ACC_FINAL, className, null, superClass, null);
|
||||
if (memberCount > 0) {
|
||||
// add fields
|
||||
@ -182,8 +181,8 @@ public class ConstructorGenerator extends ClassGenerator {
|
||||
loadMap(mi);
|
||||
} else {
|
||||
// call Function.<init>
|
||||
superClass = SCRIPTFUNCTIONIMPL_TYPE;
|
||||
superDesc = (memberCount > 0) ? SCRIPTFUNCTIONIMPL_INIT_DESC4 : SCRIPTFUNCTIONIMPL_INIT_DESC3;
|
||||
superClass = SCRIPTFUNCTION_TYPE;
|
||||
superDesc = (memberCount > 0) ? SCRIPTFUNCTION_INIT_DESC4 : SCRIPTFUNCTION_INIT_DESC3;
|
||||
mi.loadLiteral(constructor.getName());
|
||||
mi.visitLdcInsn(new Handle(H_INVOKESTATIC, scriptClassInfo.getJavaName(), constructor.getJavaName(), constructor.getJavaDesc()));
|
||||
loadMap(mi);
|
||||
|
@ -31,10 +31,9 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import jdk.internal.org.objectweb.asm.Type;
|
||||
import jdk.nashorn.internal.objects.PrototypeObject;
|
||||
import jdk.nashorn.internal.objects.ScriptFunctionImpl;
|
||||
import jdk.nashorn.internal.runtime.AccessorProperty;
|
||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import jdk.nashorn.internal.runtime.PrototypeObject;
|
||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.Specialization;
|
||||
@ -88,7 +87,6 @@ public interface StringConstants {
|
||||
static final Type TYPE_PROPERTYMAP = Type.getType(PropertyMap.class);
|
||||
static final Type TYPE_PROTOTYPEOBJECT = Type.getType(PrototypeObject.class);
|
||||
static final Type TYPE_SCRIPTFUNCTION = Type.getType(ScriptFunction.class);
|
||||
static final Type TYPE_SCRIPTFUNCTIONIMPL = Type.getType(ScriptFunctionImpl.class);
|
||||
static final Type TYPE_SCRIPTOBJECT = Type.getType(ScriptObject.class);
|
||||
|
||||
static final String PROTOTYPE_SUFFIX = "$Prototype";
|
||||
@ -122,17 +120,14 @@ public interface StringConstants {
|
||||
static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
|
||||
static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype";
|
||||
static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT);
|
||||
|
||||
// ScriptFunctionImpl
|
||||
static final String SCRIPTFUNCTIONIMPL_TYPE = TYPE_SCRIPTFUNCTIONIMPL.getInternalName();
|
||||
static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION = "makeFunction";
|
||||
static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC =
|
||||
static final String SCRIPTFUNCTION_CREATEBUILTIN = "createBuiltin";
|
||||
static final String SCRIPTFUNCTION_CREATEBUILTIN_DESC =
|
||||
Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE);
|
||||
static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC =
|
||||
static final String SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC =
|
||||
Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY);
|
||||
static final String SCRIPTFUNCTIONIMPL_INIT_DESC3 =
|
||||
static final String SCRIPTFUNCTION_INIT_DESC3 =
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY);
|
||||
static final String SCRIPTFUNCTIONIMPL_INIT_DESC4 =
|
||||
static final String SCRIPTFUNCTION_INIT_DESC4 =
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_SPECIALIZATION_ARRAY);
|
||||
|
||||
// ScriptObject
|
||||
|
@ -31,7 +31,7 @@ include MakeBase.gmk
|
||||
include JavaCompilation.gmk
|
||||
include SetupJavaCompilers.gmk
|
||||
|
||||
JDK_CLASSES := $(subst $(SPACE),$(PATH_SEP),$(strip $(addprefix $(JDK_OUTPUTDIR)/modules/, \
|
||||
JDK_CLASSES := $(call PathList, $(strip $(addprefix $(JDK_OUTPUTDIR)/modules/, \
|
||||
java.base java.logging java.scripting)))
|
||||
|
||||
NASHORN_JAR := $(IMAGES_OUTPUTDIR)/nashorn.jar
|
||||
@ -48,7 +48,7 @@ endif
|
||||
$(eval $(call SetupJavaCompiler,GENERATE_NEWBYTECODE_DEBUG, \
|
||||
JVM := $(JAVA), \
|
||||
JAVAC := $(NEW_JAVAC), \
|
||||
FLAGS := -g -source 8 -target 8 -bootclasspath "$(JDK_CLASSES)", \
|
||||
FLAGS := -g -source 8 -target 8 -bootclasspath $(JDK_CLASSES), \
|
||||
SERVER_DIR := $(SJAVAC_SERVER_DIR), \
|
||||
SERVER_JVM := $(SJAVAC_SERVER_JAVA)))
|
||||
|
||||
@ -86,7 +86,8 @@ $(NASGEN_RUN_FILE): $(BUILD_NASGEN)
|
||||
$(RM) -rf $(@D)/jdk $(@D)/netscape
|
||||
$(CP) -R -p $(SUPPORT_OUTPUTDIR)/special_classes/jdk.scripting.nashorn/classes/* $(@D)/
|
||||
$(FIXPATH) $(JAVA) \
|
||||
-Xbootclasspath/p:"$(BUILDTOOLS_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(SUPPORT_OUTPUTDIR)/special_classes/jdk.scripting.nashorn/classes" \
|
||||
-Xbootclasspath/p:$(call PathList, $(BUILDTOOLS_OUTPUTDIR)/nasgen_classes \
|
||||
$(SUPPORT_OUTPUTDIR)/special_classes/jdk.scripting.nashorn/classes) \
|
||||
jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D)
|
||||
$(TOUCH) $@
|
||||
|
||||
|
48
nashorn/samples/EvalWithArbitraryThis.java
Normal file
48
nashorn/samples/EvalWithArbitraryThis.java
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import javax.script.*;
|
||||
import jdk.nashorn.api.scripting.*;
|
||||
|
||||
// Simple nashorn demo that evals a script with arbitrary script
|
||||
// object bound as "this" for the evaluated script.
|
||||
|
||||
public class EvalWithArbitraryThis {
|
||||
public static void main(String[] args) throws Exception {
|
||||
ScriptEngineManager m = new ScriptEngineManager();
|
||||
ScriptEngine e = m.getEngineByName("nashorn");
|
||||
Object sobj = e.eval("( { foo: 343, bar: 'hello' } )");
|
||||
|
||||
// "this" bound to sobj in this eval.
|
||||
// so it prints sobj.foo and sobj.bar.
|
||||
((ScriptObjectMirror)sobj).eval("print(this.foo); print(this.bar)");
|
||||
}
|
||||
}
|
48
nashorn/samples/EvalWithArbitraryThis.java.orig
Normal file
48
nashorn/samples/EvalWithArbitraryThis.java.orig
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import javax.script.*;
|
||||
import jdk.nashorn.api.scripting.*;
|
||||
|
||||
// Simple nashorn demo that evals a script with arbitrary script
|
||||
// object bound as "this" for the evaluated script.
|
||||
|
||||
public class EvalWithArbitraryThis {
|
||||
public static void main(String[] args) throws Exception {
|
||||
ScriptEngineManager m = new ScriptEngineManager();
|
||||
ScriptEngine e = m.getEngineByName("nashorn");
|
||||
Object sobj = e.eval("( { foo: 343, bar: 'hello' } )");
|
||||
|
||||
// "this" bound to sobj in this eval.
|
||||
// so it prints sobj.foo and sobj.bar.
|
||||
((ScriptObjectMirror)sobj).eval("print(this.foo); print(this.bar)");
|
||||
}
|
||||
}
|
48
nashorn/samples/LambdaAsFunc.java
Normal file
48
nashorn/samples/LambdaAsFunc.java
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import javax.script.*;
|
||||
import java.util.function.*;
|
||||
|
||||
// example demonstrating that arbitrary Lambda can be called as function from script
|
||||
|
||||
public class LambdaAsFunc {
|
||||
public static void main(String[] args) throws Exception {
|
||||
ScriptEngineManager m = new ScriptEngineManager();
|
||||
ScriptEngine e = m.getEngineByName("nashorn");
|
||||
|
||||
// expose a lambda as top-level script function
|
||||
e.put("upper", (Function<String, String>) String::toUpperCase);
|
||||
|
||||
// call lambda as though it is a normal script function
|
||||
System.out.println(e.eval("upper('hello')"));
|
||||
}
|
||||
}
|
103
nashorn/samples/Main.asm
Normal file
103
nashorn/samples/Main.asm
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Simple sample to demonstrate openjdk asmtools assembler with
|
||||
// nashorn dynalink linker in a invokedynamic instruction.
|
||||
//
|
||||
// To assemble this file, use the following command:
|
||||
//
|
||||
// java -cp <asmtools.jar> org.openjdk.asmtools.Main jasm Main.asm
|
||||
//
|
||||
// See also: https://wiki.openjdk.java.net/display/CodeTools/asmtools
|
||||
//
|
||||
// NOTE: Uses nashorn internals and so *may* break with later nashorn!
|
||||
|
||||
super public class Main
|
||||
version 52:0
|
||||
{
|
||||
|
||||
|
||||
public Method "<init>":"()V"
|
||||
stack 1 locals 1
|
||||
{
|
||||
aload_0;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
return;
|
||||
}
|
||||
|
||||
public static Method main:"([Ljava/lang/String;)V"
|
||||
stack 2 locals 2
|
||||
{
|
||||
// List l = new ArrayList();
|
||||
new class java/util/ArrayList;
|
||||
dup;
|
||||
invokespecial Method java/util/ArrayList."<init>":"()V";
|
||||
astore_1;
|
||||
aload_1;
|
||||
|
||||
// l.add("hello");
|
||||
ldc String "hello";
|
||||
invokeinterface InterfaceMethod java/util/List.add:"(Ljava/lang/Object;)Z", 2;
|
||||
pop;
|
||||
|
||||
// l.add("world");
|
||||
aload_1;
|
||||
ldc String "world";
|
||||
invokeinterface InterfaceMethod java/util/List.add:"(Ljava/lang/Object;)Z", 2;
|
||||
pop;
|
||||
|
||||
// printLength(l);
|
||||
aload_1;
|
||||
invokestatic Method printLength:"(Ljava/lang/Object;)V";
|
||||
|
||||
// printLength(args); // args is argument of main method
|
||||
aload_0;
|
||||
invokestatic Method printLength:"(Ljava/lang/Object;)V";
|
||||
return;
|
||||
}
|
||||
|
||||
private static Method printLength:"(Ljava/lang/Object;)V"
|
||||
stack 2 locals 1
|
||||
{
|
||||
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
|
||||
aload_0;
|
||||
|
||||
// Using nashorn embedded dynalink linker with the following invokedynamic
|
||||
// 'length' property on a bean - arrays, lists supported
|
||||
|
||||
invokedynamic InvokeDynamic REF_invokeStatic:jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;":"dyn:getProp|getElem|getMethod:length":"(Ljava/lang/Object;)Ljava/lang/Object;" int 0;
|
||||
|
||||
// print 'length' value
|
||||
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/Object;)V";
|
||||
return;
|
||||
}
|
||||
|
||||
} // end Class Main
|
BIN
nashorn/samples/Main.class
Normal file
BIN
nashorn/samples/Main.class
Normal file
Binary file not shown.
47
nashorn/samples/PrintToString.java
Normal file
47
nashorn/samples/PrintToString.java
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import javax.script.*;
|
||||
import java.io.StringWriter;
|
||||
|
||||
// simple example demonstrating capturing of "print" output
|
||||
// from script execution as a String via script engine API.
|
||||
|
||||
public class PrintToString {
|
||||
public static void main(String[] args) throws ScriptException {
|
||||
ScriptEngineManager m = new ScriptEngineManager();
|
||||
ScriptEngine e = m.getEngineByName("nashorn");
|
||||
StringWriter sw = new StringWriter();
|
||||
e.getContext().setWriter(sw);
|
||||
e.eval("print('hello world')");
|
||||
System.out.println(sw.toString());
|
||||
}
|
||||
}
|
52
nashorn/samples/array_removeif.js
Normal file
52
nashorn/samples/array_removeif.js
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Sample for Collection.removeIf and Java.to
|
||||
// See http://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#removeIf-java.util.function.Predicate-
|
||||
|
||||
var langs = [
|
||||
"java", "javascript",
|
||||
"C", "C#", "C++",
|
||||
"Erlang", "Haskell"
|
||||
];
|
||||
|
||||
// convert script array to a Java List
|
||||
function asList(array) {
|
||||
return Java.to(array, java.util.List);
|
||||
}
|
||||
|
||||
// remove elements that satisfy a predicate
|
||||
// using Collection.removeIf(Predicate)
|
||||
asList(langs).removeIf(
|
||||
function(s) s.startsWith("C"));
|
||||
|
||||
// print modified array
|
||||
print(langs);
|
44
nashorn/samples/bind_on_java.js
Normal file
44
nashorn/samples/bind_on_java.js
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// sample to demonstrate calling Function.prototype.bind on Java methods.
|
||||
|
||||
var DoubleStream = java.util.stream.DoubleStream;
|
||||
var r = new java.util.Random();
|
||||
|
||||
// bind "this" for nextGaussian method of Random class
|
||||
var next = Function.bind.call(r.nextGaussian, r);
|
||||
|
||||
// next is used as no argument "function"
|
||||
DoubleStream
|
||||
.generate(function() next())
|
||||
.limit(100)
|
||||
.forEach(print);
|
59
nashorn/samples/call_bind_java.js
Normal file
59
nashorn/samples/call_bind_java.js
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Sample demonstrating calling Java methods like normal
|
||||
// functions. Bound instance methods, static methods can be
|
||||
// called like normal script functions.
|
||||
|
||||
// Java types used
|
||||
var Files = Java.type("java.nio.file.Files");
|
||||
var FileSystems = Java.type("java.nio.file.FileSystems");
|
||||
var System = Java.type("java.lang.System");
|
||||
|
||||
var fs = FileSystems.default;
|
||||
var bind = Function.prototype.bind;
|
||||
|
||||
// Java methods as "functions"
|
||||
|
||||
// Java method with bound "this"
|
||||
var Path = bind.call(fs.getPath, fs);
|
||||
// Java static method
|
||||
var Property = System.getProperty;
|
||||
|
||||
// call Java static methods and bound instance methods
|
||||
// like normal script functions.
|
||||
|
||||
var root = Path("/");
|
||||
// print URI for root dir
|
||||
print(root.toUri());
|
||||
var home = Path(Property("user.home"));
|
||||
// list home directory
|
||||
Files.walk(home).forEach(print);
|
45
nashorn/samples/check_nashorn.js
Normal file
45
nashorn/samples/check_nashorn.js
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// check if script is being run using nashorn script engine
|
||||
function isNashorn() {
|
||||
try {
|
||||
// "engine" variable is of type javax.script.ScriptEngine is defined
|
||||
// by nashorn jsr-223 engine. Check the name of the engine from
|
||||
// javax.script.ScriptEngineFactory associated
|
||||
|
||||
return engine.factory.engineName.contains("Nashorn");
|
||||
} catch (e) {
|
||||
// if engine or any of the properties are undefined
|
||||
// then script is not being run using nashorn.
|
||||
return false;
|
||||
}
|
||||
}
|
73
nashorn/samples/datetime.js
Normal file
73
nashorn/samples/datetime.js
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// converting b/w JavaScript Date and Java LocalDateTime
|
||||
|
||||
// JavaScript Date with current time
|
||||
var d = new Date();
|
||||
print(d);
|
||||
|
||||
// Java 8 java.time classes used
|
||||
var Instant = java.time.Instant;
|
||||
var LocalDateTime = java.time.LocalDateTime;
|
||||
var ZoneId = java.time.ZoneId;
|
||||
|
||||
// Date.prototype.getTime
|
||||
|
||||
// getTime() method returns the numeric value corresponding to the time
|
||||
// for the specified date according to universal time. The value returned
|
||||
// by the getTime() method is the number of milliseconds since 1 January 1970 00:00:00 UTC.
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime
|
||||
|
||||
// Java Instant.ofEpochMilli to convert time in milliseconds to Instant object
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#ofEpochMilli-long-
|
||||
|
||||
var instant = Instant.ofEpochMilli(d.getTime());
|
||||
|
||||
// Instant to LocalDateTime using LocalDateTime.ofInstant
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#ofInstant-java.time.Instant-java.time.ZoneId-
|
||||
|
||||
var ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
print(ldt);
|
||||
|
||||
// converting a LocalDateTime to JavaScript Date
|
||||
// convert LocalDateTime to Instant first
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#atZone-java.time.ZoneId-
|
||||
|
||||
var instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
|
||||
|
||||
// instant to to epoch milliseconds
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#toEpochMilli--
|
||||
// and then to JavaScript Date from time in milliseconds
|
||||
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date
|
||||
|
||||
var d1 = new Date(instant.toEpochMilli());
|
||||
print(d1);
|
43
nashorn/samples/defaults.js
Normal file
43
nashorn/samples/defaults.js
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// print default methods of a Java class
|
||||
|
||||
if (arguments.length == 0) {
|
||||
print("Usage: jjs defaults.js -- <java class name>");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
var jclass = Java.type(arguments[0]).class;
|
||||
for each (m in jclass.methods) {
|
||||
// http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#isDefault--
|
||||
if (m.default) print(m);
|
||||
}
|
59
nashorn/samples/find_max_lines.js
Normal file
59
nashorn/samples/find_max_lines.js
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Find the file with maximum number of lines
|
||||
|
||||
var Files = Java.type("java.nio.file.Files");
|
||||
var Integer = Java.type("java.lang.Integer");
|
||||
var Paths = Java.type("java.nio.file.Paths");
|
||||
|
||||
var file = arguments.length == 0? "." : arguments[0];
|
||||
var ext = arguments.length > 1? arguments[1] : ".java";
|
||||
var path = Paths.get(file);
|
||||
|
||||
// return number of lines in given Path (that represents a file)
|
||||
function lines(p) {
|
||||
var strm = Files.lines(p);
|
||||
try {
|
||||
return strm.count();
|
||||
} finally {
|
||||
strm.close();
|
||||
}
|
||||
}
|
||||
|
||||
// walk files, map to file and lines, find the max
|
||||
var obj = Files.find(path, Integer.MAX_VALUE,
|
||||
function(p, a) !p.toFile().isDirectory() && p.toString().endsWith(ext)).
|
||||
map(function(p) ({ path : p, lines: lines(p) })).
|
||||
max(function(x, y) x.lines - y.lines).get();
|
||||
|
||||
// print path and lines of the max line file
|
||||
print(obj.path, obj.lines);
|
69
nashorn/samples/fixed_point.js
Normal file
69
nashorn/samples/fixed_point.js
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Simple sample demonstrating "fixed point" computation with Streams
|
||||
|
||||
// See also https://mitpress.mit.edu/sicp/chapter1/node21.html#secprocgeneralmethods
|
||||
var Stream = Java.type("java.util.stream.Stream");
|
||||
|
||||
// generic fixed point procedure
|
||||
function fixed_point(f, init_guess) {
|
||||
var tolerance = 0.00001;
|
||||
function close_enough(v1, v2) Math.abs(v1 - v2) < tolerance;
|
||||
|
||||
var prev;
|
||||
return Stream.iterate(init_guess, f)
|
||||
.filter(function(x) {
|
||||
try {
|
||||
return prev == undefined? false : close_enough(prev, x);
|
||||
} finally {
|
||||
prev = x;
|
||||
}
|
||||
})
|
||||
.findFirst()
|
||||
.get();
|
||||
}
|
||||
|
||||
// solution to x = cos(x)
|
||||
print(fixed_point(Math.cos, 1.0))
|
||||
|
||||
// solution to x = sin(x) + cos(x)
|
||||
print(fixed_point(function(x) Math.sin(x) + Math.cos(x), 1.0));
|
||||
|
||||
// square root by Newton's method
|
||||
// http://en.wikipedia.org/wiki/Newton's_method
|
||||
function sqrt(n)
|
||||
fixed_point(function(x) (x + n/x) / 2, 2.0);
|
||||
|
||||
print(sqrt(2))
|
||||
print(sqrt(3))
|
||||
|
||||
|
52
nashorn/samples/importstatic.js
Normal file
52
nashorn/samples/importstatic.js
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Java like "import static class_name.*" for nashorn
|
||||
|
||||
function importStatic(clazz) {
|
||||
// make sure the argument is a Java type
|
||||
if (! Java.isType(clazz)) {
|
||||
throw new TypeError(clazz + " is not a Java type");
|
||||
}
|
||||
|
||||
// bind properties of clazz to an object
|
||||
var obj = Object.bindProperties({}, clazz);
|
||||
|
||||
// copy properties to global to "import" those
|
||||
for (var i in obj) {
|
||||
this[i] = obj[i];
|
||||
}
|
||||
}
|
||||
|
||||
importStatic(java.time.Instant);
|
||||
print(now());
|
||||
print(ofEpochSecond(1));
|
||||
print(parse("2007-12-03T10:15:30.00Z"));
|
41
nashorn/samples/java_completion.js
Normal file
41
nashorn/samples/java_completion.js
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Simple sample demonstrating the use of JShell API with nashorn
|
||||
|
||||
// display source code completion suggestions for a Java snippet using JShell's API
|
||||
// See http://openjdk.java.net/projects/kulla/
|
||||
|
||||
var repl = Java.type("jdk.jshell.JShell").create()
|
||||
var analysis = repl.sourceCodeAnalysis()
|
||||
var code = "System."
|
||||
var suggestions = analysis.completionSuggestions(code, code.length, [0])
|
||||
suggestions.forEach(function(s) print(s.continuation))
|
37
nashorn/samples/jrtlist.js
Normal file
37
nashorn/samples/jrtlist.js
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// list contents of "jrt" file system in Java 9
|
||||
|
||||
with(new JavaImporter(java.nio.file, java.net)) {
|
||||
var fs = FileSystems.getFileSystem(URI.create("jrt:/"))
|
||||
Files.walk(fs.getPath("/")).forEach(print);
|
||||
}
|
56
nashorn/samples/mothers_day.js
Normal file
56
nashorn/samples/mothers_day.js
Normal file
@ -0,0 +1,56 @@
|
||||
# compute Mothers day of the given the year
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// print "Mother's day" of the given year using Java Time API
|
||||
|
||||
if (arguments.length == 0) {
|
||||
print("Usage: jjs mothers_day.js -- year");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// java classes used
|
||||
var DayOfWeek = java.time.DayOfWeek;
|
||||
var LocalDate = java.time.LocalDate;
|
||||
var TemporalAdjusters = java.time.temporal.TemporalAdjusters;
|
||||
|
||||
var year = parseInt(arguments[0]);
|
||||
|
||||
// See: https://en.wikipedia.org/?title=Mother%27s_Day
|
||||
// We need second Sunday of May. Make April 30 of the given
|
||||
// year adjust and adjust to next Sunday from there twice. To adjust a Date
|
||||
// we use a common TemporalAdjuster provided in JDK8.
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAdjusters.html
|
||||
|
||||
print(LocalDate.of(year, 4, 30).
|
||||
with(TemporalAdjusters.next(DayOfWeek.SUNDAY)).
|
||||
with(TemporalAdjusters.next(DayOfWeek.SUNDAY)));
|
49
nashorn/samples/passwordgen.js
Normal file
49
nashorn/samples/passwordgen.js
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Simple password generator using SecureRandom + stream API
|
||||
|
||||
// accept optional password length from command line
|
||||
var len = arguments.length? parseInt(arguments[0]) : 8;
|
||||
|
||||
// Java types used
|
||||
var Collectors = Java.type("java.util.stream.Collectors");
|
||||
var SecureRandom = Java.type("java.security.SecureRandom");
|
||||
|
||||
// allowed password chars
|
||||
var chars =
|
||||
"!@#$%ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
// generated and print password
|
||||
print(new SecureRandom().
|
||||
ints(len, 0, chars.length).
|
||||
mapToObj(function(i) chars[i]).
|
||||
collect(Collectors.joining("")));
|
50
nashorn/samples/print_symlinks.js
Normal file
50
nashorn/samples/print_symlinks.js
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Print all symbolic links in user's home directory
|
||||
|
||||
// JavaImporter and "with" to simulate "import" statements in Java.
|
||||
// See https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions
|
||||
|
||||
with (new JavaImporter(java.nio.file, java.lang)) {
|
||||
|
||||
var userDir = System.getProperty("user.dir")
|
||||
var home = FileSystems.default.getPath(userDir);
|
||||
|
||||
// JS functions can be passed where Java lambdas are required.
|
||||
// Also, using "Expression closure" extension here.
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Expression_Closures
|
||||
|
||||
Files.walk(home).
|
||||
filter(function(p) Files.isSymbolicLink(p)).
|
||||
forEach(function(p)
|
||||
print(p, '->', Files.readSymbolicLink(p)));
|
||||
}
|
59
nashorn/samples/sort_by_java8.js
Normal file
59
nashorn/samples/sort_by_java8.js
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Simple sorting with Java8 APIs
|
||||
|
||||
// Separation key-extraction from key ordering
|
||||
|
||||
// Simple demo for Comparator.comparing
|
||||
// http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#comparing-java.util.function.Function-
|
||||
|
||||
// data to be sorted
|
||||
var cards = [
|
||||
{ name: "hello", email: "foo@hello.com" },
|
||||
{ name: "world", email: "bar@world.com" },
|
||||
{ name: "see", email: "see@dontsee.com" },
|
||||
];
|
||||
|
||||
var Collections = java.util.Collections;
|
||||
var Comparator = java.util.Comparator;
|
||||
|
||||
// sort records name in reverse order of names
|
||||
Collections.sort(cards,
|
||||
Comparator.comparing(function(a) a.name).reversed());
|
||||
|
||||
print(JSON.stringify(cards))
|
||||
|
||||
// sort records by email
|
||||
Collections.sort(cards,
|
||||
Comparator.comparing(function(a) a.email));
|
||||
|
||||
print(JSON.stringify(cards))
|
54
nashorn/samples/this_for_eval.js
Normal file
54
nashorn/samples/this_for_eval.js
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// how to pass arbitrary "this" object for eval'ed script?
|
||||
|
||||
var obj = { foo: 44 };
|
||||
|
||||
// the following won't work. eval.apply is indirect eval call
|
||||
// and so 'this' will be global object always! So, this
|
||||
// line will print 'undefined'
|
||||
eval.apply(obj, [ " print(this.foo)" ]);
|
||||
|
||||
obj.myEval = eval;
|
||||
|
||||
// still won't work - still indirect 'eval' call!
|
||||
// still undefined is printed!
|
||||
obj.myEval("print(this.foo)");
|
||||
|
||||
function func(code) {
|
||||
eval(code);
|
||||
}
|
||||
|
||||
// eval called inside func and so get's func's "this" as it's "this"!
|
||||
// So, 44 is printed
|
||||
|
||||
func.apply(obj, [ "print(this.foo)" ]);
|
@ -49,9 +49,9 @@ class Console implements AutoCloseable {
|
||||
|
||||
Console(final InputStream cmdin, final PrintStream cmdout, final File historyFile,
|
||||
final Completer completer) throws IOException {
|
||||
TerminalFactory.registerFlavor(Flavor.WINDOWS, isCygwin()? JJSUnixTerminal::new : JJSWindowsTerminal::new);
|
||||
TerminalFactory.registerFlavor(Flavor.UNIX, JJSUnixTerminal::new);
|
||||
in = new ConsoleReader(cmdin, cmdout);
|
||||
TerminalFactory.registerFlavor(Flavor.WINDOWS, JJSWindowsTerminal :: new);
|
||||
TerminalFactory.registerFlavor(Flavor.UNIX, JJSUnixTerminal :: new);
|
||||
in.setExpandEvents(false);
|
||||
in.setHandleUserInterrupt(true);
|
||||
in.setBellEnabled(true);
|
||||
@ -134,4 +134,8 @@ class Console implements AutoCloseable {
|
||||
setAnsiSupported(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCygwin() {
|
||||
return System.getenv("SHELL") != null;
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ import jdk.internal.dynalink.support.RuntimeContextLinkRequestImpl;
|
||||
* return factory.createLinker();
|
||||
* }
|
||||
*
|
||||
* public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
|
||||
* public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) {
|
||||
* return dynamicLinker.link(new MonomorphicCallSite(CallSiteDescriptorFactory.create(lookup, name, type)));
|
||||
* }
|
||||
* }
|
||||
|
2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/FacetIntrospector.java
2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/FacetIntrospector.java
@ -152,7 +152,7 @@ abstract class FacetIntrospector {
|
||||
boolean isAccessible(final Member m) {
|
||||
final Class<?> declaring = m.getDeclaringClass();
|
||||
// (declaring == clazz) is just an optimization - we're calling this only from code that operates on a
|
||||
// non-restriced class, so if the declaring class is identical to the class being inspected, then forego
|
||||
// non-restricted class, so if the declaring class is identical to the class being inspected, then forego
|
||||
// a potentially expensive restricted-package check.
|
||||
return declaring == clazz || !CheckRestrictedPackage.isRestrictedClass(declaring);
|
||||
}
|
||||
|
1
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/SingleDynamicMethod.java
1
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/SingleDynamicMethod.java
@ -98,7 +98,6 @@ import jdk.internal.dynalink.support.Lookup;
|
||||
* target method to a call site type (including mapping variable arity methods to a call site signature with different
|
||||
* arity).
|
||||
* @author Attila Szegedi
|
||||
* @version $Id: $
|
||||
*/
|
||||
abstract class SingleDynamicMethod extends DynamicMethod {
|
||||
|
||||
|
2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedInvocation.java
2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedInvocation.java
@ -353,7 +353,7 @@ public class GuardedInvocation {
|
||||
|
||||
/**
|
||||
* Applies argument filters to both the invocation and the guard (if there is one).
|
||||
* @param pos the position of the first argumen being filtered
|
||||
* @param pos the position of the first argument being filtered
|
||||
* @param filters the argument filters
|
||||
* @return a filtered invocation
|
||||
*/
|
||||
|
@ -110,7 +110,7 @@ public class GuardedTypeConversion {
|
||||
|
||||
/**
|
||||
* Check if invocation is cacheable
|
||||
* @return true if cachable, false otherwise
|
||||
* @return true if cacheable, false otherwise
|
||||
*/
|
||||
public boolean isCacheable() {
|
||||
return cacheable;
|
||||
|
@ -77,7 +77,7 @@ public final class ScriptUtils {
|
||||
* @return a synchronizing wrapper function
|
||||
*/
|
||||
public static Object makeSynchronizedFunction(final ScriptFunction func, final Object sync) {
|
||||
return func.makeSynchronizedFunction(unwrap(sync));
|
||||
return func.createSynchronized(unwrap(sync));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,7 +103,7 @@ public final class URLReader extends Reader {
|
||||
/**
|
||||
* Charset used by this reader
|
||||
*
|
||||
* @return the Chartset used to convert bytes to chars
|
||||
* @return the Charset used to convert bytes to chars
|
||||
*/
|
||||
public Charset getCharset() {
|
||||
return cs;
|
||||
|
@ -80,7 +80,7 @@ public interface Parser {
|
||||
public CompilationUnitTree parse(final URL url, final DiagnosticListener listener) throws IOException, NashornException;
|
||||
|
||||
/**
|
||||
* Parses the readerand returns compilation unit tree
|
||||
* Parses the reader and returns compilation unit tree
|
||||
*
|
||||
* @param name name of the source file to parse
|
||||
* @param reader from which source is read
|
||||
@ -133,7 +133,7 @@ public interface Parser {
|
||||
* <dt>"-strict"</dt><dd>enable ECMAScript strict mode</dd>
|
||||
* </dl>
|
||||
*
|
||||
* @throws NullPointerException if options arrry or any of it's element is null
|
||||
* @throws NullPointerException if options array or any of its element is null
|
||||
* @throws IllegalArgumentException on unsupported option value.
|
||||
* @return a new Parser instance.
|
||||
*/
|
||||
|
@ -35,7 +35,7 @@ public interface RegExpLiteralTree extends Tree {
|
||||
/**
|
||||
* Regular expression pattern to match.
|
||||
*
|
||||
* @return regular expression patten
|
||||
* @return regular expression pattern
|
||||
*/
|
||||
public String getPattern();
|
||||
|
||||
|
@ -298,7 +298,28 @@ public final class ApplySpecialization extends NodeVisitor<LexicalContext> imple
|
||||
|
||||
@Override
|
||||
public boolean enterFunctionNode(final FunctionNode functionNode) {
|
||||
if (!USE_APPLY2CALL) {
|
||||
// Cheap tests first
|
||||
if (!(
|
||||
// is the transform globally enabled?
|
||||
USE_APPLY2CALL
|
||||
|
||||
// Are we compiling lazily? We can't known the number and types of the actual parameters at
|
||||
// the caller when compiling eagerly, so this only works with on-demand compilation.
|
||||
&& compiler.isOnDemandCompilation()
|
||||
|
||||
// Does the function even reference the "arguments" identifier (without redefining it)? If not,
|
||||
// it trivially can't have an expression of form "f.apply(self, arguments)" that this transform
|
||||
// is targeting.
|
||||
&& functionNode.needsArguments()
|
||||
|
||||
// Does the function have eval? If so, it can arbitrarily modify arguments so we can't touch it.
|
||||
&& !functionNode.hasEval()
|
||||
|
||||
// Finally, does the function declare any parameters explicitly? We don't support that. It could
|
||||
// be done, but has some complications. Therefore only a function with no explicit parameters
|
||||
// is considered.
|
||||
&& functionNode.getNumOfParams() == 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -308,18 +329,6 @@ public final class ApplySpecialization extends NodeVisitor<LexicalContext> imple
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!compiler.isOnDemandCompilation()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (functionNode.getNumOfParams() != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (functionNode.hasEval()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hasApplies(functionNode)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ final class AssignSymbols extends NodeVisitor<LexicalContext> implements Loggabl
|
||||
|
||||
/**
|
||||
* Creates a synthetic initializer for a variable (a var statement that doesn't occur in the source code). Typically
|
||||
* used to create assignmnent of {@code :callee} to the function name symbol in self-referential function
|
||||
* used to create assignment of {@code :callee} to the function name symbol in self-referential function
|
||||
* expressions as well as for assignment of {@code :arguments} to {@code arguments}.
|
||||
*
|
||||
* @param name the ident node identifying the variable to initialize
|
||||
|
@ -132,7 +132,6 @@ import jdk.nashorn.internal.ir.WithNode;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.objects.ScriptFunctionImpl;
|
||||
import jdk.nashorn.internal.parser.Lexer.RegexToken;
|
||||
import jdk.nashorn.internal.parser.TokenType;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
@ -195,9 +194,9 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
|
||||
"ensureNumber", double.class, Object.class, int.class);
|
||||
|
||||
private static final Call CREATE_FUNCTION_OBJECT = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class,
|
||||
private static final Call CREATE_FUNCTION_OBJECT = CompilerConstants.staticCallNoLookup(ScriptFunction.class,
|
||||
"create", ScriptFunction.class, Object[].class, int.class, ScriptObject.class);
|
||||
private static final Call CREATE_FUNCTION_OBJECT_NO_SCOPE = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class,
|
||||
private static final Call CREATE_FUNCTION_OBJECT_NO_SCOPE = CompilerConstants.staticCallNoLookup(ScriptFunction.class,
|
||||
"create", ScriptFunction.class, Object[].class, int.class);
|
||||
|
||||
private static final Call TO_NUMBER_FOR_EQ = CompilerConstants.staticCallNoLookup(JSType.class,
|
||||
@ -1495,7 +1494,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
int argsCount;
|
||||
@Override
|
||||
void loadStack() {
|
||||
/**
|
||||
/*
|
||||
* We want to load 'eval' to check if it is indeed global builtin eval.
|
||||
* If this eval call is inside a 'with' statement, dyn:getMethod|getProp|getElem
|
||||
* would be generated if ident is a "isFunction". But, that would result in a
|
||||
@ -4330,7 +4329,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
}
|
||||
|
||||
private void prologue() {
|
||||
/**
|
||||
/*
|
||||
* This loads the parts of the target, e.g base and index. they are kept
|
||||
* on the stack throughout the store and used at the end to execute it
|
||||
*/
|
||||
@ -4798,7 +4797,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
* conversion has no side effects.
|
||||
* @param name the name of the property being get
|
||||
* @param flags call site flags
|
||||
* @param isMethod whether we're preferrably retrieving a function
|
||||
* @param isMethod whether we're preferably retrieving a function
|
||||
* @return the current method emitter
|
||||
*/
|
||||
MethodEmitter dynamicGet(final String name, final int flags, final boolean isMethod, final boolean isIndex) {
|
||||
@ -5230,7 +5229,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
private Type returnValueType;
|
||||
// If we are in the middle of an object literal initialization, we need to update the map
|
||||
private PropertyMap objectLiteralMap;
|
||||
// Object literal stack depth for object literal - not necessarly top if property is a tree
|
||||
// Object literal stack depth for object literal - not necessarily top if property is a tree
|
||||
private int objectLiteralStackDepth = -1;
|
||||
// The line number at the continuation point
|
||||
private int lineNumber;
|
||||
@ -5395,7 +5394,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
method.load(lvarTypes.get(slot), slot);
|
||||
method.convert(stackTypes[i]);
|
||||
// stack: s0=object literal being initialized
|
||||
// change map of s0 so that the property we are initilizing when we failed
|
||||
// change map of s0 so that the property we are initializing when we failed
|
||||
// is now ci.returnValueType
|
||||
if (i == objectLiteralStackDepth) {
|
||||
method.dup();
|
||||
|
6
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilationPhase.java
6
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilationPhase.java
@ -591,8 +591,8 @@ enum CompilationPhase {
|
||||
Class<?> rootClass = null;
|
||||
long length = 0L;
|
||||
|
||||
final CodeInstaller<ScriptEnvironment> codeInstaller = compiler.getCodeInstaller();
|
||||
final Map<String, byte[]> bytecode = compiler.getBytecode();
|
||||
final CodeInstaller codeInstaller = compiler.getCodeInstaller();
|
||||
final Map<String, byte[]> bytecode = compiler.getBytecode();
|
||||
|
||||
for (final Entry<String, byte[]> entry : bytecode.entrySet()) {
|
||||
final String className = entry.getKey();
|
||||
@ -745,7 +745,7 @@ enum CompilationPhase {
|
||||
abstract FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode functionNode) throws CompilationException;
|
||||
|
||||
/**
|
||||
* Apply a transform to a function node, returning the transfored function node. If the transform is not
|
||||
* Apply a transform to a function node, returning the transformed function node. If the transform is not
|
||||
* applicable, an exception is thrown. Every transform requires the function to have a certain number of
|
||||
* states to operate. It can have more states set, but not fewer. The state list, i.e. the constructor
|
||||
* arguments to any of the CompilationPhase enum entries, is a set of REQUIRED states.
|
||||
|
@ -101,7 +101,7 @@ public final class Compiler implements Loggable {
|
||||
|
||||
private final ConstantData constantData;
|
||||
|
||||
private final CodeInstaller<ScriptEnvironment> installer;
|
||||
private final CodeInstaller installer;
|
||||
|
||||
/** logger for compiler, trampolines and related code generation events
|
||||
* that affect classes */
|
||||
@ -352,47 +352,83 @@ public final class Compiler implements Loggable {
|
||||
private static final AtomicInteger COMPILATION_ID = new AtomicInteger(0);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Creates a new compiler instance for initial compilation of a script.
|
||||
*
|
||||
* @param context context
|
||||
* @param env script environment
|
||||
* @param installer code installer
|
||||
* @param source source to compile
|
||||
* @param errors error manager
|
||||
* @param isStrict is this a strict compilation
|
||||
* @return a new compiler
|
||||
*/
|
||||
public Compiler(
|
||||
final Context context,
|
||||
final ScriptEnvironment env,
|
||||
final CodeInstaller<ScriptEnvironment> installer,
|
||||
public static Compiler forInitialCompilation(
|
||||
final CodeInstaller installer,
|
||||
final Source source,
|
||||
final ErrorManager errors,
|
||||
final boolean isStrict) {
|
||||
this(context, env, installer, source, errors, isStrict, false, null, null, null, null, null, null);
|
||||
return new Compiler(installer.getContext(), installer, source, errors, isStrict);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Creates a compiler without a code installer. It can only be used to compile code, not install the
|
||||
* generated classes and as such it is useful only for implementation of {@code --compile-only} command
|
||||
* line option.
|
||||
* @param context the current context
|
||||
* @param source source to compile
|
||||
* @param isStrict is this a strict compilation
|
||||
* @return a new compiler
|
||||
*/
|
||||
public static Compiler forNoInstallerCompilation(
|
||||
final Context context,
|
||||
final Source source,
|
||||
final boolean isStrict) {
|
||||
return new Compiler(context, null, source, context.getErrorManager(), isStrict);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a compiler for an on-demand compilation job.
|
||||
*
|
||||
* @param context context
|
||||
* @param env script environment
|
||||
* @param installer code installer
|
||||
* @param source source to compile
|
||||
* @param errors error manager
|
||||
* @param isStrict is this a strict compilation
|
||||
* @param isOnDemand is this an on demand compilation
|
||||
* @param compiledFunction compiled function, if any
|
||||
* @param types parameter and return value type information, if any is known
|
||||
* @param invalidatedProgramPoints invalidated program points for recompilation
|
||||
* @param typeInformationFile descriptor of the location where type information is persisted
|
||||
* @param continuationEntryPoints continuation entry points for restof method
|
||||
* @param runtimeScope runtime scope for recompilation type lookup in {@code TypeEvaluator}
|
||||
* @return a new compiler
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public Compiler(
|
||||
public static Compiler forOnDemandCompilation(
|
||||
final CodeInstaller installer,
|
||||
final Source source,
|
||||
final boolean isStrict,
|
||||
final RecompilableScriptFunctionData compiledFunction,
|
||||
final TypeMap types,
|
||||
final Map<Integer, Type> invalidatedProgramPoints,
|
||||
final Object typeInformationFile,
|
||||
final int[] continuationEntryPoints,
|
||||
final ScriptObject runtimeScope) {
|
||||
final Context context = installer.getContext();
|
||||
return new Compiler(context, installer, source, context.getErrorManager(), isStrict, true,
|
||||
compiledFunction, types, invalidatedProgramPoints, typeInformationFile,
|
||||
continuationEntryPoints, runtimeScope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor for non on-demand compiler instances.
|
||||
*/
|
||||
private Compiler(
|
||||
final Context context,
|
||||
final ScriptEnvironment env,
|
||||
final CodeInstaller<ScriptEnvironment> installer,
|
||||
final CodeInstaller installer,
|
||||
final Source source,
|
||||
final ErrorManager errors,
|
||||
final boolean isStrict) {
|
||||
this(context, installer, source, errors, isStrict, false, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
private Compiler(
|
||||
final Context context,
|
||||
final CodeInstaller installer,
|
||||
final Source source,
|
||||
final ErrorManager errors,
|
||||
final boolean isStrict,
|
||||
@ -404,7 +440,7 @@ public final class Compiler implements Loggable {
|
||||
final int[] continuationEntryPoints,
|
||||
final ScriptObject runtimeScope) {
|
||||
this.context = context;
|
||||
this.env = env;
|
||||
this.env = context.getEnv();
|
||||
this.installer = installer;
|
||||
this.constantData = new ConstantData();
|
||||
this.compileUnits = CompileUnit.createCompileUnitSet();
|
||||
@ -416,7 +452,7 @@ public final class Compiler implements Loggable {
|
||||
this.onDemand = isOnDemand;
|
||||
this.compiledFunction = compiledFunction;
|
||||
this.types = types;
|
||||
this.invalidatedProgramPoints = invalidatedProgramPoints == null ? new HashMap<Integer, Type>() : invalidatedProgramPoints;
|
||||
this.invalidatedProgramPoints = invalidatedProgramPoints == null ? new HashMap<>() : invalidatedProgramPoints;
|
||||
this.typeInformationFile = typeInformationFile;
|
||||
this.continuationEntryPoints = continuationEntryPoints == null ? null: continuationEntryPoints.clone();
|
||||
this.typeEvaluator = new TypeEvaluator(this, runtimeScope);
|
||||
@ -426,7 +462,7 @@ public final class Compiler implements Loggable {
|
||||
this.optimistic = env._optimistic_types;
|
||||
}
|
||||
|
||||
private static String safeSourceName(final ScriptEnvironment env, final CodeInstaller<ScriptEnvironment> installer, final Source source) {
|
||||
private String safeSourceName() {
|
||||
String baseName = new File(source.getName()).getName();
|
||||
|
||||
final int index = baseName.lastIndexOf(".js");
|
||||
@ -485,7 +521,7 @@ public final class Compiler implements Loggable {
|
||||
sb.append('$');
|
||||
}
|
||||
|
||||
sb.append(Compiler.safeSourceName(env, installer, source));
|
||||
sb.append(safeSourceName());
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
@ -684,7 +720,7 @@ public final class Compiler implements Loggable {
|
||||
return constantData;
|
||||
}
|
||||
|
||||
CodeInstaller<ScriptEnvironment> getCodeInstaller() {
|
||||
CodeInstaller getCodeInstaller() {
|
||||
return installer;
|
||||
}
|
||||
|
||||
|
4
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilerConstants.java
4
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilerConstants.java
@ -192,7 +192,7 @@ public enum CompilerConstants {
|
||||
private static Set<String> symbolNames;
|
||||
|
||||
/**
|
||||
* Prefix used for internal methods generated in script clases.
|
||||
* Prefix used for internal methods generated in script classes.
|
||||
*/
|
||||
private static final String INTERNAL_METHOD_PREFIX = ":";
|
||||
|
||||
@ -225,7 +225,7 @@ public enum CompilerConstants {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a name is that of a reserved compiler constnat
|
||||
* Check whether a name is that of a reserved compiler constant
|
||||
* @param name name
|
||||
* @return true if compiler constant name
|
||||
*/
|
||||
|
@ -447,7 +447,7 @@ public final class Label implements Serializable {
|
||||
undefineLocalVariables(liveLocalCount, true);
|
||||
// Temporaries are promoted
|
||||
firstTemp = liveLocalCount;
|
||||
// No trailing undefineds
|
||||
// No trailing undefined values
|
||||
localVariableTypes.subList(firstTemp, localVariableTypes.size()).clear();
|
||||
assert symbolBoundary.length() == firstTemp;
|
||||
// Generalize all reference types to Object, and promote boolean to int
|
||||
|
@ -521,7 +521,7 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Lo
|
||||
}
|
||||
|
||||
/*
|
||||
* create a new trynode
|
||||
* create a new try node
|
||||
* if we have catches:
|
||||
*
|
||||
* try try
|
||||
@ -532,7 +532,7 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Lo
|
||||
* catchall
|
||||
* rethrow
|
||||
*
|
||||
* otheriwse
|
||||
* otherwise
|
||||
*
|
||||
* try try
|
||||
* x x
|
||||
|
@ -1158,7 +1158,7 @@ public class MethodEmitter {
|
||||
/**
|
||||
* Pop a value from the stack and store it in a variable denoted by the given symbol. The variable should be either
|
||||
* a local variable, or a function parameter (and not a scoped variable). For local variables, this method will also
|
||||
* do the bookeeping of the local variable table as well as mark values in all alternative slots for the symbol as
|
||||
* do the bookkeeping of the local variable table as well as mark values in all alternative slots for the symbol as
|
||||
* dead. In this regard it differs from {@link #storeHidden(Type, int)}.
|
||||
*
|
||||
* @param symbol the symbol to store into.
|
||||
|
@ -786,7 +786,7 @@ public final class ObjectClassGenerator implements Loggable {
|
||||
* @param primitiveSetter primitive setter for the current type with an element of the current type
|
||||
* @param objectSetter the object setter
|
||||
*
|
||||
* @return method handle that checks if the element to be set is of the currenttype, even though it's boxed
|
||||
* @return method handle that checks if the element to be set is of the current type, even though it's boxed
|
||||
* and instead of using the generic object setter, that would blow up the type and invalidate the map,
|
||||
* unbox it and call the primitive setter instead
|
||||
*/
|
||||
|
2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/BytecodeOps.java
2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/BytecodeOps.java
@ -36,7 +36,7 @@ import jdk.internal.org.objectweb.asm.MethodVisitor;
|
||||
* The bytecode ops are coupled to a MethodVisitor from ASM for
|
||||
* byte code generation. They know nothing about our MethodGenerator,
|
||||
* which is the abstraction for working with Nashorn JS types
|
||||
* For exmaple, anything like "two or one slots" for a type, which
|
||||
* For example, anything like "two or one slots" for a type, which
|
||||
* is represented in bytecode and ASM, is abstracted away in the
|
||||
* MethodGenerator. There you just say "dup" or "store".
|
||||
*
|
||||
|
@ -34,7 +34,7 @@ import java.util.List;
|
||||
* This is a subclass of lexical context used for filling
|
||||
* blocks (and function nodes) with statements. When popping
|
||||
* a block from the lexical context, any statements that have
|
||||
* been generated in it are commited to the block. This saves
|
||||
* been generated in it are committed to the block. This saves
|
||||
* unnecessary object mutations and lexical context replacement
|
||||
*/
|
||||
public class BlockLexicalContext extends LexicalContext {
|
||||
|
@ -452,7 +452,7 @@ public abstract class LiteralNode<T> extends Expression implements PropertyKey {
|
||||
*
|
||||
* @param token token
|
||||
* @param finish finish
|
||||
* @param value undefined value, passed only for polymorphisism discrimination
|
||||
* @param value undefined value, passed only for polymorphism discrimination
|
||||
*
|
||||
* @return the new literal node
|
||||
*/
|
||||
|
@ -276,7 +276,7 @@ public class RuntimeNode extends Expression {
|
||||
*
|
||||
* @param request a request
|
||||
*
|
||||
* @return the inverted rquest, or null if not applicable
|
||||
* @return the inverted request, or null if not applicable
|
||||
*/
|
||||
public static Request invert(final Request request) {
|
||||
switch (request) {
|
||||
|
@ -36,7 +36,7 @@ import jdk.internal.org.objectweb.asm.Label;
|
||||
import jdk.nashorn.internal.ir.debug.NashornTextifier.NashornLabel;
|
||||
|
||||
/**
|
||||
* Subclass of the ASM classs reader that retains more info, such
|
||||
* Subclass of the ASM class reader that retains more info, such
|
||||
* as bytecode offsets
|
||||
*/
|
||||
public class NashornClassReader extends ClassReader {
|
||||
|
@ -193,7 +193,7 @@ public final class ObjectSizeCalculator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class histograpm
|
||||
* Get the class histogram
|
||||
* @return class histogram element list
|
||||
*/
|
||||
public List<ClassHistogramElement> getClassHistogram() {
|
||||
|
@ -192,7 +192,7 @@ public abstract class ArrayBufferView extends ScriptObject {
|
||||
/**
|
||||
* Factory method for array data
|
||||
*
|
||||
* @param nb underlying nativebuffer
|
||||
* @param nb underlying native buffer
|
||||
* @param start start element
|
||||
* @param end end element
|
||||
*
|
||||
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package jdk.nashorn.internal.objects;
|
||||
|
||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import jdk.nashorn.internal.runtime.ScriptFunctionData;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
|
||||
/**
|
||||
* A {@code ScriptFunctionImpl} subclass for functions created using {@code Function.prototype.bind}. Such functions
|
||||
* must track their {@code [[TargetFunction]]} property for purposes of correctly implementing {@code [[HasInstance]]};
|
||||
* see {@link ScriptFunction#isInstance(ScriptObject)}.
|
||||
*/
|
||||
final class BoundScriptFunctionImpl extends ScriptFunctionImpl {
|
||||
private final ScriptFunction targetFunction;
|
||||
|
||||
BoundScriptFunctionImpl(final ScriptFunctionData data, final ScriptFunction targetFunction) {
|
||||
super(data, Global.instance());
|
||||
setPrototype(ScriptRuntime.UNDEFINED);
|
||||
this.targetFunction = targetFunction;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ScriptFunction getTargetFunction() {
|
||||
return targetFunction;
|
||||
}
|
||||
}
|
@ -1583,7 +1583,11 @@ public final class Global extends Scope {
|
||||
return ScriptFunction.getPrototype(builtinObject);
|
||||
}
|
||||
|
||||
ScriptObject getFunctionPrototype() {
|
||||
/**
|
||||
* Get the builtin Function prototype.
|
||||
* @return the Function.prototype.
|
||||
*/
|
||||
public ScriptObject getFunctionPrototype() {
|
||||
return ScriptFunction.getPrototype(builtinFunction);
|
||||
}
|
||||
|
||||
@ -1768,7 +1772,12 @@ public final class Global extends Scope {
|
||||
return ScriptFunction.getPrototype(getBuiltinFloat64Array());
|
||||
}
|
||||
|
||||
ScriptFunction getTypeErrorThrower() {
|
||||
/**
|
||||
* Return the function that throws TypeError unconditionally. Used as "poison" methods for certain Function properties.
|
||||
*
|
||||
* @return the TypeError throwing function
|
||||
*/
|
||||
public ScriptFunction getTypeErrorThrower() {
|
||||
return typeErrorThrower;
|
||||
}
|
||||
|
||||
@ -2157,7 +2166,7 @@ public final class Global extends Scope {
|
||||
|
||||
// We want to avoid adding our generic lexical scope switchpoint to global constant invocations,
|
||||
// because those are invalidated per-key in the addBoundProperties method above.
|
||||
// We therefor check if the invocation does already have a switchpoint and the property is non-inherited,
|
||||
// We therefore check if the invocation does already have a switchpoint and the property is non-inherited,
|
||||
// assuming this only applies to global constants. If other non-inherited properties will
|
||||
// start using switchpoints some time in the future we'll have to revisit this.
|
||||
if (isScope && context.getEnv()._es6 && (invocation.getSwitchPoints() == null || !hasOwnProperty(name))) {
|
||||
@ -2202,10 +2211,10 @@ public final class Global extends Scope {
|
||||
* Adds jjs shell interactive mode builtin functions to global scope.
|
||||
*/
|
||||
public void addShellBuiltins() {
|
||||
Object value = ScriptFunctionImpl.makeFunction("input", ShellFunctions.INPUT);
|
||||
Object value = ScriptFunction.createBuiltin("input", ShellFunctions.INPUT);
|
||||
addOwnProperty("input", Attribute.NOT_ENUMERABLE, value);
|
||||
|
||||
value = ScriptFunctionImpl.makeFunction("evalinput", ShellFunctions.EVALINPUT);
|
||||
value = ScriptFunction.createBuiltin("evalinput", ShellFunctions.EVALINPUT);
|
||||
addOwnProperty("evalinput", Attribute.NOT_ENUMERABLE, value);
|
||||
}
|
||||
|
||||
@ -2251,35 +2260,35 @@ public final class Global extends Scope {
|
||||
this.setInitialProto(getObjectPrototype());
|
||||
|
||||
// initialize global function properties
|
||||
this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL);
|
||||
this.eval = this.builtinEval = ScriptFunction.createBuiltin("eval", EVAL);
|
||||
|
||||
this.parseInt = ScriptFunctionImpl.makeFunction("parseInt", GlobalFunctions.PARSEINT,
|
||||
this.parseInt = ScriptFunction.createBuiltin("parseInt", GlobalFunctions.PARSEINT,
|
||||
new Specialization[] {
|
||||
new Specialization(GlobalFunctions.PARSEINT_Z),
|
||||
new Specialization(GlobalFunctions.PARSEINT_I),
|
||||
new Specialization(GlobalFunctions.PARSEINT_J),
|
||||
new Specialization(GlobalFunctions.PARSEINT_OI),
|
||||
new Specialization(GlobalFunctions.PARSEINT_O) });
|
||||
this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
|
||||
this.isNaN = ScriptFunctionImpl.makeFunction("isNaN", GlobalFunctions.IS_NAN,
|
||||
this.parseFloat = ScriptFunction.createBuiltin("parseFloat", GlobalFunctions.PARSEFLOAT);
|
||||
this.isNaN = ScriptFunction.createBuiltin("isNaN", GlobalFunctions.IS_NAN,
|
||||
new Specialization[] {
|
||||
new Specialization(GlobalFunctions.IS_NAN_I),
|
||||
new Specialization(GlobalFunctions.IS_NAN_J),
|
||||
new Specialization(GlobalFunctions.IS_NAN_D) });
|
||||
this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
|
||||
this.isNaN = ScriptFunctionImpl.makeFunction("isNaN", GlobalFunctions.IS_NAN);
|
||||
this.isFinite = ScriptFunctionImpl.makeFunction("isFinite", GlobalFunctions.IS_FINITE);
|
||||
this.encodeURI = ScriptFunctionImpl.makeFunction("encodeURI", GlobalFunctions.ENCODE_URI);
|
||||
this.encodeURIComponent = ScriptFunctionImpl.makeFunction("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
|
||||
this.decodeURI = ScriptFunctionImpl.makeFunction("decodeURI", GlobalFunctions.DECODE_URI);
|
||||
this.decodeURIComponent = ScriptFunctionImpl.makeFunction("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
|
||||
this.escape = ScriptFunctionImpl.makeFunction("escape", GlobalFunctions.ESCAPE);
|
||||
this.unescape = ScriptFunctionImpl.makeFunction("unescape", GlobalFunctions.UNESCAPE);
|
||||
this.print = ScriptFunctionImpl.makeFunction("print", env._print_no_newline ? PRINT : PRINTLN);
|
||||
this.load = ScriptFunctionImpl.makeFunction("load", LOAD);
|
||||
this.loadWithNewGlobal = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOAD_WITH_NEW_GLOBAL);
|
||||
this.exit = ScriptFunctionImpl.makeFunction("exit", EXIT);
|
||||
this.quit = ScriptFunctionImpl.makeFunction("quit", EXIT);
|
||||
this.parseFloat = ScriptFunction.createBuiltin("parseFloat", GlobalFunctions.PARSEFLOAT);
|
||||
this.isNaN = ScriptFunction.createBuiltin("isNaN", GlobalFunctions.IS_NAN);
|
||||
this.isFinite = ScriptFunction.createBuiltin("isFinite", GlobalFunctions.IS_FINITE);
|
||||
this.encodeURI = ScriptFunction.createBuiltin("encodeURI", GlobalFunctions.ENCODE_URI);
|
||||
this.encodeURIComponent = ScriptFunction.createBuiltin("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
|
||||
this.decodeURI = ScriptFunction.createBuiltin("decodeURI", GlobalFunctions.DECODE_URI);
|
||||
this.decodeURIComponent = ScriptFunction.createBuiltin("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
|
||||
this.escape = ScriptFunction.createBuiltin("escape", GlobalFunctions.ESCAPE);
|
||||
this.unescape = ScriptFunction.createBuiltin("unescape", GlobalFunctions.UNESCAPE);
|
||||
this.print = ScriptFunction.createBuiltin("print", env._print_no_newline ? PRINT : PRINTLN);
|
||||
this.load = ScriptFunction.createBuiltin("load", LOAD);
|
||||
this.loadWithNewGlobal = ScriptFunction.createBuiltin("loadWithNewGlobal", LOAD_WITH_NEW_GLOBAL);
|
||||
this.exit = ScriptFunction.createBuiltin("exit", EXIT);
|
||||
this.quit = ScriptFunction.createBuiltin("quit", EXIT);
|
||||
|
||||
// built-in constructors
|
||||
this.builtinArray = initConstructorAndSwitchPoint("Array", ScriptFunction.class);
|
||||
@ -2359,7 +2368,7 @@ public final class Global extends Scope {
|
||||
// default file name
|
||||
addOwnProperty(ScriptEngine.FILENAME, Attribute.NOT_ENUMERABLE, null);
|
||||
// __noSuchProperty__ hook for ScriptContext search of missing variables
|
||||
final ScriptFunction noSuchProp = ScriptFunctionImpl.makeStrictFunction(NO_SUCH_PROPERTY_NAME, NO_SUCH_PROPERTY);
|
||||
final ScriptFunction noSuchProp = ScriptFunction.createStrictBuiltin(NO_SUCH_PROPERTY_NAME, NO_SUCH_PROPERTY);
|
||||
addOwnProperty(NO_SUCH_PROPERTY_NAME, Attribute.NOT_ENUMERABLE, noSuchProp);
|
||||
}
|
||||
}
|
||||
@ -2370,17 +2379,17 @@ public final class Global extends Scope {
|
||||
final ScriptObject errorProto = getErrorPrototype();
|
||||
|
||||
// Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
|
||||
final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", NativeError.GET_STACK);
|
||||
final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", NativeError.SET_STACK);
|
||||
final ScriptFunction getStack = ScriptFunction.createBuiltin("getStack", NativeError.GET_STACK);
|
||||
final ScriptFunction setStack = ScriptFunction.createBuiltin("setStack", NativeError.SET_STACK);
|
||||
errorProto.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
|
||||
final ScriptFunction getLineNumber = ScriptFunctionImpl.makeFunction("getLineNumber", NativeError.GET_LINENUMBER);
|
||||
final ScriptFunction setLineNumber = ScriptFunctionImpl.makeFunction("setLineNumber", NativeError.SET_LINENUMBER);
|
||||
final ScriptFunction getLineNumber = ScriptFunction.createBuiltin("getLineNumber", NativeError.GET_LINENUMBER);
|
||||
final ScriptFunction setLineNumber = ScriptFunction.createBuiltin("setLineNumber", NativeError.SET_LINENUMBER);
|
||||
errorProto.addOwnProperty("lineNumber", Attribute.NOT_ENUMERABLE, getLineNumber, setLineNumber);
|
||||
final ScriptFunction getColumnNumber = ScriptFunctionImpl.makeFunction("getColumnNumber", NativeError.GET_COLUMNNUMBER);
|
||||
final ScriptFunction setColumnNumber = ScriptFunctionImpl.makeFunction("setColumnNumber", NativeError.SET_COLUMNNUMBER);
|
||||
final ScriptFunction getColumnNumber = ScriptFunction.createBuiltin("getColumnNumber", NativeError.GET_COLUMNNUMBER);
|
||||
final ScriptFunction setColumnNumber = ScriptFunction.createBuiltin("setColumnNumber", NativeError.SET_COLUMNNUMBER);
|
||||
errorProto.addOwnProperty("columnNumber", Attribute.NOT_ENUMERABLE, getColumnNumber, setColumnNumber);
|
||||
final ScriptFunction getFileName = ScriptFunctionImpl.makeFunction("getFileName", NativeError.GET_FILENAME);
|
||||
final ScriptFunction setFileName = ScriptFunctionImpl.makeFunction("setFileName", NativeError.SET_FILENAME);
|
||||
final ScriptFunction getFileName = ScriptFunction.createBuiltin("getFileName", NativeError.GET_FILENAME);
|
||||
final ScriptFunction setFileName = ScriptFunction.createBuiltin("setFileName", NativeError.SET_FILENAME);
|
||||
errorProto.addOwnProperty("fileName", Attribute.NOT_ENUMERABLE, getFileName, setFileName);
|
||||
|
||||
// ECMA 15.11.4.2 Error.prototype.name
|
||||
@ -2420,14 +2429,14 @@ public final class Global extends Scope {
|
||||
|
||||
private void initScripting(final ScriptEnvironment scriptEnv) {
|
||||
ScriptObject value;
|
||||
value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE);
|
||||
value = ScriptFunction.createBuiltin("readLine", ScriptingFunctions.READLINE);
|
||||
addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value);
|
||||
|
||||
value = ScriptFunctionImpl.makeFunction("readFully", ScriptingFunctions.READFULLY);
|
||||
value = ScriptFunction.createBuiltin("readFully", ScriptingFunctions.READFULLY);
|
||||
addOwnProperty("readFully", Attribute.NOT_ENUMERABLE, value);
|
||||
|
||||
final String execName = ScriptingFunctions.EXEC_NAME;
|
||||
value = ScriptFunctionImpl.makeFunction(execName, ScriptingFunctions.EXEC);
|
||||
value = ScriptFunction.createBuiltin(execName, ScriptingFunctions.EXEC);
|
||||
value.addOwnProperty(ScriptingFunctions.THROW_ON_ERROR_NAME, Attribute.NOT_ENUMERABLE, false);
|
||||
|
||||
addOwnProperty(execName, Attribute.NOT_ENUMERABLE, value);
|
||||
@ -2610,7 +2619,7 @@ public final class Global extends Scope {
|
||||
this.builtinFunction = initConstructor("Function", ScriptFunction.class);
|
||||
|
||||
// create global anonymous function
|
||||
final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction();
|
||||
final ScriptFunction anon = ScriptFunction.createAnonymous();
|
||||
// need to copy over members of Function.prototype to anon function
|
||||
anon.addBoundProperties(getFunctionPrototype());
|
||||
|
||||
@ -2622,10 +2631,7 @@ public final class Global extends Scope {
|
||||
anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
|
||||
|
||||
// use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
|
||||
this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, 0);
|
||||
typeErrorThrower.setPrototype(UNDEFINED);
|
||||
// Non-constructor built-in functions do not have "prototype" property
|
||||
typeErrorThrower.deleteOwnProperty(typeErrorThrower.getMap().findProperty("prototype"));
|
||||
this.typeErrorThrower = ScriptFunction.createBuiltin("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER);
|
||||
typeErrorThrower.preventExtensions();
|
||||
|
||||
// now initialize Object
|
||||
@ -2636,8 +2642,8 @@ public final class Global extends Scope {
|
||||
|
||||
// ES6 draft compliant __proto__ property of Object.prototype
|
||||
// accessors on Object.prototype for "__proto__"
|
||||
final ScriptFunction getProto = ScriptFunctionImpl.makeFunction("getProto", NativeObject.GET__PROTO__);
|
||||
final ScriptFunction setProto = ScriptFunctionImpl.makeFunction("setProto", NativeObject.SET__PROTO__);
|
||||
final ScriptFunction getProto = ScriptFunction.createBuiltin("getProto", NativeObject.GET__PROTO__);
|
||||
final ScriptFunction setProto = ScriptFunction.createBuiltin("setProto", NativeObject.SET__PROTO__);
|
||||
ObjectPrototype.addOwnProperty("__proto__", Attribute.NOT_ENUMERABLE, getProto, setProto);
|
||||
|
||||
// Function valued properties of Function.prototype were not properly
|
||||
|
@ -26,6 +26,7 @@
|
||||
package jdk.nashorn.internal.objects;
|
||||
|
||||
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Objects;
|
||||
@ -246,7 +247,7 @@ public final class NativeDebug extends ScriptObject {
|
||||
final PrintWriter out = Context.getCurrentErr();
|
||||
|
||||
out.println("ScriptObject count " + ScriptObject.getCount());
|
||||
out.println("Scope count " + Scope.getCount());
|
||||
out.println("Scope count " + Scope.getScopeCount());
|
||||
out.println("ScriptObject listeners added " + PropertyListeners.getListenersAdded());
|
||||
out.println("ScriptObject listeners removed " + PropertyListeners.getListenersRemoved());
|
||||
out.println("ScriptFunction constructor calls " + ScriptFunction.getConstructorCount());
|
||||
|
@ -148,8 +148,8 @@ public final class NativeError extends ScriptObject {
|
||||
initException(sobj);
|
||||
sobj.delete(STACK, false);
|
||||
if (! sobj.has("stack")) {
|
||||
final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", GET_STACK);
|
||||
final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", SET_STACK);
|
||||
final ScriptFunction getStack = ScriptFunction.createBuiltin("getStack", GET_STACK);
|
||||
final ScriptFunction setStack = ScriptFunction.createBuiltin("setStack", SET_STACK);
|
||||
sobj.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
|
||||
}
|
||||
return UNDEFINED;
|
||||
|
@ -621,11 +621,11 @@ public final class NativeJSAdapter extends ScriptObject {
|
||||
if (find != null) {
|
||||
final Object value = find.getObjectValue();
|
||||
if (value instanceof ScriptFunction) {
|
||||
final ScriptFunctionImpl func = (ScriptFunctionImpl)value;
|
||||
final ScriptFunction func = (ScriptFunction)value;
|
||||
// TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
|
||||
// to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
|
||||
return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
|
||||
func.makeBoundFunction(this, new Object[] { name })), 0, Object.class),
|
||||
func.createBound(this, new Object[] { name })), 0, Object.class),
|
||||
testJSAdaptor(adaptee, null, null, null),
|
||||
adaptee.getProtoSwitchPoint(__call__, find.getOwner()));
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ 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) {
|
||||
if (func instanceof ScriptFunction) {
|
||||
return ((ScriptFunction)func).makeSynchronizedFunction(obj);
|
||||
return ((ScriptFunction)func).createSynchronized(obj);
|
||||
}
|
||||
|
||||
throw typeError("not.a.function", ScriptRuntime.safeToString(func));
|
||||
|
@ -33,6 +33,7 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
@ -187,6 +188,7 @@ public final class NativeNumber extends ScriptObject {
|
||||
format.setMinimumFractionDigits(fractionDigits);
|
||||
format.setMaximumFractionDigits(fractionDigits);
|
||||
format.setGroupingUsed(false);
|
||||
format.setRoundingMode(RoundingMode.HALF_UP);
|
||||
|
||||
return format.format(x);
|
||||
}
|
||||
|
@ -728,7 +728,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
*
|
||||
* $$ -> $
|
||||
* $& -> the matched substring
|
||||
* $` -> the portion of string that preceeds matched substring
|
||||
* $` -> the portion of string that precedes matched substring
|
||||
* $' -> the portion of string that follows the matched substring
|
||||
* $n -> the nth capture, where n is [1-9] and $n is NOT followed by a decimal digit
|
||||
* $nn -> the nnth capture, where nn is a two digit decimal number [01-99].
|
||||
|
313
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
313
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
@ -1,313 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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.util.ArrayList;
|
||||
import jdk.nashorn.internal.runtime.AccessorProperty;
|
||||
import jdk.nashorn.internal.runtime.GlobalFunctions;
|
||||
import jdk.nashorn.internal.runtime.Property;
|
||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
|
||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import jdk.nashorn.internal.runtime.ScriptFunctionData;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.Specialization;
|
||||
|
||||
/**
|
||||
* Concrete implementation of ScriptFunction. This sets correct map for the
|
||||
* function objects -- to expose properties like "prototype", "length" etc.
|
||||
*/
|
||||
public class ScriptFunctionImpl extends ScriptFunction {
|
||||
|
||||
/** Reference to constructor prototype. */
|
||||
private Object prototype;
|
||||
|
||||
// property map for strict mode functions
|
||||
private static final PropertyMap strictmodemap$;
|
||||
// property map for bound functions
|
||||
private static final PropertyMap boundfunctionmap$;
|
||||
// property map for non-strict, non-bound functions.
|
||||
private static final PropertyMap map$;
|
||||
|
||||
// Marker object for lazily initialized prototype object
|
||||
private static final Object LAZY_PROTOTYPE = new Object();
|
||||
|
||||
private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final Specialization[] specs, final Global global) {
|
||||
super(name, invokeHandle, map$, null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
|
||||
init(global);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called by Nasgen generated code, no membercount, use the default map.
|
||||
* Creates builtin functions only.
|
||||
*
|
||||
* @param name name of function
|
||||
* @param invokeHandle handle for invocation
|
||||
* @param specs specialized versions of this method, if available, null otherwise
|
||||
*/
|
||||
ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final Specialization[] specs) {
|
||||
this(name, invokeHandle, specs, Global.instance());
|
||||
}
|
||||
|
||||
private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs, final Global global) {
|
||||
super(name, invokeHandle, map.addAll(map$), null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
|
||||
init(global);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called by Nasgen generated code, no membercount, use the map passed as argument.
|
||||
* Creates builtin functions only.
|
||||
*
|
||||
* @param name name of function
|
||||
* @param invokeHandle handle for invocation
|
||||
* @param map initial property map
|
||||
* @param specs specialized versions of this method, if available, null otherwise
|
||||
*/
|
||||
ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs) {
|
||||
this(name, invokeHandle, map, specs, Global.instance());
|
||||
}
|
||||
|
||||
private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final Specialization[] specs, final int flags, final Global global) {
|
||||
super(name, methodHandle, getMap(isStrict(flags)), scope, specs, flags);
|
||||
init(global);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called by Global.newScriptFunction (runtime).
|
||||
*
|
||||
* @param name name of function
|
||||
* @param methodHandle handle for invocation
|
||||
* @param scope scope object
|
||||
* @param specs specialized versions of this method, if available, null otherwise
|
||||
* @param flags {@link ScriptFunctionData} flags
|
||||
*/
|
||||
ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final Specialization[] specs, final int flags) {
|
||||
this(name, methodHandle, scope, specs, flags, Global.instance());
|
||||
}
|
||||
|
||||
private ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope, final Global global) {
|
||||
super(data, getMap(data.isStrict()), scope);
|
||||
init(global);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method called by compiler generated code for functions that need parent scope.
|
||||
*
|
||||
* @param constants the generated class' constant array
|
||||
* @param index the index of the {@code RecompilableScriptFunctionData} object in the constants array.
|
||||
* @param scope the parent scope object
|
||||
* @return a newly created function object
|
||||
*/
|
||||
public static ScriptFunction create(final Object[] constants, final int index, final ScriptObject scope) {
|
||||
return new ScriptFunctionImpl((RecompilableScriptFunctionData)constants[index], scope, Global.instance());
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method called by compiler generated code for functions that don't need parent scope.
|
||||
*
|
||||
* @param constants the generated class' constant array
|
||||
* @param index the index of the {@code RecompilableScriptFunctionData} object in the constants array.
|
||||
* @return a newly created function object
|
||||
*/
|
||||
public static ScriptFunction create(final Object[] constants, final int index) {
|
||||
return create(constants, index, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only invoked internally from {@link BoundScriptFunctionImpl} constructor.
|
||||
* @param data the script function data for the bound function.
|
||||
* @param global the global object
|
||||
*/
|
||||
ScriptFunctionImpl(final ScriptFunctionData data, final Global global) {
|
||||
super(data, boundfunctionmap$, null);
|
||||
init(global);
|
||||
}
|
||||
|
||||
static {
|
||||
final ArrayList<Property> properties = new ArrayList<>(3);
|
||||
properties.add(AccessorProperty.create("prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE));
|
||||
properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null));
|
||||
properties.add(AccessorProperty.create("name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null));
|
||||
map$ = PropertyMap.newMap(properties);
|
||||
strictmodemap$ = createStrictModeMap(map$);
|
||||
boundfunctionmap$ = createBoundFunctionMap(strictmodemap$);
|
||||
}
|
||||
|
||||
private static PropertyMap createStrictModeMap(final PropertyMap map) {
|
||||
final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
|
||||
PropertyMap newMap = map;
|
||||
// Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
|
||||
newMap = newMap.addPropertyNoHistory(map.newUserAccessors("arguments", flags));
|
||||
newMap = newMap.addPropertyNoHistory(map.newUserAccessors("caller", flags));
|
||||
return newMap;
|
||||
}
|
||||
|
||||
private static boolean isStrict(final int flags) {
|
||||
return (flags & ScriptFunctionData.IS_STRICT) != 0;
|
||||
}
|
||||
|
||||
// Choose the map based on strict mode!
|
||||
private static PropertyMap getMap(final boolean strict) {
|
||||
return strict ? strictmodemap$ : map$;
|
||||
}
|
||||
|
||||
private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
|
||||
// Bound function map is same as strict function map, but additionally lacks the "prototype" property, see
|
||||
// ECMAScript 5.1 section 15.3.4.5
|
||||
return strictModeMap.deleteProperty(strictModeMap.findProperty("prototype"));
|
||||
}
|
||||
|
||||
// Instance of this class is used as global anonymous function which
|
||||
// serves as Function.prototype object.
|
||||
private static class AnonymousFunction extends ScriptFunctionImpl {
|
||||
private static final PropertyMap anonmap$ = PropertyMap.newMap();
|
||||
|
||||
AnonymousFunction() {
|
||||
super("", GlobalFunctions.ANONYMOUS, anonmap$, null);
|
||||
}
|
||||
}
|
||||
|
||||
static ScriptFunctionImpl newAnonymousFunction() {
|
||||
return new AnonymousFunction();
|
||||
}
|
||||
|
||||
private static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final Specialization[] specs, final int flags) {
|
||||
final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, flags);
|
||||
func.setPrototype(UNDEFINED);
|
||||
// Non-constructor built-in functions do not have "prototype" property
|
||||
func.deleteOwnProperty(func.getMap().findProperty("prototype"));
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for non-constructor built-in functions
|
||||
*
|
||||
* @param name function name
|
||||
* @param methodHandle handle for invocation
|
||||
* @param specs specialized versions of function if available, null otherwise
|
||||
* @return new ScriptFunction
|
||||
*/
|
||||
static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final Specialization[] specs) {
|
||||
return makeFunction(name, methodHandle, specs, ScriptFunctionData.IS_BUILTIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for non-constructor built-in, strict functions
|
||||
*
|
||||
* @param name function name
|
||||
* @param methodHandle handle for invocation
|
||||
* @return new ScriptFunction
|
||||
*/
|
||||
static ScriptFunction makeStrictFunction(final String name, final MethodHandle methodHandle) {
|
||||
return makeFunction(name, methodHandle, null, ScriptFunctionData.IS_BUILTIN | ScriptFunctionData.IS_STRICT );
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for non-constructor built-in functions
|
||||
*
|
||||
* @param name function name
|
||||
* @param methodHandle handle for invocation
|
||||
* @return new ScriptFunction
|
||||
*/
|
||||
static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle) {
|
||||
return makeFunction(name, methodHandle, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptFunction makeSynchronizedFunction(final Object sync) {
|
||||
final MethodHandle mh = MH.insertArguments(ScriptFunction.INVOKE_SYNC, 0, this, sync);
|
||||
return makeFunction(getName(), mh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link ScriptFunction#makeBoundFunction(Object, Object[])}. The only reason we override it is so that we
|
||||
* can expose it.
|
||||
* @param self the self to bind to this function. Can be null (in which case, null is bound as this).
|
||||
* @param args additional arguments to bind to this function. Can be null or empty to not bind additional arguments.
|
||||
* @return a function with the specified self and parameters bound.
|
||||
*/
|
||||
@Override
|
||||
public ScriptFunction makeBoundFunction(final Object self, final Object[] args) {
|
||||
return super.makeBoundFunction(self, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to create a bound function based on this function.
|
||||
*
|
||||
* @param data the {@code ScriptFunctionData} specifying the functions immutable portion.
|
||||
* @return a function initialized from the specified data. Its parent scope will be set to null, therefore the
|
||||
* passed in data should not expect a callee.
|
||||
*/
|
||||
@Override
|
||||
protected ScriptFunction makeBoundFunction(final ScriptFunctionData data) {
|
||||
return new BoundScriptFunctionImpl(data, getTargetFunction());
|
||||
}
|
||||
|
||||
// return Object.prototype - used by "allocate"
|
||||
@Override
|
||||
protected final ScriptObject getObjectPrototype() {
|
||||
return Global.objectPrototype();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object getPrototype() {
|
||||
if (prototype == LAZY_PROTOTYPE) {
|
||||
prototype = new PrototypeObject(this);
|
||||
}
|
||||
return prototype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setPrototype(final Object newProto) {
|
||||
if (newProto instanceof ScriptObject && newProto != this.prototype && allocatorMap != null) {
|
||||
// Replace our current allocator map with one that is associated with the new prototype.
|
||||
allocatorMap = allocatorMap.changeProto((ScriptObject)newProto);
|
||||
}
|
||||
this.prototype = newProto;
|
||||
}
|
||||
|
||||
// Internals below..
|
||||
private void init(final Global global) {
|
||||
this.setInitialProto(global.getFunctionPrototype());
|
||||
this.prototype = LAZY_PROTOTYPE;
|
||||
|
||||
// We have to fill user accessor functions late as these are stored
|
||||
// in this object rather than in the PropertyMap of this object.
|
||||
assert objectSpill == null;
|
||||
final ScriptFunction typeErrorThrower = global.getTypeErrorThrower();
|
||||
if (findProperty("arguments", true) != null) {
|
||||
initUserAccessors("arguments", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
|
||||
}
|
||||
if (findProperty("caller", true) != null) {
|
||||
initUserAccessors("caller", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
|
||||
}
|
||||
}
|
||||
}
|
@ -808,7 +808,7 @@ loop:
|
||||
if (!oldStrictMode && directiveStmts != null) {
|
||||
// check that directives preceding this one do not violate strictness
|
||||
for (final Node statement : directiveStmts) {
|
||||
// the get value will force unescape of preceeding
|
||||
// the get value will force unescape of preceding
|
||||
// escaped string directives
|
||||
getValue(statement.getToken());
|
||||
}
|
||||
@ -2507,7 +2507,7 @@ loop:
|
||||
// run: function() { println("run"); }
|
||||
// };
|
||||
//
|
||||
// The object literal following the "new Constructor()" expresssion
|
||||
// The object literal following the "new Constructor()" expression
|
||||
// is passed as an additional (last) argument to the constructor.
|
||||
if (!env._no_syntax_extensions && type == LBRACE) {
|
||||
arguments.add(objectLiteral());
|
||||
|
@ -90,7 +90,7 @@ abstract class ParserContextBaseNode implements ParserContextNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Statement at the end of the Statementlist
|
||||
* Adds a statement at the end of the statement list
|
||||
* @param statement The statement to add
|
||||
*/
|
||||
@Override
|
||||
@ -99,7 +99,7 @@ abstract class ParserContextBaseNode implements ParserContextNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a statement at the begining of the statementlist
|
||||
* Adds a statement at the beginning of the statement list
|
||||
* @param statement The statement to add
|
||||
*/
|
||||
@Override
|
||||
|
4
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextNode.java
4
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextNode.java
@ -53,13 +53,13 @@ interface ParserContextNode {
|
||||
public void setStatements(final List<Statement> statements);
|
||||
|
||||
/**
|
||||
* Adds a Statement at the end of the Statementlist
|
||||
* Adds a statement at the end of the statement list
|
||||
* @param statement The statement to add
|
||||
*/
|
||||
public void appendStatement(final Statement statement);
|
||||
|
||||
/**
|
||||
* Adds a statement at the begining of the statementlist
|
||||
* Adds a statement at the beginning of the statement list
|
||||
* @param statement The statement to add
|
||||
*/
|
||||
public void prependStatement(final Statement statement);
|
||||
|
@ -38,15 +38,14 @@ import jdk.nashorn.internal.codegen.ClassEmitter;
|
||||
* The compiler still retains most of the state around code emission
|
||||
* and management internally, so this is to avoid passing around any
|
||||
* logic that isn't directly related to installing a class
|
||||
* @param <T> owner class type for this code installer
|
||||
*
|
||||
*/
|
||||
public interface CodeInstaller<T> {
|
||||
public interface CodeInstaller {
|
||||
/**
|
||||
* Return the owner for the CodeInstaller, e.g. a {@link Context}
|
||||
* @return owner
|
||||
* Return the {@link Context} associated with this code installer.
|
||||
* @return the context.
|
||||
*/
|
||||
public T getOwner();
|
||||
public Context getContext();
|
||||
|
||||
/**
|
||||
* Install a class.
|
||||
@ -106,7 +105,7 @@ public interface CodeInstaller<T> {
|
||||
* new, independent class loader.
|
||||
* @return a new code installer with a new independent class loader.
|
||||
*/
|
||||
public CodeInstaller<T> withNewLoader();
|
||||
public CodeInstaller withNewLoader();
|
||||
|
||||
/**
|
||||
* Returns true if this code installer is compatible with the other code installer. Compatibility is expected to be
|
||||
@ -115,6 +114,6 @@ public interface CodeInstaller<T> {
|
||||
* @param other the other code installer tested for compatibility with this code installer.
|
||||
* @return true if this code installer is compatible with the other code installer.
|
||||
*/
|
||||
public boolean isCompatibleWith(CodeInstaller<T> other);
|
||||
public boolean isCompatibleWith(CodeInstaller other);
|
||||
|
||||
}
|
||||
|
4
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/CompiledFunction.java
4
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/CompiledFunction.java
@ -102,7 +102,7 @@ final class CompiledFunction {
|
||||
/*
|
||||
* An optimistic builtin with isOptimistic=true works like any optimistic generated function, i.e. it
|
||||
* can throw unwarranted optimism exceptions. As native functions trivially can't have parts of them
|
||||
* regenerated as restof methods, this only works if the methods are atomic/functional in their behavior
|
||||
* regenerated as "restOf" methods, this only works if the methods are atomic/functional in their behavior
|
||||
* and doesn't modify state before an UOE can be thrown. If they aren't, we can reexecute a wider version
|
||||
* of the same builtin in a recompilation handler for FinalScriptFunctionData. There are several
|
||||
* candidate methods in Native* that would benefit from this, but I haven't had time to implement any
|
||||
@ -567,7 +567,7 @@ final class CompiledFunction {
|
||||
return handle;
|
||||
}
|
||||
|
||||
// Otherwise, we need a new level of indirection; need to introduce a mutable call site that can relink itslef
|
||||
// Otherwise, we need a new level of indirection; need to introduce a mutable call site that can relink itself
|
||||
// to the compiled function's changed target whenever the optimistic assumptions are invalidated.
|
||||
final CallSite cs = new MutableCallSite(handle.type());
|
||||
relinkComposableInvoker(cs, this, isConstructor);
|
||||
|
@ -153,7 +153,7 @@ public final class Context {
|
||||
* Currently we are conservative and associate the name of a builtin class with all
|
||||
* its properties, so it's enough to invalidate a property to break all assumptions
|
||||
* about a prototype. This can be changed to a more fine grained approach, but no one
|
||||
* ever needs this, given the very rare occurance of swapping out only parts of
|
||||
* ever needs this, given the very rare occurrence of swapping out only parts of
|
||||
* a builtin v.s. the entire builtin object
|
||||
*/
|
||||
private final Map<String, SwitchPoint> builtinSwitchPoints = new HashMap<>();
|
||||
@ -167,7 +167,7 @@ public final class Context {
|
||||
* ContextCodeInstaller that has the privilege of installing classes in the Context.
|
||||
* Can only be instantiated from inside the context and is opaque to other classes
|
||||
*/
|
||||
public static class ContextCodeInstaller implements CodeInstaller<ScriptEnvironment> {
|
||||
public static class ContextCodeInstaller implements CodeInstaller {
|
||||
private final Context context;
|
||||
private final ScriptLoader loader;
|
||||
private final CodeSource codeSource;
|
||||
@ -185,13 +185,9 @@ public final class Context {
|
||||
this.codeSource = codeSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the script environment for this installer
|
||||
* @return ScriptEnvironment
|
||||
*/
|
||||
@Override
|
||||
public ScriptEnvironment getOwner() {
|
||||
return context.env;
|
||||
public Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -254,7 +250,7 @@ public final class Context {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeInstaller<ScriptEnvironment> withNewLoader() {
|
||||
public CodeInstaller withNewLoader() {
|
||||
// Reuse this installer if we're within our limits.
|
||||
if (usageCount < MAX_USAGES && bytesDefined < MAX_BYTES_DEFINED) {
|
||||
return this;
|
||||
@ -263,7 +259,7 @@ public final class Context {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompatibleWith(final CodeInstaller<ScriptEnvironment> other) {
|
||||
public boolean isCompatibleWith(final CodeInstaller other) {
|
||||
if (other instanceof ContextCodeInstaller) {
|
||||
final ContextCodeInstaller cci = (ContextCodeInstaller)other;
|
||||
return cci.context == context && cci.codeSource == codeSource;
|
||||
@ -1300,14 +1296,12 @@ public final class Context {
|
||||
final URL url = source.getURL();
|
||||
final ScriptLoader loader = env._loader_per_compile ? createNewLoader() : scriptLoader;
|
||||
final CodeSource cs = new CodeSource(url, (CodeSigner[])null);
|
||||
final CodeInstaller<ScriptEnvironment> installer = new ContextCodeInstaller(this, loader, cs);
|
||||
final CodeInstaller installer = new ContextCodeInstaller(this, loader, cs);
|
||||
|
||||
if (storedScript == null) {
|
||||
final CompilationPhases phases = Compiler.CompilationPhases.COMPILE_ALL;
|
||||
|
||||
final Compiler compiler = new Compiler(
|
||||
this,
|
||||
env,
|
||||
final Compiler compiler = Compiler.forInitialCompilation(
|
||||
installer,
|
||||
source,
|
||||
errMan,
|
||||
@ -1481,7 +1475,7 @@ public final class Context {
|
||||
* @param level log level
|
||||
* @param mh method handle
|
||||
* @param paramStart first parameter to print
|
||||
* @param printReturnValue should we print the return vaulue?
|
||||
* @param printReturnValue should we print the return value?
|
||||
* @param text debug printout to add
|
||||
*
|
||||
* @return instrumented method handle, or null if logger not enabled
|
||||
|
@ -297,4 +297,3 @@ public final class FindProperty {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ import jdk.nashorn.internal.runtime.logging.Logger;
|
||||
*
|
||||
* Thus everything registered as a global constant gets an extra chance. Set once,
|
||||
* reregister the switchpoint. Set twice or more - don't try again forever, or we'd
|
||||
* just end up relinking our way into megamorphisism.
|
||||
* just end up relinking our way into megamorphism.
|
||||
*
|
||||
* Also it has to be noted that this kind of linking creates a coupling between a Global
|
||||
* and the call sites in compiled code belonging to the Context. For this reason, the
|
||||
|
@ -26,7 +26,6 @@
|
||||
package jdk.nashorn.internal.runtime;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.Callable;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.parser.JSONParser;
|
||||
|
@ -1967,7 +1967,7 @@ public enum JSType {
|
||||
/**
|
||||
* Get the unboxed (primitive) type for an object
|
||||
* @param o object
|
||||
* @return primive type or Object.class if not primitive
|
||||
* @return primitive type or Object.class if not primitive
|
||||
*/
|
||||
public static Class<?> unboxedFieldType(final Object o) {
|
||||
if (o == null) {
|
||||
|
@ -38,7 +38,7 @@ public final class ParserException extends NashornException {
|
||||
private final Source source;
|
||||
// token responsible for this exception
|
||||
private final long token;
|
||||
// if this is traslated as ECMA error, which type should be used?
|
||||
// if this is translated as ECMA error, which type should be used?
|
||||
private final JSErrorType errorType;
|
||||
|
||||
/**
|
||||
|
31
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyListeners.java
31
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyListeners.java
@ -28,6 +28,7 @@ package jdk.nashorn.internal.runtime;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
|
||||
/**
|
||||
* Helper class to manage property listeners and notification.
|
||||
@ -37,8 +38,15 @@ public class PropertyListeners {
|
||||
private Map<String, WeakPropertyMapSet> listeners;
|
||||
|
||||
// These counters are updated in debug mode
|
||||
private static int listenersAdded;
|
||||
private static int listenersRemoved;
|
||||
private static LongAdder listenersAdded;
|
||||
private static LongAdder listenersRemoved;
|
||||
|
||||
static {
|
||||
if (Context.DEBUG) {
|
||||
listenersAdded = new LongAdder();
|
||||
listenersRemoved = new LongAdder();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
@ -54,16 +62,16 @@ public class PropertyListeners {
|
||||
* Return aggregate listeners added to all PropertyListenerManagers
|
||||
* @return the listenersAdded
|
||||
*/
|
||||
public static int getListenersAdded() {
|
||||
return listenersAdded;
|
||||
public static long getListenersAdded() {
|
||||
return listenersAdded.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return aggregate listeners removed from all PropertyListenerManagers
|
||||
* @return the listenersRemoved
|
||||
*/
|
||||
public static int getListenersRemoved() {
|
||||
return listenersRemoved;
|
||||
public static long getListenersRemoved() {
|
||||
return listenersRemoved.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,7 +130,7 @@ public class PropertyListeners {
|
||||
*/
|
||||
synchronized final void addListener(final String key, final PropertyMap propertyMap) {
|
||||
if (Context.DEBUG) {
|
||||
listenersAdded++;
|
||||
listenersAdded.increment();
|
||||
}
|
||||
if (listeners == null) {
|
||||
listeners = new WeakHashMap<>();
|
||||
@ -151,6 +159,9 @@ public class PropertyListeners {
|
||||
propertyMap.propertyAdded(prop);
|
||||
}
|
||||
listeners.remove(prop.getKey());
|
||||
if (Context.DEBUG) {
|
||||
listenersRemoved.increment();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -168,6 +179,9 @@ public class PropertyListeners {
|
||||
propertyMap.propertyDeleted(prop);
|
||||
}
|
||||
listeners.remove(prop.getKey());
|
||||
if (Context.DEBUG) {
|
||||
listenersRemoved.increment();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,6 +201,9 @@ public class PropertyListeners {
|
||||
propertyMap.propertyModified(oldProp, newProp);
|
||||
}
|
||||
listeners.remove(oldProp.getKey());
|
||||
if (Context.DEBUG) {
|
||||
listenersRemoved.increment();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
/**
|
||||
@ -114,7 +115,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
|
||||
}
|
||||
|
||||
if (Context.DEBUG) {
|
||||
count++;
|
||||
count.increment();
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,8 +136,8 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
|
||||
this.freeSlots = propertyMap.freeSlots;
|
||||
|
||||
if (Context.DEBUG) {
|
||||
count++;
|
||||
clonedCount++;
|
||||
count.increment();
|
||||
clonedCount.increment();
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,7 +329,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
|
||||
if (sp != null) {
|
||||
protoGetSwitches.remove(key);
|
||||
if (Context.DEBUG) {
|
||||
protoInvalidations++;
|
||||
protoInvalidations.increment();
|
||||
}
|
||||
SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
|
||||
}
|
||||
@ -343,7 +344,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
|
||||
final int size = protoGetSwitches.size();
|
||||
if (size > 0) {
|
||||
if (Context.DEBUG) {
|
||||
protoInvalidations += size;
|
||||
protoInvalidations.add(size);
|
||||
}
|
||||
SwitchPoint.invalidateAll(protoGetSwitches.values().toArray(new SwitchPoint[size]));
|
||||
protoGetSwitches.clear();
|
||||
@ -713,7 +714,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
|
||||
}
|
||||
|
||||
if (Context.DEBUG && cachedMap != null) {
|
||||
protoHistoryHit++;
|
||||
protoHistoryHit.increment();
|
||||
}
|
||||
|
||||
return cachedMap;
|
||||
@ -762,7 +763,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
|
||||
|
||||
if (historicMap != null) {
|
||||
if (Context.DEBUG) {
|
||||
historyHit++;
|
||||
historyHit.increment();
|
||||
}
|
||||
|
||||
return historicMap;
|
||||
@ -910,7 +911,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
|
||||
}
|
||||
|
||||
if (Context.DEBUG) {
|
||||
setProtoNewMapCount++;
|
||||
setProtoNewMapCount.increment();
|
||||
}
|
||||
|
||||
final PropertyMap newMap = new PropertyMap(this);
|
||||
@ -1030,52 +1031,62 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
|
||||
}
|
||||
|
||||
// counters updated only in debug mode
|
||||
private static int count;
|
||||
private static int clonedCount;
|
||||
private static int historyHit;
|
||||
private static int protoInvalidations;
|
||||
private static int protoHistoryHit;
|
||||
private static int setProtoNewMapCount;
|
||||
private static LongAdder count;
|
||||
private static LongAdder clonedCount;
|
||||
private static LongAdder historyHit;
|
||||
private static LongAdder protoInvalidations;
|
||||
private static LongAdder protoHistoryHit;
|
||||
private static LongAdder setProtoNewMapCount;
|
||||
static {
|
||||
if (Context.DEBUG) {
|
||||
count = new LongAdder();
|
||||
clonedCount = new LongAdder();
|
||||
historyHit = new LongAdder();
|
||||
protoInvalidations = new LongAdder();
|
||||
protoHistoryHit = new LongAdder();
|
||||
setProtoNewMapCount = new LongAdder();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Total number of maps.
|
||||
*/
|
||||
public static int getCount() {
|
||||
return count;
|
||||
public static long getCount() {
|
||||
return count.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of maps that were cloned.
|
||||
*/
|
||||
public static int getClonedCount() {
|
||||
return clonedCount;
|
||||
public static long getClonedCount() {
|
||||
return clonedCount.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of times history was successfully used.
|
||||
*/
|
||||
public static int getHistoryHit() {
|
||||
return historyHit;
|
||||
public static long getHistoryHit() {
|
||||
return historyHit.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of times prototype changes caused invalidation.
|
||||
*/
|
||||
public static int getProtoInvalidations() {
|
||||
return protoInvalidations;
|
||||
public static long getProtoInvalidations() {
|
||||
return protoInvalidations.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of times proto history was successfully used.
|
||||
*/
|
||||
public static int getProtoHistoryHit() {
|
||||
return protoHistoryHit;
|
||||
public static long getProtoHistoryHit() {
|
||||
return protoHistoryHit.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of times prototypes were modified.
|
||||
*/
|
||||
public static int getSetProtoNewMapCount() {
|
||||
return setProtoNewMapCount;
|
||||
public static long getSetProtoNewMapCount() {
|
||||
return setProtoNewMapCount.longValue();
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.nashorn.internal.objects;
|
||||
package jdk.nashorn.internal.runtime;
|
||||
|
||||
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||
@ -31,17 +31,12 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.ArrayList;
|
||||
import jdk.nashorn.internal.runtime.AccessorProperty;
|
||||
import jdk.nashorn.internal.runtime.Property;
|
||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
|
||||
/**
|
||||
* Instances of this class serve as "prototype" object for script functions.
|
||||
* The purpose is to expose "constructor" property from "prototype". Also, nasgen
|
||||
* generated prototype classes extend from this class.
|
||||
*
|
||||
*/
|
||||
public class PrototypeObject extends ScriptObject {
|
||||
private static final PropertyMap map$;
|
||||
@ -61,7 +56,10 @@ public class PrototypeObject extends ScriptObject {
|
||||
super(global.getObjectPrototype(), map != map$? map.addAll(map$) : map$);
|
||||
}
|
||||
|
||||
PrototypeObject() {
|
||||
/**
|
||||
* Prototype constructor
|
||||
*/
|
||||
protected PrototypeObject() {
|
||||
this(Global.instance(), map$);
|
||||
}
|
||||
|
||||
@ -70,11 +68,16 @@ public class PrototypeObject extends ScriptObject {
|
||||
*
|
||||
* @param map property map
|
||||
*/
|
||||
PrototypeObject(final PropertyMap map) {
|
||||
protected PrototypeObject(final PropertyMap map) {
|
||||
this(Global.instance(), map);
|
||||
}
|
||||
|
||||
PrototypeObject(final ScriptFunction func) {
|
||||
/**
|
||||
* PropertyObject constructor
|
||||
*
|
||||
* @param func constructor function
|
||||
*/
|
||||
protected PrototypeObject(final ScriptFunction func) {
|
||||
this(Global.instance(), map$);
|
||||
this.constructor = func;
|
||||
}
|
||||
@ -84,7 +87,7 @@ public class PrototypeObject extends ScriptObject {
|
||||
* @param self self reference
|
||||
* @return constructor, probably, but not necessarily, a {@link ScriptFunction}
|
||||
*/
|
||||
static Object getConstructor(final Object self) {
|
||||
public static Object getConstructor(final Object self) {
|
||||
return (self instanceof PrototypeObject) ?
|
||||
((PrototypeObject)self).getConstructor() :
|
||||
UNDEFINED;
|
||||
@ -95,7 +98,7 @@ public class PrototypeObject extends ScriptObject {
|
||||
* @param self self reference
|
||||
* @param constructor constructor, probably, but not necessarily, a {@link ScriptFunction}
|
||||
*/
|
||||
static void setConstructor(final Object self, final Object constructor) {
|
||||
public static void setConstructor(final Object self, final Object constructor) {
|
||||
if (self instanceof PrototypeObject) {
|
||||
((PrototypeObject)self).setConstructor(constructor);
|
||||
}
|
@ -119,7 +119,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
||||
private final Object endParserState;
|
||||
|
||||
/** Code installer used for all further recompilation/specialization of this ScriptFunction */
|
||||
private transient CodeInstaller<ScriptEnvironment> installer;
|
||||
private transient CodeInstaller installer;
|
||||
|
||||
private final Map<Integer, RecompilableScriptFunctionData> nestedFunctions;
|
||||
|
||||
@ -153,7 +153,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
||||
*/
|
||||
public RecompilableScriptFunctionData(
|
||||
final FunctionNode functionNode,
|
||||
final CodeInstaller<ScriptEnvironment> installer,
|
||||
final CodeInstaller installer,
|
||||
final AllocationStrategy allocationStrategy,
|
||||
final Map<Integer, RecompilableScriptFunctionData> nestedFunctions,
|
||||
final Map<String, Integer> externalScopeDepths,
|
||||
@ -285,7 +285,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
||||
* @param src source
|
||||
* @param inst code installer
|
||||
*/
|
||||
public void initTransients(final Source src, final CodeInstaller<ScriptEnvironment> inst) {
|
||||
public void initTransients(final Source src, final CodeInstaller inst) {
|
||||
if (this.source == null && this.installer == null) {
|
||||
this.source = src;
|
||||
this.installer = inst;
|
||||
@ -500,7 +500,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
||||
}
|
||||
|
||||
private FunctionNode deserialize(final byte[] serializedAst) {
|
||||
final ScriptEnvironment env = installer.getOwner();
|
||||
final ScriptEnvironment env = installer.getContext().getEnv();
|
||||
final Timing timing = env._timing;
|
||||
final long t1 = System.nanoTime();
|
||||
try {
|
||||
@ -647,8 +647,8 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
||||
* a new class loader with optimistic typing so that deoptimized code can get reclaimed by GC.
|
||||
* @return a code installer for installing new code.
|
||||
*/
|
||||
private CodeInstaller<ScriptEnvironment> getInstallerForNewCode() {
|
||||
final ScriptEnvironment env = installer.getOwner();
|
||||
private CodeInstaller getInstallerForNewCode() {
|
||||
final ScriptEnvironment env = installer.getContext().getEnv();
|
||||
return env._optimistic_types || env._loader_per_compile ? installer.withNewLoader() : installer;
|
||||
}
|
||||
|
||||
@ -658,15 +658,10 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
||||
final TypeMap typeMap = typeMap(actualCallSiteType);
|
||||
final Type[] paramTypes = typeMap == null ? null : typeMap.getParameterTypes(functionNodeId);
|
||||
final Object typeInformationFile = OptimisticTypesPersistence.getLocationDescriptor(source, functionNodeId, paramTypes);
|
||||
final Context context = Context.getContextTrusted();
|
||||
return new Compiler(
|
||||
context,
|
||||
context.getEnv(),
|
||||
return Compiler.forOnDemandCompilation(
|
||||
getInstallerForNewCode(),
|
||||
functionNode.getSource(), // source
|
||||
context.getErrorManager(),
|
||||
isStrict() | functionNode.isStrict(), // is strict
|
||||
true, // is on demand
|
||||
this, // compiledFunction, i.e. this RecompilableScriptFunctionData
|
||||
typeMap, // type map
|
||||
getEffectiveInvalidatedProgramPoints(invalidatedProgramPoints, typeInformationFile), // invalidated program points
|
||||
@ -709,7 +704,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
||||
final TypeMap typeMap = typeMap(actualCallSiteType);
|
||||
final Type[] paramTypes = typeMap == null ? null : typeMap.getParameterTypes(functionNodeId);
|
||||
cacheKey = CodeStore.getCacheKey(functionNodeId, paramTypes);
|
||||
final CodeInstaller<ScriptEnvironment> newInstaller = getInstallerForNewCode();
|
||||
final CodeInstaller newInstaller = getInstallerForNewCode();
|
||||
final StoredScript script = newInstaller.loadScript(source, cacheKey);
|
||||
|
||||
if (script != null) {
|
||||
@ -730,7 +725,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
||||
}
|
||||
|
||||
boolean usePersistentCodeCache() {
|
||||
return installer != null && installer.getOwner()._persistent_cache;
|
||||
return installer != null && installer.getContext().getEnv()._persistent_cache;
|
||||
}
|
||||
|
||||
private MethodType explicitParams(final MethodType callSiteType) {
|
||||
|
@ -27,6 +27,7 @@ package jdk.nashorn.internal.runtime;
|
||||
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
|
||||
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import jdk.nashorn.internal.codegen.CompilerConstants;
|
||||
|
||||
/**
|
||||
@ -38,7 +39,7 @@ public class Scope extends ScriptObject {
|
||||
private int splitState = -1;
|
||||
|
||||
/** This is updated only in debug mode - counts number of {@code ScriptObject} instances created that are scope */
|
||||
private static int count;
|
||||
private static final LongAdder count = Context.DEBUG ? new LongAdder() : null;
|
||||
|
||||
/** Method handle that points to {@link Scope#getSplitState}. */
|
||||
public static final CompilerConstants.Call GET_SPLIT_STATE = virtualCallNoLookup(Scope.class, "getSplitState", int.class);
|
||||
@ -52,9 +53,7 @@ public class Scope extends ScriptObject {
|
||||
*/
|
||||
public Scope(final PropertyMap map) {
|
||||
super(map);
|
||||
if (Context.DEBUG) {
|
||||
count++;
|
||||
}
|
||||
incrementCount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,9 +64,7 @@ public class Scope extends ScriptObject {
|
||||
*/
|
||||
public Scope(final ScriptObject proto, final PropertyMap map) {
|
||||
super(proto, map);
|
||||
if (Context.DEBUG) {
|
||||
count++;
|
||||
}
|
||||
incrementCount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,9 +76,7 @@ public class Scope extends ScriptObject {
|
||||
*/
|
||||
public Scope(final PropertyMap map, final long[] primitiveSpill, final Object[] objectSpill) {
|
||||
super(map, primitiveSpill, objectSpill);
|
||||
if (Context.DEBUG) {
|
||||
count++;
|
||||
}
|
||||
incrementCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -123,7 +118,13 @@ public class Scope extends ScriptObject {
|
||||
*
|
||||
* @return number of scope ScriptObjects created
|
||||
*/
|
||||
public static int getScopeCount() {
|
||||
return count;
|
||||
public static long getScopeCount() {
|
||||
return count != null ? count.sum() : 0;
|
||||
}
|
||||
|
||||
private static void incrementCount() {
|
||||
if (Context.DEBUG) {
|
||||
count.increment();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
609
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java
609
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java
@ -22,7 +22,6 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.nashorn.internal.runtime;
|
||||
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
|
||||
@ -40,6 +39,7 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
import jdk.internal.dynalink.linker.LinkRequest;
|
||||
@ -55,38 +55,54 @@ import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
|
||||
import jdk.nashorn.internal.runtime.logging.DebugLogger;
|
||||
|
||||
/**
|
||||
* Runtime representation of a JavaScript function.
|
||||
* Runtime representation of a JavaScript function. This class has only private
|
||||
* and protected constructors. There are no *public* constructors - but only
|
||||
* factory methods that follow the naming pattern "createXYZ".
|
||||
*/
|
||||
public abstract class ScriptFunction extends ScriptObject {
|
||||
public class ScriptFunction extends ScriptObject {
|
||||
|
||||
/** Method handle for prototype getter for this ScriptFunction */
|
||||
/**
|
||||
* Method handle for prototype getter for this ScriptFunction
|
||||
*/
|
||||
public static final MethodHandle G$PROTOTYPE = findOwnMH_S("G$prototype", Object.class, Object.class);
|
||||
|
||||
/** Method handle for prototype setter for this ScriptFunction */
|
||||
/**
|
||||
* Method handle for prototype setter for this ScriptFunction
|
||||
*/
|
||||
public static final MethodHandle S$PROTOTYPE = findOwnMH_S("S$prototype", void.class, Object.class, Object.class);
|
||||
|
||||
/** Method handle for length getter for this ScriptFunction */
|
||||
/**
|
||||
* Method handle for length getter for this ScriptFunction
|
||||
*/
|
||||
public static final MethodHandle G$LENGTH = findOwnMH_S("G$length", int.class, Object.class);
|
||||
|
||||
/** Method handle for name getter for this ScriptFunction */
|
||||
/**
|
||||
* Method handle for name getter for this ScriptFunction
|
||||
*/
|
||||
public static final MethodHandle G$NAME = findOwnMH_S("G$name", Object.class, Object.class);
|
||||
|
||||
/** Method handle used for implementing sync() in mozilla_compat */
|
||||
/**
|
||||
* Method handle used for implementing sync() in mozilla_compat
|
||||
*/
|
||||
public static final MethodHandle INVOKE_SYNC = findOwnMH_S("invokeSync", Object.class, ScriptFunction.class, Object.class, Object.class, Object[].class);
|
||||
|
||||
/** Method handle for allocate function for this ScriptFunction */
|
||||
/**
|
||||
* Method handle for allocate function for this ScriptFunction
|
||||
*/
|
||||
static final MethodHandle ALLOCATE = findOwnMH_V("allocate", Object.class);
|
||||
|
||||
private static final MethodHandle WRAPFILTER = findOwnMH_S("wrapFilter", Object.class, Object.class);
|
||||
|
||||
private static final MethodHandle SCRIPTFUNCTION_GLOBALFILTER = findOwnMH_S("globalFilter", Object.class, Object.class);
|
||||
|
||||
/** method handle to scope getter for this ScriptFunction */
|
||||
/**
|
||||
* method handle to scope getter for this ScriptFunction
|
||||
*/
|
||||
public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class);
|
||||
|
||||
private static final MethodHandle IS_FUNCTION_MH = findOwnMH_S("isFunctionMH", boolean.class, Object.class, ScriptFunctionData.class);
|
||||
private static final MethodHandle IS_FUNCTION_MH = findOwnMH_S("isFunctionMH", boolean.class, Object.class, ScriptFunctionData.class);
|
||||
|
||||
private static final MethodHandle IS_APPLY_FUNCTION = findOwnMH_S("isApplyFunction", boolean.class, boolean.class, Object.class, Object.class);
|
||||
private static final MethodHandle IS_APPLY_FUNCTION = findOwnMH_S("isApplyFunction", boolean.class, boolean.class, Object.class, Object.class);
|
||||
|
||||
private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH_S("isNonStrictFunction", boolean.class, Object.class, Object.class, ScriptFunctionData.class);
|
||||
|
||||
@ -94,55 +110,298 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
|
||||
private static final MethodHandle WRAP_THIS = MH.findStatic(MethodHandles.lookup(), ScriptFunctionData.class, "wrapThis", MH.type(Object.class, Object.class));
|
||||
|
||||
/** The parent scope. */
|
||||
// various property maps used for different kinds of functions
|
||||
// property map for anonymous function that serves as Function.prototype
|
||||
private static final PropertyMap anonmap$;
|
||||
// property map for strict mode functions
|
||||
private static final PropertyMap strictmodemap$;
|
||||
// property map for bound functions
|
||||
private static final PropertyMap boundfunctionmap$;
|
||||
// property map for non-strict, non-bound functions.
|
||||
private static final PropertyMap map$;
|
||||
|
||||
// Marker object for lazily initialized prototype object
|
||||
private static final Object LAZY_PROTOTYPE = new Object();
|
||||
|
||||
private static PropertyMap createStrictModeMap(final PropertyMap map) {
|
||||
final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
|
||||
PropertyMap newMap = map;
|
||||
// Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
|
||||
newMap = newMap.addPropertyNoHistory(map.newUserAccessors("arguments", flags));
|
||||
newMap = newMap.addPropertyNoHistory(map.newUserAccessors("caller", flags));
|
||||
return newMap;
|
||||
}
|
||||
|
||||
private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
|
||||
// Bound function map is same as strict function map, but additionally lacks the "prototype" property, see
|
||||
// ECMAScript 5.1 section 15.3.4.5
|
||||
return strictModeMap.deleteProperty(strictModeMap.findProperty("prototype"));
|
||||
}
|
||||
|
||||
static {
|
||||
anonmap$ = PropertyMap.newMap();
|
||||
final ArrayList<Property> properties = new ArrayList<>(3);
|
||||
properties.add(AccessorProperty.create("prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE));
|
||||
properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null));
|
||||
properties.add(AccessorProperty.create("name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null));
|
||||
map$ = PropertyMap.newMap(properties);
|
||||
strictmodemap$ = createStrictModeMap(map$);
|
||||
boundfunctionmap$ = createBoundFunctionMap(strictmodemap$);
|
||||
}
|
||||
|
||||
private static boolean isStrict(final int flags) {
|
||||
return (flags & ScriptFunctionData.IS_STRICT) != 0;
|
||||
}
|
||||
|
||||
// Choose the map based on strict mode!
|
||||
private static PropertyMap getMap(final boolean strict) {
|
||||
return strict ? strictmodemap$ : map$;
|
||||
}
|
||||
|
||||
/**
|
||||
* The parent scope.
|
||||
*/
|
||||
private final ScriptObject scope;
|
||||
|
||||
private final ScriptFunctionData data;
|
||||
|
||||
/** The property map used for newly allocated object when function is used as constructor. */
|
||||
/**
|
||||
* The property map used for newly allocated object when function is used as
|
||||
* constructor.
|
||||
*/
|
||||
protected PropertyMap allocatorMap;
|
||||
|
||||
/**
|
||||
* Reference to constructor prototype.
|
||||
*/
|
||||
protected Object prototype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param name function name
|
||||
* @param methodHandle method handle to function (if specializations are present, assumed to be most generic)
|
||||
* @param map property map
|
||||
* @param scope scope
|
||||
* @param specs specialized version of this function - other method handles
|
||||
* @param flags {@link ScriptFunctionData} flags
|
||||
* @param data static function data
|
||||
* @param map property map
|
||||
* @param scope scope
|
||||
*/
|
||||
protected ScriptFunction(
|
||||
final String name,
|
||||
final MethodHandle methodHandle,
|
||||
private ScriptFunction(
|
||||
final ScriptFunctionData data,
|
||||
final PropertyMap map,
|
||||
final ScriptObject scope,
|
||||
final Specialization[] specs,
|
||||
final int flags) {
|
||||
final Global global) {
|
||||
|
||||
this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope);
|
||||
super(map);
|
||||
|
||||
if (Context.DEBUG) {
|
||||
constructorCount.increment();
|
||||
}
|
||||
|
||||
this.data = data;
|
||||
this.scope = scope;
|
||||
this.setInitialProto(global.getFunctionPrototype());
|
||||
this.prototype = LAZY_PROTOTYPE;
|
||||
|
||||
// We have to fill user accessor functions late as these are stored
|
||||
// in this object rather than in the PropertyMap of this object.
|
||||
assert objectSpill == null;
|
||||
if (isStrict() || isBoundFunction()) {
|
||||
final ScriptFunction typeErrorThrower = global.getTypeErrorThrower();
|
||||
initUserAccessors("arguments", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
|
||||
initUserAccessors("caller", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param data static function data
|
||||
* @param map property map
|
||||
* @param scope scope
|
||||
* @param name function name
|
||||
* @param methodHandle method handle to function (if specializations are
|
||||
* present, assumed to be most generic)
|
||||
* @param map property map
|
||||
* @param scope scope
|
||||
* @param specs specialized version of this function - other method handles
|
||||
* @param flags {@link ScriptFunctionData} flags
|
||||
*/
|
||||
protected ScriptFunction(
|
||||
final ScriptFunctionData data,
|
||||
private ScriptFunction(
|
||||
final String name,
|
||||
final MethodHandle methodHandle,
|
||||
final PropertyMap map,
|
||||
final ScriptObject scope) {
|
||||
final ScriptObject scope,
|
||||
final Specialization[] specs,
|
||||
final int flags,
|
||||
final Global global) {
|
||||
this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope, global);
|
||||
}
|
||||
|
||||
super(map);
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param name name of function
|
||||
* @param methodHandle handle for invocation
|
||||
* @param scope scope object
|
||||
* @param specs specialized versions of this method, if available, null
|
||||
* otherwise
|
||||
* @param flags {@link ScriptFunctionData} flags
|
||||
*/
|
||||
private ScriptFunction(
|
||||
final String name,
|
||||
final MethodHandle methodHandle,
|
||||
final ScriptObject scope,
|
||||
final Specialization[] specs,
|
||||
final int flags) {
|
||||
this(name, methodHandle, getMap(isStrict(flags)), scope, specs, flags, Global.instance());
|
||||
}
|
||||
|
||||
if (Context.DEBUG) {
|
||||
constructorCount++;
|
||||
/**
|
||||
* Constructor called by Nasgen generated code, zero added members, use the
|
||||
* default map. Creates builtin functions only.
|
||||
*
|
||||
* @param name name of function
|
||||
* @param invokeHandle handle for invocation
|
||||
* @param specs specialized versions of this method, if available, null
|
||||
* otherwise
|
||||
*/
|
||||
protected ScriptFunction(final String name, final MethodHandle invokeHandle, final Specialization[] specs) {
|
||||
this(name, invokeHandle, map$, null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR, Global.instance());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called by Nasgen generated code, non zero member count, use
|
||||
* the map passed as argument. Creates builtin functions only.
|
||||
*
|
||||
* @param name name of function
|
||||
* @param invokeHandle handle for invocation
|
||||
* @param map initial property map
|
||||
* @param specs specialized versions of this method, if available, null
|
||||
* otherwise
|
||||
*/
|
||||
protected ScriptFunction(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs) {
|
||||
this(name, invokeHandle, map.addAll(map$), null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR, Global.instance());
|
||||
}
|
||||
|
||||
// Factory methods to create various functions
|
||||
/**
|
||||
* Factory method called by compiler generated code for functions that need
|
||||
* parent scope.
|
||||
*
|
||||
* @param constants the generated class' constant array
|
||||
* @param index the index of the {@code RecompilableScriptFunctionData}
|
||||
* object in the constants array.
|
||||
* @param scope the parent scope object
|
||||
* @return a newly created function object
|
||||
*/
|
||||
public static ScriptFunction create(final Object[] constants, final int index, final ScriptObject scope) {
|
||||
final RecompilableScriptFunctionData data = (RecompilableScriptFunctionData) constants[index];
|
||||
return new ScriptFunction(data, getMap(data.isStrict()), scope, Global.instance());
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method called by compiler generated code for functions that don't
|
||||
* need parent scope.
|
||||
*
|
||||
* @param constants the generated class' constant array
|
||||
* @param index the index of the {@code RecompilableScriptFunctionData}
|
||||
* object in the constants array.
|
||||
* @return a newly created function object
|
||||
*/
|
||||
public static ScriptFunction create(final Object[] constants, final int index) {
|
||||
return create(constants, index, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create anonymous function that serves as Function.prototype
|
||||
*
|
||||
* @return anonymous function object
|
||||
*/
|
||||
public static ScriptFunction createAnonymous() {
|
||||
return new ScriptFunction("", GlobalFunctions.ANONYMOUS, anonmap$, null);
|
||||
}
|
||||
|
||||
// builtin function create helper factory
|
||||
private static ScriptFunction createBuiltin(final String name, final MethodHandle methodHandle, final Specialization[] specs, final int flags) {
|
||||
final ScriptFunction func = new ScriptFunction(name, methodHandle, null, specs, flags);
|
||||
func.setPrototype(UNDEFINED);
|
||||
// Non-constructor built-in functions do not have "prototype" property
|
||||
func.deleteOwnProperty(func.getMap().findProperty("prototype"));
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for non-constructor built-in functions
|
||||
*
|
||||
* @param name function name
|
||||
* @param methodHandle handle for invocation
|
||||
* @param specs specialized versions of function if available, null
|
||||
* otherwise
|
||||
* @return new ScriptFunction
|
||||
*/
|
||||
public static ScriptFunction createBuiltin(final String name, final MethodHandle methodHandle, final Specialization[] specs) {
|
||||
return ScriptFunction.createBuiltin(name, methodHandle, specs, ScriptFunctionData.IS_BUILTIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for non-constructor built-in functions
|
||||
*
|
||||
* @param name function name
|
||||
* @param methodHandle handle for invocation
|
||||
* @return new ScriptFunction
|
||||
*/
|
||||
public static ScriptFunction createBuiltin(final String name, final MethodHandle methodHandle) {
|
||||
return ScriptFunction.createBuiltin(name, methodHandle, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for non-constructor built-in, strict functions
|
||||
*
|
||||
* @param name function name
|
||||
* @param methodHandle handle for invocation
|
||||
* @return new ScriptFunction
|
||||
*/
|
||||
public static ScriptFunction createStrictBuiltin(final String name, final MethodHandle methodHandle) {
|
||||
return ScriptFunction.createBuiltin(name, methodHandle, null, ScriptFunctionData.IS_BUILTIN | ScriptFunctionData.IS_STRICT);
|
||||
}
|
||||
|
||||
// Subclass to represent bound functions
|
||||
private static class Bound extends ScriptFunction {
|
||||
private final ScriptFunction target;
|
||||
|
||||
Bound(final ScriptFunctionData boundData, final ScriptFunction target) {
|
||||
super(boundData, boundfunctionmap$, null, Global.instance());
|
||||
setPrototype(ScriptRuntime.UNDEFINED);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
this.data = data;
|
||||
this.scope = scope;
|
||||
@Override
|
||||
protected ScriptFunction getTargetFunction() {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a version of this function bound to a specific "self" and other
|
||||
* arguments, as per {@code Function.prototype.bind} functionality in
|
||||
* ECMAScript 5.1 section 15.3.4.5.
|
||||
*
|
||||
* @param self the self to bind to this function. Can be null (in which
|
||||
* case, null is bound as this).
|
||||
* @param args additional arguments to bind to this function. Can be null or
|
||||
* empty to not bind additional arguments.
|
||||
* @return a function with the specified self and parameters bound.
|
||||
*/
|
||||
public final ScriptFunction createBound(final Object self, final Object[] args) {
|
||||
return new Bound(data.makeBoundFunctionData(this, self, args), getTargetFunction());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a function that invokes this function synchronized on {@code sync}
|
||||
* or the self object of the invocation.
|
||||
*
|
||||
* @param sync the Object to synchronize on, or undefined
|
||||
* @return synchronized function
|
||||
*/
|
||||
public final ScriptFunction createSynchronized(final Object sync) {
|
||||
final MethodHandle mh = MH.insertArguments(ScriptFunction.INVOKE_SYNC, 0, this, sync);
|
||||
return createBuiltin(getName(), mh);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -151,8 +410,8 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.3.5.3 [[HasInstance]] (V)
|
||||
* Step 3 if "prototype" value is not an Object, throw TypeError
|
||||
* ECMA 15.3.5.3 [[HasInstance]] (V) Step 3 if "prototype" value is not an
|
||||
* Object, throw TypeError
|
||||
*/
|
||||
@Override
|
||||
public boolean isInstance(final ScriptObject instance) {
|
||||
@ -171,22 +430,25 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the target function for this function. If the function was not created using
|
||||
* {@link #makeBoundFunction(Object, Object[])}, its target function is itself. If it is bound, its target function
|
||||
* is the target function of the function it was made from (therefore, the target function is always the final,
|
||||
* unbound recipient of the calls).
|
||||
* Returns the target function for this function. If the function was not
|
||||
* created using {@link #createBound(Object, Object[])}, its target
|
||||
* function is itself. If it is bound, its target function is the target
|
||||
* function of the function it was made from (therefore, the target function
|
||||
* is always the final, unbound recipient of the calls).
|
||||
*
|
||||
* @return the target function for this function.
|
||||
*/
|
||||
protected ScriptFunction getTargetFunction() {
|
||||
return this;
|
||||
}
|
||||
|
||||
boolean isBoundFunction() {
|
||||
final boolean isBoundFunction() {
|
||||
return getTargetFunction() != this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the arity of this ScriptFunction
|
||||
*
|
||||
* @param arity arity
|
||||
*/
|
||||
public final void setArity(final int arity) {
|
||||
@ -195,59 +457,66 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
|
||||
/**
|
||||
* Is this a ECMAScript 'use strict' function?
|
||||
*
|
||||
* @return true if function is in strict mode
|
||||
*/
|
||||
public boolean isStrict() {
|
||||
public final boolean isStrict() {
|
||||
return data.isStrict();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a non-strict, non-built-in function that requires non-primitive this argument
|
||||
* according to ECMA 10.4.3.
|
||||
* Returns true if this is a non-strict, non-built-in function that requires
|
||||
* non-primitive this argument according to ECMA 10.4.3.
|
||||
*
|
||||
* @return true if this argument must be an object
|
||||
*/
|
||||
public boolean needsWrappedThis() {
|
||||
public final boolean needsWrappedThis() {
|
||||
return data.needsWrappedThis();
|
||||
}
|
||||
|
||||
private static boolean needsWrappedThis(final Object fn) {
|
||||
return fn instanceof ScriptFunction ? ((ScriptFunction)fn).needsWrappedThis() : false;
|
||||
return fn instanceof ScriptFunction ? ((ScriptFunction) fn).needsWrappedThis() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute this script function.
|
||||
* @param self Target object.
|
||||
* @param arguments Call arguments.
|
||||
*
|
||||
* @param self Target object.
|
||||
* @param arguments Call arguments.
|
||||
* @return ScriptFunction result.
|
||||
* @throws Throwable if there is an exception/error with the invocation or thrown from it
|
||||
* @throws Throwable if there is an exception/error with the invocation or
|
||||
* thrown from it
|
||||
*/
|
||||
Object invoke(final Object self, final Object... arguments) throws Throwable {
|
||||
final Object invoke(final Object self, final Object... arguments) throws Throwable {
|
||||
if (Context.DEBUG) {
|
||||
invokes++;
|
||||
invokes.increment();
|
||||
}
|
||||
return data.invoke(this, self, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute this script function as a constructor.
|
||||
* @param arguments Call arguments.
|
||||
*
|
||||
* @param arguments Call arguments.
|
||||
* @return Newly constructed result.
|
||||
* @throws Throwable if there is an exception/error with the invocation or thrown from it
|
||||
* @throws Throwable if there is an exception/error with the invocation or
|
||||
* thrown from it
|
||||
*/
|
||||
Object construct(final Object... arguments) throws Throwable {
|
||||
final Object construct(final Object... arguments) throws Throwable {
|
||||
return data.construct(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate function. Called from generated {@link ScriptObject} code
|
||||
* for allocation as a factory method
|
||||
* Allocate function. Called from generated {@link ScriptObject} code for
|
||||
* allocation as a factory method
|
||||
*
|
||||
* @return a new instance of the {@link ScriptObject} whose allocator this is
|
||||
* @return a new instance of the {@link ScriptObject} whose allocator this
|
||||
* is
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private Object allocate() {
|
||||
if (Context.DEBUG) {
|
||||
allocations++;
|
||||
allocations.increment();
|
||||
}
|
||||
|
||||
assert !isBoundFunction(); // allocate never invoked on bound functions
|
||||
@ -257,7 +526,7 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
if (object != null) {
|
||||
final Object prototype = getPrototype();
|
||||
if (prototype instanceof ScriptObject) {
|
||||
object.setInitialProto((ScriptObject)prototype);
|
||||
object.setInitialProto((ScriptObject) prototype);
|
||||
}
|
||||
|
||||
if (object.getProto() == null) {
|
||||
@ -277,43 +546,28 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
|
||||
/**
|
||||
* Return Object.prototype - used by "allocate"
|
||||
*
|
||||
* @return Object.prototype
|
||||
*/
|
||||
protected abstract ScriptObject getObjectPrototype();
|
||||
|
||||
/**
|
||||
* Creates a version of this function bound to a specific "self" and other arguments, as per
|
||||
* {@code Function.prototype.bind} functionality in ECMAScript 5.1 section 15.3.4.5.
|
||||
* @param self the self to bind to this function. Can be null (in which case, null is bound as this).
|
||||
* @param args additional arguments to bind to this function. Can be null or empty to not bind additional arguments.
|
||||
* @return a function with the specified self and parameters bound.
|
||||
*/
|
||||
protected ScriptFunction makeBoundFunction(final Object self, final Object[] args) {
|
||||
return makeBoundFunction(data.makeBoundFunctionData(this, self, args));
|
||||
protected final ScriptObject getObjectPrototype() {
|
||||
return Global.objectPrototype();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a version of this function as in {@link ScriptFunction#makeBoundFunction(Object, Object[])},
|
||||
* but using a {@link ScriptFunctionData} for the bound data.
|
||||
*
|
||||
* @param boundData ScriptFuntionData for the bound function
|
||||
* @return a function with the bindings performed according to the given data
|
||||
*/
|
||||
protected abstract ScriptFunction makeBoundFunction(ScriptFunctionData boundData);
|
||||
|
||||
@Override
|
||||
public final String safeToString() {
|
||||
return toSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
public final String toString() {
|
||||
return data.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this function as a String containing its source code. If no source code
|
||||
* exists in this ScriptFunction, its contents will be displayed as {@code [native code]}
|
||||
* Get this function as a String containing its source code. If no source
|
||||
* code exists in this ScriptFunction, its contents will be displayed as
|
||||
* {@code [native code]}
|
||||
*
|
||||
* @return string representation of this function's source
|
||||
*/
|
||||
public final String toSource() {
|
||||
@ -322,27 +576,32 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
|
||||
/**
|
||||
* Get the prototype object for this function
|
||||
*
|
||||
* @return prototype
|
||||
*/
|
||||
public abstract Object getPrototype();
|
||||
public final Object getPrototype() {
|
||||
if (prototype == LAZY_PROTOTYPE) {
|
||||
prototype = new PrototypeObject(this);
|
||||
}
|
||||
return prototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the prototype object for this function
|
||||
* @param prototype new prototype object
|
||||
*
|
||||
* @param newPrototype new prototype object
|
||||
*/
|
||||
public abstract void setPrototype(Object prototype);
|
||||
public final void setPrototype(Object newPrototype) {
|
||||
if (newPrototype instanceof ScriptObject && newPrototype != this.prototype && allocatorMap != null) {
|
||||
// Replace our current allocator map with one that is associated with the new prototype.
|
||||
allocatorMap = allocatorMap.changeProto((ScriptObject) newPrototype);
|
||||
}
|
||||
this.prototype = newPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a function that invokes this function synchronized on {@code sync} or the self object
|
||||
* of the invocation.
|
||||
* @param sync the Object to synchronize on, or undefined
|
||||
* @return synchronized function
|
||||
*/
|
||||
public abstract ScriptFunction makeSynchronizedFunction(Object sync);
|
||||
|
||||
/**
|
||||
* Return the invoke handle bound to a given ScriptObject self reference.
|
||||
* If callee parameter is required result is rebound to this.
|
||||
* Return the invoke handle bound to a given ScriptObject self reference. If
|
||||
* callee parameter is required result is rebound to this.
|
||||
*
|
||||
* @param self self reference
|
||||
* @return bound invoke handle
|
||||
@ -352,9 +611,12 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind the method handle to this {@code ScriptFunction} instance if it needs a callee parameter. If this function's
|
||||
* method handles don't have a callee parameter, the handle is returned unchanged.
|
||||
* @param methodHandle the method handle to potentially bind to this function instance.
|
||||
* Bind the method handle to this {@code ScriptFunction} instance if it
|
||||
* needs a callee parameter. If this function's method handles don't have a
|
||||
* callee parameter, the handle is returned unchanged.
|
||||
*
|
||||
* @param methodHandle the method handle to potentially bind to this
|
||||
* function instance.
|
||||
* @return the potentially bound method handle
|
||||
*/
|
||||
private MethodHandle bindToCalleeIfNeeded(final MethodHandle methodHandle) {
|
||||
@ -364,15 +626,16 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
|
||||
/**
|
||||
* Get the name for this function
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public final String getName() {
|
||||
return data.getName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the scope for this function
|
||||
*
|
||||
* @return the scope
|
||||
*/
|
||||
public final ScriptObject getScope() {
|
||||
@ -383,36 +646,37 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
* Prototype getter for this ScriptFunction - follows the naming convention
|
||||
* used by Nasgen and the code generator
|
||||
*
|
||||
* @param self self reference
|
||||
* @param self self reference
|
||||
* @return self's prototype
|
||||
*/
|
||||
public static Object G$prototype(final Object self) {
|
||||
return self instanceof ScriptFunction ?
|
||||
((ScriptFunction)self).getPrototype() :
|
||||
UNDEFINED;
|
||||
return self instanceof ScriptFunction
|
||||
? ((ScriptFunction) self).getPrototype()
|
||||
: UNDEFINED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prototype setter for this ScriptFunction - follows the naming convention
|
||||
* used by Nasgen and the code generator
|
||||
*
|
||||
* @param self self reference
|
||||
* @param self self reference
|
||||
* @param prototype prototype to set
|
||||
*/
|
||||
public static void S$prototype(final Object self, final Object prototype) {
|
||||
if (self instanceof ScriptFunction) {
|
||||
((ScriptFunction)self).setPrototype(prototype);
|
||||
((ScriptFunction) self).setPrototype(prototype);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Length getter - ECMA 15.3.3.2: Function.length
|
||||
*
|
||||
* @param self self reference
|
||||
* @return length
|
||||
*/
|
||||
public static int G$length(final Object self) {
|
||||
if (self instanceof ScriptFunction) {
|
||||
return ((ScriptFunction)self).data.getArity();
|
||||
return ((ScriptFunction) self).data.getArity();
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -420,12 +684,13 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
|
||||
/**
|
||||
* Name getter - ECMA Function.name
|
||||
*
|
||||
* @param self self refence
|
||||
* @return the name, or undefined if none
|
||||
*/
|
||||
public static Object G$name(final Object self) {
|
||||
if (self instanceof ScriptFunction) {
|
||||
return ((ScriptFunction)self).getName();
|
||||
return ((ScriptFunction) self).getName();
|
||||
}
|
||||
|
||||
return UNDEFINED;
|
||||
@ -433,6 +698,7 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
|
||||
/**
|
||||
* Get the prototype for this ScriptFunction
|
||||
*
|
||||
* @param constructor constructor
|
||||
* @return prototype, or null if given constructor is not a ScriptFunction
|
||||
*/
|
||||
@ -440,7 +706,7 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
if (constructor != null) {
|
||||
final Object proto = constructor.getPrototype();
|
||||
if (proto instanceof ScriptObject) {
|
||||
return (ScriptObject)proto;
|
||||
return (ScriptObject) proto;
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,29 +714,37 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
}
|
||||
|
||||
// These counters are updated only in debug mode.
|
||||
private static int constructorCount;
|
||||
private static int invokes;
|
||||
private static int allocations;
|
||||
private static LongAdder constructorCount;
|
||||
private static LongAdder invokes;
|
||||
private static LongAdder allocations;
|
||||
|
||||
static {
|
||||
if (Context.DEBUG) {
|
||||
constructorCount = new LongAdder();
|
||||
invokes = new LongAdder();
|
||||
allocations = new LongAdder();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the constructorCount
|
||||
*/
|
||||
public static int getConstructorCount() {
|
||||
return constructorCount;
|
||||
public static long getConstructorCount() {
|
||||
return constructorCount.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the invokes
|
||||
*/
|
||||
public static int getInvokes() {
|
||||
return invokes;
|
||||
public static long getInvokes() {
|
||||
return invokes.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the allocations
|
||||
*/
|
||||
public static int getAllocations() {
|
||||
return allocations;
|
||||
public static long getAllocations() {
|
||||
return allocations.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -490,7 +764,6 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
return Context.getGlobal().wrapAsObject(obj);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Object globalFilter(final Object object) {
|
||||
// replace whatever we get with the current global object
|
||||
@ -498,14 +771,16 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Some receivers are primitive, in that case, according to the Spec we create a new
|
||||
* native object per callsite with the wrap filter. We can only apply optimistic builtins
|
||||
* if there is no per instance state saved for these wrapped objects (e.g. currently NativeStrings),
|
||||
* otherwise we can't create optimistic versions
|
||||
* Some receivers are primitive, in that case, according to the Spec we
|
||||
* create a new native object per callsite with the wrap filter. We can only
|
||||
* apply optimistic builtins if there is no per instance state saved for
|
||||
* these wrapped objects (e.g. currently NativeStrings), otherwise we can't
|
||||
* create optimistic versions
|
||||
*
|
||||
* @param self receiver
|
||||
* @param linkLogicClass linkLogicClass, or null if no link logic exists
|
||||
* @return link logic instance, or null if one could not be constructed for this receiver
|
||||
* @param self receiver
|
||||
* @param linkLogicClass linkLogicClass, or null if no link logic exists
|
||||
* @return link logic instance, or null if one could not be constructed for
|
||||
* this receiver
|
||||
*/
|
||||
private static LinkLogic getLinkLogic(final Object self, final Class<? extends LinkLogic> linkLogicClass) {
|
||||
if (linkLogicClass == null) {
|
||||
@ -518,25 +793,25 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
|
||||
final Object wrappedSelf = wrapFilter(self);
|
||||
if (wrappedSelf instanceof OptimisticBuiltins) {
|
||||
if (wrappedSelf != self && ((OptimisticBuiltins)wrappedSelf).hasPerInstanceAssumptions()) {
|
||||
if (wrappedSelf != self && ((OptimisticBuiltins) wrappedSelf).hasPerInstanceAssumptions()) {
|
||||
return null; //pessimistic - we created a wrapped object different from the primitive, but the assumptions have instance state
|
||||
}
|
||||
return ((OptimisticBuiltins)wrappedSelf).getLinkLogic(linkLogicClass);
|
||||
return ((OptimisticBuiltins) wrappedSelf).getLinkLogic(linkLogicClass);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* dyn:call call site signature: (callee, thiz, [args...])
|
||||
* generated method signature: (callee, thiz, [args...])
|
||||
* dyn:call call site signature: (callee, thiz, [args...]) generated method
|
||||
* signature: (callee, thiz, [args...])
|
||||
*
|
||||
* cases:
|
||||
* (a) method has callee parameter
|
||||
* (1) for local/scope calls, we just bind thiz and drop the second argument.
|
||||
* (2) for normal this-calls, we have to swap thiz and callee to get matching signatures.
|
||||
* (1) for local/scope calls, we just bind thiz and drop the second argument.
|
||||
* (2) for normal this-calls, we have to swap thiz and callee to get matching signatures.
|
||||
* (b) method doesn't have callee parameter (builtin functions)
|
||||
* (3) for local/scope calls, bind thiz and drop both callee and thiz.
|
||||
* (4) for normal this-calls, drop callee.
|
||||
* (3) for local/scope calls, bind thiz and drop both callee and thiz.
|
||||
* (4) for normal this-calls, drop callee.
|
||||
*
|
||||
* @return guarded invocation for call
|
||||
*/
|
||||
@ -544,11 +819,11 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
|
||||
final MethodType type = desc.getMethodType();
|
||||
|
||||
final String name = getName();
|
||||
final String name = getName();
|
||||
final boolean isUnstable = request.isCallSiteUnstable();
|
||||
final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
|
||||
final boolean isCall = !scopeCall && data.isBuiltin() && "call".equals(name);
|
||||
final boolean isApply = !scopeCall && data.isBuiltin() && "apply".equals(name);
|
||||
final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
|
||||
final boolean isCall = !scopeCall && data.isBuiltin() && "call".equals(name);
|
||||
final boolean isApply = !scopeCall && data.isBuiltin() && "apply".equals(name);
|
||||
|
||||
final boolean isApplyOrCall = isCall | isApply;
|
||||
|
||||
@ -569,7 +844,7 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
return new GuardedInvocation(
|
||||
handle,
|
||||
null,
|
||||
(SwitchPoint)null,
|
||||
(SwitchPoint) null,
|
||||
ClassCastException.class);
|
||||
}
|
||||
|
||||
@ -672,14 +947,14 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
this,
|
||||
cf.getFlags()) :
|
||||
guard,
|
||||
spsArray,
|
||||
spsArray,
|
||||
exceptionGuard);
|
||||
}
|
||||
|
||||
private GuardedInvocation createApplyOrCallCall(final boolean isApply, final CallSiteDescriptor desc, final LinkRequest request, final Object[] args) {
|
||||
final MethodType descType = desc.getMethodType();
|
||||
final int paramCount = descType.parameterCount();
|
||||
if(descType.parameterType(paramCount - 1).isArray()) {
|
||||
if (descType.parameterType(paramCount - 1).isArray()) {
|
||||
// This is vararg invocation of apply or call. This can normally only happen when we do a recursive
|
||||
// invocation of createApplyOrCallCall (because we're doing apply-of-apply). In this case, create delegate
|
||||
// linkage by unpacking the vararg invocation and use pairArguments to introduce the necessary spreader.
|
||||
@ -786,7 +1061,7 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
inv = MH.filterArguments(inv, 2, NativeFunction.TO_APPLY_ARGS);
|
||||
} else {
|
||||
// If the original call site doesn't pass argArray, pass in an empty array
|
||||
inv = MH.insertArguments(inv, 2, (Object)ScriptRuntime.EMPTY_ARRAY);
|
||||
inv = MH.insertArguments(inv, 2, (Object) ScriptRuntime.EMPTY_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -851,7 +1126,7 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
final LinkRequest request, final Object[] args) {
|
||||
final MethodType descType = desc.getMethodType();
|
||||
final int paramCount = descType.parameterCount();
|
||||
final Object[] varArgs = (Object[])args[paramCount - 1];
|
||||
final Object[] varArgs = (Object[]) args[paramCount - 1];
|
||||
// -1 'cause we're not passing the vararg array itself
|
||||
final int copiedArgCount = args.length - 1;
|
||||
final int varArgCount = varArgs.length;
|
||||
@ -893,7 +1168,7 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
// If the last parameter type of the guard is an array, then it is already itself a guard for a vararg apply
|
||||
// invocation. We must filter the last argument with toApplyArgs otherwise deeper levels of nesting will fail
|
||||
// with ClassCastException of NativeArray to Object[].
|
||||
if(guardType.parameterType(guardParamCount - 1).isArray()) {
|
||||
if (guardType.parameterType(guardParamCount - 1).isArray()) {
|
||||
arrayConvertingGuard = MH.filterArguments(guard, guardParamCount - 1, NativeFunction.TO_APPLY_ARGS);
|
||||
} else {
|
||||
arrayConvertingGuard = guard;
|
||||
@ -903,19 +1178,20 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
}
|
||||
|
||||
private static MethodHandle bindImplicitThis(final Object fn, final MethodHandle mh) {
|
||||
final MethodHandle bound;
|
||||
if(fn instanceof ScriptFunction && ((ScriptFunction)fn).needsWrappedThis()) {
|
||||
bound = MH.filterArguments(mh, 1, SCRIPTFUNCTION_GLOBALFILTER);
|
||||
} else {
|
||||
bound = mh;
|
||||
}
|
||||
return MH.insertArguments(bound, 1, ScriptRuntime.UNDEFINED);
|
||||
}
|
||||
final MethodHandle bound;
|
||||
if (fn instanceof ScriptFunction && ((ScriptFunction) fn).needsWrappedThis()) {
|
||||
bound = MH.filterArguments(mh, 1, SCRIPTFUNCTION_GLOBALFILTER);
|
||||
} else {
|
||||
bound = mh;
|
||||
}
|
||||
return MH.insertArguments(bound, 1, ScriptRuntime.UNDEFINED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for noSuchMethod/noSuchProperty and JSAdapter hooks.
|
||||
*
|
||||
* These don't want a callee parameter, so bind that. Name binding is optional.
|
||||
* These don't want a callee parameter, so bind that. Name binding is
|
||||
* optional.
|
||||
*/
|
||||
MethodHandle getCallMethodHandle(final MethodType type, final String bindName) {
|
||||
return pairArguments(bindToNameIfNeeded(bindToCalleeIfNeeded(data.getGenericInvoker(scope)), bindName), type);
|
||||
@ -939,10 +1215,11 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guard that checks if a {@link ScriptFunction} is equal to
|
||||
* a known ScriptFunction, using reference comparison
|
||||
* Get the guard that checks if a {@link ScriptFunction} is equal to a known
|
||||
* ScriptFunction, using reference comparison
|
||||
*
|
||||
* @param function The ScriptFunction to check against. This will be bound to the guard method handle
|
||||
* @param function The ScriptFunction to check against. This will be bound
|
||||
* to the guard method handle
|
||||
*
|
||||
* @return method handle for guard
|
||||
*/
|
||||
@ -957,11 +1234,12 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a guard that checks if a {@link ScriptFunction} is equal to
|
||||
* a known ScriptFunction using reference comparison, and whether the type of
|
||||
* the second argument (this-object) is not a JavaScript primitive type.
|
||||
* Get a guard that checks if a {@link ScriptFunction} is equal to a known
|
||||
* ScriptFunction using reference comparison, and whether the type of the
|
||||
* second argument (this-object) is not a JavaScript primitive type.
|
||||
*
|
||||
* @param function The ScriptFunction to check against. This will be bound to the guard method handle
|
||||
* @param function The ScriptFunction to check against. This will be bound
|
||||
* to the guard method handle
|
||||
*
|
||||
* @return method handle for guard
|
||||
*/
|
||||
@ -972,12 +1250,12 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isFunctionMH(final Object self, final ScriptFunctionData data) {
|
||||
return self instanceof ScriptFunction && ((ScriptFunction)self).data == data;
|
||||
return self instanceof ScriptFunction && ((ScriptFunction) self).data == data;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isNonStrictFunction(final Object self, final Object arg, final ScriptFunctionData data) {
|
||||
return self instanceof ScriptFunction && ((ScriptFunction)self).data == data && arg instanceof ScriptObject;
|
||||
return self instanceof ScriptFunction && ((ScriptFunction) self).data == data && arg instanceof ScriptObject;
|
||||
}
|
||||
|
||||
//TODO this can probably be removed given that we have builtin switchpoints in the context
|
||||
@ -990,7 +1268,7 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
@SuppressWarnings("unused")
|
||||
private static Object[] addZerothElement(final Object[] args, final Object value) {
|
||||
// extends input array with by adding new zeroth element
|
||||
final Object[] src = args == null? ScriptRuntime.EMPTY_ARRAY : args;
|
||||
final Object[] src = args == null ? ScriptRuntime.EMPTY_ARRAY : args;
|
||||
final Object[] result = new Object[src.length + 1];
|
||||
System.arraycopy(src, 0, result, 1, src.length);
|
||||
result[0] = value;
|
||||
@ -1014,4 +1292,3 @@ public abstract class ScriptFunction extends ScriptObject {
|
||||
return MH.findVirtual(MethodHandles.lookup(), ScriptFunction.class, name, MH.type(rtype, types));
|
||||
}
|
||||
}
|
||||
|
||||
|
12
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunctionData.java
12
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunctionData.java
@ -151,7 +151,7 @@ public abstract class ScriptFunctionData implements Serializable {
|
||||
* Is this a ScriptFunction generated with strict semantics?
|
||||
* @return true if strict, false otherwise
|
||||
*/
|
||||
public boolean isStrict() {
|
||||
public final boolean isStrict() {
|
||||
return (flags & IS_STRICT) != 0;
|
||||
}
|
||||
|
||||
@ -164,11 +164,11 @@ public abstract class ScriptFunctionData implements Serializable {
|
||||
return getName();
|
||||
}
|
||||
|
||||
boolean isBuiltin() {
|
||||
final boolean isBuiltin() {
|
||||
return (flags & IS_BUILTIN) != 0;
|
||||
}
|
||||
|
||||
boolean isConstructor() {
|
||||
final boolean isConstructor() {
|
||||
return (flags & IS_CONSTRUCTOR) != 0;
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ public abstract class ScriptFunctionData implements Serializable {
|
||||
* according to ECMA 10.4.3.
|
||||
* @return true if this argument must be an object
|
||||
*/
|
||||
boolean needsWrappedThis() {
|
||||
final boolean needsWrappedThis() {
|
||||
return (flags & USES_THIS) != 0 && (flags & IS_STRICT_OR_BUILTIN) == 0;
|
||||
}
|
||||
|
||||
@ -318,7 +318,7 @@ public abstract class ScriptFunctionData implements Serializable {
|
||||
* Used to find an apply to call version that fits this callsite.
|
||||
* We cannot just, as in the normal matcher case, return e.g. (Object, Object, int)
|
||||
* for (Object, Object, int, int, int) or we will destroy the semantics and get
|
||||
* a function that, when padded with undefineds, behaves differently
|
||||
* a function that, when padded with undefined values, behaves differently
|
||||
* @param type actual call site type
|
||||
* @return apply to call that perfectly fits this callsite or null if none found
|
||||
*/
|
||||
@ -397,7 +397,7 @@ public abstract class ScriptFunctionData implements Serializable {
|
||||
|
||||
/**
|
||||
* This method is used to create the immutable portion of a bound function.
|
||||
* See {@link ScriptFunction#makeBoundFunction(Object, Object[])}
|
||||
* See {@link ScriptFunction#createBound(Object, Object[])}
|
||||
*
|
||||
* @param fn the original function being bound
|
||||
* @param self this reference to bind. Can be null.
|
||||
|
@ -64,6 +64,7 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
import jdk.internal.dynalink.linker.LinkRequest;
|
||||
@ -211,7 +212,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
*/
|
||||
public ScriptObject(final PropertyMap map) {
|
||||
if (Context.DEBUG) {
|
||||
ScriptObject.count++;
|
||||
ScriptObject.count.increment();
|
||||
}
|
||||
this.arrayData = ArrayData.EMPTY_ARRAY;
|
||||
this.setMap(map == null ? PropertyMap.newMap() : map);
|
||||
@ -2316,7 +2317,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
MH.dropArguments(
|
||||
MH.constant(
|
||||
ScriptFunction.class,
|
||||
func.makeBoundFunction(thiz, new Object[] { name })),
|
||||
func.createBound(thiz, new Object[] { name })),
|
||||
0,
|
||||
Object.class),
|
||||
NashornGuards.combineGuards(
|
||||
@ -2422,7 +2423,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
return UNDEFINED;
|
||||
}
|
||||
|
||||
return ((ScriptFunction)value).makeBoundFunction(this, new Object[] {name});
|
||||
return ((ScriptFunction)value).createBound(this, new Object[] {name});
|
||||
}
|
||||
|
||||
private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String name) {
|
||||
@ -3811,15 +3812,20 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
}
|
||||
|
||||
/** This is updated only in debug mode - counts number of {@code ScriptObject} instances created */
|
||||
private static int count;
|
||||
private static LongAdder count;
|
||||
|
||||
static {
|
||||
if (Context.DEBUG) {
|
||||
count = new LongAdder();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get number of {@code ScriptObject} instances created. If not running in debug
|
||||
* mode this is always 0
|
||||
*
|
||||
* @return number of ScriptObjects created
|
||||
*/
|
||||
public static int getCount() {
|
||||
return count;
|
||||
public static long getCount() {
|
||||
return count.longValue();
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ public final class StoredScript implements Serializable {
|
||||
return compilationId;
|
||||
}
|
||||
|
||||
private Map<String, Class<?>> installClasses(final Source source, final CodeInstaller<ScriptEnvironment> installer) {
|
||||
private Map<String, Class<?>> installClasses(final Source source, final CodeInstaller installer) {
|
||||
final Map<String, Class<?>> installedClasses = new HashMap<>();
|
||||
final byte[] mainClassBytes = classBytes.get(mainClassName);
|
||||
final Class<?> mainClass = installer.install(mainClassName, mainClassBytes);
|
||||
@ -96,7 +96,7 @@ public final class StoredScript implements Serializable {
|
||||
return installedClasses;
|
||||
}
|
||||
|
||||
FunctionInitializer installFunction(final RecompilableScriptFunctionData data, final CodeInstaller<ScriptEnvironment> installer) {
|
||||
FunctionInitializer installFunction(final RecompilableScriptFunctionData data, final CodeInstaller installer) {
|
||||
final Map<String, Class<?>> installedClasses = installClasses(data.getSource(), installer);
|
||||
|
||||
assert initializers != null;
|
||||
@ -124,7 +124,7 @@ public final class StoredScript implements Serializable {
|
||||
* @param installer the installer
|
||||
* @return main script class
|
||||
*/
|
||||
Class<?> installScript(final Source source, final CodeInstaller<ScriptEnvironment> installer) {
|
||||
Class<?> installScript(final Source source, final CodeInstaller installer) {
|
||||
|
||||
final Map<String, Class<?>> installedClasses = installClasses(source, installer);
|
||||
|
||||
|
@ -352,7 +352,7 @@ public final class WithObject extends Scope {
|
||||
}
|
||||
|
||||
private static Object bindToExpression(final ScriptFunction fn, final Object receiver) {
|
||||
return fn.makeBoundFunction(withFilterExpression(receiver), ScriptRuntime.EMPTY_ARRAY);
|
||||
return fn.createBound(withFilterExpression(receiver), ScriptRuntime.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
private MethodHandle expressionGuard(final String name, final ScriptObject owner) {
|
||||
|
@ -191,7 +191,7 @@ public abstract class ContinuousArrayData extends ArrayData {
|
||||
|
||||
/**
|
||||
* Return element setter for a {@link ContinuousArrayData}
|
||||
* @param clazz clazz for exact type guard
|
||||
* @param clazz class for exact type guard
|
||||
* @param setHas set has guard
|
||||
* @param elementType element type
|
||||
* @return method handle for element setter
|
||||
|
@ -34,7 +34,7 @@ import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
|
||||
* This filter handles the presence of undefined array elements.
|
||||
*/
|
||||
final class UndefinedArrayFilter extends ArrayFilter {
|
||||
/** Bit vector tracking undefines. */
|
||||
/** Bit vector tracking undefined slots. */
|
||||
private final BitVector undefined;
|
||||
|
||||
UndefinedArrayFilter(final ArrayData underlying) {
|
||||
|
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java
@ -49,7 +49,6 @@ import jdk.nashorn.api.scripting.JSObject;
|
||||
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
|
||||
import jdk.nashorn.internal.lookup.MethodHandleFactory;
|
||||
import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
|
||||
import jdk.nashorn.internal.objects.ScriptFunctionImpl;
|
||||
import jdk.nashorn.internal.runtime.ECMAException;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
import jdk.nashorn.internal.runtime.OptimisticReturnFilters;
|
||||
@ -396,8 +395,8 @@ public final class Bootstrap {
|
||||
* @throws ECMAException with {@code TypeError} if the object is not a callable.
|
||||
*/
|
||||
public static Object bindCallable(final Object callable, final Object boundThis, final Object[] boundArgs) {
|
||||
if (callable instanceof ScriptFunctionImpl) {
|
||||
return ((ScriptFunctionImpl)callable).makeBoundFunction(boundThis, boundArgs);
|
||||
if (callable instanceof ScriptFunction) {
|
||||
return ((ScriptFunction)callable).createBound(boundThis, boundArgs);
|
||||
} else if (callable instanceof BoundCallable) {
|
||||
return ((BoundCallable)callable).bind(boundArgs);
|
||||
} else if (isCallable(callable)) {
|
||||
|
@ -43,6 +43,7 @@ import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import jdk.internal.dynalink.ChainedCallSite;
|
||||
import jdk.internal.dynalink.DynamicLinker;
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
@ -70,7 +71,7 @@ public class LinkerCallSite extends ChainedCallSite {
|
||||
LinkerCallSite(final NashornCallSiteDescriptor descriptor) {
|
||||
super(descriptor);
|
||||
if (Context.DEBUG) {
|
||||
LinkerCallSite.count++;
|
||||
LinkerCallSite.count.increment();
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,7 +174,7 @@ public class LinkerCallSite extends ChainedCallSite {
|
||||
* @return self reference
|
||||
*/
|
||||
public static Object increaseMissCount(final String desc, final Object self) {
|
||||
++missCount;
|
||||
missCount.increment();
|
||||
if (r.nextInt(100) < missSamplingPercentage) {
|
||||
final AtomicInteger i = missCounts.get(desc);
|
||||
if (i == null) {
|
||||
@ -509,12 +510,19 @@ public class LinkerCallSite extends ChainedCallSite {
|
||||
}
|
||||
|
||||
// counters updated in debug mode
|
||||
private static int count;
|
||||
private static LongAdder count;
|
||||
private static final HashMap<String, AtomicInteger> missCounts = new HashMap<>();
|
||||
private static int missCount;
|
||||
private static LongAdder missCount;
|
||||
private static final Random r = new Random();
|
||||
private static final int missSamplingPercentage = Options.getIntProperty("nashorn.tcs.miss.samplePercent", 1);
|
||||
|
||||
static {
|
||||
if (Context.DEBUG) {
|
||||
count = new LongAdder();
|
||||
missCount = new LongAdder();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxChainLength() {
|
||||
return 8;
|
||||
@ -524,16 +532,16 @@ public class LinkerCallSite extends ChainedCallSite {
|
||||
* Get the callsite count
|
||||
* @return the count
|
||||
*/
|
||||
public static int getCount() {
|
||||
return count;
|
||||
public static long getCount() {
|
||||
return count.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the callsite miss count
|
||||
* @return the missCount
|
||||
*/
|
||||
public static int getMissCount() {
|
||||
return missCount;
|
||||
public static long getMissCount() {
|
||||
return missCount.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -26,7 +26,6 @@
|
||||
package jdk.nashorn.internal.runtime.linker;
|
||||
|
||||
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
@ -42,13 +41,11 @@ import jdk.internal.dynalink.linker.LinkRequest;
|
||||
import jdk.internal.dynalink.linker.LinkerServices;
|
||||
import jdk.internal.dynalink.linker.MethodHandleTransformer;
|
||||
import jdk.internal.dynalink.support.DefaultInternalObjectFilter;
|
||||
import jdk.internal.dynalink.support.Guards;
|
||||
import jdk.internal.dynalink.support.Lookup;
|
||||
import jdk.nashorn.api.scripting.ScriptUtils;
|
||||
import jdk.nashorn.internal.runtime.ConsString;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
import jdk.nashorn.internal.runtime.options.Options;
|
||||
|
||||
/**
|
||||
|
2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/joni/Config.java
2
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/joni/Config.java
@ -65,7 +65,7 @@ public interface Config {
|
||||
|
||||
final boolean DONT_OPTIMIZE = false;
|
||||
|
||||
final boolean USE_STRING_TEMPLATES = true; // use embeded string templates in Regex object as byte arrays instead of compiling them into int bytecode array
|
||||
final boolean USE_STRING_TEMPLATES = true; // use embedded string templates in Regex object as byte arrays instead of compiling them into int bytecode array
|
||||
|
||||
final boolean NON_UNICODE_SDW = true;
|
||||
|
||||
|
@ -55,7 +55,7 @@ function parse(/*code, [name], [location]*/) {
|
||||
// do not start with '/'. If regexp, then eval it to make RegExp object
|
||||
return value.startsWith('/')? eval(value) : value.substring(1);
|
||||
} else {
|
||||
// anythin else is returned "as is""
|
||||
// anything else is returned "as is"
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
@ -42,8 +42,8 @@ import java.util.ResourceBundle;
|
||||
import jdk.nashorn.api.scripting.NashornException;
|
||||
import jdk.nashorn.internal.codegen.Compiler;
|
||||
import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
|
||||
import jdk.nashorn.internal.ir.FunctionNode;
|
||||
import jdk.nashorn.internal.ir.Expression;
|
||||
import jdk.nashorn.internal.ir.FunctionNode;
|
||||
import jdk.nashorn.internal.ir.debug.ASTWriter;
|
||||
import jdk.nashorn.internal.ir.debug.PrintVisitor;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
@ -255,12 +255,9 @@ public class Shell implements PartialParser {
|
||||
return COMPILATION_ERROR;
|
||||
}
|
||||
|
||||
new Compiler(
|
||||
Compiler.forNoInstallerCompilation(
|
||||
context,
|
||||
env,
|
||||
null, //null - pass no code installer - this is compile only
|
||||
functionNode.getSource(),
|
||||
context.getErrorManager(),
|
||||
env._strict | functionNode.isStrict()).
|
||||
compile(functionNode, CompilationPhases.COMPILE_ALL_NO_INSTALL);
|
||||
|
||||
|
128
nashorn/test/script/basic/JDK-8134569.js
Normal file
128
nashorn/test/script/basic/JDK-8134569.js
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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-8134569: Add tests for prototype callsites
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
function create() {
|
||||
function C() {
|
||||
this.i1 = 1;
|
||||
this.i2 = 2;
|
||||
this.i3 = 3;
|
||||
return this;
|
||||
}
|
||||
return new C();
|
||||
}
|
||||
|
||||
function createEmpty() {
|
||||
function C() {
|
||||
return this;
|
||||
}
|
||||
return new C();
|
||||
}
|
||||
|
||||
function createDeep() {
|
||||
function C() {
|
||||
this.i1 = 1;
|
||||
this.i2 = 2;
|
||||
this.i3 = 3;
|
||||
return this;
|
||||
}
|
||||
function D() {
|
||||
this.p1 = 1;
|
||||
this.p2 = 2;
|
||||
this.p3 = 3;
|
||||
return this;
|
||||
}
|
||||
C.prototype = new D();
|
||||
return new C();
|
||||
}
|
||||
|
||||
function createEval() {
|
||||
return eval("Object.create({})");
|
||||
}
|
||||
|
||||
function p(o) { print(o.x) }
|
||||
|
||||
var a, b;
|
||||
|
||||
create();
|
||||
a = create();
|
||||
b = create();
|
||||
a.__proto__.x = 123;
|
||||
|
||||
p(a);
|
||||
p(b);
|
||||
|
||||
a = create();
|
||||
b = create();
|
||||
b.__proto__.x = 123;
|
||||
|
||||
p(a);
|
||||
p(b);
|
||||
|
||||
a = createEmpty();
|
||||
b = createEmpty();
|
||||
a.__proto__.x = 123;
|
||||
|
||||
p(a);
|
||||
p(b);
|
||||
|
||||
a = createEmpty();
|
||||
b = createEmpty();
|
||||
b.__proto__.x = 123;
|
||||
|
||||
p(a);
|
||||
p(b);
|
||||
|
||||
a = createDeep();
|
||||
b = createDeep();
|
||||
a.__proto__.__proto__.x = 123;
|
||||
|
||||
p(a);
|
||||
p(b);
|
||||
|
||||
a = createDeep();
|
||||
b = createDeep();
|
||||
b.__proto__.__proto__.x = 123;
|
||||
|
||||
p(a);
|
||||
p(b);
|
||||
|
||||
a = createEval();
|
||||
b = createEval();
|
||||
a.__proto__.x = 123;
|
||||
|
||||
p(a);
|
||||
p(b);
|
||||
|
||||
a = createEval();
|
||||
b = createEval();
|
||||
b.__proto__.x = 123;
|
||||
|
||||
p(a);
|
||||
p(b);
|
16
nashorn/test/script/basic/JDK-8134569.js.EXPECTED
Normal file
16
nashorn/test/script/basic/JDK-8134569.js.EXPECTED
Normal file
@ -0,0 +1,16 @@
|
||||
123
|
||||
undefined
|
||||
undefined
|
||||
123
|
||||
123
|
||||
undefined
|
||||
undefined
|
||||
123
|
||||
123
|
||||
undefined
|
||||
undefined
|
||||
123
|
||||
123
|
||||
undefined
|
||||
undefined
|
||||
123
|
48
nashorn/test/script/basic/JDK-8135000.js
Normal file
48
nashorn/test/script/basic/JDK-8135000.js
Normal file
@ -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-8135000: Number.prototype.toFixed returns wrong string for 0.5 and -0.5
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
print(-2.6.toFixed());
|
||||
print(-2.5.toFixed());
|
||||
print(-2.4.toFixed());
|
||||
print(-1.6.toFixed());
|
||||
print(-1.5.toFixed());
|
||||
print(-1.4.toFixed());
|
||||
print(-0.6.toFixed());
|
||||
print(-0.5.toFixed());
|
||||
print(-0.4.toFixed());
|
||||
print(0.4.toFixed());
|
||||
print(0.5.toFixed());
|
||||
print(0.6.toFixed());
|
||||
print(1.4.toFixed());
|
||||
print(1.5.toFixed());
|
||||
print(1.6.toFixed());
|
||||
print(2.4.toFixed());
|
||||
print(2.5.toFixed());
|
||||
print(2.6.toFixed());
|
18
nashorn/test/script/basic/JDK-8135000.js.EXPECTED
Normal file
18
nashorn/test/script/basic/JDK-8135000.js.EXPECTED
Normal file
@ -0,0 +1,18 @@
|
||||
-3
|
||||
-3
|
||||
-2
|
||||
-2
|
||||
-2
|
||||
-1
|
||||
-1
|
||||
-1
|
||||
0
|
||||
0
|
||||
1
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
3
|
||||
3
|
@ -120,7 +120,7 @@ var getEnvMethod = Context.class.getMethod("getEnv")
|
||||
|
||||
var sourceForMethod = Source.class.getMethod("sourceFor", java.lang.String.class, java.lang.String.class)
|
||||
var ParserConstructor = Parser.class.getConstructor(ScriptEnvironment.class, Source.class, ErrorManager.class)
|
||||
var CompilerConstructor = Compiler.class.getConstructor(Context.class, ScriptEnvironment.class, CodeInstaller.class, Source.class, ErrorManager.class, boolean.class);
|
||||
var CompilerConstructor = Compiler.class.getMethod("forNoInstallerCompilation", Context.class, Source.class, boolean.class);
|
||||
|
||||
// compile(script) -- compiles a script specified as a string with its
|
||||
// source code, returns a jdk.nashorn.internal.ir.FunctionNode object
|
||||
@ -134,7 +134,7 @@ function compile(source, phases) {
|
||||
var parser = ParserConstructor.newInstance(env, source, ThrowErrorManager.class.newInstance());
|
||||
var func = parseMethod.invoke(parser);
|
||||
|
||||
var compiler = CompilerConstructor.newInstance(ctxt, env, null, source, null, false);
|
||||
var compiler = CompilerConstructor.invoke(null, ctxt, source, false);
|
||||
|
||||
return compileMethod.invoke(compiler, func, phases);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user