From 019ff918e8861d7045ca6807457cf743419fd2dd Mon Sep 17 00:00:00 2001 From: sundar Date: Wed, 4 Sep 2013 14:29:07 +0530 Subject: 8024120: Setting __proto__ to null removes the __proto__ property Reviewed-by: lagergren, attila --- src/jdk/nashorn/internal/runtime/ScriptObject.java | 19 ++++++++-- .../internal/runtime/resources/mozilla_compat.js | 11 ------ test/script/basic/JDK-8023368.js | 2 -- test/script/basic/JDK-8023368.js.EXPECTED | 8 ++--- test/script/basic/JDK-8024120.js | 42 ++++++++++++++++++++++ test/script/basic/circular_proto.js | 1 - test/script/basic/nonextensible_proto_assign.js | 2 -- 7 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 test/script/basic/JDK-8024120.js diff --git a/src/jdk/nashorn/internal/runtime/ScriptObject.java b/src/jdk/nashorn/internal/runtime/ScriptObject.java index 9d7a7a6b..1fd795fb 100644 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -87,6 +87,8 @@ import jdk.nashorn.internal.runtime.linker.NashornGuards; */ public abstract class ScriptObject extends PropertyListenerManager implements PropertyAccess { + /** __proto__ special property name */ + static final String PROTO_PROPERTY_NAME = "__proto__"; /** Search fall back routine name for "no such method" */ static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__"; @@ -130,6 +132,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr /** Indexed array data. */ private ArrayData arrayData; + static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class); + static final MethodHandle SETPROTOCHECK = findOwnMH("setProtoCheck", void.class, Object.class); + static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class); static final MethodHandle SETSPILL = findOwnMH("setSpill", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class); static final MethodHandle SETSPILLWITHNEW = findOwnMH("setSpillWithNew", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class); @@ -1745,6 +1750,10 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr MethodHandle methodHandle; if (find == null) { + if (PROTO_PROPERTY_NAME.equals(name)) { + return new GuardedInvocation(GETPROTO, NashornGuards.getScriptObjectGuard()); + } + if ("getProp".equals(operator)) { return noSuchProperty(desc, request); } else if ("getMethod".equals(operator)) { @@ -1851,6 +1860,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * toString = function() { print("global toString"); } // don't affect Object.prototype.toString */ FindProperty find = findProperty(name, true, scope, this); + // If it's not a scope search, then we don't want any inherited properties except those with user defined accessors. if (!scope && find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) { // We should still check if inherited data property is not writable @@ -1866,9 +1876,12 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr // Existing, non-writable property return createEmptySetMethod(desc, "property.not.writable", true); } - } else if (!isExtensible()) { - // Non-existing property on a non-extensible object - return createEmptySetMethod(desc, "object.non.extensible", false); + } else { + if (PROTO_PROPERTY_NAME.equals(name)) { + return new GuardedInvocation(SETPROTOCHECK, NashornGuards.getScriptObjectGuard()); + } else if (! isExtensible()) { + return createEmptySetMethod(desc, "object.non.extensible", false); + } } return new SetMethodCreator(this, find, desc).createGuardedInvocation(); diff --git a/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js b/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js index 60bdc7b1..6b934ad4 100644 --- a/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js +++ b/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js @@ -137,17 +137,6 @@ Object.defineProperty(Object.prototype, "__lookupSetter__", { } }); -// Object.prototype.__proto__ (read-only) -Object.defineProperty(Object.prototype, "__proto__", { - configurable: true, enumerable: false, - get: function() { - return Object.getPrototypeOf(this); - }, - set: function(x) { - Object.setPrototypeOf(this, x); - } -}); - // Object.prototype.toSource Object.defineProperty(Object.prototype, "toSource", { configurable: true, enumerable: false, writable: true, diff --git a/test/script/basic/JDK-8023368.js b/test/script/basic/JDK-8023368.js index 9f32805c..da034dbc 100644 --- a/test/script/basic/JDK-8023368.js +++ b/test/script/basic/JDK-8023368.js @@ -28,8 +28,6 @@ * @run */ -load("nashorn:mozilla_compat.js"); - // function to force same callsites function check(obj) { print(obj.func()); diff --git a/test/script/basic/JDK-8023368.js.EXPECTED b/test/script/basic/JDK-8023368.js.EXPECTED index 4ca8d077..c116a6b7 100644 --- a/test/script/basic/JDK-8023368.js.EXPECTED +++ b/test/script/basic/JDK-8023368.js.EXPECTED @@ -4,15 +4,15 @@ hello Func.prototype.func hello [object Object] -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 [object Object] -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 [object Object] -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 new object.toString -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 new object.toString diff --git a/test/script/basic/JDK-8024120.js b/test/script/basic/JDK-8024120.js new file mode 100644 index 00000000..0ac4ff98 --- /dev/null +++ b/test/script/basic/JDK-8024120.js @@ -0,0 +1,42 @@ +/* + * 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. + * + * 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-8024120: Setting __proto__ to null removes the __proto__ property + * + * @test + * @run + */ + +var obj = {}; + +obj.__proto__ = null; + +if (obj.__proto__ !== null || typeof(obj.__proto__) != 'object') { + fail("obj.__proto__ is expected to be null"); +} + +var p = Object.getPrototypeOf(obj); +if (p !== null || typeof(p) != 'object') { + fail("Object.getPrototypeOf(obj) is expected to be null"); +} diff --git a/test/script/basic/circular_proto.js b/test/script/basic/circular_proto.js index 5ae8f9cd..b381b7cf 100644 --- a/test/script/basic/circular_proto.js +++ b/test/script/basic/circular_proto.js @@ -29,7 +29,6 @@ */ // check that we cannot create __proto__ cycle -load("nashorn:mozilla_compat.js"); var obj = {}; var obj2 = Object.create(obj); diff --git a/test/script/basic/nonextensible_proto_assign.js b/test/script/basic/nonextensible_proto_assign.js index 0240420d..10ce4f53 100644 --- a/test/script/basic/nonextensible_proto_assign.js +++ b/test/script/basic/nonextensible_proto_assign.js @@ -28,8 +28,6 @@ * @run */ -load("nashorn:mozilla_compat.js") - // check that we cannot assign to __proto__ of a non-extensible object try { var obj = {} -- cgit v1.2.3 From 0ec1c5d4a918222dc82d6ee8fb8c70b1cef38a1d Mon Sep 17 00:00:00 2001 From: sundar Date: Wed, 4 Sep 2013 19:58:16 +0530 Subject: 8024174: Setting __proto__ property in Object literal should be supported Reviewed-by: jlaskey, lagergren --- .../nashorn/internal/codegen/CodeGenerator.java | 13 +++++- src/jdk/nashorn/internal/runtime/ScriptObject.java | 5 ++- test/script/basic/JDK-8024174.js | 51 ++++++++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 test/script/basic/JDK-8024174.js diff --git a/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 0ccc8a40..809b2ec2 100644 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -1361,6 +1361,7 @@ final class CodeGenerator extends NodeOperatorVisitor values = new ArrayList<>(); boolean hasGettersSetters = false; + Expression protoNode = null; for (PropertyNode propertyNode: elements) { final Expression value = propertyNode.getValue(); @@ -1369,6 +1370,9 @@ final class CodeGenerator extends NodeOperatorVisitor Date: Thu, 5 Sep 2013 21:17:06 +0530 Subject: 8024255: When a keyword is used as object property name, the property can not be deleted Reviewed-by: jlaskey, lagergren --- src/jdk/nashorn/internal/parser/Parser.java | 2 +- test/script/basic/JDK-8024255.js | 51 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 test/script/basic/JDK-8024255.js diff --git a/src/jdk/nashorn/internal/parser/Parser.java b/src/jdk/nashorn/internal/parser/Parser.java index ab008900..ea01f598 100644 --- a/src/jdk/nashorn/internal/parser/Parser.java +++ b/src/jdk/nashorn/internal/parser/Parser.java @@ -2060,7 +2060,7 @@ loop: case FLOATING: return getLiteral(); default: - return getIdentifierName(); + return getIdentifierName().setIsPropertyName(); } } diff --git a/test/script/basic/JDK-8024255.js b/test/script/basic/JDK-8024255.js new file mode 100644 index 00000000..54022a5c --- /dev/null +++ b/test/script/basic/JDK-8024255.js @@ -0,0 +1,51 @@ +/* + * 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. + * + * 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-8024255: When a keyword is used as object property name, the property can not be deleted + * + * @test + * @run + */ + +function check(obj, name) { + var desc = Object.getOwnPropertyDescriptor(obj, name); + if (! desc.configurable) { + fail("Property " + name + " is not configurable"); + } + + if (! (delete obj[name])) { + fail("Property " + name + " can not be deleted"); + } +} + +var obj = { + default: 344, + in: 'hello', + if: false, + class: 4.223 +} + +for (var p in obj) { + check(obj, p); +} -- cgit v1.2.3 From d1bfa3d123a836f5cda89065d204296ae1ff5b82 Mon Sep 17 00:00:00 2001 From: sundar Date: Mon, 9 Sep 2013 20:10:41 +0530 Subject: 8024180: Incorrect handling of expression and parent scope in 'with' statements Reviewed-by: jlaskey, hannesw --- .../nashorn/api/scripting/NashornScriptEngine.java | 15 ++-- .../nashorn/api/scripting/ScriptObjectMirror.java | 20 +++--- src/jdk/nashorn/internal/objects/Global.java | 22 +++++- src/jdk/nashorn/internal/runtime/Context.java | 2 +- src/jdk/nashorn/internal/runtime/GlobalObject.java | 12 ++++ .../internal/runtime/NativeJavaPackage.java | 2 +- src/jdk/nashorn/internal/runtime/ScriptObject.java | 70 ++++-------------- .../nashorn/internal/runtime/ScriptRuntime.java | 60 ++-------------- src/jdk/nashorn/internal/runtime/WithObject.java | 82 +++++++++++++--------- .../internal/runtime/resources/Messages.properties | 1 + test/script/basic/8024180/global_var_delete.js | 50 +++++++++++++ .../basic/8024180/global_var_delete.js.EXPECTED | 2 + test/script/basic/8024180/global_var_shadow.js | 45 ++++++++++++ .../basic/8024180/global_var_shadow.js.EXPECTED | 2 + test/script/basic/8024180/scope_no_such_prop.js | 51 ++++++++++++++ .../basic/8024180/scope_no_such_prop.js.EXPECTED | 2 + test/script/basic/8024180/with_expr_prop_add.js | 47 +++++++++++++ .../basic/8024180/with_expr_prop_add.js.EXPECTED | 2 + .../basic/8024180/with_expr_proto_prop_add.js | 49 +++++++++++++ .../8024180/with_expr_proto_prop_add.js.EXPECTED | 2 + test/script/basic/8024180/with_java_object.js | 36 ++++++++++ .../basic/8024180/with_java_object.js.EXPECTED | 1 + .../jdk/nashorn/internal/runtime/ContextTest.java | 3 +- 23 files changed, 415 insertions(+), 163 deletions(-) create mode 100644 test/script/basic/8024180/global_var_delete.js create mode 100644 test/script/basic/8024180/global_var_delete.js.EXPECTED create mode 100644 test/script/basic/8024180/global_var_shadow.js create mode 100644 test/script/basic/8024180/global_var_shadow.js.EXPECTED create mode 100644 test/script/basic/8024180/scope_no_such_prop.js create mode 100644 test/script/basic/8024180/scope_no_such_prop.js.EXPECTED create mode 100644 test/script/basic/8024180/with_expr_prop_add.js create mode 100644 test/script/basic/8024180/with_expr_prop_add.js.EXPECTED create mode 100644 test/script/basic/8024180/with_expr_proto_prop_add.js create mode 100644 test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED create mode 100644 test/script/basic/8024180/with_java_object.js create mode 100644 test/script/basic/8024180/with_java_object.js.EXPECTED diff --git a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 9745d432..ce42a46c 100644 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -315,7 +315,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C final ScriptObjectMirror mirror = (ScriptObjectMirror)thiz; realSelf = mirror.getScriptObject(); realGlobal = mirror.getHomeGlobal(); - if (! realGlobal.isOfContext(nashornContext)) { + if (! isOfContext(realGlobal, nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } } else if (thiz instanceof ScriptObject) { @@ -326,7 +326,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C throw new IllegalArgumentException(getMessage("no.current.nashorn.global")); } - if (! realGlobal.isOfContext(nashornContext)) { + if (! isOfContext(realGlobal, nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } } @@ -394,7 +394,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C // Retrieve nashorn Global object from a given ScriptObjectMirror private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) { ScriptObject sobj = mirror.getScriptObject(); - if (sobj instanceof GlobalObject && sobj.isOfContext(nashornContext)) { + if (sobj instanceof GlobalObject && isOfContext(sobj, nashornContext)) { return sobj; } @@ -470,7 +470,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ScriptObjectMirror selfMirror = null; if (selfObject instanceof ScriptObjectMirror) { selfMirror = (ScriptObjectMirror)selfObject; - if (! selfMirror.getHomeGlobal().isOfContext(nashornContext)) { + if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } } else if (selfObject instanceof ScriptObject) { @@ -481,7 +481,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C throw new IllegalArgumentException(getMessage("no.current.nashorn.global")); } - if (! oldGlobal.isOfContext(nashornContext)) { + if (! isOfContext(oldGlobal, nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } @@ -617,4 +617,9 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } return true; } + + private static boolean isOfContext(final ScriptObject global, final Context context) { + assert global instanceof GlobalObject: "Not a Global object"; + return ((GlobalObject)global).isOfContext(context); + } } diff --git a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java index 99ce73c1..e8546cd6 100644 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java @@ -42,6 +42,7 @@ import java.util.Set; import java.util.concurrent.Callable; import javax.script.Bindings; import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.GlobalObject; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; @@ -62,6 +63,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { private final ScriptObject sobj; private final ScriptObject global; + private final boolean strict; @Override public boolean equals(final Object other) { @@ -101,7 +103,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { final Object val = functionName == null? sobj : sobj.get(functionName); if (val instanceof ScriptFunction) { final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; - return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); + return wrap(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { return ((ScriptObjectMirror)val).call(null, args); } @@ -131,7 +133,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { final Object val = functionName == null? sobj : sobj.get(functionName); if (val instanceof ScriptFunction) { final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; - return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global); + return wrap(ScriptRuntime.construct((ScriptFunction)val, unwrapArray(modArgs, global)), global); } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { return ((ScriptObjectMirror)val).newObject(null, args); } @@ -197,7 +199,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { public void setSlot(final int index, final Object value) { inGlobal(new Callable() { @Override public Void call() { - sobj.set(index, unwrap(value, global), global.isStrictContext()); + sobj.set(index, unwrap(value, global), strict); return null; } }); @@ -209,7 +211,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { public void clear() { inGlobal(new Callable() { @Override public Object call() { - sobj.clear(); + sobj.clear(strict); return null; } }); @@ -292,7 +294,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { return inGlobal(new Callable() { @Override public Object call() { final Object modValue = globalChanged? wrap(value, oldGlobal) : value; - return translateUndefined(wrap(sobj.put(key, unwrap(modValue, global)), global)); + return translateUndefined(wrap(sobj.put(key, unwrap(modValue, global), strict), global)); } }); } @@ -303,7 +305,6 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { final boolean globalChanged = (oldGlobal != global); inGlobal(new Callable() { @Override public Object call() { - final boolean strict = global.isStrictContext(); for (final Map.Entry entry : map.entrySet()) { final Object value = entry.getValue(); final Object modValue = globalChanged? wrap(value, oldGlobal) : value; @@ -318,7 +319,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { public Object remove(final Object key) { return inGlobal(new Callable() { @Override public Object call() { - return wrap(sobj.remove(unwrap(key, global)), global); + return wrap(sobj.remove(unwrap(key, global), strict), global); } }); } @@ -333,7 +334,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { public boolean delete(final Object key) { return inGlobal(new Callable() { @Override public Boolean call() { - return sobj.delete(unwrap(key, global)); + return sobj.delete(unwrap(key, global), strict); } }); } @@ -637,10 +638,11 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { ScriptObjectMirror(final ScriptObject sobj, final ScriptObject global) { assert sobj != null : "ScriptObjectMirror on null!"; - assert global != null : "null global for ScriptObjectMirror!"; + assert global instanceof GlobalObject : "global is not a GlobalObject"; this.sobj = sobj; this.global = global; + this.strict = ((GlobalObject)global).isStrictContext(); } // accessors for script engine diff --git a/src/jdk/nashorn/internal/objects/Global.java b/src/jdk/nashorn/internal/objects/Global.java index 6d7be378..b7a902b7 100644 --- a/src/jdk/nashorn/internal/objects/Global.java +++ b/src/jdk/nashorn/internal/objects/Global.java @@ -412,6 +412,14 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // initialized by nasgen private static PropertyMap $nasgenmap$; + // context to which this global belongs to + private final Context context; + + @Override + protected Context getContext() { + return context; + } + // performs initialization checks for Global constructor and returns the // PropertyMap, if everything is fine. private static PropertyMap checkAndGetMap(final Context context) { @@ -439,7 +447,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { */ public Global(final Context context) { super(checkAndGetMap(context)); - this.setContext(context); + this.context = context; this.setIsScope(); final int cacheSize = context.getEnv()._class_cache_size; @@ -481,6 +489,16 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // GlobalObject interface implementation + @Override + public boolean isOfContext(final Context context) { + return this.context == context; + } + + @Override + public boolean isStrictContext() { + return context.getEnv()._strict; + } + @Override public void initBuiltinObjects() { if (this.builtinObject != null) { @@ -1765,7 +1783,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // do not fill $ENV if we have a security manager around // Retrieve current state of ENV variables. final ScriptObject env = newObject(); - env.putAll(System.getenv()); + env.putAll(System.getenv(), scriptEnv._strict); addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, env); } else { addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED); diff --git a/src/jdk/nashorn/internal/runtime/Context.java b/src/jdk/nashorn/internal/runtime/Context.java index 2f0c95d8..4651b508 100644 --- a/src/jdk/nashorn/internal/runtime/Context.java +++ b/src/jdk/nashorn/internal/runtime/Context.java @@ -573,7 +573,7 @@ public final class Context { setGlobalTrusted(newGlobal); final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY : ScriptObjectMirror.wrapArray(args, oldGlobal); - newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped)); + newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped), env._strict); try { // wrap objects from newGlobal's world as mirrors - but if result diff --git a/src/jdk/nashorn/internal/runtime/GlobalObject.java b/src/jdk/nashorn/internal/runtime/GlobalObject.java index 087b3455..7e01fd6e 100644 --- a/src/jdk/nashorn/internal/runtime/GlobalObject.java +++ b/src/jdk/nashorn/internal/runtime/GlobalObject.java @@ -36,6 +36,18 @@ import jdk.nashorn.internal.runtime.linker.InvokeByName; */ public interface GlobalObject { + /** + * Is this global of the given Context? + * @return true if this global belongs to the given Context + */ + public boolean isOfContext(Context context); + + /** + * Does this global belong to a strict Context? + * @return true if this global belongs to a strict Context + */ + public boolean isStrictContext(); + /** * Initialize standard builtin objects like "Object", "Array", "Function" etc. * as well as our extension builtin objects like "Java", "JSAdapter" as properties diff --git a/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java b/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java index 9e725e33..99ba9e19 100644 --- a/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java +++ b/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java @@ -198,7 +198,7 @@ public final class NativeJavaPackage extends ScriptObject { final String propertyName = desc.getNameToken(2); final String fullName = name.isEmpty() ? propertyName : name + "." + propertyName; - final Context context = getContext(); + final Context context = Context.getContextTrusted(); Class javaClass = null; try { diff --git a/src/jdk/nashorn/internal/runtime/ScriptObject.java b/src/jdk/nashorn/internal/runtime/ScriptObject.java index f4a7c145..a4ca6017 100644 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -120,9 +120,6 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr /** objects proto. */ private ScriptObject proto; - /** Context of the object, lazily cached. */ - private Context context; - /** Object flags. */ private int flags; @@ -1042,41 +1039,12 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr set(key, value, false); } - /** - * Return true if the script object context is strict - * @return true if strict context - */ - public final boolean isStrictContext() { - return getContext()._strict; - } - - /** - * Checks if this object belongs to the given context - * @param ctx context to check against - * @return true if this object belongs to the given context - */ - public final boolean isOfContext(final Context ctx) { - return context == ctx; - } - /** * Return the current context from the object's map. * @return Current context. */ - protected final Context getContext() { - if (context == null) { - context = Context.fromClass(getClass()); - } - return context; - } - - /** - * Set the current context. - * @param ctx context instance to set - */ - protected final void setContext(final Context ctx) { - ctx.getClass(); - this.context = ctx; + protected Context getContext() { + return Context.fromClass(getClass()); } /** @@ -1482,9 +1450,10 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr /** * Clears the properties from a ScriptObject * (java.util.Map-like method to help ScriptObjectMirror implementation) + * + * @param strict strict mode or not */ - public void clear() { - final boolean strict = isStrictContext(); + public void clear(final boolean strict) { final Iterator iter = propertyIterator(); while (iter.hasNext()) { delete(iter.next(), strict); @@ -1568,11 +1537,12 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * * @param key property key * @param value property value + * @param strict strict mode or not * @return oldValue if property with same key existed already */ - public Object put(final Object key, final Object value) { + public Object put(final Object key, final Object value, final boolean strict) { final Object oldValue = get(key); - set(key, value, isStrictContext()); + set(key, value, strict); return oldValue; } @@ -1582,9 +1552,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * (java.util.Map-like method to help ScriptObjectMirror implementation) * * @param otherMap a {@literal } map of properties to add + * @param strict strict mode or not */ - public void putAll(final Map otherMap) { - final boolean strict = isStrictContext(); + public void putAll(final Map otherMap, final boolean strict) { for (final Map.Entry entry : otherMap.entrySet()) { set(entry.getKey(), entry.getValue(), strict); } @@ -1595,25 +1565,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * (java.util.Map-like method to help ScriptObjectMirror implementation) * * @param key the key of the property + * @param strict strict mode or not * @return the oldValue of the removed property */ - public Object remove(final Object key) { + public Object remove(final Object key, final boolean strict) { final Object oldValue = get(key); - delete(key, isStrictContext()); + delete(key, strict); return oldValue; } - /** - * Delete a property from the ScriptObject. - * (to help ScriptObjectMirror implementation) - * - * @param key the key of the property - * @return if the delete was successful or not - */ - public boolean delete(final Object key) { - return delete(key, isStrictContext()); - } - /** * Return the size of the ScriptObject - i.e. the number of properties * it contains @@ -2333,11 +2293,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - final boolean isStrict = isStrictContext(); - if (newLength > arrayLength) { setArray(getArray().ensure(newLength - 1)); - if (getArray().canDelete(arrayLength, (newLength - 1), isStrict)) { + if (getArray().canDelete(arrayLength, (newLength - 1), false)) { setArray(getArray().delete(arrayLength, (newLength - 1))); } return; diff --git a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java index 0fa0cc8a..aa146f1d 100644 --- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java @@ -351,35 +351,6 @@ public final class ScriptRuntime { return global; } - /** - * Check that the target function is associated with current Context. And also make sure that 'self', if - * ScriptObject, is from current context. - * - * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve - * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker} - * for operation {@code "dyn:call"}, then using its {@link MethodHandle#invokeExact(Object...)} method instead. - * - * @param target ScriptFunction object. - * @param self Receiver in call. - * @param args Call arguments. - * @return Call result. - */ - public static Object checkAndApply(final ScriptFunction target, final Object self, final Object... args) { - final ScriptObject global = Context.getGlobalTrusted(); - assert (global instanceof GlobalObject): "No current global set"; - - if (target.getContext() != global.getContext()) { - throw new IllegalArgumentException("'target' function is not from current Context"); - } - - if (self instanceof ScriptObject && ((ScriptObject)self).getContext() != global.getContext()) { - throw new IllegalArgumentException("'self' object is not from current Context"); - } - - // all in order - call real 'apply' - return apply(target, self, args); - } - /** * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker} @@ -400,28 +371,6 @@ public final class ScriptRuntime { } } - /** - * Check that the target function is associated with current Context. - * And also make sure that 'self', if ScriptObject, is from current context. - * - * Call a function as a constructor given args. - * - * @param target ScriptFunction object. - * @param args Call arguments. - * @return Constructor call result. - */ - public static Object checkAndConstruct(final ScriptFunction target, final Object... args) { - final ScriptObject global = Context.getGlobalTrusted(); - assert (global instanceof GlobalObject): "No current global set"; - - if (target.getContext() != global.getContext()) { - throw new IllegalArgumentException("'target' function is not from current Context"); - } - - // all in order - call real 'construct' - return construct(target, args); - } - /** * Call a script function as a constructor with given args. * @@ -520,9 +469,12 @@ public final class ScriptRuntime { throw typeError(global, "cant.apply.with.to.null"); } - final ScriptObject withObject = new WithObject(scope, JSType.toScriptObject(global, expression)); + final Object wrappedExpr = JSType.toScriptObject(global, expression); + if (wrappedExpr instanceof ScriptObject) { + return new WithObject(scope, (ScriptObject)wrappedExpr); + } - return withObject; + throw typeError(global, "cant.apply.with.to.non.scriptobject"); } /** @@ -534,7 +486,7 @@ public final class ScriptRuntime { */ public static ScriptObject closeWith(final ScriptObject scope) { if (scope instanceof WithObject) { - return scope.getProto(); + return ((WithObject)scope).getParentScope(); } return scope; } diff --git a/src/jdk/nashorn/internal/runtime/WithObject.java b/src/jdk/nashorn/internal/runtime/WithObject.java index 46de1d13..7dc8307c 100644 --- a/src/jdk/nashorn/internal/runtime/WithObject.java +++ b/src/jdk/nashorn/internal/runtime/WithObject.java @@ -30,26 +30,26 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.lang.invoke.SwitchPoint; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.support.CallSiteDescriptorFactory; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; - /** * This class supports the handling of scope in a with body. * */ public final class WithObject extends ScriptObject implements Scope { - + private static final MethodHandle WITHEXPRESSIONGUARD = findOwnMH("withExpressionGuard", boolean.class, Object.class, PropertyMap.class, SwitchPoint.class); private static final MethodHandle WITHEXPRESSIONFILTER = findOwnMH("withFilterExpression", Object.class, Object.class); private static final MethodHandle WITHSCOPEFILTER = findOwnMH("withFilterScope", Object.class, Object.class); private static final MethodHandle BIND_TO_EXPRESSION_OBJ = findOwnMH("bindToExpression", Object.class, Object.class, Object.class); private static final MethodHandle BIND_TO_EXPRESSION_FN = findOwnMH("bindToExpression", Object.class, ScriptFunction.class, Object.class); /** With expression object. */ - private final Object expression; + private final ScriptObject expression; /** * Constructor @@ -57,12 +57,13 @@ public final class WithObject extends ScriptObject implements Scope { * @param scope scope object * @param expression with expression */ - WithObject(final ScriptObject scope, final Object expression) { + WithObject(final ScriptObject scope, final ScriptObject expression) { super(scope, null); setIsScope(); this.expression = expression; } + /** * Delete a property based on a key. * @param key Any valid JavaScript value. @@ -71,15 +72,13 @@ public final class WithObject extends ScriptObject implements Scope { */ @Override public boolean delete(final Object key, final boolean strict) { - if (expression instanceof ScriptObject) { - final ScriptObject self = (ScriptObject)expression; - final String propName = JSType.toString(key); + final ScriptObject self = expression; + final String propName = JSType.toString(key); - final FindProperty find = self.findProperty(propName, true); + final FindProperty find = self.findProperty(propName, true); - if (find != null) { - return self.delete(propName, strict); - } + if (find != null) { + return self.delete(propName, strict); } return false; @@ -105,18 +104,16 @@ public final class WithObject extends ScriptObject implements Scope { name = null; } - if (expression instanceof ScriptObject) { - self = (ScriptObject)expression; - if (isNamedOperation) { - find = self.findProperty(name, true); - } + self = expression; + if (isNamedOperation) { + find = self.findProperty(name, true); + } - if (find != null) { - link = self.lookup(desc, request); + if (find != null) { + link = self.lookup(desc, request); - if (link != null) { - return fixExpressionCallSite(ndesc, link); - } + if (link != null) { + return fixExpressionCallSite(ndesc, link); } } @@ -126,7 +123,7 @@ public final class WithObject extends ScriptObject implements Scope { } if (find != null) { - return fixScopeCallSite(scope.lookup(desc, request)); + return fixScopeCallSite(scope.lookup(desc, request), name); } // the property is not found - now check for @@ -178,7 +175,7 @@ public final class WithObject extends ScriptObject implements Scope { link = scope.lookup(desc, request); if (link != null) { - return fixScopeCallSite(link); + return fixScopeCallSite(link, name); } return null; @@ -197,11 +194,9 @@ public final class WithObject extends ScriptObject implements Scope { */ @Override FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) { - if (expression instanceof ScriptObject) { - final FindProperty exprProperty = ((ScriptObject)expression).findProperty(key, deep, stopOnNonScope, start); - if(exprProperty != null) { - return exprProperty; - } + final FindProperty exprProperty = expression.findProperty(key, deep, stopOnNonScope, start); + if (exprProperty != null) { + return exprProperty; } return super.findProperty(key, deep, stopOnNonScope, start); } @@ -220,16 +215,17 @@ public final class WithObject extends ScriptObject implements Scope { * Get first parent scope that is not an instance of WithObject. */ private Scope getNonWithParent() { - ScriptObject proto = getProto(); + ScriptObject proto = getParentScope(); while (proto != null && proto instanceof WithObject) { - proto = proto.getProto(); + proto = ((WithObject)proto).getParentScope(); } assert proto instanceof Scope : "with scope without parent scope"; return (Scope) proto; } + private static GuardedInvocation fixReceiverType(final GuardedInvocation link, final MethodHandle filter) { // The receiver may be an Object or a ScriptObject. final MethodType invType = link.getInvocation().type(); @@ -256,9 +252,13 @@ public final class WithObject extends ScriptObject implements Scope { filterGuard(link, WITHEXPRESSIONFILTER)); } - private static GuardedInvocation fixScopeCallSite(final GuardedInvocation link) { + private GuardedInvocation fixScopeCallSite(final GuardedInvocation link, final String name) { final GuardedInvocation newLink = fixReceiverType(link, WITHSCOPEFILTER); - return link.replaceMethods(filter(newLink.getInvocation(), WITHSCOPEFILTER), filterGuard(newLink, WITHSCOPEFILTER)); + return link.replaceMethods(filter(newLink.getInvocation(), WITHSCOPEFILTER), + MH.guardWithTest( + expressionGuard(name), + filterGuard(newLink, WITHSCOPEFILTER), + MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class))); } private static MethodHandle filterGuard(final GuardedInvocation link, final MethodHandle filter) { @@ -279,7 +279,6 @@ public final class WithObject extends ScriptObject implements Scope { return ((WithObject)receiver).expression; } - @SuppressWarnings("unused") private static Object bindToExpression(final Object fn, final Object receiver) { return fn instanceof ScriptFunction ? bindToExpression((ScriptFunction) fn, receiver) : fn; @@ -289,6 +288,17 @@ public final class WithObject extends ScriptObject implements Scope { return fn.makeBoundFunction(withFilterExpression(receiver), new Object[0]); } + private MethodHandle expressionGuard(final String name) { + final PropertyMap map = expression.getMap(); + final SwitchPoint sp = map.getProtoGetSwitchPoint(expression.getProto(), name); + return MH.insertArguments(WITHEXPRESSIONGUARD, 1, map, sp); + } + + @SuppressWarnings("unused") + private static boolean withExpressionGuard(final Object receiver, final PropertyMap map, final SwitchPoint sp) { + return ((WithObject)receiver).expression.getMap() == map && (sp == null || !sp.hasBeenInvalidated()); + } + /** * Drops the WithObject wrapper from the scope. * @param receiver WithObject wrapper. @@ -302,10 +312,14 @@ public final class WithObject extends ScriptObject implements Scope { * Get the with expression for this {@code WithObject} * @return the with expression */ - public Object getExpression() { + public ScriptObject getExpression() { return expression; } + public ScriptObject getParentScope() { + return getProto(); + } + private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { return MH.findStatic(MethodHandles.lookup(), WithObject.class, name, MH.type(rtype, types)); } diff --git a/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/src/jdk/nashorn/internal/runtime/resources/Messages.properties index 68f68c0a..5115e2ce 100644 --- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties @@ -110,6 +110,7 @@ type.error.cannot.get.default.string=Cannot get default string value type.error.cannot.get.default.number=Cannot get default number value type.error.cant.apply.with.to.null=Cannot apply "with" to null type.error.cant.apply.with.to.undefined=Cannot apply "with" to undefined +type.error.cant.apply.with.to.non.scriptobject=Cannot apply "with" to non script object type.error.in.with.non.object=Right hand side of "in" cannot be non-Object, found {0} type.error.prototype.not.an.object="prototype" of {0} is not an Object, it is {1} type.error.cant.load.script=Cannot load script from {0} diff --git a/test/script/basic/8024180/global_var_delete.js b/test/script/basic/8024180/global_var_delete.js new file mode 100644 index 00000000..f099dd33 --- /dev/null +++ b/test/script/basic/8024180/global_var_delete.js @@ -0,0 +1,50 @@ +/* + * 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. + * + * 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-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + + +this.x = 44; + +function func() { + with({ }) { + print(x); + } +} + +func(); + +// delete global 'x' +delete this.x; + +try { + func(); +} catch(e) { + // expect ReferenceError + print(e); +} diff --git a/test/script/basic/8024180/global_var_delete.js.EXPECTED b/test/script/basic/8024180/global_var_delete.js.EXPECTED new file mode 100644 index 00000000..7e54b9e6 --- /dev/null +++ b/test/script/basic/8024180/global_var_delete.js.EXPECTED @@ -0,0 +1,2 @@ +44 +ReferenceError: "x" is not defined diff --git a/test/script/basic/8024180/global_var_shadow.js b/test/script/basic/8024180/global_var_shadow.js new file mode 100644 index 00000000..5ba5f5e2 --- /dev/null +++ b/test/script/basic/8024180/global_var_shadow.js @@ -0,0 +1,45 @@ +/* + * 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. + * + * 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-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +// global variable is shadowed by with 'expression' property +var user = { name: 'foo' }; + +function func(locals) { + with (locals) { + print(user.name); + } +} + +// global user.name 'foo' printed +func({}); + +// local user.name 'toto' printed +func({ user: { name: 'toto' } }); + diff --git a/test/script/basic/8024180/global_var_shadow.js.EXPECTED b/test/script/basic/8024180/global_var_shadow.js.EXPECTED new file mode 100644 index 00000000..7f1a102b --- /dev/null +++ b/test/script/basic/8024180/global_var_shadow.js.EXPECTED @@ -0,0 +1,2 @@ +foo +toto diff --git a/test/script/basic/8024180/scope_no_such_prop.js b/test/script/basic/8024180/scope_no_such_prop.js new file mode 100644 index 00000000..5973c469 --- /dev/null +++ b/test/script/basic/8024180/scope_no_such_prop.js @@ -0,0 +1,51 @@ +/* + * 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. + * + * 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-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +// __noSuchProperty__ defined here confuses 'with' +// results in ReferenceError even when 'with' expression has +// the property + +load("nashorn:mozilla_compat.js") + +function func(locals) { + with (locals) { + print(user.name); + } +} + +try { + func({}); +} catch (e) { + print(e); +} + +// 'toto' expected in the call below +func({ user: { name: 'toto' } }); + diff --git a/test/script/basic/8024180/scope_no_such_prop.js.EXPECTED b/test/script/basic/8024180/scope_no_such_prop.js.EXPECTED new file mode 100644 index 00000000..ad4d247e --- /dev/null +++ b/test/script/basic/8024180/scope_no_such_prop.js.EXPECTED @@ -0,0 +1,2 @@ +ReferenceError: user is not defined +toto diff --git a/test/script/basic/8024180/with_expr_prop_add.js b/test/script/basic/8024180/with_expr_prop_add.js new file mode 100644 index 00000000..7c3b3a54 --- /dev/null +++ b/test/script/basic/8024180/with_expr_prop_add.js @@ -0,0 +1,47 @@ +/* + * 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. + * + * 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-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +var obj = {}; +var x = "global x"; + +// adding property to 'with' xpression object should reflect +// as variable inside the 'with' block. +function func() { + with(obj) { + for (i = 0; i < 2; i++) { + print(x); + if (i == 0) { + obj.x = "obj.x"; + } + } + } +} + +func(); diff --git a/test/script/basic/8024180/with_expr_prop_add.js.EXPECTED b/test/script/basic/8024180/with_expr_prop_add.js.EXPECTED new file mode 100644 index 00000000..4139e361 --- /dev/null +++ b/test/script/basic/8024180/with_expr_prop_add.js.EXPECTED @@ -0,0 +1,2 @@ +global x +obj.x diff --git a/test/script/basic/8024180/with_expr_proto_prop_add.js b/test/script/basic/8024180/with_expr_proto_prop_add.js new file mode 100644 index 00000000..a6a17e70 --- /dev/null +++ b/test/script/basic/8024180/with_expr_proto_prop_add.js @@ -0,0 +1,49 @@ +/* + * 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. + * + * 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-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +var p = { }; +var obj = Object.create(p); + +var x = "global x"; + +// adding property to __proto__ of 'with' expression should +// reflect as a variable immediately. +function func() { + with(obj) { + for (i = 0; i < 2; i++) { + print(x); + if (i == 0) { + p.x = "p.x"; + } + } + } +} + +func(); diff --git a/test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED b/test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED new file mode 100644 index 00000000..aa6d3681 --- /dev/null +++ b/test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED @@ -0,0 +1,2 @@ +global x +p.x diff --git a/test/script/basic/8024180/with_java_object.js b/test/script/basic/8024180/with_java_object.js new file mode 100644 index 00000000..32db2a5c --- /dev/null +++ b/test/script/basic/8024180/with_java_object.js @@ -0,0 +1,36 @@ +/* + * 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. + * + * 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-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +// TypeError for with expression being non script object +try { + with(new java.lang.Object()) {} +} catch (e) { + print(e); +} diff --git a/test/script/basic/8024180/with_java_object.js.EXPECTED b/test/script/basic/8024180/with_java_object.js.EXPECTED new file mode 100644 index 00000000..3f0facfa --- /dev/null +++ b/test/script/basic/8024180/with_java_object.js.EXPECTED @@ -0,0 +1 @@ +TypeError: Cannot apply "with" to non script object diff --git a/test/src/jdk/nashorn/internal/runtime/ContextTest.java b/test/src/jdk/nashorn/internal/runtime/ContextTest.java index 16165ce7..1b21c23f 100644 --- a/test/src/jdk/nashorn/internal/runtime/ContextTest.java +++ b/test/src/jdk/nashorn/internal/runtime/ContextTest.java @@ -64,6 +64,7 @@ public class ContextTest { final Options options = new Options(""); final ErrorManager errors = new ErrorManager(); final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader()); + final boolean strict = cx.getEnv()._strict; final ScriptObject oldGlobal = Context.getGlobal(); Context.setGlobal(cx.createGlobal()); @@ -95,7 +96,7 @@ public class ContextTest { assertEquals(sobj.size(), 2); // add property - sobj.put("zee", "hello"); + sobj.put("zee", "hello", strict); assertEquals(sobj.get("zee"), "hello"); assertEquals(sobj.size(), 3); -- cgit v1.2.3 From cffead5c89ce9c6e230f24c2b3db7f2bc1293ba7 Mon Sep 17 00:00:00 2001 From: jlaskey Date: Mon, 9 Sep 2013 13:35:35 -0300 Subject: 8024397: Nashorn FX Libraries need to be finalized. Reviewed-by: sundar, hannesw, lagergren Contributed-by: james.laskey@oracle.com --- .../nashorn/internal/runtime/resources/fx/base.js | 324 ++++++---------- .../nashorn/internal/runtime/resources/fx/fxml.js | 10 +- .../internal/runtime/resources/fx/graphics.js | 411 +-------------------- .../nashorn/internal/runtime/resources/fx/media.js | 25 +- .../nashorn/internal/runtime/resources/fx/swing.js | 9 +- .../nashorn/internal/runtime/resources/fx/swt.js | 9 +- .../nashorn/internal/runtime/resources/fx/web.js | 16 +- 7 files changed, 154 insertions(+), 650 deletions(-) diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/base.js b/src/jdk/nashorn/internal/runtime/resources/fx/base.js index 00559129..b0bfc3fb 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/base.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/base.js @@ -23,204 +23,126 @@ * questions. */ -Scene = Java.type("javafx.scene.Scene"); -Group = Java.type("javafx.scene.Group"); -Stage = Java.type("javafx.stage.Stage"); - -Binding = Java.type("javafx.beans.binding.Binding"); -Bindings = Java.type("javafx.beans.binding.Bindings"); -BooleanBinding = Java.type("javafx.beans.binding.BooleanBinding"); -BooleanExpression = Java.type("javafx.beans.binding.BooleanExpression"); -DoubleBinding = Java.type("javafx.beans.binding.DoubleBinding"); -DoubleExpression = Java.type("javafx.beans.binding.DoubleExpression"); -FloatBinding = Java.type("javafx.beans.binding.FloatBinding"); -FloatExpression = Java.type("javafx.beans.binding.FloatExpression"); -IntegerBinding = Java.type("javafx.beans.binding.IntegerBinding"); -IntegerExpression = Java.type("javafx.beans.binding.IntegerExpression"); -ListBinding = Java.type("javafx.beans.binding.ListBinding"); -ListExpression = Java.type("javafx.beans.binding.ListExpression"); -LongBinding = Java.type("javafx.beans.binding.LongBinding"); -LongExpression = Java.type("javafx.beans.binding.LongExpression"); -MapBinding = Java.type("javafx.beans.binding.MapBinding"); -MapExpression = Java.type("javafx.beans.binding.MapExpression"); -NumberBinding = Java.type("javafx.beans.binding.NumberBinding"); -NumberExpression = Java.type("javafx.beans.binding.NumberExpression"); -NumberExpressionBase = Java.type("javafx.beans.binding.NumberExpressionBase"); -ObjectBinding = Java.type("javafx.beans.binding.ObjectBinding"); -ObjectExpression = Java.type("javafx.beans.binding.ObjectExpression"); -SetBinding = Java.type("javafx.beans.binding.SetBinding"); -SetExpression = Java.type("javafx.beans.binding.SetExpression"); -StringBinding = Java.type("javafx.beans.binding.StringBinding"); -StringExpression = Java.type("javafx.beans.binding.StringExpression"); -When = Java.type("javafx.beans.binding.When"); -DefaultProperty = Java.type("javafx.beans.DefaultProperty"); -InvalidationListener = Java.type("javafx.beans.InvalidationListener"); -Observable = Java.type("javafx.beans.Observable"); -JavaBeanBooleanProperty = Java.type("javafx.beans.property.adapter.JavaBeanBooleanProperty"); -JavaBeanBooleanPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanBooleanPropertyBuilder"); -JavaBeanDoubleProperty = Java.type("javafx.beans.property.adapter.JavaBeanDoubleProperty"); -JavaBeanDoublePropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanDoublePropertyBuilder"); -JavaBeanFloatProperty = Java.type("javafx.beans.property.adapter.JavaBeanFloatProperty"); -JavaBeanFloatPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanFloatPropertyBuilder"); -JavaBeanIntegerProperty = Java.type("javafx.beans.property.adapter.JavaBeanIntegerProperty"); -JavaBeanIntegerPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanIntegerPropertyBuilder"); -JavaBeanLongProperty = Java.type("javafx.beans.property.adapter.JavaBeanLongProperty"); -JavaBeanLongPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanLongPropertyBuilder"); -JavaBeanObjectProperty = Java.type("javafx.beans.property.adapter.JavaBeanObjectProperty"); -JavaBeanObjectPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanObjectPropertyBuilder"); -JavaBeanProperty = Java.type("javafx.beans.property.adapter.JavaBeanProperty"); -JavaBeanStringProperty = Java.type("javafx.beans.property.adapter.JavaBeanStringProperty"); -JavaBeanStringPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanStringPropertyBuilder"); -ReadOnlyJavaBeanBooleanProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanBooleanProperty"); -ReadOnlyJavaBeanBooleanPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanBooleanPropertyBuilder"); -ReadOnlyJavaBeanDoubleProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanDoubleProperty"); -ReadOnlyJavaBeanDoublePropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanDoublePropertyBuilder"); -ReadOnlyJavaBeanFloatProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanFloatProperty"); -ReadOnlyJavaBeanFloatPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanFloatPropertyBuilder"); -ReadOnlyJavaBeanIntegerProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanIntegerProperty"); -ReadOnlyJavaBeanIntegerPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanIntegerPropertyBuilder"); -ReadOnlyJavaBeanLongProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanLongProperty"); -ReadOnlyJavaBeanLongPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanLongPropertyBuilder"); -ReadOnlyJavaBeanObjectProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanObjectProperty"); -ReadOnlyJavaBeanObjectPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanObjectPropertyBuilder"); -ReadOnlyJavaBeanProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanProperty"); -ReadOnlyJavaBeanStringProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanStringProperty"); -ReadOnlyJavaBeanStringPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanStringPropertyBuilder"); -BooleanProperty = Java.type("javafx.beans.property.BooleanProperty"); -BooleanPropertyBase = Java.type("javafx.beans.property.BooleanPropertyBase"); -DoubleProperty = Java.type("javafx.beans.property.DoubleProperty"); -DoublePropertyBase = Java.type("javafx.beans.property.DoublePropertyBase"); -FloatProperty = Java.type("javafx.beans.property.FloatProperty"); -FloatPropertyBase = Java.type("javafx.beans.property.FloatPropertyBase"); -IntegerProperty = Java.type("javafx.beans.property.IntegerProperty"); -IntegerPropertyBase = Java.type("javafx.beans.property.IntegerPropertyBase"); -ListProperty = Java.type("javafx.beans.property.ListProperty"); -ListPropertyBase = Java.type("javafx.beans.property.ListPropertyBase"); -LongProperty = Java.type("javafx.beans.property.LongProperty"); -LongPropertyBase = Java.type("javafx.beans.property.LongPropertyBase"); -MapProperty = Java.type("javafx.beans.property.MapProperty"); -MapPropertyBase = Java.type("javafx.beans.property.MapPropertyBase"); -ObjectProperty = Java.type("javafx.beans.property.ObjectProperty"); -ObjectPropertyBase = Java.type("javafx.beans.property.ObjectPropertyBase"); -Property = Java.type("javafx.beans.property.Property"); -ReadOnlyBooleanProperty = Java.type("javafx.beans.property.ReadOnlyBooleanProperty"); -ReadOnlyBooleanPropertyBase = Java.type("javafx.beans.property.ReadOnlyBooleanPropertyBase"); -ReadOnlyBooleanWrapper = Java.type("javafx.beans.property.ReadOnlyBooleanWrapper"); -ReadOnlyDoubleProperty = Java.type("javafx.beans.property.ReadOnlyDoubleProperty"); -ReadOnlyDoublePropertyBase = Java.type("javafx.beans.property.ReadOnlyDoublePropertyBase"); -ReadOnlyDoubleWrapper = Java.type("javafx.beans.property.ReadOnlyDoubleWrapper"); -ReadOnlyFloatProperty = Java.type("javafx.beans.property.ReadOnlyFloatProperty"); -ReadOnlyFloatPropertyBase = Java.type("javafx.beans.property.ReadOnlyFloatPropertyBase"); -ReadOnlyFloatWrapper = Java.type("javafx.beans.property.ReadOnlyFloatWrapper"); -ReadOnlyIntegerProperty = Java.type("javafx.beans.property.ReadOnlyIntegerProperty"); -ReadOnlyIntegerPropertyBase = Java.type("javafx.beans.property.ReadOnlyIntegerPropertyBase"); -ReadOnlyIntegerWrapper = Java.type("javafx.beans.property.ReadOnlyIntegerWrapper"); -ReadOnlyListProperty = Java.type("javafx.beans.property.ReadOnlyListProperty"); -ReadOnlyListPropertyBase = Java.type("javafx.beans.property.ReadOnlyListPropertyBase"); -ReadOnlyListWrapper = Java.type("javafx.beans.property.ReadOnlyListWrapper"); -ReadOnlyLongProperty = Java.type("javafx.beans.property.ReadOnlyLongProperty"); -ReadOnlyLongPropertyBase = Java.type("javafx.beans.property.ReadOnlyLongPropertyBase"); -ReadOnlyLongWrapper = Java.type("javafx.beans.property.ReadOnlyLongWrapper"); -ReadOnlyMapProperty = Java.type("javafx.beans.property.ReadOnlyMapProperty"); -ReadOnlyMapPropertyBase = Java.type("javafx.beans.property.ReadOnlyMapPropertyBase"); -ReadOnlyMapWrapper = Java.type("javafx.beans.property.ReadOnlyMapWrapper"); -ReadOnlyObjectProperty = Java.type("javafx.beans.property.ReadOnlyObjectProperty"); -ReadOnlyObjectPropertyBase = Java.type("javafx.beans.property.ReadOnlyObjectPropertyBase"); -ReadOnlyObjectWrapper = Java.type("javafx.beans.property.ReadOnlyObjectWrapper"); -ReadOnlyProperty = Java.type("javafx.beans.property.ReadOnlyProperty"); -ReadOnlySetProperty = Java.type("javafx.beans.property.ReadOnlySetProperty"); -ReadOnlySetPropertyBase = Java.type("javafx.beans.property.ReadOnlySetPropertyBase"); -ReadOnlySetWrapper = Java.type("javafx.beans.property.ReadOnlySetWrapper"); -ReadOnlyStringProperty = Java.type("javafx.beans.property.ReadOnlyStringProperty"); -ReadOnlyStringPropertyBase = Java.type("javafx.beans.property.ReadOnlyStringPropertyBase"); -ReadOnlyStringWrapper = Java.type("javafx.beans.property.ReadOnlyStringWrapper"); -SetProperty = Java.type("javafx.beans.property.SetProperty"); -SetPropertyBase = Java.type("javafx.beans.property.SetPropertyBase"); -SimpleBooleanProperty = Java.type("javafx.beans.property.SimpleBooleanProperty"); -SimpleDoubleProperty = Java.type("javafx.beans.property.SimpleDoubleProperty"); -SimpleFloatProperty = Java.type("javafx.beans.property.SimpleFloatProperty"); -SimpleIntegerProperty = Java.type("javafx.beans.property.SimpleIntegerProperty"); -SimpleListProperty = Java.type("javafx.beans.property.SimpleListProperty"); -SimpleLongProperty = Java.type("javafx.beans.property.SimpleLongProperty"); -SimpleMapProperty = Java.type("javafx.beans.property.SimpleMapProperty"); -SimpleObjectProperty = Java.type("javafx.beans.property.SimpleObjectProperty"); -SimpleSetProperty = Java.type("javafx.beans.property.SimpleSetProperty"); -SimpleStringProperty = Java.type("javafx.beans.property.SimpleStringProperty"); -StringProperty = Java.type("javafx.beans.property.StringProperty"); -StringPropertyBase = Java.type("javafx.beans.property.StringPropertyBase"); -ChangeListener = Java.type("javafx.beans.value.ChangeListener"); -ObservableBooleanValue = Java.type("javafx.beans.value.ObservableBooleanValue"); -ObservableDoubleValue = Java.type("javafx.beans.value.ObservableDoubleValue"); -ObservableFloatValue = Java.type("javafx.beans.value.ObservableFloatValue"); -ObservableIntegerValue = Java.type("javafx.beans.value.ObservableIntegerValue"); -ObservableListValue = Java.type("javafx.beans.value.ObservableListValue"); -ObservableLongValue = Java.type("javafx.beans.value.ObservableLongValue"); -ObservableMapValue = Java.type("javafx.beans.value.ObservableMapValue"); -ObservableNumberValue = Java.type("javafx.beans.value.ObservableNumberValue"); -ObservableObjectValue = Java.type("javafx.beans.value.ObservableObjectValue"); -ObservableSetValue = Java.type("javafx.beans.value.ObservableSetValue"); -ObservableStringValue = Java.type("javafx.beans.value.ObservableStringValue"); -ObservableValue = Java.type("javafx.beans.value.ObservableValue"); -ObservableValueBase = Java.type("javafx.beans.value.ObservableValueBase"); -WeakChangeListener = Java.type("javafx.beans.value.WeakChangeListener"); -WritableBooleanValue = Java.type("javafx.beans.value.WritableBooleanValue"); -WritableDoubleValue = Java.type("javafx.beans.value.WritableDoubleValue"); -WritableFloatValue = Java.type("javafx.beans.value.WritableFloatValue"); -WritableIntegerValue = Java.type("javafx.beans.value.WritableIntegerValue"); -WritableListValue = Java.type("javafx.beans.value.WritableListValue"); -WritableLongValue = Java.type("javafx.beans.value.WritableLongValue"); -WritableMapValue = Java.type("javafx.beans.value.WritableMapValue"); -WritableNumberValue = Java.type("javafx.beans.value.WritableNumberValue"); -WritableObjectValue = Java.type("javafx.beans.value.WritableObjectValue"); -WritableSetValue = Java.type("javafx.beans.value.WritableSetValue"); -WritableStringValue = Java.type("javafx.beans.value.WritableStringValue"); -WritableValue = Java.type("javafx.beans.value.WritableValue"); -WeakInvalidationListener = Java.type("javafx.beans.WeakInvalidationListener"); -WeakListener = Java.type("javafx.beans.WeakListener"); -FXCollections = Java.type("javafx.collections.FXCollections"); -ListChangeListener = Java.type("javafx.collections.ListChangeListener"); -ListChangeListener$Change = Java.type("javafx.collections.ListChangeListener$Change"); -MapChangeListener = Java.type("javafx.collections.MapChangeListener"); -MapChangeListener$Change = Java.type("javafx.collections.MapChangeListener$Change"); -ModifiableObservableListBase = Java.type("javafx.collections.ModifiableObservableListBase"); -ObservableList = Java.type("javafx.collections.ObservableList"); -ObservableListBase = Java.type("javafx.collections.ObservableListBase"); -ObservableMap = Java.type("javafx.collections.ObservableMap"); -ObservableSet = Java.type("javafx.collections.ObservableSet"); -SetChangeListener = Java.type("javafx.collections.SetChangeListener"); -SetChangeListener$Change = Java.type("javafx.collections.SetChangeListener$Change"); -WeakListChangeListener = Java.type("javafx.collections.WeakListChangeListener"); -WeakMapChangeListener = Java.type("javafx.collections.WeakMapChangeListener"); -WeakSetChangeListener = Java.type("javafx.collections.WeakSetChangeListener"); -ActionEvent = Java.type("javafx.event.ActionEvent"); -Event = Java.type("javafx.event.Event"); -EventDispatchChain = Java.type("javafx.event.EventDispatchChain"); -EventDispatcher = Java.type("javafx.event.EventDispatcher"); -EventHandler = Java.type("javafx.event.EventHandler"); -EventTarget = Java.type("javafx.event.EventTarget"); -EventType = Java.type("javafx.event.EventType"); -WeakEventHandler = Java.type("javafx.event.WeakEventHandler"); -Builder = Java.type("javafx.util.Builder"); -BuilderFactory = Java.type("javafx.util.BuilderFactory"); -Callback = Java.type("javafx.util.Callback"); -BigDecimalStringConverter = Java.type("javafx.util.converter.BigDecimalStringConverter"); -BigIntegerStringConverter = Java.type("javafx.util.converter.BigIntegerStringConverter"); -BooleanStringConverter = Java.type("javafx.util.converter.BooleanStringConverter"); -ByteStringConverter = Java.type("javafx.util.converter.ByteStringConverter"); -CharacterStringConverter = Java.type("javafx.util.converter.CharacterStringConverter"); -CurrencyStringConverter = Java.type("javafx.util.converter.CurrencyStringConverter"); -DateStringConverter = Java.type("javafx.util.converter.DateStringConverter"); -DateTimeStringConverter = Java.type("javafx.util.converter.DateTimeStringConverter"); -DefaultStringConverter = Java.type("javafx.util.converter.DefaultStringConverter"); -DoubleStringConverter = Java.type("javafx.util.converter.DoubleStringConverter"); -FloatStringConverter = Java.type("javafx.util.converter.FloatStringConverter"); -FormatStringConverter = Java.type("javafx.util.converter.FormatStringConverter"); -IntegerStringConverter = Java.type("javafx.util.converter.IntegerStringConverter"); -LongStringConverter = Java.type("javafx.util.converter.LongStringConverter"); -NumberStringConverter = Java.type("javafx.util.converter.NumberStringConverter"); -PercentageStringConverter = Java.type("javafx.util.converter.PercentageStringConverter"); -ShortStringConverter = Java.type("javafx.util.converter.ShortStringConverter"); -TimeStringConverter = Java.type("javafx.util.converter.TimeStringConverter"); -Duration = Java.type("javafx.util.Duration"); -Pair = Java.type("javafx.util.Pair"); -StringConverter = Java.type("javafx.util.StringConverter"); +var JFX_BASE_CLASSES = []; +var JFX_GRAPHICS_CLASSES = []; +var JFX_CONTROLS_CLASSES = []; +var JFX_FXML_CLASSES = []; +var JFX_WEB_CLASSES = []; +var JFX_MEDIA_CLASSES = []; +var JFX_SWING_CLASSES = []; +var JFX_SWT_CLASSES = []; + +function LOAD_FX_CLASSES(clsList) { + + for each (var cls in clsList) { + // Ex. Stage = Java.type("javafx.stage.Stage"); + this[cls[cls.length - 1]] = Java.type(cls.join(".")); + } +} + +(function() { + var System = Java.type("java.lang.System"); + var ZipFile = Java.type("java.util.zip.ZipFile"); + + var SUFFIX_LENGTH = ".class".length; + + try { + var jfxrtJar = new ZipFile(System.getProperty("java.home") + "/lib/ext/jfxrt.jar"); + } catch (ex) { + throw new Error("JavaFX runtime not found"); + } + + var entries = jfxrtJar.entries(); + + while (entries.hasMoreElements()) { + var entry = entries.nextElement(); + + if (entry.isDirectory()) { + continue; + } + + var name = entry.name; + + if (!name.endsWith(".class")) { + continue; + } + + name = name.substring(0, name.length - SUFFIX_LENGTH); + cls = name.split("/"); + + if (cls[0] != "javafx") { + continue; + } + + var last = cls[cls.length - 1]; + var nested = last.lastIndexOf("$"); + + // If class name ends with $nnn + if (nested != -1 && !(last.substring(nested) - 0)) { + continue; + } + + switch (cls[1]) { + case "stage": + if (cls[2] == "Stage") { + JFX_BASE_CLASSES.push(cls); + } else { + JFX_GRAPHICS_CLASSES.push(cls); + } + break; + + case "scene": + switch (cls[2]) { + case "Scene": + case "Group": + JFX_BASE_CLASSES.push(cls); + break; + + case "chart": + case "control": + JFX_CONTROLS_CLASSES.push(cls); + break; + + case "web": + JFX_WEB_CLASSES.push(cls); + break; + + case "media": + JFX_MEDIA_CLASSES.push(cls); + break; + + default: + JFX_GRAPHICS_CLASSES.push(cls); + break; + } + break; + + case "beans": + case "collections": + case "events": + case "util": + JFX_BASE_CLASSES.push(cls); + break; + + case "animation": + case "application": + case "concurrent": + case "css": + case "geometry": + JFX_GRAPHICS_CLASSES.push(cls); + break; + + case "fxml": + JFX_FXML_CLASSES.push(cls); + break; + + case "embed": + if (cls[2] == "swing") { + JFX_SWING_CLASSES.push(cls); + } else { + JFX_SWT_CLASSES.push(cls); + } + break; + } + } +})(); diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js b/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js index bc018a9e..0ce18168 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js @@ -23,8 +23,8 @@ * questions. */ -FXML = Java.type("javafx.fxml.FXML"); -FXMLLoader = Java.type("javafx.fxml.FXMLLoader"); -Initializable = Java.type("javafx.fxml.Initializable"); -JavaFXBuilderFactory = Java.type("javafx.fxml.JavaFXBuilderFactory"); -LoadException = Java.type("javafx.fxml.LoadException"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_FXML_CLASSES); diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js b/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js index 72f55cd1..f41661fa 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js @@ -23,409 +23,10 @@ * questions. */ -Animation = Java.type("javafx.animation.Animation"); -Animation$Status = Java.type("javafx.animation.Animation$Status"); -AnimationBuilder = Java.type("javafx.animation.AnimationBuilder"); -AnimationTimer = Java.type("javafx.animation.AnimationTimer"); -FadeTransition = Java.type("javafx.animation.FadeTransition"); -FadeTransitionBuilder = Java.type("javafx.animation.FadeTransitionBuilder"); -FillTransition = Java.type("javafx.animation.FillTransition"); -FillTransitionBuilder = Java.type("javafx.animation.FillTransitionBuilder"); -Interpolatable = Java.type("javafx.animation.Interpolatable"); -Interpolator = Java.type("javafx.animation.Interpolator"); -KeyFrame = Java.type("javafx.animation.KeyFrame"); -KeyValue = Java.type("javafx.animation.KeyValue"); -ParallelTransition = Java.type("javafx.animation.ParallelTransition"); -ParallelTransitionBuilder = Java.type("javafx.animation.ParallelTransitionBuilder"); -PathTransition = Java.type("javafx.animation.PathTransition"); -PathTransition$OrientationType = Java.type("javafx.animation.PathTransition$OrientationType"); -PathTransitionBuilder = Java.type("javafx.animation.PathTransitionBuilder"); -PauseTransition = Java.type("javafx.animation.PauseTransition"); -PauseTransitionBuilder = Java.type("javafx.animation.PauseTransitionBuilder"); -RotateTransition = Java.type("javafx.animation.RotateTransition"); -RotateTransitionBuilder = Java.type("javafx.animation.RotateTransitionBuilder"); -ScaleTransition = Java.type("javafx.animation.ScaleTransition"); -ScaleTransitionBuilder = Java.type("javafx.animation.ScaleTransitionBuilder"); -SequentialTransition = Java.type("javafx.animation.SequentialTransition"); -SequentialTransitionBuilder = Java.type("javafx.animation.SequentialTransitionBuilder"); -StrokeTransition = Java.type("javafx.animation.StrokeTransition"); -StrokeTransitionBuilder = Java.type("javafx.animation.StrokeTransitionBuilder"); -Timeline = Java.type("javafx.animation.Timeline"); -TimelineBuilder = Java.type("javafx.animation.TimelineBuilder"); -Transition = Java.type("javafx.animation.Transition"); -TransitionBuilder = Java.type("javafx.animation.TransitionBuilder"); -TranslateTransition = Java.type("javafx.animation.TranslateTransition"); -TranslateTransitionBuilder = Java.type("javafx.animation.TranslateTransitionBuilder"); -Application = Java.type("javafx.application.Application"); -Application$Parameters = Java.type("javafx.application.Application$Parameters"); -ConditionalFeature = Java.type("javafx.application.ConditionalFeature"); -HostServices = Java.type("javafx.application.HostServices"); -Platform = Java.type("javafx.application.Platform"); -Preloader = Java.type("javafx.application.Preloader"); -Preloader$ErrorNotification = Java.type("javafx.application.Preloader$ErrorNotification"); -Preloader$PreloaderNotification = Java.type("javafx.application.Preloader$PreloaderNotification"); -Preloader$ProgressNotification = Java.type("javafx.application.Preloader$ProgressNotification"); -Preloader$StateChangeNotification = Java.type("javafx.application.Preloader$StateChangeNotification"); -Preloader$StateChangeNotification$Type = Java.type("javafx.application.Preloader$StateChangeNotification$Type"); -ScheduledService = Java.type("javafx.concurrent.ScheduledService"); -Service = Java.type("javafx.concurrent.Service"); -Task = Java.type("javafx.concurrent.Task"); -Worker = Java.type("javafx.concurrent.Worker"); -Worker$State = Java.type("javafx.concurrent.Worker$State"); -WorkerStateEvent = Java.type("javafx.concurrent.WorkerStateEvent"); -CssMetaData = Java.type("javafx.css.CssMetaData"); -FontCssMetaData = Java.type("javafx.css.FontCssMetaData"); -ParsedValue = Java.type("javafx.css.ParsedValue"); -PseudoClass = Java.type("javafx.css.PseudoClass"); -SimpleStyleableBooleanProperty = Java.type("javafx.css.SimpleStyleableBooleanProperty"); -SimpleStyleableDoubleProperty = Java.type("javafx.css.SimpleStyleableDoubleProperty"); -SimpleStyleableFloatProperty = Java.type("javafx.css.SimpleStyleableFloatProperty"); -SimpleStyleableIntegerProperty = Java.type("javafx.css.SimpleStyleableIntegerProperty"); -SimpleStyleableLongProperty = Java.type("javafx.css.SimpleStyleableLongProperty"); -SimpleStyleableObjectProperty = Java.type("javafx.css.SimpleStyleableObjectProperty"); -SimpleStyleableStringProperty = Java.type("javafx.css.SimpleStyleableStringProperty"); -Styleable = Java.type("javafx.css.Styleable"); -StyleableBooleanProperty = Java.type("javafx.css.StyleableBooleanProperty"); -StyleableDoubleProperty = Java.type("javafx.css.StyleableDoubleProperty"); -StyleableFloatProperty = Java.type("javafx.css.StyleableFloatProperty"); -StyleableIntegerProperty = Java.type("javafx.css.StyleableIntegerProperty"); -StyleableLongProperty = Java.type("javafx.css.StyleableLongProperty"); -StyleableObjectProperty = Java.type("javafx.css.StyleableObjectProperty"); -StyleableProperty = Java.type("javafx.css.StyleableProperty"); -StyleableStringProperty = Java.type("javafx.css.StyleableStringProperty"); -StyleConverter = Java.type("javafx.css.StyleConverter"); -StyleOrigin = Java.type("javafx.css.StyleOrigin"); -BoundingBox = Java.type("javafx.geometry.BoundingBox"); -BoundingBoxBuilder = Java.type("javafx.geometry.BoundingBoxBuilder"); -Bounds = Java.type("javafx.geometry.Bounds"); -Dimension2D = Java.type("javafx.geometry.Dimension2D"); -Dimension2DBuilder = Java.type("javafx.geometry.Dimension2DBuilder"); -HorizontalDirection = Java.type("javafx.geometry.HorizontalDirection"); -HPos = Java.type("javafx.geometry.HPos"); -Insets = Java.type("javafx.geometry.Insets"); -InsetsBuilder = Java.type("javafx.geometry.InsetsBuilder"); -NodeOrientation = Java.type("javafx.geometry.NodeOrientation"); -Orientation = Java.type("javafx.geometry.Orientation"); -Point2D = Java.type("javafx.geometry.Point2D"); -Point2DBuilder = Java.type("javafx.geometry.Point2DBuilder"); -Point3D = Java.type("javafx.geometry.Point3D"); -Point3DBuilder = Java.type("javafx.geometry.Point3DBuilder"); -Pos = Java.type("javafx.geometry.Pos"); -Rectangle2D = Java.type("javafx.geometry.Rectangle2D"); -Rectangle2DBuilder = Java.type("javafx.geometry.Rectangle2DBuilder"); -Side = Java.type("javafx.geometry.Side"); -VerticalDirection = Java.type("javafx.geometry.VerticalDirection"); -VPos = Java.type("javafx.geometry.VPos"); -Collation = Java.type("javafx.print.Collation"); -JobSettings = Java.type("javafx.print.JobSettings"); -PageLayout = Java.type("javafx.print.PageLayout"); -PageOrientation = Java.type("javafx.print.PageOrientation"); -PageRange = Java.type("javafx.print.PageRange"); -Paper = Java.type("javafx.print.Paper"); -Paper$Units = Java.type("javafx.print.Paper$Units"); -PaperSource = Java.type("javafx.print.PaperSource"); -PrintColor = Java.type("javafx.print.PrintColor"); -Printer = Java.type("javafx.print.Printer"); -Printer$MarginType = Java.type("javafx.print.Printer$MarginType"); -PrinterAttributes = Java.type("javafx.print.PrinterAttributes"); -PrinterJob = Java.type("javafx.print.PrinterJob"); -PrinterJob$JobStatus = Java.type("javafx.print.PrinterJob$JobStatus"); -PrintQuality = Java.type("javafx.print.PrintQuality"); -PrintResolution = Java.type("javafx.print.PrintResolution"); -PrintSides = Java.type("javafx.print.PrintSides"); -AmbientLight = Java.type("javafx.scene.AmbientLight"); -//AmbientLightBuilder = Java.type("javafx.scene.AmbientLightBuilder"); -CacheHint = Java.type("javafx.scene.CacheHint"); -Camera = Java.type("javafx.scene.Camera"); -//CameraBuilder = Java.type("javafx.scene.CameraBuilder"); -Canvas = Java.type("javafx.scene.canvas.Canvas"); -CanvasBuilder = Java.type("javafx.scene.canvas.CanvasBuilder"); -GraphicsContext = Java.type("javafx.scene.canvas.GraphicsContext"); -Cursor = Java.type("javafx.scene.Cursor"); -DepthTest = Java.type("javafx.scene.DepthTest"); -Blend = Java.type("javafx.scene.effect.Blend"); -BlendBuilder = Java.type("javafx.scene.effect.BlendBuilder"); -BlendMode = Java.type("javafx.scene.effect.BlendMode"); -Bloom = Java.type("javafx.scene.effect.Bloom"); -BloomBuilder = Java.type("javafx.scene.effect.BloomBuilder"); -BlurType = Java.type("javafx.scene.effect.BlurType"); -BoxBlur = Java.type("javafx.scene.effect.BoxBlur"); -BoxBlurBuilder = Java.type("javafx.scene.effect.BoxBlurBuilder"); -ColorAdjust = Java.type("javafx.scene.effect.ColorAdjust"); -ColorAdjustBuilder = Java.type("javafx.scene.effect.ColorAdjustBuilder"); -ColorInput = Java.type("javafx.scene.effect.ColorInput"); -ColorInputBuilder = Java.type("javafx.scene.effect.ColorInputBuilder"); -DisplacementMap = Java.type("javafx.scene.effect.DisplacementMap"); -DisplacementMapBuilder = Java.type("javafx.scene.effect.DisplacementMapBuilder"); -DropShadow = Java.type("javafx.scene.effect.DropShadow"); -DropShadowBuilder = Java.type("javafx.scene.effect.DropShadowBuilder"); -Effect = Java.type("javafx.scene.effect.Effect"); -FloatMap = Java.type("javafx.scene.effect.FloatMap"); -FloatMapBuilder = Java.type("javafx.scene.effect.FloatMapBuilder"); -GaussianBlur = Java.type("javafx.scene.effect.GaussianBlur"); -GaussianBlurBuilder = Java.type("javafx.scene.effect.GaussianBlurBuilder"); -Glow = Java.type("javafx.scene.effect.Glow"); -GlowBuilder = Java.type("javafx.scene.effect.GlowBuilder"); -ImageInput = Java.type("javafx.scene.effect.ImageInput"); -ImageInputBuilder = Java.type("javafx.scene.effect.ImageInputBuilder"); -InnerShadow = Java.type("javafx.scene.effect.InnerShadow"); -InnerShadowBuilder = Java.type("javafx.scene.effect.InnerShadowBuilder"); -Light = Java.type("javafx.scene.effect.Light"); -Light$Distant = Java.type("javafx.scene.effect.Light$Distant"); -Light$Point = Java.type("javafx.scene.effect.Light$Point"); -Light$Spot = Java.type("javafx.scene.effect.Light$Spot"); -LightBuilder = Java.type("javafx.scene.effect.LightBuilder"); -Lighting = Java.type("javafx.scene.effect.Lighting"); -LightingBuilder = Java.type("javafx.scene.effect.LightingBuilder"); -MotionBlur = Java.type("javafx.scene.effect.MotionBlur"); -MotionBlurBuilder = Java.type("javafx.scene.effect.MotionBlurBuilder"); -PerspectiveTransform = Java.type("javafx.scene.effect.PerspectiveTransform"); -PerspectiveTransformBuilder = Java.type("javafx.scene.effect.PerspectiveTransformBuilder"); -Reflection = Java.type("javafx.scene.effect.Reflection"); -ReflectionBuilder = Java.type("javafx.scene.effect.ReflectionBuilder"); -SepiaTone = Java.type("javafx.scene.effect.SepiaTone"); -SepiaToneBuilder = Java.type("javafx.scene.effect.SepiaToneBuilder"); -Shadow = Java.type("javafx.scene.effect.Shadow"); -ShadowBuilder = Java.type("javafx.scene.effect.ShadowBuilder"); -//Group = Java.type("javafx.scene.Group"); -GroupBuilder = Java.type("javafx.scene.GroupBuilder"); -Image = Java.type("javafx.scene.image.Image"); -ImageView = Java.type("javafx.scene.image.ImageView"); -ImageViewBuilder = Java.type("javafx.scene.image.ImageViewBuilder"); -PixelFormat = Java.type("javafx.scene.image.PixelFormat"); -PixelFormat$Type = Java.type("javafx.scene.image.PixelFormat$Type"); -PixelReader = Java.type("javafx.scene.image.PixelReader"); -PixelWriter = Java.type("javafx.scene.image.PixelWriter"); -WritableImage = Java.type("javafx.scene.image.WritableImage"); -WritablePixelFormat = Java.type("javafx.scene.image.WritablePixelFormat"); -ImageCursor = Java.type("javafx.scene.ImageCursor"); -ImageCursorBuilder = Java.type("javafx.scene.ImageCursorBuilder"); -Clipboard = Java.type("javafx.scene.input.Clipboard"); -ClipboardContent = Java.type("javafx.scene.input.ClipboardContent"); -ClipboardContentBuilder = Java.type("javafx.scene.input.ClipboardContentBuilder"); -ContextMenuEvent = Java.type("javafx.scene.input.ContextMenuEvent"); -DataFormat = Java.type("javafx.scene.input.DataFormat"); -Dragboard = Java.type("javafx.scene.input.Dragboard"); -DragEvent = Java.type("javafx.scene.input.DragEvent"); -GestureEvent = Java.type("javafx.scene.input.GestureEvent"); -InputEvent = Java.type("javafx.scene.input.InputEvent"); -//InputEventBuilder = Java.type("javafx.scene.input.InputEventBuilder"); -InputMethodEvent = Java.type("javafx.scene.input.InputMethodEvent"); -InputMethodHighlight = Java.type("javafx.scene.input.InputMethodHighlight"); -InputMethodRequests = Java.type("javafx.scene.input.InputMethodRequests"); -InputMethodTextRun = Java.type("javafx.scene.input.InputMethodTextRun"); -//InputMethodTextRunBuilder = Java.type("javafx.scene.input.InputMethodTextRunBuilder"); -KeyCharacterCombination = Java.type("javafx.scene.input.KeyCharacterCombination"); -KeyCharacterCombinationBuilder = Java.type("javafx.scene.input.KeyCharacterCombinationBuilder"); -KeyCode = Java.type("javafx.scene.input.KeyCode"); -KeyCodeCombination = Java.type("javafx.scene.input.KeyCodeCombination"); -KeyCodeCombinationBuilder = Java.type("javafx.scene.input.KeyCodeCombinationBuilder"); -KeyCombination = Java.type("javafx.scene.input.KeyCombination"); -KeyCombination$Modifier = Java.type("javafx.scene.input.KeyCombination$Modifier"); -KeyCombination$ModifierValue = Java.type("javafx.scene.input.KeyCombination$ModifierValue"); -KeyEvent = Java.type("javafx.scene.input.KeyEvent"); -Mnemonic = Java.type("javafx.scene.input.Mnemonic"); -MnemonicBuilder = Java.type("javafx.scene.input.MnemonicBuilder"); -MouseButton = Java.type("javafx.scene.input.MouseButton"); -MouseDragEvent = Java.type("javafx.scene.input.MouseDragEvent"); -MouseEvent = Java.type("javafx.scene.input.MouseEvent"); -PickResult = Java.type("javafx.scene.input.PickResult"); -RotateEvent = Java.type("javafx.scene.input.RotateEvent"); -ScrollEvent = Java.type("javafx.scene.input.ScrollEvent"); -ScrollEvent$HorizontalTextScrollUnits = Java.type("javafx.scene.input.ScrollEvent$HorizontalTextScrollUnits"); -ScrollEvent$VerticalTextScrollUnits = Java.type("javafx.scene.input.ScrollEvent$VerticalTextScrollUnits"); -SwipeEvent = Java.type("javafx.scene.input.SwipeEvent"); -TouchEvent = Java.type("javafx.scene.input.TouchEvent"); -TouchPoint = Java.type("javafx.scene.input.TouchPoint"); -TouchPoint$State = Java.type("javafx.scene.input.TouchPoint$State"); -//TouchPointBuilder = Java.type("javafx.scene.input.TouchPointBuilder"); -TransferMode = Java.type("javafx.scene.input.TransferMode"); -ZoomEvent = Java.type("javafx.scene.input.ZoomEvent"); -AnchorPane = Java.type("javafx.scene.layout.AnchorPane"); -AnchorPaneBuilder = Java.type("javafx.scene.layout.AnchorPaneBuilder"); -Background = Java.type("javafx.scene.layout.Background"); -//BackgroundBuilder = Java.type("javafx.scene.layout.BackgroundBuilder"); -BackgroundFill = Java.type("javafx.scene.layout.BackgroundFill"); -//BackgroundFillBuilder = Java.type("javafx.scene.layout.BackgroundFillBuilder"); -BackgroundImage = Java.type("javafx.scene.layout.BackgroundImage"); -//BackgroundImageBuilder = Java.type("javafx.scene.layout.BackgroundImageBuilder"); -BackgroundPosition = Java.type("javafx.scene.layout.BackgroundPosition"); -//BackgroundPositionBuilder = Java.type("javafx.scene.layout.BackgroundPositionBuilder"); -BackgroundRepeat = Java.type("javafx.scene.layout.BackgroundRepeat"); -BackgroundSize = Java.type("javafx.scene.layout.BackgroundSize"); -//BackgroundSizeBuilder = Java.type("javafx.scene.layout.BackgroundSizeBuilder"); -Border = Java.type("javafx.scene.layout.Border"); -//BorderBuilder = Java.type("javafx.scene.layout.BorderBuilder"); -BorderImage = Java.type("javafx.scene.layout.BorderImage"); -//BorderImageBuilder = Java.type("javafx.scene.layout.BorderImageBuilder"); -BorderPane = Java.type("javafx.scene.layout.BorderPane"); -BorderPaneBuilder = Java.type("javafx.scene.layout.BorderPaneBuilder"); -BorderRepeat = Java.type("javafx.scene.layout.BorderRepeat"); -BorderStroke = Java.type("javafx.scene.layout.BorderStroke"); -//BorderStrokeBuilder = Java.type("javafx.scene.layout.BorderStrokeBuilder"); -BorderStrokeStyle = Java.type("javafx.scene.layout.BorderStrokeStyle"); -//BorderStrokeStyleBuilder = Java.type("javafx.scene.layout.BorderStrokeStyleBuilder"); -BorderWidths = Java.type("javafx.scene.layout.BorderWidths"); -//BorderWidthsBuilder = Java.type("javafx.scene.layout.BorderWidthsBuilder"); -ColumnConstraints = Java.type("javafx.scene.layout.ColumnConstraints"); -ColumnConstraintsBuilder = Java.type("javafx.scene.layout.ColumnConstraintsBuilder"); -ConstraintsBase = Java.type("javafx.scene.layout.ConstraintsBase"); -CornerRadii = Java.type("javafx.scene.layout.CornerRadii"); -FlowPane = Java.type("javafx.scene.layout.FlowPane"); -FlowPaneBuilder = Java.type("javafx.scene.layout.FlowPaneBuilder"); -GridPane = Java.type("javafx.scene.layout.GridPane"); -GridPaneBuilder = Java.type("javafx.scene.layout.GridPaneBuilder"); -HBox = Java.type("javafx.scene.layout.HBox"); -HBoxBuilder = Java.type("javafx.scene.layout.HBoxBuilder"); -Pane = Java.type("javafx.scene.layout.Pane"); -PaneBuilder = Java.type("javafx.scene.layout.PaneBuilder"); -Priority = Java.type("javafx.scene.layout.Priority"); -Region = Java.type("javafx.scene.layout.Region"); -RegionBuilder = Java.type("javafx.scene.layout.RegionBuilder"); -RowConstraints = Java.type("javafx.scene.layout.RowConstraints"); -RowConstraintsBuilder = Java.type("javafx.scene.layout.RowConstraintsBuilder"); -StackPane = Java.type("javafx.scene.layout.StackPane"); -StackPaneBuilder = Java.type("javafx.scene.layout.StackPaneBuilder"); -TilePane = Java.type("javafx.scene.layout.TilePane"); -TilePaneBuilder = Java.type("javafx.scene.layout.TilePaneBuilder"); -VBox = Java.type("javafx.scene.layout.VBox"); -VBoxBuilder = Java.type("javafx.scene.layout.VBoxBuilder"); -LightBase = Java.type("javafx.scene.LightBase"); -//LightBaseBuilder = Java.type("javafx.scene.LightBaseBuilder"); -Node = Java.type("javafx.scene.Node"); -NodeBuilder = Java.type("javafx.scene.NodeBuilder"); -Color = Java.type("javafx.scene.paint.Color"); -ColorBuilder = Java.type("javafx.scene.paint.ColorBuilder"); -CycleMethod = Java.type("javafx.scene.paint.CycleMethod"); -ImagePattern = Java.type("javafx.scene.paint.ImagePattern"); -ImagePatternBuilder = Java.type("javafx.scene.paint.ImagePatternBuilder"); -LinearGradient = Java.type("javafx.scene.paint.LinearGradient"); -LinearGradientBuilder = Java.type("javafx.scene.paint.LinearGradientBuilder"); -Material = Java.type("javafx.scene.paint.Material"); -Paint = Java.type("javafx.scene.paint.Paint"); -PhongMaterial = Java.type("javafx.scene.paint.PhongMaterial"); -//PhongMaterialBuilder = Java.type("javafx.scene.paint.PhongMaterialBuilder"); -RadialGradient = Java.type("javafx.scene.paint.RadialGradient"); -RadialGradientBuilder = Java.type("javafx.scene.paint.RadialGradientBuilder"); -Stop = Java.type("javafx.scene.paint.Stop"); -StopBuilder = Java.type("javafx.scene.paint.StopBuilder"); -ParallelCamera = Java.type("javafx.scene.ParallelCamera"); -//ParallelCameraBuilder = Java.type("javafx.scene.ParallelCameraBuilder"); -Parent = Java.type("javafx.scene.Parent"); -ParentBuilder = Java.type("javafx.scene.ParentBuilder"); -PerspectiveCamera = Java.type("javafx.scene.PerspectiveCamera"); -PerspectiveCameraBuilder = Java.type("javafx.scene.PerspectiveCameraBuilder"); -PointLight = Java.type("javafx.scene.PointLight"); -//PointLightBuilder = Java.type("javafx.scene.PointLightBuilder"); -//Scene = Java.type("javafx.scene.Scene"); -SceneBuilder = Java.type("javafx.scene.SceneBuilder"); -Arc = Java.type("javafx.scene.shape.Arc"); -ArcBuilder = Java.type("javafx.scene.shape.ArcBuilder"); -ArcTo = Java.type("javafx.scene.shape.ArcTo"); -ArcToBuilder = Java.type("javafx.scene.shape.ArcToBuilder"); -ArcType = Java.type("javafx.scene.shape.ArcType"); -Box = Java.type("javafx.scene.shape.Box"); -//BoxBuilder = Java.type("javafx.scene.shape.BoxBuilder"); -Circle = Java.type("javafx.scene.shape.Circle"); -CircleBuilder = Java.type("javafx.scene.shape.CircleBuilder"); -ClosePath = Java.type("javafx.scene.shape.ClosePath"); -ClosePathBuilder = Java.type("javafx.scene.shape.ClosePathBuilder"); -CubicCurve = Java.type("javafx.scene.shape.CubicCurve"); -CubicCurveBuilder = Java.type("javafx.scene.shape.CubicCurveBuilder"); -CubicCurveTo = Java.type("javafx.scene.shape.CubicCurveTo"); -CubicCurveToBuilder = Java.type("javafx.scene.shape.CubicCurveToBuilder"); -CullFace = Java.type("javafx.scene.shape.CullFace"); -Cylinder = Java.type("javafx.scene.shape.Cylinder"); -//CylinderBuilder = Java.type("javafx.scene.shape.CylinderBuilder"); -DrawMode = Java.type("javafx.scene.shape.DrawMode"); -Ellipse = Java.type("javafx.scene.shape.Ellipse"); -EllipseBuilder = Java.type("javafx.scene.shape.EllipseBuilder"); -FillRule = Java.type("javafx.scene.shape.FillRule"); -HLineTo = Java.type("javafx.scene.shape.HLineTo"); -HLineToBuilder = Java.type("javafx.scene.shape.HLineToBuilder"); -Line = Java.type("javafx.scene.shape.Line"); -LineBuilder = Java.type("javafx.scene.shape.LineBuilder"); -LineTo = Java.type("javafx.scene.shape.LineTo"); -LineToBuilder = Java.type("javafx.scene.shape.LineToBuilder"); -Mesh = Java.type("javafx.scene.shape.Mesh"); -MeshView = Java.type("javafx.scene.shape.MeshView"); -//MeshViewBuilder = Java.type("javafx.scene.shape.MeshViewBuilder"); -MoveTo = Java.type("javafx.scene.shape.MoveTo"); -MoveToBuilder = Java.type("javafx.scene.shape.MoveToBuilder"); -Path = Java.type("javafx.scene.shape.Path"); -PathBuilder = Java.type("javafx.scene.shape.PathBuilder"); -PathElement = Java.type("javafx.scene.shape.PathElement"); -PathElementBuilder = Java.type("javafx.scene.shape.PathElementBuilder"); -Polygon = Java.type("javafx.scene.shape.Polygon"); -PolygonBuilder = Java.type("javafx.scene.shape.PolygonBuilder"); -Polyline = Java.type("javafx.scene.shape.Polyline"); -PolylineBuilder = Java.type("javafx.scene.shape.PolylineBuilder"); -QuadCurve = Java.type("javafx.scene.shape.QuadCurve"); -QuadCurveBuilder = Java.type("javafx.scene.shape.QuadCurveBuilder"); -QuadCurveTo = Java.type("javafx.scene.shape.QuadCurveTo"); -QuadCurveToBuilder = Java.type("javafx.scene.shape.QuadCurveToBuilder"); -Rectangle = Java.type("javafx.scene.shape.Rectangle"); -RectangleBuilder = Java.type("javafx.scene.shape.RectangleBuilder"); -Shape = Java.type("javafx.scene.shape.Shape"); -Shape3D = Java.type("javafx.scene.shape.Shape3D"); -//Shape3DBuilder = Java.type("javafx.scene.shape.Shape3DBuilder"); -ShapeBuilder = Java.type("javafx.scene.shape.ShapeBuilder"); -Sphere = Java.type("javafx.scene.shape.Sphere"); -//SphereBuilder = Java.type("javafx.scene.shape.SphereBuilder"); -StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap"); -StrokeLineJoin = Java.type("javafx.scene.shape.StrokeLineJoin"); -StrokeType = Java.type("javafx.scene.shape.StrokeType"); -SVGPath = Java.type("javafx.scene.shape.SVGPath"); -SVGPathBuilder = Java.type("javafx.scene.shape.SVGPathBuilder"); -TriangleMesh = Java.type("javafx.scene.shape.TriangleMesh"); -VLineTo = Java.type("javafx.scene.shape.VLineTo"); -VLineToBuilder = Java.type("javafx.scene.shape.VLineToBuilder"); -SnapshotParameters = Java.type("javafx.scene.SnapshotParameters"); -SnapshotParametersBuilder = Java.type("javafx.scene.SnapshotParametersBuilder"); -SnapshotResult = Java.type("javafx.scene.SnapshotResult"); -SubScene = Java.type("javafx.scene.SubScene"); -//SubSceneBuilder = Java.type("javafx.scene.SubSceneBuilder"); -Font = Java.type("javafx.scene.text.Font"); -FontBuilder = Java.type("javafx.scene.text.FontBuilder"); -FontPosture = Java.type("javafx.scene.text.FontPosture"); -FontSmoothingType = Java.type("javafx.scene.text.FontSmoothingType"); -FontWeight = Java.type("javafx.scene.text.FontWeight"); -Text = Java.type("javafx.scene.text.Text"); -TextAlignment = Java.type("javafx.scene.text.TextAlignment"); -TextBoundsType = Java.type("javafx.scene.text.TextBoundsType"); -TextBuilder = Java.type("javafx.scene.text.TextBuilder"); -TextFlow = Java.type("javafx.scene.text.TextFlow"); -//TextFlowBuilder = Java.type("javafx.scene.text.TextFlowBuilder"); -Affine = Java.type("javafx.scene.transform.Affine"); -AffineBuilder = Java.type("javafx.scene.transform.AffineBuilder"); -MatrixType = Java.type("javafx.scene.transform.MatrixType"); -NonInvertibleTransformException = Java.type("javafx.scene.transform.NonInvertibleTransformException"); -Rotate = Java.type("javafx.scene.transform.Rotate"); -RotateBuilder = Java.type("javafx.scene.transform.RotateBuilder"); -Scale = Java.type("javafx.scene.transform.Scale"); -ScaleBuilder = Java.type("javafx.scene.transform.ScaleBuilder"); -Shear = Java.type("javafx.scene.transform.Shear"); -ShearBuilder = Java.type("javafx.scene.transform.ShearBuilder"); -Transform = Java.type("javafx.scene.transform.Transform"); -//TransformBuilder = Java.type("javafx.scene.transform.TransformBuilder"); -TransformChangedEvent = Java.type("javafx.scene.transform.TransformChangedEvent"); -Translate = Java.type("javafx.scene.transform.Translate"); -TranslateBuilder = Java.type("javafx.scene.transform.TranslateBuilder"); -DirectoryChooser = Java.type("javafx.stage.DirectoryChooser"); -DirectoryChooserBuilder = Java.type("javafx.stage.DirectoryChooserBuilder"); -FileChooser = Java.type("javafx.stage.FileChooser"); -FileChooser$ExtensionFilter = Java.type("javafx.stage.FileChooser$ExtensionFilter"); -FileChooserBuilder = Java.type("javafx.stage.FileChooserBuilder"); -Modality = Java.type("javafx.stage.Modality"); -Popup = Java.type("javafx.stage.Popup"); -PopupBuilder = Java.type("javafx.stage.PopupBuilder"); -PopupWindow = Java.type("javafx.stage.PopupWindow"); -PopupWindowBuilder = Java.type("javafx.stage.PopupWindowBuilder"); -Screen = Java.type("javafx.stage.Screen"); -//Stage = Java.type("javafx.stage.Stage"); -StageBuilder = Java.type("javafx.stage.StageBuilder"); -StageStyle = Java.type("javafx.stage.StageStyle"); -Window = Java.type("javafx.stage.Window"); -WindowBuilder = Java.type("javafx.stage.WindowBuilder"); -WindowEvent = Java.type("javafx.stage.WindowEvent"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_GRAPHICS_CLASSES); + diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/media.js b/src/jdk/nashorn/internal/runtime/resources/fx/media.js index 7cc7887b..29640255 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/media.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/media.js @@ -23,23 +23,8 @@ * questions. */ -AudioClip = Java.type("javafx.scene.media.AudioClip"); -AudioClipBuilder = Java.type("javafx.scene.media.AudioClipBuilder"); -AudioEqualizer = Java.type("javafx.scene.media.AudioEqualizer"); -AudioSpectrumListener = Java.type("javafx.scene.media.AudioSpectrumListener"); -AudioTrack = Java.type("javafx.scene.media.AudioTrack"); -EqualizerBand = Java.type("javafx.scene.media.EqualizerBand"); -Media = Java.type("javafx.scene.media.Media"); -MediaBuilder = Java.type("javafx.scene.media.MediaBuilder"); -MediaErrorEvent = Java.type("javafx.scene.media.MediaErrorEvent"); -MediaException = Java.type("javafx.scene.media.MediaException"); -MediaException$Type = Java.type("javafx.scene.media.MediaException$Type"); -MediaMarkerEvent = Java.type("javafx.scene.media.MediaMarkerEvent"); -MediaPlayer = Java.type("javafx.scene.media.MediaPlayer"); -MediaPlayer$Status = Java.type("javafx.scene.media.MediaPlayer$Status"); -MediaPlayerBuilder = Java.type("javafx.scene.media.MediaPlayerBuilder"); -MediaView = Java.type("javafx.scene.media.MediaView"); -MediaViewBuilder = Java.type("javafx.scene.media.MediaViewBuilder"); -SubtitleTrack = Java.type("javafx.scene.media.SubtitleTrack"); -Track = Java.type("javafx.scene.media.Track"); -VideoTrack = Java.type("javafx.scene.media.VideoTrack"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_MEDIA_CLASSES); diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/swing.js b/src/jdk/nashorn/internal/runtime/resources/fx/swing.js index 241205d1..e4021af9 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/swing.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/swing.js @@ -23,7 +23,8 @@ * questions. */ -JFXPanel = Java.type("javafx.embed.swing.JFXPanel"); -JFXPanelBuilder = Java.type("javafx.embed.swing.JFXPanelBuilder"); -SwingFXUtils = Java.type("javafx.embed.swing.SwingFXUtils"); -SwingNode = Java.type("javafx.embed.swing.SwingNode"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_SWING_CLASSES); diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/swt.js b/src/jdk/nashorn/internal/runtime/resources/fx/swt.js index 82197c71..144bcd5d 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/swt.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/swt.js @@ -23,7 +23,8 @@ * questions. */ -CustomTransfer = Java.type("javafx.embed.swt.CustomTransfer"); -//CustomTransferBuilder = Java.type("javafx.embed.swt.CustomTransferBuilder"); -FXCanvas = Java.type("javafx.embed.swt.FXCanvas"); -SWTFXUtils = Java.type("javafx.embed.swt.SWTFXUtils"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_SWT_CLASSES); diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/web.js b/src/jdk/nashorn/internal/runtime/resources/fx/web.js index 606c3c31..fa66cb25 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/web.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/web.js @@ -23,14 +23,8 @@ * questions. */ -HTMLEditor = Java.type("javafx.scene.web.HTMLEditor"); -//HTMLEditorBuilder = Java.type("javafx.scene.web.HTMLEditorBuilder"); -PopupFeatures = Java.type("javafx.scene.web.PopupFeatures"); -PromptData = Java.type("javafx.scene.web.PromptData"); -//PromptDataBuilder = Java.type("javafx.scene.web.PromptDataBuilder"); -WebEngine = Java.type("javafx.scene.web.WebEngine"); -WebEngineBuilder = Java.type("javafx.scene.web.WebEngineBuilder"); -WebEvent = Java.type("javafx.scene.web.WebEvent"); -WebHistory = Java.type("javafx.scene.web.WebHistory"); -WebView = Java.type("javafx.scene.web.WebView"); -WebViewBuilder = Java.type("javafx.scene.web.WebViewBuilder"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_WEB_CLASSES); -- cgit v1.2.3 From 9bd50e64f30c4619ea2f6e316619c2d679fbe5af Mon Sep 17 00:00:00 2001 From: jlaskey Date: Tue, 10 Sep 2013 14:21:28 -0300 Subject: 8024539: FX Libraries update missing file Reviewed-by: sundar Contributed-by: james.laskey@oracle.com --- .../internal/runtime/resources/fx/controls.js | 244 +-------------------- 1 file changed, 5 insertions(+), 239 deletions(-) diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/controls.js b/src/jdk/nashorn/internal/runtime/resources/fx/controls.js index 6a2a89c4..ca3f284c 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/controls.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/controls.js @@ -23,242 +23,8 @@ * questions. */ -AreaChart = Java.type("javafx.scene.chart.AreaChart"); -AreaChartBuilder = Java.type("javafx.scene.chart.AreaChartBuilder"); -Axis = Java.type("javafx.scene.chart.Axis"); -Axis$TickMark = Java.type("javafx.scene.chart.Axis$TickMark"); -AxisBuilder = Java.type("javafx.scene.chart.AxisBuilder"); -BarChart = Java.type("javafx.scene.chart.BarChart"); -BarChartBuilder = Java.type("javafx.scene.chart.BarChartBuilder"); -BubbleChart = Java.type("javafx.scene.chart.BubbleChart"); -BubbleChartBuilder = Java.type("javafx.scene.chart.BubbleChartBuilder"); -CategoryAxis = Java.type("javafx.scene.chart.CategoryAxis"); -CategoryAxisBuilder = Java.type("javafx.scene.chart.CategoryAxisBuilder"); -Chart = Java.type("javafx.scene.chart.Chart"); -ChartBuilder = Java.type("javafx.scene.chart.ChartBuilder"); -LineChart = Java.type("javafx.scene.chart.LineChart"); -LineChartBuilder = Java.type("javafx.scene.chart.LineChartBuilder"); -NumberAxis = Java.type("javafx.scene.chart.NumberAxis"); -NumberAxis$DefaultFormatter = Java.type("javafx.scene.chart.NumberAxis$DefaultFormatter"); -NumberAxisBuilder = Java.type("javafx.scene.chart.NumberAxisBuilder"); -PieChart = Java.type("javafx.scene.chart.PieChart"); -PieChart$Data = Java.type("javafx.scene.chart.PieChart$Data"); -PieChartBuilder = Java.type("javafx.scene.chart.PieChartBuilder"); -ScatterChart = Java.type("javafx.scene.chart.ScatterChart"); -ScatterChartBuilder = Java.type("javafx.scene.chart.ScatterChartBuilder"); -StackedAreaChart = Java.type("javafx.scene.chart.StackedAreaChart"); -StackedAreaChartBuilder = Java.type("javafx.scene.chart.StackedAreaChartBuilder"); -StackedBarChart = Java.type("javafx.scene.chart.StackedBarChart"); -StackedBarChartBuilder = Java.type("javafx.scene.chart.StackedBarChartBuilder"); -ValueAxis = Java.type("javafx.scene.chart.ValueAxis"); -ValueAxisBuilder = Java.type("javafx.scene.chart.ValueAxisBuilder"); -XYChart = Java.type("javafx.scene.chart.XYChart"); -XYChart$Data = Java.type("javafx.scene.chart.XYChart$Data"); -XYChart$Series = Java.type("javafx.scene.chart.XYChart$Series"); -XYChartBuilder = Java.type("javafx.scene.chart.XYChartBuilder"); -Accordion = Java.type("javafx.scene.control.Accordion"); -AccordionBuilder = Java.type("javafx.scene.control.AccordionBuilder"); -Button = Java.type("javafx.scene.control.Button"); -ButtonBase = Java.type("javafx.scene.control.ButtonBase"); -ButtonBaseBuilder = Java.type("javafx.scene.control.ButtonBaseBuilder"); -ButtonBuilder = Java.type("javafx.scene.control.ButtonBuilder"); -Cell = Java.type("javafx.scene.control.Cell"); -CheckBoxListCell = Java.type("javafx.scene.control.cell.CheckBoxListCell"); -CheckBoxListCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxListCellBuilder"); -CheckBoxTableCell = Java.type("javafx.scene.control.cell.CheckBoxTableCell"); -CheckBoxTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTableCellBuilder"); -CheckBoxTreeCell = Java.type("javafx.scene.control.cell.CheckBoxTreeCell"); -CheckBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeCellBuilder"); -CheckBoxTreeTableCell = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCell"); -//CheckBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCellBuilder"); -ChoiceBoxListCell = Java.type("javafx.scene.control.cell.ChoiceBoxListCell"); -ChoiceBoxListCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxListCellBuilder"); -ChoiceBoxTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTableCell"); -ChoiceBoxTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTableCellBuilder"); -ChoiceBoxTreeCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCell"); -ChoiceBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCellBuilder"); -ChoiceBoxTreeTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCell"); -//ChoiceBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCellBuilder"); -ComboBoxListCell = Java.type("javafx.scene.control.cell.ComboBoxListCell"); -ComboBoxListCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxListCellBuilder"); -ComboBoxTableCell = Java.type("javafx.scene.control.cell.ComboBoxTableCell"); -ComboBoxTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTableCellBuilder"); -ComboBoxTreeCell = Java.type("javafx.scene.control.cell.ComboBoxTreeCell"); -ComboBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeCellBuilder"); -ComboBoxTreeTableCell = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCell"); -//ComboBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCellBuilder"); -MapValueFactory = Java.type("javafx.scene.control.cell.MapValueFactory"); -ProgressBarTableCell = Java.type("javafx.scene.control.cell.ProgressBarTableCell"); -ProgressBarTreeTableCell = Java.type("javafx.scene.control.cell.ProgressBarTreeTableCell"); -PropertyValueFactory = Java.type("javafx.scene.control.cell.PropertyValueFactory"); -PropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.PropertyValueFactoryBuilder"); -TextFieldListCell = Java.type("javafx.scene.control.cell.TextFieldListCell"); -TextFieldListCellBuilder = Java.type("javafx.scene.control.cell.TextFieldListCellBuilder"); -TextFieldTableCell = Java.type("javafx.scene.control.cell.TextFieldTableCell"); -TextFieldTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTableCellBuilder"); -TextFieldTreeCell = Java.type("javafx.scene.control.cell.TextFieldTreeCell"); -TextFieldTreeCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeCellBuilder"); -TextFieldTreeTableCell = Java.type("javafx.scene.control.cell.TextFieldTreeTableCell"); -//TextFieldTreeTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeTableCellBuilder"); -TreeItemPropertyValueFactory = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactory"); -//TreeItemPropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactoryBuilder"); -CellBuilder = Java.type("javafx.scene.control.CellBuilder"); -CheckBox = Java.type("javafx.scene.control.CheckBox"); -CheckBoxBuilder = Java.type("javafx.scene.control.CheckBoxBuilder"); -CheckBoxTreeItem = Java.type("javafx.scene.control.CheckBoxTreeItem"); -CheckBoxTreeItem$TreeModificationEvent = Java.type("javafx.scene.control.CheckBoxTreeItem$TreeModificationEvent"); -CheckBoxTreeItemBuilder = Java.type("javafx.scene.control.CheckBoxTreeItemBuilder"); -CheckMenuItem = Java.type("javafx.scene.control.CheckMenuItem"); -CheckMenuItemBuilder = Java.type("javafx.scene.control.CheckMenuItemBuilder"); -ChoiceBox = Java.type("javafx.scene.control.ChoiceBox"); -ChoiceBoxBuilder = Java.type("javafx.scene.control.ChoiceBoxBuilder"); -ColorPicker = Java.type("javafx.scene.control.ColorPicker"); -ColorPickerBuilder = Java.type("javafx.scene.control.ColorPickerBuilder"); -ComboBox = Java.type("javafx.scene.control.ComboBox"); -ComboBoxBase = Java.type("javafx.scene.control.ComboBoxBase"); -ComboBoxBaseBuilder = Java.type("javafx.scene.control.ComboBoxBaseBuilder"); -ComboBoxBuilder = Java.type("javafx.scene.control.ComboBoxBuilder"); -ContentDisplay = Java.type("javafx.scene.control.ContentDisplay"); -ContextMenu = Java.type("javafx.scene.control.ContextMenu"); -ContextMenuBuilder = Java.type("javafx.scene.control.ContextMenuBuilder"); -Control = Java.type("javafx.scene.control.Control"); -ControlBuilder = Java.type("javafx.scene.control.ControlBuilder"); -CustomMenuItem = Java.type("javafx.scene.control.CustomMenuItem"); -CustomMenuItemBuilder = Java.type("javafx.scene.control.CustomMenuItemBuilder"); -FocusModel = Java.type("javafx.scene.control.FocusModel"); -Hyperlink = Java.type("javafx.scene.control.Hyperlink"); -HyperlinkBuilder = Java.type("javafx.scene.control.HyperlinkBuilder"); -IndexedCell = Java.type("javafx.scene.control.IndexedCell"); -IndexedCellBuilder = Java.type("javafx.scene.control.IndexedCellBuilder"); -IndexRange = Java.type("javafx.scene.control.IndexRange"); -IndexRangeBuilder = Java.type("javafx.scene.control.IndexRangeBuilder"); -Label = Java.type("javafx.scene.control.Label"); -LabelBuilder = Java.type("javafx.scene.control.LabelBuilder"); -Labeled = Java.type("javafx.scene.control.Labeled"); -LabeledBuilder = Java.type("javafx.scene.control.LabeledBuilder"); -ListCell = Java.type("javafx.scene.control.ListCell"); -ListCellBuilder = Java.type("javafx.scene.control.ListCellBuilder"); -ListView = Java.type("javafx.scene.control.ListView"); -ListView$EditEvent = Java.type("javafx.scene.control.ListView$EditEvent"); -ListViewBuilder = Java.type("javafx.scene.control.ListViewBuilder"); -Menu = Java.type("javafx.scene.control.Menu"); -MenuBar = Java.type("javafx.scene.control.MenuBar"); -MenuBarBuilder = Java.type("javafx.scene.control.MenuBarBuilder"); -MenuBuilder = Java.type("javafx.scene.control.MenuBuilder"); -MenuButton = Java.type("javafx.scene.control.MenuButton"); -MenuButtonBuilder = Java.type("javafx.scene.control.MenuButtonBuilder"); -MenuItem = Java.type("javafx.scene.control.MenuItem"); -MenuItemBuilder = Java.type("javafx.scene.control.MenuItemBuilder"); -MultipleSelectionModel = Java.type("javafx.scene.control.MultipleSelectionModel"); -MultipleSelectionModelBuilder = Java.type("javafx.scene.control.MultipleSelectionModelBuilder"); -OverrunStyle = Java.type("javafx.scene.control.OverrunStyle"); -Pagination = Java.type("javafx.scene.control.Pagination"); -PaginationBuilder = Java.type("javafx.scene.control.PaginationBuilder"); -PasswordField = Java.type("javafx.scene.control.PasswordField"); -PasswordFieldBuilder = Java.type("javafx.scene.control.PasswordFieldBuilder"); -PopupControl = Java.type("javafx.scene.control.PopupControl"); -PopupControlBuilder = Java.type("javafx.scene.control.PopupControlBuilder"); -ProgressBar = Java.type("javafx.scene.control.ProgressBar"); -ProgressBarBuilder = Java.type("javafx.scene.control.ProgressBarBuilder"); -ProgressIndicator = Java.type("javafx.scene.control.ProgressIndicator"); -ProgressIndicatorBuilder = Java.type("javafx.scene.control.ProgressIndicatorBuilder"); -RadioButton = Java.type("javafx.scene.control.RadioButton"); -RadioButtonBuilder = Java.type("javafx.scene.control.RadioButtonBuilder"); -RadioMenuItem = Java.type("javafx.scene.control.RadioMenuItem"); -RadioMenuItemBuilder = Java.type("javafx.scene.control.RadioMenuItemBuilder"); -ResizeFeaturesBase = Java.type("javafx.scene.control.ResizeFeaturesBase"); -//ResizeFeaturesBaseBuilder = Java.type("javafx.scene.control.ResizeFeaturesBaseBuilder"); -ScrollBar = Java.type("javafx.scene.control.ScrollBar"); -ScrollBarBuilder = Java.type("javafx.scene.control.ScrollBarBuilder"); -ScrollPane = Java.type("javafx.scene.control.ScrollPane"); -ScrollPane$ScrollBarPolicy = Java.type("javafx.scene.control.ScrollPane$ScrollBarPolicy"); -ScrollPaneBuilder = Java.type("javafx.scene.control.ScrollPaneBuilder"); -ScrollToEvent = Java.type("javafx.scene.control.ScrollToEvent"); -SelectionMode = Java.type("javafx.scene.control.SelectionMode"); -SelectionModel = Java.type("javafx.scene.control.SelectionModel"); -Separator = Java.type("javafx.scene.control.Separator"); -SeparatorBuilder = Java.type("javafx.scene.control.SeparatorBuilder"); -SeparatorMenuItem = Java.type("javafx.scene.control.SeparatorMenuItem"); -SeparatorMenuItemBuilder = Java.type("javafx.scene.control.SeparatorMenuItemBuilder"); -SingleSelectionModel = Java.type("javafx.scene.control.SingleSelectionModel"); -Skin = Java.type("javafx.scene.control.Skin"); -SkinBase = Java.type("javafx.scene.control.SkinBase"); -//SkinBaseBuilder = Java.type("javafx.scene.control.SkinBaseBuilder"); -Skinnable = Java.type("javafx.scene.control.Skinnable"); -Slider = Java.type("javafx.scene.control.Slider"); -SliderBuilder = Java.type("javafx.scene.control.SliderBuilder"); -SortEvent = Java.type("javafx.scene.control.SortEvent"); -SplitMenuButton = Java.type("javafx.scene.control.SplitMenuButton"); -SplitMenuButtonBuilder = Java.type("javafx.scene.control.SplitMenuButtonBuilder"); -SplitPane = Java.type("javafx.scene.control.SplitPane"); -SplitPane$Divider = Java.type("javafx.scene.control.SplitPane$Divider"); -SplitPaneBuilder = Java.type("javafx.scene.control.SplitPaneBuilder"); -Tab = Java.type("javafx.scene.control.Tab"); -TabBuilder = Java.type("javafx.scene.control.TabBuilder"); -TableCell = Java.type("javafx.scene.control.TableCell"); -TableCellBuilder = Java.type("javafx.scene.control.TableCellBuilder"); -TableColumn = Java.type("javafx.scene.control.TableColumn"); -TableColumn$CellDataFeatures = Java.type("javafx.scene.control.TableColumn$CellDataFeatures"); -TableColumn$CellEditEvent = Java.type("javafx.scene.control.TableColumn$CellEditEvent"); -TableColumn$SortType = Java.type("javafx.scene.control.TableColumn$SortType"); -TableColumnBase = Java.type("javafx.scene.control.TableColumnBase"); -//TableColumnBaseBuilder = Java.type("javafx.scene.control.TableColumnBaseBuilder"); -TableColumnBuilder = Java.type("javafx.scene.control.TableColumnBuilder"); -TableFocusModel = Java.type("javafx.scene.control.TableFocusModel"); -TablePosition = Java.type("javafx.scene.control.TablePosition"); -TablePositionBase = Java.type("javafx.scene.control.TablePositionBase"); -TableRow = Java.type("javafx.scene.control.TableRow"); -TableRowBuilder = Java.type("javafx.scene.control.TableRowBuilder"); -TableSelectionModel = Java.type("javafx.scene.control.TableSelectionModel"); -//TableSelectionModelBuilder = Java.type("javafx.scene.control.TableSelectionModelBuilder"); -TableView = Java.type("javafx.scene.control.TableView"); -TableView$ResizeFeatures = Java.type("javafx.scene.control.TableView$ResizeFeatures"); -TableView$TableViewFocusModel = Java.type("javafx.scene.control.TableView$TableViewFocusModel"); -TableView$TableViewSelectionModel = Java.type("javafx.scene.control.TableView$TableViewSelectionModel"); -TableViewBuilder = Java.type("javafx.scene.control.TableViewBuilder"); -TabPane = Java.type("javafx.scene.control.TabPane"); -TabPane$TabClosingPolicy = Java.type("javafx.scene.control.TabPane$TabClosingPolicy"); -TabPaneBuilder = Java.type("javafx.scene.control.TabPaneBuilder"); -TextArea = Java.type("javafx.scene.control.TextArea"); -TextAreaBuilder = Java.type("javafx.scene.control.TextAreaBuilder"); -TextField = Java.type("javafx.scene.control.TextField"); -TextFieldBuilder = Java.type("javafx.scene.control.TextFieldBuilder"); -TextInputControl = Java.type("javafx.scene.control.TextInputControl"); -TextInputControl$Content = Java.type("javafx.scene.control.TextInputControl$Content"); -TextInputControlBuilder = Java.type("javafx.scene.control.TextInputControlBuilder"); -TitledPane = Java.type("javafx.scene.control.TitledPane"); -TitledPaneBuilder = Java.type("javafx.scene.control.TitledPaneBuilder"); -Toggle = Java.type("javafx.scene.control.Toggle"); -ToggleButton = Java.type("javafx.scene.control.ToggleButton"); -ToggleButtonBuilder = Java.type("javafx.scene.control.ToggleButtonBuilder"); -ToggleGroup = Java.type("javafx.scene.control.ToggleGroup"); -ToggleGroupBuilder = Java.type("javafx.scene.control.ToggleGroupBuilder"); -ToolBar = Java.type("javafx.scene.control.ToolBar"); -ToolBarBuilder = Java.type("javafx.scene.control.ToolBarBuilder"); -Tooltip = Java.type("javafx.scene.control.Tooltip"); -TooltipBuilder = Java.type("javafx.scene.control.TooltipBuilder"); -TreeCell = Java.type("javafx.scene.control.TreeCell"); -TreeCellBuilder = Java.type("javafx.scene.control.TreeCellBuilder"); -TreeItem = Java.type("javafx.scene.control.TreeItem"); -TreeItem$TreeModificationEvent = Java.type("javafx.scene.control.TreeItem$TreeModificationEvent"); -TreeItemBuilder = Java.type("javafx.scene.control.TreeItemBuilder"); -TreeSortMode = Java.type("javafx.scene.control.TreeSortMode"); -TreeTableCell = Java.type("javafx.scene.control.TreeTableCell"); -//TreeTableCellBuilder = Java.type("javafx.scene.control.TreeTableCellBuilder"); -TreeTableColumn = Java.type("javafx.scene.control.TreeTableColumn"); -TreeTableColumn$CellDataFeatures = Java.type("javafx.scene.control.TreeTableColumn$CellDataFeatures"); -TreeTableColumn$CellEditEvent = Java.type("javafx.scene.control.TreeTableColumn$CellEditEvent"); -TreeTableColumn$SortType = Java.type("javafx.scene.control.TreeTableColumn$SortType"); -//TreeTableColumnBuilder = Java.type("javafx.scene.control.TreeTableColumnBuilder"); -TreeTablePosition = Java.type("javafx.scene.control.TreeTablePosition"); -TreeTableRow = Java.type("javafx.scene.control.TreeTableRow"); -//TreeTableRowBuilder = Java.type("javafx.scene.control.TreeTableRowBuilder"); -TreeTableView = Java.type("javafx.scene.control.TreeTableView"); -TreeTableView$EditEvent = Java.type("javafx.scene.control.TreeTableView$EditEvent"); -TreeTableView$ResizeFeatures = Java.type("javafx.scene.control.TreeTableView$ResizeFeatures"); -TreeTableView$TreeTableViewFocusModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewFocusModel"); -TreeTableView$TreeTableViewSelectionModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewSelectionModel"); -//TreeTableViewBuilder = Java.type("javafx.scene.control.TreeTableViewBuilder"); -TreeView = Java.type("javafx.scene.control.TreeView"); -TreeView$EditEvent = Java.type("javafx.scene.control.TreeView$EditEvent"); -TreeViewBuilder = Java.type("javafx.scene.control.TreeViewBuilder"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_CONTROLS_CLASSES); -- cgit v1.2.3 From 365c6b9e6b0d5bb9f5ab55e58c9d9ee43317cc6b Mon Sep 17 00:00:00 2001 From: attila Date: Wed, 11 Sep 2013 10:27:25 +0200 Subject: 8024130: We no longer need slots for temporaries in self-assign indices Reviewed-by: jlaskey, lagergren --- src/jdk/nashorn/internal/codegen/Attr.java | 40 +++--------------------------- 1 file changed, 3 insertions(+), 37 deletions(-) diff --git a/src/jdk/nashorn/internal/codegen/Attr.java b/src/jdk/nashorn/internal/codegen/Attr.java index 29430062..88e904dc 100644 --- a/src/jdk/nashorn/internal/codegen/Attr.java +++ b/src/jdk/nashorn/internal/codegen/Attr.java @@ -886,10 +886,9 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveDECINC(final UnaryNode unaryNode) { // @see assignOffset - final UnaryNode newUnaryNode = unaryNode.setRHS(ensureAssignmentSlots(unaryNode.rhs())); final Type type = arithType(); - newType(newUnaryNode.rhs().getSymbol(), type); - return end(ensureSymbol(type, newUnaryNode)); + newType(unaryNode.rhs().getSymbol(), type); + return end(ensureSymbol(type, unaryNode)); } @Override @@ -1574,39 +1573,6 @@ final class Attr extends NodeOperatorVisitor { return newInternal(lc.getCurrentFunction().uniqueName(EXCEPTION_PREFIX.symbolName()), Type.typeFor(EXCEPTION_PREFIX.type())); } - /** - * In an assignment, recursively make sure that there are slots for - * everything that has to be laid out as temporary storage, which is the - * case if we are assign-op:ing a BaseNode subclass. This has to be - * recursive to handle things like multi dimensional arrays as lhs - * - * see NASHORN-258 - * - * @param assignmentDest the destination node of the assignment, e.g. lhs for binary nodes - */ - private Expression ensureAssignmentSlots(final Expression assignmentDest) { - final LexicalContext attrLexicalContext = lc; - return (Expression)assignmentDest.accept(new NodeVisitor(new LexicalContext()) { - @Override - public Node leaveIndexNode(final IndexNode indexNode) { - assert indexNode.getSymbol().isTemp(); - final Expression index = indexNode.getIndex(); - //only temps can be set as needing slots. the others will self resolve - //it is illegal to take a scope var and force it to be a slot, that breaks - Symbol indexSymbol = index.getSymbol(); - if (indexSymbol.isTemp() && !indexSymbol.isConstant() && !indexSymbol.hasSlot()) { - if(indexSymbol.isShared()) { - indexSymbol = temporarySymbols.createUnshared(indexSymbol); - } - indexSymbol.setNeedsSlot(true); - attrLexicalContext.getCurrentBlock().putSymbol(attrLexicalContext, indexSymbol); - return indexNode.setIndex(index.setSymbol(attrLexicalContext, indexSymbol)); - } - return indexNode; - } - }); - } - /** * Return the type that arithmetic ops should use. Until we have implemented better type * analysis (range based) or overflow checks that are fast enough for int arithmetic, @@ -1704,7 +1670,7 @@ final class Attr extends NodeOperatorVisitor { newType(lhs.getSymbol(), destType); //may not narrow if dest is already wider than destType // ensureSymbol(destType, binaryNode); //for OP= nodes, the node can carry a narrower types than its lhs rhs. This is perfectly fine - return end(ensureSymbol(destType, ensureAssignmentSlots(binaryNode))); + return end(ensureSymbol(destType, binaryNode)); } private Expression ensureSymbol(final Type type, final Expression expr) { -- cgit v1.2.3 From b50b5aed303aec9924c31bb281bd5ee66bd7d335 Mon Sep 17 00:00:00 2001 From: sundar Date: Wed, 11 Sep 2013 20:49:28 +0530 Subject: 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations Reviewed-by: jlaskey, hannesw --HG-- rename : src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java => src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java rename : src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java => src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java --- src/jdk/nashorn/api/scripting/JSObject.java | 187 +++++++++++++-- .../nashorn/api/scripting/NashornScriptEngine.java | 2 +- .../nashorn/api/scripting/ScriptObjectMirror.java | 178 ++++++++------ src/jdk/nashorn/internal/ir/IdentNode.java | 1 + .../internal/lookup/MethodHandleFactory.java | 2 +- src/jdk/nashorn/internal/objects/NativeArray.java | 4 +- .../nashorn/internal/objects/NativeFunction.java | 32 ++- .../nashorn/internal/runtime/ScriptRuntime.java | 38 +-- .../internal/runtime/arrays/ArrayLikeIterator.java | 10 +- .../internal/runtime/arrays/IteratorAction.java | 8 +- .../internal/runtime/arrays/JSObjectIterator.java | 81 +++++++ .../runtime/arrays/ReverseJSObjectIterator.java | 56 +++++ .../arrays/ReverseScriptObjectMirrorIterator.java | 56 ----- .../runtime/arrays/ScriptObjectMirrorIterator.java | 81 ------- .../nashorn/internal/runtime/linker/Bootstrap.java | 4 +- .../internal/runtime/linker/JSObjectLinker.java | 74 +++--- .../api/scripting/PluggableJSObjectTest.java | 257 +++++++++++++++++++++ .../api/scripting/ScriptObjectMirrorTest.java | 12 +- 18 files changed, 772 insertions(+), 311 deletions(-) create mode 100644 src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java create mode 100644 src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java delete mode 100644 src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java delete mode 100644 src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java create mode 100644 test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java diff --git a/src/jdk/nashorn/api/scripting/JSObject.java b/src/jdk/nashorn/api/scripting/JSObject.java index 4f3a8e88..53b5790e 100644 --- a/src/jdk/nashorn/api/scripting/JSObject.java +++ b/src/jdk/nashorn/api/scripting/JSObject.java @@ -25,73 +25,210 @@ package jdk.nashorn.api.scripting; +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + /** - * netscape.javascript.JSObject-like interface for nashorn script objects. + * This is the base class for nashorn ScriptObjectMirror class. + * + * This class can also be subclassed by an arbitrary Java class. Nashorn will + * treat objects of such classes just like nashorn script objects. Usual nashorn + * operations like obj[i], obj.foo, obj.func(), delete obj.foo will be glued + * to appropriate method call of this class. */ public abstract class JSObject { /** - * Call a JavaScript function + * Call this object as a JavaScript function. This is equivalent to + * 'func.apply(thiz, args)' in JavaScript. * - * @param functionName name of function + * @param thiz 'this' object to be passed to the function * @param args arguments to method * @return result of call */ - public abstract Object call(String functionName, Object... args); + public Object call(Object thiz, Object... args) { + throw new UnsupportedOperationException("call"); + } /** - * Call a JavaScript method as a constructor. This is equivalent to - * calling new obj.Method(arg1, arg2...) in JavaScript. + * Call this 'constructor' JavaScript function to create a new object. + * This is equivalent to 'new func(arg1, arg2...)' in JavaScript. * - * @param functionName name of function * @param args arguments to method * @return result of constructor call */ - public abstract Object newObject(String functionName, Object... args); + public Object newObject(Object... args) { + throw new UnsupportedOperationException("newObject"); + } /** - * Evaluate a JavaScript expression + * Evaluate a JavaScript expression. * * @param s JavaScript expression to evaluate * @return evaluation result */ - public abstract Object eval(String s); + public Object eval(String s) { + throw new UnsupportedOperationException("eval"); + } + + /** + * Call a JavaScript function member of this object. + * + * @param name name of the member function to call + * @param args arguments to be passed to the member function + * @return result of call + */ + public Object callMember(String name, Object... args) { + throw new UnsupportedOperationException("call"); + } /** - * Retrieves a named member of a JavaScript object. + * Retrieves a named member of this JavaScript object. * * @param name of member * @return member */ - public abstract Object getMember(String name); + public Object getMember(String name) { + return null; + } /** - * Retrieves an indexed member of a JavaScript object. + * Retrieves an indexed member of this JavaScript object. * - * @param index index of member slot + * @param index index slot to retrieve * @return member */ - public abstract Object getSlot(int index); + public Object getSlot(int index) { + return null; + } /** - * Remove a named member from a JavaScript object + * Does this object have a named member? * * @param name name of member + * @return true if this object has a member of the given name + */ + public boolean hasMember(String name) { + return false; + } + + /** + * Does this object have a indexed property? + * + * @param slot index to check + * @return true if this object has a slot + */ + public boolean hasSlot(int slot) { + return false; + } + + /** + * Remove a named member from this JavaScript object + * + * @param name name of the member + */ + public void removeMember(String name) { + } + + /** + * Set a named member in this JavaScript object + * + * @param name name of the member + * @param value value of the member + */ + public void setMember(String name, Object value) { + } + + /** + * Set an indexed member in this JavaScript object + * + * @param index index of the member slot + * @param value value of the member + */ + public void setSlot(int index, Object value) { + } + + // property and value iteration + + /** + * Returns the set of all property names of this object. + * + * @return set of property names + */ + @SuppressWarnings("unchecked") + public Set keySet() { + return Collections.EMPTY_SET; + } + + /** + * Returns the set of all property values of this object. + * + * @return set of property values. + */ + @SuppressWarnings("unchecked") + public Collection values() { + return Collections.EMPTY_SET; + } + + // JavaScript instanceof check + + /** + * Checking whether the given object is an instance of 'this' object. + * + * @param instance instace to check + * @return true if the given 'instance' is an instance of this 'function' object + */ + public boolean isInstance(final Object instance) { + return false; + } + + /** + * Checking whether this object is an instance of the given 'clazz' object. + * + * @param clazz clazz to check + * @return true if this object is an instance of the given 'clazz' + */ + public boolean isInstanceOf(final Object clazz) { + if (clazz instanceof JSObject) { + return ((JSObject)clazz).isInstance(this); + } + + return false; + } + + /** + * ECMA [[Class]] property + * + * @return ECMA [[Class]] property value of this object + */ + public String getClassName() { + return getClass().getName(); + } + + /** + * Is this a function object? + * + * @return if this mirror wraps a ECMAScript function instance */ - public abstract void removeMember(String name); + public boolean isFunction() { + return false; + } /** - * Set a named member in a JavaScript object + * Is this a 'use strict' function object? * - * @param name name of member - * @param value value of member + * @return true if this mirror represents a ECMAScript 'use strict' function */ - public abstract void setMember(String name, Object value); + public boolean isStrictFunction() { + return false; + } /** - * Set an indexed member in a JavaScript object + * Is this an array object? * - * @param index index of member slot - * @param value value of member + * @return if this mirror wraps a ECMAScript array object */ - public abstract void setSlot(int index, Object value); + public boolean isArray() { + return false; + } } diff --git a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index ce42a46c..45eddd11 100644 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -494,7 +494,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C if (selfMirror != null) { try { - return ScriptObjectMirror.translateUndefined(selfMirror.call(name, args)); + return ScriptObjectMirror.translateUndefined(selfMirror.callMember(name, args)); } catch (final Exception e) { final Throwable cause = e.getCause(); if (cause instanceof NoSuchMethodException) { diff --git a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java index e8546cd6..3a27d23e 100644 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java @@ -48,9 +48,7 @@ import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; /** - * Mirror object that wraps a given ScriptObject instance. User can - * access ScriptObject via the javax.script.Bindings interface or - * netscape.javascript.JSObject interface. + * Mirror object that wraps a given Nashorn Script object. */ public final class ScriptObjectMirror extends JSObject implements Bindings { private static AccessControlContext getContextAccCtxt() { @@ -90,8 +88,9 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { } // JSObject methods + @Override - public Object call(final String functionName, final Object... args) { + public Object call(final Object thiz, final Object... args) { final ScriptObject oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); @@ -100,15 +99,13 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { Context.setGlobal(global); } - final Object val = functionName == null? sobj : sobj.get(functionName); - if (val instanceof ScriptFunction) { + if (sobj instanceof ScriptFunction) { final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; - return wrap(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); - } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { - return ((ScriptObjectMirror)val).call(null, args); + final Object self = globalChanged? wrap(thiz, oldGlobal) : thiz; + return wrap(ScriptRuntime.apply((ScriptFunction)sobj, unwrap(self, global), unwrapArray(modArgs, global)), global); } - throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : "")); + throw new RuntimeException("not a function: " + toString()); } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { @@ -121,7 +118,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { } @Override - public Object newObject(final String functionName, final Object... args) { + public Object newObject(final Object... args) { final ScriptObject oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); @@ -130,15 +127,12 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { Context.setGlobal(global); } - final Object val = functionName == null? sobj : sobj.get(functionName); - if (val instanceof ScriptFunction) { + if (sobj instanceof ScriptFunction) { final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; - return wrap(ScriptRuntime.construct((ScriptFunction)val, unwrapArray(modArgs, global)), global); - } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { - return ((ScriptObjectMirror)val).newObject(null, args); + return wrap(ScriptRuntime.construct((ScriptFunction)sobj, unwrapArray(modArgs, global)), global); } - throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : "")); + throw new RuntimeException("not a constructor: " + toString()); } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { @@ -167,8 +161,40 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } + @Override + public Object callMember(final String functionName, final Object... args) { + functionName.getClass(); // null check + final ScriptObject oldGlobal = Context.getGlobal(); + final boolean globalChanged = (oldGlobal != global); + + try { + if (globalChanged) { + Context.setGlobal(global); + } + + final Object val = sobj.get(functionName); + if (val instanceof ScriptFunction) { + final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; + return wrap(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); + } else if (val instanceof JSObject && ((JSObject)val).isFunction()) { + return ((JSObject)val).call(sobj, args); + } + + throw new NoSuchMethodException("No such function " + functionName); + } catch (final RuntimeException | Error e) { + throw e; + } catch (final Throwable t) { + throw new RuntimeException(t); + } finally { + if (globalChanged) { + Context.setGlobal(oldGlobal); + } + } + } + @Override public Object getMember(final String name) { + name.getClass(); return inGlobal(new Callable() { @Override public Object call() { return wrap(sobj.get(name), global); @@ -185,13 +211,34 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } + @Override + public boolean hasMember(final String name) { + name.getClass(); + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.has(name); + } + }); + } + + @Override + public boolean hasSlot(final int slot) { + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.has(slot); + } + }); + } + @Override public void removeMember(final String name) { + name.getClass(); remove(name); } @Override public void setMember(final String name, final Object value) { + name.getClass(); put(name, value); } @@ -205,6 +252,45 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } + @Override + public boolean isInstance(final Object obj) { + if (! (obj instanceof ScriptObjectMirror)) { + return false; + } + + final ScriptObjectMirror instance = (ScriptObjectMirror)obj; + // if not belongs to my global scope, return false + if (global != instance.global) { + return false; + } + + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.isInstance(instance.sobj); + } + }); + } + + @Override + public String getClassName() { + return sobj.getClassName(); + } + + @Override + public boolean isFunction() { + return sobj instanceof ScriptFunction; + } + + @Override + public boolean isStrictFunction() { + return isFunction() && ((ScriptFunction)sobj).isStrict(); + } + + @Override + public boolean isArray() { + return sobj.isArray(); + } + // javax.script.Bindings methods @Override @@ -391,15 +477,6 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } - /** - * ECMA [[Class]] property - * - * @return ECMA [[Class]] property value of this object - */ - public String getClassName() { - return sobj.getClassName(); - } - /** * ECMA 8.12.1 [[GetOwnProperty]] (P) * @@ -506,55 +583,6 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } - // ECMAScript instanceof check - - /** - * Checking whether a script object is an instance of another by - * walking the proto chain - * - * @param instance instace to check - * @return true if 'instance' is an instance of this object - */ - public boolean isInstance(final ScriptObjectMirror instance) { - // if not belongs to my global scope, return false - if (instance == null || global != instance.global) { - return false; - } - - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.isInstance(instance.sobj); - } - }); - } - - /** - * is this a function object? - * - * @return if this mirror wraps a ECMAScript function instance - */ - public boolean isFunction() { - return sobj instanceof ScriptFunction; - } - - /** - * is this a 'use strict' function object? - * - * @return true if this mirror represents a ECMAScript 'use strict' function - */ - public boolean isStrictFunction() { - return isFunction() && ((ScriptFunction)sobj).isStrict(); - } - - /** - * is this an array object? - * - * @return if this mirror wraps a ECMAScript array object - */ - public boolean isArray() { - return sobj.isArray(); - } - /** * Utility to check if given object is ECMAScript undefined value * diff --git a/src/jdk/nashorn/internal/ir/IdentNode.java b/src/jdk/nashorn/internal/ir/IdentNode.java index cec111a2..4b139b25 100644 --- a/src/jdk/nashorn/internal/ir/IdentNode.java +++ b/src/jdk/nashorn/internal/ir/IdentNode.java @@ -168,6 +168,7 @@ public final class IdentNode extends Expression implements PropertyKey, TypeOver * return 3; * } * } + * * * @return true if can have callsite type */ diff --git a/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java b/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java index 4d8a2977..34fe2eb6 100644 --- a/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java +++ b/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java @@ -565,7 +565,7 @@ public final class MethodHandleFactory { @Override public MethodHandle asSpreader(final MethodHandle handle, final Class arrayType, final int arrayLength) { - final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength); + final MethodHandle mh = super.asSpreader(handle, arrayType, arrayLength); return debug(mh, "asSpreader", handle, arrayType, arrayLength); } diff --git a/src/jdk/nashorn/internal/objects/NativeArray.java b/src/jdk/nashorn/internal/objects/NativeArray.java index 54f29387..8cb1ded9 100644 --- a/src/jdk/nashorn/internal/objects/NativeArray.java +++ b/src/jdk/nashorn/internal/objects/NativeArray.java @@ -41,7 +41,7 @@ import java.util.Iterator; import java.util.List; import java.util.concurrent.Callable; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; @@ -374,7 +374,7 @@ public final class NativeArray extends ScriptObject { public static Object isArray(final Object self, final Object arg) { return isArray(arg) || (arg == Global.instance().getArrayPrototype()) || (arg instanceof NativeRegExpExecResult) - || (arg instanceof ScriptObjectMirror && ((ScriptObjectMirror)arg).isArray()); + || (arg instanceof JSObject && ((JSObject)arg).isArray()); } /** diff --git a/src/jdk/nashorn/internal/objects/NativeFunction.java b/src/jdk/nashorn/internal/objects/NativeFunction.java index c208a35c..c77002e3 100644 --- a/src/jdk/nashorn/internal/objects/NativeFunction.java +++ b/src/jdk/nashorn/internal/objects/NativeFunction.java @@ -30,7 +30,7 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; import java.util.List; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; @@ -88,7 +88,7 @@ public final class NativeFunction { */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object apply(final Object self, final Object thiz, final Object array) { - if (!(self instanceof ScriptFunction)) { + if (!(self instanceof ScriptFunction) && !(self instanceof JSObject)) { throw typeError("not.a.function", ScriptRuntime.safeToString(self)); } @@ -111,21 +111,27 @@ public final class NativeFunction { list.toArray(args = new Object[list.size()]); } else if (array == null || array == UNDEFINED) { args = ScriptRuntime.EMPTY_ARRAY; - } else if (array instanceof ScriptObjectMirror) { - // look for array-like ScriptObjectMirror object - final ScriptObjectMirror mirror = (ScriptObjectMirror)array; - final Object len = mirror.containsKey("length")? mirror.getMember("length") : Integer.valueOf(0); + } else if (array instanceof JSObject) { + // look for array-like JSObject object + final JSObject jsObj = (JSObject)array; + final Object len = jsObj.hasMember("length")? jsObj.getMember("length") : Integer.valueOf(0); final int n = (int)JSType.toUint32(len); args = new Object[n]; for (int i = 0; i < args.length; i++) { - args[i] = mirror.containsKey(i)? mirror.getSlot(i) : UNDEFINED; + args[i] = jsObj.hasSlot(i)? jsObj.getSlot(i) : UNDEFINED; } } else { throw typeError("function.apply.expects.array"); } - return ScriptRuntime.apply((ScriptFunction)self, thiz, args); + if (self instanceof ScriptFunction) { + return ScriptRuntime.apply((ScriptFunction)self, thiz, args); + } else if (self instanceof JSObject) { + return ((JSObject)self).call(thiz, args); + } + + throw new AssertionError("should not reach here"); } /** @@ -137,7 +143,7 @@ public final class NativeFunction { */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static Object call(final Object self, final Object... args) { - if (!(self instanceof ScriptFunction)) { + if (!(self instanceof ScriptFunction) && !(self instanceof JSObject)) { throw typeError("not.a.function", ScriptRuntime.safeToString(self)); } @@ -151,7 +157,13 @@ public final class NativeFunction { arguments = ScriptRuntime.EMPTY_ARRAY; } - return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments); + if (self instanceof ScriptFunction) { + return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments); + } else if (self instanceof JSObject) { + return ((JSObject)self).call(thiz, arguments); + } + + throw new AssertionError("should not reach here"); } /** diff --git a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java index aa146f1d..c9b40512 100644 --- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java @@ -43,6 +43,7 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; import jdk.internal.dynalink.beans.StaticClass; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.ir.debug.JSONWriter; @@ -190,8 +191,8 @@ public final class ScriptRuntime { case FUNCTION: if (self instanceof ScriptObject) { className = ((ScriptObject)self).getClassName(); - } else if (self instanceof ScriptObjectMirror) { - className = ((ScriptObjectMirror)self).getClassName(); + } else if (self instanceof JSObject) { + className = ((JSObject)self).getClassName(); } else { className = self.getClass().getName(); } @@ -245,8 +246,8 @@ public final class ScriptRuntime { return new RangeIterator(Array.getLength(obj)); } - if (obj instanceof ScriptObjectMirror) { - return ((ScriptObjectMirror)obj).keySet().iterator(); + if (obj instanceof JSObject) { + return ((JSObject)obj).keySet().iterator(); } if (obj instanceof List) { @@ -323,8 +324,8 @@ public final class ScriptRuntime { }; } - if (obj instanceof ScriptObjectMirror) { - return ((ScriptObjectMirror)obj).values().iterator(); + if (obj instanceof JSObject) { + return ((JSObject)obj).values().iterator(); } if (obj instanceof Map) { @@ -571,8 +572,8 @@ public final class ScriptRuntime { throw typeError("cant.get.property", safeToString(property), "null"); } else if (JSType.isPrimitive(obj)) { obj = ((ScriptObject)JSType.toScriptObject(obj)).get(property); - } else if (obj instanceof ScriptObjectMirror) { - obj = ((ScriptObjectMirror)obj).getMember(property.toString()); + } else if (obj instanceof JSObject) { + obj = ((JSObject)obj).getMember(property.toString()); } else { obj = UNDEFINED; } @@ -624,6 +625,11 @@ public final class ScriptRuntime { return ((ScriptObject) JSType.toScriptObject(obj)).delete(property, Boolean.TRUE.equals(strict)); } + if (obj instanceof JSObject) { + ((JSObject)obj).removeMember(Objects.toString(property)); + return true; + } + // if object is not reference type, vacuously delete is successful. return true; } @@ -815,6 +821,10 @@ public final class ScriptRuntime { return ((ScriptObject)obj).has(property); } + if (obj instanceof JSObject) { + return ((JSObject)obj).hasMember(Objects.toString(property)); + } + return false; } @@ -841,11 +851,13 @@ public final class ScriptRuntime { return ((StaticClass)clazz).getRepresentedClass().isInstance(obj); } - if (clazz instanceof ScriptObjectMirror) { - if (obj instanceof ScriptObjectMirror) { - return ((ScriptObjectMirror)clazz).isInstance((ScriptObjectMirror)obj); - } - return false; + if (clazz instanceof JSObject) { + return ((JSObject)clazz).isInstance(obj); + } + + // provide for reverse hook + if (obj instanceof JSObject) { + return ((JSObject)obj).isInstanceOf(clazz); } throw typeError("instanceof.on.non.object"); diff --git a/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java b/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java index 044b21d5..962b1f9e 100644 --- a/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java @@ -27,7 +27,7 @@ package jdk.nashorn.internal.runtime.arrays; import java.util.Iterator; import java.util.List; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptObject; @@ -127,8 +127,8 @@ abstract public class ArrayLikeIterator implements Iterator { return new ScriptObjectIterator((ScriptObject)obj, includeUndefined); } - if (obj instanceof ScriptObjectMirror) { - return new ScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined); + if (obj instanceof JSObject) { + return new JSObjectIterator((JSObject)obj, includeUndefined); } if (obj instanceof List) { @@ -160,8 +160,8 @@ abstract public class ArrayLikeIterator implements Iterator { return new ReverseScriptObjectIterator((ScriptObject)obj, includeUndefined); } - if (obj instanceof ScriptObjectMirror) { - return new ReverseScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined); + if (obj instanceof JSObject) { + return new ReverseJSObjectIterator((JSObject)obj, includeUndefined); } if (obj instanceof List) { diff --git a/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java b/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java index 9b6cbb44..244739b3 100644 --- a/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java +++ b/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java @@ -27,7 +27,7 @@ package jdk.nashorn.internal.runtime.arrays; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptRuntime; @@ -101,9 +101,9 @@ public abstract class IteratorAction { final boolean strict; if (callbackfn instanceof ScriptFunction) { strict = ((ScriptFunction)callbackfn).isStrict(); - } else if (callbackfn instanceof ScriptObjectMirror && - ((ScriptObjectMirror)callbackfn).isFunction()) { - strict = ((ScriptObjectMirror)callbackfn).isStrictFunction(); + } else if (callbackfn instanceof JSObject && + ((JSObject)callbackfn).isFunction()) { + strict = ((JSObject)callbackfn).isStrictFunction(); } else if (Bootstrap.isDynamicMethod(callbackfn) || Bootstrap.isFunctionalInterfaceObject(callbackfn)) { strict = false; } else { diff --git a/src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java b/src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java new file mode 100644 index 00000000..885c77eb --- /dev/null +++ b/src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java @@ -0,0 +1,81 @@ +/* + * 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.runtime.arrays; + +import java.util.NoSuchElementException; +import jdk.nashorn.api.scripting.JSObject; +import jdk.nashorn.internal.runtime.JSType; + +/** + * Iterator over a ScriptObjectMirror + */ +class JSObjectIterator extends ArrayLikeIterator { + + protected final JSObject obj; + private final long length; + + JSObjectIterator(final JSObject obj, final boolean includeUndefined) { + super(includeUndefined); + this.obj = obj; + this.length = JSType.toUint32(obj.hasMember("length")? obj.getMember("length") : 0); + this.index = 0; + } + + protected boolean indexInArray() { + return index < length; + } + + @Override + public long getLength() { + return length; + } + + @Override + public boolean hasNext() { + if (length == 0L) { + return false; //return empty string if toUint32(length) == 0 + } + + while (indexInArray()) { + if (obj.hasSlot((int)index) || includeUndefined) { + break; + } + bumpIndex(); + } + + return indexInArray(); + } + + @Override + public Object next() { + if (indexInArray()) { + return obj.getSlot((int)bumpIndex()); + } + + throw new NoSuchElementException(); + } +} + diff --git a/src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java b/src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java new file mode 100644 index 00000000..84c5c46d --- /dev/null +++ b/src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java @@ -0,0 +1,56 @@ +/* + * 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.runtime.arrays; + +import jdk.nashorn.api.scripting.JSObject; +import jdk.nashorn.internal.runtime.JSType; + +/** + * Reverse iterator over a ScriptObjectMirror + */ +final class ReverseJSObjectIterator extends JSObjectIterator { + + ReverseJSObjectIterator(final JSObject obj, final boolean includeUndefined) { + super(obj, includeUndefined); + this.index = JSType.toUint32(obj.hasMember("length")? obj.getMember("length") : 0) - 1; + } + + @Override + public boolean isReverse() { + return true; + } + + @Override + protected boolean indexInArray() { + return index >= 0; + } + + @Override + protected long bumpIndex() { + return index--; + } +} + diff --git a/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java b/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java deleted file mode 100644 index 1e3e4000..00000000 --- a/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java +++ /dev/null @@ -1,56 +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.runtime.arrays; - -import jdk.nashorn.api.scripting.ScriptObjectMirror; -import jdk.nashorn.internal.runtime.JSType; - -/** - * Reverse iterator over a ScriptObjectMirror - */ -final class ReverseScriptObjectMirrorIterator extends ScriptObjectMirrorIterator { - - ReverseScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) { - super(obj, includeUndefined); - this.index = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0) - 1; - } - - @Override - public boolean isReverse() { - return true; - } - - @Override - protected boolean indexInArray() { - return index >= 0; - } - - @Override - protected long bumpIndex() { - return index--; - } -} - diff --git a/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java b/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java deleted file mode 100644 index a7bef158..00000000 --- a/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java +++ /dev/null @@ -1,81 +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.runtime.arrays; - -import java.util.NoSuchElementException; -import jdk.nashorn.api.scripting.ScriptObjectMirror; -import jdk.nashorn.internal.runtime.JSType; - -/** - * Iterator over a ScriptObjectMirror - */ -class ScriptObjectMirrorIterator extends ArrayLikeIterator { - - protected final ScriptObjectMirror obj; - private final long length; - - ScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) { - super(includeUndefined); - this.obj = obj; - this.length = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0); - this.index = 0; - } - - protected boolean indexInArray() { - return index < length; - } - - @Override - public long getLength() { - return length; - } - - @Override - public boolean hasNext() { - if (length == 0L) { - return false; //return empty string if toUint32(length) == 0 - } - - while (indexInArray()) { - if (obj.containsKey(index) || includeUndefined) { - break; - } - bumpIndex(); - } - - return indexInArray(); - } - - @Override - public Object next() { - if (indexInArray()) { - return obj.get(bumpIndex()); - } - - throw new NoSuchElementException(); - } -} - diff --git a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java index e190224a..f725817a 100644 --- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java +++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java @@ -39,7 +39,7 @@ import jdk.internal.dynalink.beans.BeansLinker; import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkerServices; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.codegen.RuntimeCallSite; import jdk.nashorn.internal.runtime.JSType; @@ -87,7 +87,7 @@ public final class Bootstrap { } return obj instanceof ScriptFunction || - ((obj instanceof ScriptObjectMirror) && ((ScriptObjectMirror)obj).isFunction()) || + ((obj instanceof JSObject) && ((JSObject)obj).isFunction()) || isDynamicMethod(obj) || isFunctionalInterfaceObject(obj) || obj instanceof StaticClass; diff --git a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java index 1b7eb66b..45451a8b 100644 --- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java +++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java @@ -30,7 +30,6 @@ import jdk.nashorn.internal.lookup.MethodHandleFactory; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; -import java.util.Objects; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; @@ -88,8 +87,9 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { case "setElem": return c > 2 ? findSetMethod(desc) : findSetIndexMethod(); case "call": - case "callMethod": return findCallMethod(desc, operator); + case "callMethod": + return findCallMethodMethod(desc, operator); case "new": return findNewMethod(desc); default: @@ -98,33 +98,37 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { } private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc) { - final MethodHandle getter = MH.insertArguments(JSOBJECT_GET, 1, desc.getNameToken(2)); + final MethodHandle getter = MH.insertArguments(JSOBJECT_GETMEMBER, 1, desc.getNameToken(2)); return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD); } private static GuardedInvocation findGetIndexMethod() { - return new GuardedInvocation(JSOBJECT_GET, null, IS_JSOBJECT_GUARD); + return new GuardedInvocation(JSOBJECTLINKER_GET, null, IS_JSOBJECT_GUARD); } private static GuardedInvocation findSetMethod(final CallSiteDescriptor desc) { - final MethodHandle getter = MH.insertArguments(JSOBJECT_PUT, 1, desc.getNameToken(2)); + final MethodHandle getter = MH.insertArguments(JSOBJECT_SETMEMBER, 1, desc.getNameToken(2)); return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD); } private static GuardedInvocation findSetIndexMethod() { - return new GuardedInvocation(JSOBJECT_PUT, null, IS_JSOBJECT_GUARD); + return new GuardedInvocation(JSOBJECTLINKER_PUT, null, IS_JSOBJECT_GUARD); } - private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final String operator) { - // if operator is "call", then 'self' is a JSObject function object already. Use 'call' as the method name - final String methodName = "callMethod".equals(operator)? desc.getNameToken(2) : "call"; - MethodHandle func = MH.insertArguments(JSOBJECT_CALL, 1, methodName); + private static GuardedInvocation findCallMethodMethod(final CallSiteDescriptor desc, final String operator) { + final String methodName = desc.getNameToken(2); + MethodHandle func = MH.insertArguments(JSOBJECT_CALLMEMBER, 1, methodName); func = MH.asCollector(func, Object[].class, desc.getMethodType().parameterCount() - 1); return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD); } + private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final String operator) { + final MethodHandle func = MH.asCollector(JSOBJECT_CALL, Object[].class, desc.getMethodType().parameterCount() - 2); + return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD); + } + private static GuardedInvocation findNewMethod(final CallSiteDescriptor desc) { - MethodHandle func = MH.asCollector(JSOBJECT_NEW, Object[].class, desc.getMethodType().parameterCount() - 1); + final MethodHandle func = MH.asCollector(JSOBJECT_NEW, Object[].class, desc.getMethodType().parameterCount() - 1); return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD); } @@ -135,36 +139,30 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { @SuppressWarnings("unused") private static Object get(final Object jsobj, final Object key) { - if (key instanceof String) { - return ((JSObject)jsobj).getMember((String)key); + if (key instanceof Integer) { + return ((JSObject)jsobj).getSlot((int)(Integer)key); } else if (key instanceof Number) { final int index = getIndex((Number)key); if (index > -1) { return ((JSObject)jsobj).getSlot(index); } + } else if (key instanceof String) { + return ((JSObject)jsobj).getMember((String)key); } return null; } @SuppressWarnings("unused") private static void put(final Object jsobj, final Object key, final Object value) { - if (key instanceof String) { - ((JSObject)jsobj).setMember((String)key, value); + if (key instanceof Integer) { + ((JSObject)jsobj).setSlot((int)(Integer)key, value); } else if (key instanceof Number) { ((JSObject)jsobj).setSlot(getIndex((Number)key), value); + } else if (key instanceof String) { + ((JSObject)jsobj).setMember((String)key, value); } } - @SuppressWarnings("unused") - private static Object call(final Object jsobj, final Object method, final Object... args) { - return ((JSObject)jsobj).call(Objects.toString(method), args); - } - - @SuppressWarnings("unused") - private static Object newObject(final Object jsobj, final Object... args) { - return ((JSObject)jsobj).newObject(null, args); - } - private static int getIndex(final Number n) { final double value = n.doubleValue(); return JSType.isRepresentableAsInt(value) ? (int)value : -1; @@ -172,11 +170,17 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality(); - private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class); - private static final MethodHandle JSOBJECT_GET = findOwnMH("get", Object.class, Object.class, Object.class); - private static final MethodHandle JSOBJECT_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class); - private static final MethodHandle JSOBJECT_CALL = findOwnMH("call", Object.class, Object.class, Object.class, Object[].class); - private static final MethodHandle JSOBJECT_NEW = findOwnMH("newObject", Object.class, Object.class, Object[].class); + // method handles of the current class + private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class); + private static final MethodHandle JSOBJECTLINKER_GET = findOwnMH("get", Object.class, Object.class, Object.class); + private static final MethodHandle JSOBJECTLINKER_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class); + + // method handles of JSObject class + private static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH("getMember", Object.class, String.class); + private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH("setMember", Void.TYPE, String.class, Object.class); + private static final MethodHandle JSOBJECT_CALLMEMBER = findJSObjectMH("callMember", Object.class, String.class, Object[].class); + private static final MethodHandle JSOBJECT_CALL = findJSObjectMH("call", Object.class, Object.class, Object[].class); + private static final MethodHandle JSOBJECT_NEW = findJSObjectMH("newObject", Object.class, Object[].class); private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { final Class own = JSObjectLinker.class; @@ -187,4 +191,14 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { return MH.findVirtual(MethodHandles.lookup(), own, name, mt); } } + + private static MethodHandle findJSObjectMH(final String name, final Class rtype, final Class... types) { + final Class own = JSObject.class; + final MethodType mt = MH.type(rtype, types); + try { + return MH.findVirtual(MethodHandles.publicLookup(), own, name, mt); + } catch (final MethodHandleFactory.LookupException e) { + return MH.findVirtual(MethodHandles.lookup(), own, name, mt); + } + } } diff --git a/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java b/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java new file mode 100644 index 00000000..1b531dfc --- /dev/null +++ b/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java @@ -0,0 +1,257 @@ +/* + * 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.api.scripting; + +import java.nio.IntBuffer; +import java.util.Collection; +import java.util.HashMap; +import java.util.Set; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.fail; +import org.testng.annotations.Test; + +/** + * Tests for pluggable external impls. of jdk.nashorn.api.scripting.JSObject. + * + * JDK-8024615: Refactor ScriptObjectMirror and JSObject to support external + * JSObject implementations. + */ +public class PluggableJSObjectTest { + public static class MapWrapperObject extends JSObject { + private final HashMap map = new HashMap<>(); + + public HashMap getMap() { + return map; + } + + @Override + public Object getMember(String name) { + return map.get(name); + } + + @Override + public void setMember(String name, Object value) { + map.put(name, value); + } + + @Override + public boolean hasMember(String name) { + return map.containsKey(name); + } + + @Override + public void removeMember(String name) { + map.remove(name); + } + + @Override + public Set keySet() { + return map.keySet(); + } + + @Override + public Collection values() { + return map.values(); + } + } + + @Test + // Named property access on a JSObject + public void namedAccessTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final MapWrapperObject obj = new MapWrapperObject(); + e.put("obj", obj); + obj.getMap().put("foo", "bar"); + + // property-like access on MapWrapperObject objects + assertEquals(e.eval("obj.foo"), "bar"); + e.eval("obj.foo = 'hello'"); + assertEquals(e.eval("'foo' in obj"), Boolean.TRUE); + assertEquals(e.eval("obj.foo"), "hello"); + assertEquals(obj.getMap().get("foo"), "hello"); + e.eval("delete obj.foo"); + assertFalse(obj.getMap().containsKey("foo")); + assertEquals(e.eval("'foo' in obj"), Boolean.FALSE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class BufferObject extends JSObject { + private final IntBuffer buf; + + public BufferObject(int size) { + buf = IntBuffer.allocate(size); + } + + public IntBuffer getBuffer() { + return buf; + } + + @Override + public Object getMember(String name) { + return name.equals("length")? buf.capacity() : null; + } + + @Override + public boolean hasSlot(int i) { + return i > -1 && i < buf.capacity(); + } + + @Override + public Object getSlot(int i) { + return buf.get(i); + } + + @Override + public void setSlot(int i, Object value) { + buf.put(i, ((Number)value).intValue()); + } + + @Override + public boolean isArray() { + return true; + } + } + + @Test + // array-like indexed access for a JSObject + public void indexedAccessTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final BufferObject buf = new BufferObject(2); + e.put("buf", buf); + + // array-like access on BufferObject objects + assertEquals(e.eval("buf.length"), buf.getBuffer().capacity()); + e.eval("buf[0] = 23"); + assertEquals(buf.getBuffer().get(0), 23); + assertEquals(e.eval("buf[0]"), 23); + assertEquals(e.eval("buf[1]"), 0); + buf.getBuffer().put(1, 42); + assertEquals(e.eval("buf[1]"), 42); + assertEquals(e.eval("Array.isArray(buf)"), Boolean.TRUE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class Adder extends JSObject { + @Override + public Object call(Object thiz, Object... args) { + double res = 0.0; + for (Object arg : args) { + res += ((Number)arg).doubleValue(); + } + return res; + } + + @Override + public boolean isFunction() { + return true; + } + } + + @Test + // a callable JSObject + public void callableJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.put("sum", new Adder()); + // check callability of Adder objects + assertEquals(e.eval("typeof sum"), "function"); + assertEquals(((Number)e.eval("sum(1, 2, 3, 4, 5)")).intValue(), 15); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class Factory extends JSObject { + @Override + public Object newObject(Object... args) { + return new HashMap(); + } + + @Override + public boolean isFunction() { + return true; + } + } + + @Test + // a factory JSObject + public void factoryJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.put("Factory", new Factory()); + + // check new on Factory + assertEquals(e.eval("typeof Factory"), "function"); + assertEquals(e.eval("typeof new Factory()"), "object"); + assertEquals(e.eval("(new Factory()) instanceof java.util.Map"), Boolean.TRUE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + // iteration tests + public void iteratingJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final MapWrapperObject obj = new MapWrapperObject(); + obj.setMember("foo", "hello"); + obj.setMember("bar", "world"); + e.put("obj", obj); + + // check for..in + Object val = e.eval("var str = ''; for (i in obj) str += i; str"); + assertEquals(val.toString(), "foobar"); + + // check for..each..in + val = e.eval("var str = ''; for each (i in obj) str += i; str"); + assertEquals(val.toString(), "helloworld"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } +} diff --git a/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java b/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java index 75f636ae..c7b40c63 100644 --- a/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java +++ b/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java @@ -140,8 +140,8 @@ public class ScriptObjectMirrorTest { fail("obj[1] != 'world'"); } - if (!obj.call("func", new Object[0]).equals("hello")) { - fail("obj.call('func') != 'hello'"); + if (!obj.callMember("func", new Object[0]).equals("hello")) { + fail("obj.func() != 'hello'"); } // try setting properties @@ -210,8 +210,8 @@ public class ScriptObjectMirrorTest { e.eval("function func() {}"); e2.put("foo", e.get("func")); - final Object e2global = e2.eval("this"); - final Object newObj = ((ScriptObjectMirror) e2global).newObject("foo"); + final ScriptObjectMirror e2global = (ScriptObjectMirror)e2.eval("this"); + final Object newObj = ((ScriptObjectMirror)e2global.getMember("foo")).newObject(); assertTrue(newObj instanceof ScriptObjectMirror); } @@ -223,8 +223,8 @@ public class ScriptObjectMirrorTest { e.eval("function func() {}"); e2.put("func", e.get("func")); - final Object e2obj = e2.eval("({ foo: func })"); - final Object newObj = ((ScriptObjectMirror) e2obj).newObject("foo"); + final ScriptObjectMirror e2obj = (ScriptObjectMirror)e2.eval("({ foo: func })"); + final Object newObj = ((ScriptObjectMirror)e2obj.getMember("foo")).newObject(); assertTrue(newObj instanceof ScriptObjectMirror); } } -- cgit v1.2.3 From 431ef2d260c2d258064d7b8fd3412fcec5da9585 Mon Sep 17 00:00:00 2001 From: sundar Date: Wed, 11 Sep 2013 22:51:34 +0530 Subject: 8024644: PluggableJSObject.iteratingJSObjectTest fails with jdk8-tl build Reviewed-by: jlaskey, hannesw --- test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java b/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java index 1b531dfc..acb57164 100644 --- a/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java +++ b/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java @@ -28,6 +28,7 @@ package jdk.nashorn.api.scripting; import java.nio.IntBuffer; import java.util.Collection; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Set; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; @@ -46,7 +47,7 @@ import org.testng.annotations.Test; */ public class PluggableJSObjectTest { public static class MapWrapperObject extends JSObject { - private final HashMap map = new HashMap<>(); + private final HashMap map = new LinkedHashMap<>(); public HashMap getMap() { return map; -- cgit v1.2.3 From d67532f94bdbc416a3773fda6f91bb819ddc1a48 Mon Sep 17 00:00:00 2001 From: hannesw Date: Thu, 12 Sep 2013 14:02:15 +0200 Subject: 8024476: Octane regression on Richards Reviewed-by: sundar, jlaskey --- src/jdk/nashorn/internal/runtime/JSType.java | 53 +++++++++++++++++----------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/jdk/nashorn/internal/runtime/JSType.java b/src/jdk/nashorn/internal/runtime/JSType.java index 073c237c..6098eb27 100644 --- a/src/jdk/nashorn/internal/runtime/JSType.java +++ b/src/jdk/nashorn/internal/runtime/JSType.java @@ -29,7 +29,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import java.lang.invoke.MethodHandles; -import java.util.Locale; import jdk.internal.dynalink.beans.StaticClass; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.parser.Lexer; @@ -40,25 +39,28 @@ import jdk.nashorn.internal.runtime.linker.Bootstrap; */ public enum JSType { /** The undefined type */ - UNDEFINED, + UNDEFINED("undefined"), /** The null type */ - NULL, + NULL("object"), /** The boolean type */ - BOOLEAN, + BOOLEAN("boolean"), /** The number type */ - NUMBER, + NUMBER("number"), /** The string type */ - STRING, + STRING("string"), /** The object type */ - OBJECT, + OBJECT("object"), /** The function type */ - FUNCTION; + FUNCTION("function"); + + /** The type name as returned by ECMAScript "typeof" operator*/ + private final String typeName; /** Max value for an uint32 in JavaScript */ public static final long MAX_UINT = 0xFFFF_FFFFL; @@ -109,14 +111,22 @@ public enum JSType { private static final double INT32_LIMIT = 4294967296.0; + /** + * Constructor + * + * @param typeName the type name + */ + private JSType(final String typeName) { + this.typeName = typeName; + } + /** * The external type name as returned by ECMAScript "typeof" operator * * @return type name for this type */ public final String typeName() { - // For NULL, "object" has to be returned! - return ((this == NULL) ? OBJECT : this).name().toLowerCase(Locale.ENGLISH); + return this.typeName; } /** @@ -127,31 +137,32 @@ public enum JSType { * @return the JSType for the object */ public static JSType of(final Object obj) { - if (obj == ScriptRuntime.UNDEFINED) { - return JSType.UNDEFINED; - } - + // Order of these statements is tuned for performance (see JDK-8024476) if (obj == null) { return JSType.NULL; } - if (obj instanceof Boolean) { - return JSType.BOOLEAN; + if (obj instanceof ScriptObject) { + return (obj instanceof ScriptFunction) ? JSType.FUNCTION : JSType.OBJECT; } - if (obj instanceof Number) { - return JSType.NUMBER; + if (obj instanceof Boolean) { + return JSType.BOOLEAN; } if (obj instanceof String || obj instanceof ConsString) { return JSType.STRING; } - if (Bootstrap.isCallable(obj)) { - return JSType.FUNCTION; + if (obj instanceof Number) { + return JSType.NUMBER; + } + + if (obj == ScriptRuntime.UNDEFINED) { + return JSType.UNDEFINED; } - return JSType.OBJECT; + return Bootstrap.isCallable(obj) ? JSType.FUNCTION : JSType.OBJECT; } /** -- cgit v1.2.3 From d307d3fc8e3572e3c1bc89c610916a17f95d0b8c Mon Sep 17 00:00:00 2001 From: hannesw Date: Thu, 12 Sep 2013 17:13:59 +0200 Subject: 8024512: Regex /[^\[]/ doesn't match Reviewed-by: jlaskey, sundar --- .../internal/runtime/regexp/RegExpScanner.java | 22 ++++---- test/script/basic/JDK-8024512.js | 59 ++++++++++++++++++++++ test/script/basic/JDK-8024512.js.EXPECTED | 21 ++++++++ 3 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 test/script/basic/JDK-8024512.js create mode 100644 test/script/basic/JDK-8024512.js.EXPECTED diff --git a/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java b/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java index 68df99f3..f4edecc4 100644 --- a/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java +++ b/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java @@ -263,15 +263,6 @@ final class RegExpScanner extends Scanner { } if (atom()) { - // Check for character classes that never or always match - if (sb.toString().endsWith("[]")) { - sb.setLength(sb.length() - 1); - sb.append("^\\s\\S]"); - } else if (sb.toString().endsWith("[^]")) { - sb.setLength(sb.length() - 2); - sb.append("\\s\\S]"); - } - quantifier(); return true; } @@ -767,7 +758,18 @@ final class RegExpScanner extends Scanner { if (classRanges() && ch0 == ']') { pop(']'); - return commit(1); + commit(1); + + // Substitute empty character classes [] and [^] that never or always match + if (position == startIn + 2) { + sb.setLength(sb.length() - 1); + sb.append("^\\s\\S]"); + } else if (position == startIn + 3 && inNegativeClass) { + sb.setLength(sb.length() - 2); + sb.append("\\s\\S]"); + } + + return true; } } finally { inCharClass = false; // no nested character classes in JavaScript diff --git a/test/script/basic/JDK-8024512.js b/test/script/basic/JDK-8024512.js new file mode 100644 index 00000000..c03ba212 --- /dev/null +++ b/test/script/basic/JDK-8024512.js @@ -0,0 +1,59 @@ +/* + * 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. + * + * 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-8024512: Regex /[^\[]/ doesn't match + * + * @test + * @run + */ + +print("[M]".match(/(\[[^\[]*\])/)); +print("[[]".match(/(\[[^\[]*\])/)); + +print("[M]".match(/(\[[^\[^]*\])/)); +print("[[]".match(/(\[[^\[^]*\])/)); +print("[^]".match(/(\[[^\[^]*\])/)); + +print("[M]".match(/(\[[^\[]\])/)); +print("[[]".match(/(\[[^\[]\])/)); + +print("[M]".match(/(\[[^\[^]\])/)); +print("[[]".match(/(\[[^\[^]\])/)); +print("[^]".match(/(\[[^\[^]\])/)); + +print("M".match(/[^\[]/)); +print("[".match(/[^\[]/)); +print("^".match(/[^\[]/)); + +// Repeat above without escaping inner square bracket +print("[M]".match(/(\[[^[]\])/)); +print("[[]".match(/(\[[^[]\])/)); + +print("[M]".match(/(\[[^[^]\])/)); +print("[[]".match(/(\[[^[^]\])/)); +print("[^]".match(/(\[[^[^]\])/)); + +print("M".match(/[^[]/)); +print("[".match(/[^[]/)); +print("^".match(/[^[]/)); diff --git a/test/script/basic/JDK-8024512.js.EXPECTED b/test/script/basic/JDK-8024512.js.EXPECTED new file mode 100644 index 00000000..9bb84de9 --- /dev/null +++ b/test/script/basic/JDK-8024512.js.EXPECTED @@ -0,0 +1,21 @@ +[M],[M] +[],[] +[M],[M] +[],[] +null +[M],[M] +null +[M],[M] +null +null +M +null +^ +[M],[M] +null +[M],[M] +null +null +M +null +^ -- cgit v1.2.3 From 97656e9b16fd87124f34fc7881517c25d2f22a7e Mon Sep 17 00:00:00 2001 From: sundar Date: Thu, 12 Sep 2013 22:16:40 +0530 Subject: 8024693: Various minor issues with JSONWriter used by script parser API Reviewed-by: jlaskey, hannesw --- make/build.xml | 7 + src/jdk/nashorn/internal/ir/debug/JSONWriter.java | 135 +++++-- test/script/basic/NASHORN-737.js | 2 +- test/script/basic/NASHORN-737.js.EXPECTED | 37 +- test/script/basic/parser/assignmentExpr.js | 44 +++ .../script/basic/parser/assignmentExpr.js.EXPECTED | 240 +++++++++++ test/script/basic/parser/binaryExpr.js | 54 +++ test/script/basic/parser/binaryExpr.js.EXPECTED | 440 +++++++++++++++++++++ test/script/basic/parser/breakStat.js | 35 ++ test/script/basic/parser/breakStat.js.EXPECTED | 92 +++++ test/script/basic/parser/condExpr.js | 33 ++ test/script/basic/parser/condExpr.js.EXPECTED | 23 ++ test/script/basic/parser/continueStat.js | 35 ++ test/script/basic/parser/continueStat.js.EXPECTED | 92 +++++ test/script/basic/parser/debuggerStat.js | 33 ++ test/script/basic/parser/debuggerStat.js.EXPECTED | 8 + test/script/basic/parser/functions.js | 39 ++ test/script/basic/parser/functions.js.EXPECTED | 279 +++++++++++++ test/script/basic/parser/ifStat.js | 34 ++ test/script/basic/parser/ifStat.js.EXPECTED | 73 ++++ test/script/basic/parser/labelledStat.js | 34 ++ test/script/basic/parser/labelledStat.js.EXPECTED | 71 ++++ test/script/basic/parser/lhsExpr.js | 47 +++ test/script/basic/parser/lhsExpr.js.EXPECTED | 344 ++++++++++++++++ test/script/basic/parser/loopStat.js | 37 ++ test/script/basic/parser/loopStat.js.EXPECTED | 212 ++++++++++ test/script/basic/parser/objectLitExpr.js | 36 ++ test/script/basic/parser/objectLitExpr.js.EXPECTED | 189 +++++++++ test/script/basic/parser/parenExpr.js | 34 ++ test/script/basic/parser/parenExpr.js.EXPECTED | 56 +++ test/script/basic/parser/primaryExpr.js | 45 +++ test/script/basic/parser/primaryExpr.js.EXPECTED | 199 ++++++++++ test/script/basic/parser/returnStat.js | 35 ++ test/script/basic/parser/returnStat.js.EXPECTED | 88 +++++ test/script/basic/parser/switchStat.js | 35 ++ test/script/basic/parser/switchStat.js.EXPECTED | 123 ++++++ test/script/basic/parser/throwStat.js | 37 ++ test/script/basic/parser/throwStat.js.EXPECTED | 85 ++++ test/script/basic/parser/tryCatchStat.js | 38 ++ test/script/basic/parser/tryCatchStat.js.EXPECTED | 305 ++++++++++++++ test/script/basic/parser/unaryExpr.js | 43 ++ test/script/basic/parser/unaryExpr.js.EXPECTED | 187 +++++++++ test/script/basic/parser/useStrict.js | 34 ++ test/script/basic/parser/useStrict.js.EXPECTED | 41 ++ test/script/basic/parser/util.js | 33 ++ test/script/basic/parser/varDecl.js | 39 ++ test/script/basic/parser/varDecl.js.EXPECTED | 123 ++++++ test/script/basic/parser/withStat.js | 33 ++ test/script/basic/parser/withStat.js.EXPECTED | 32 ++ 49 files changed, 4311 insertions(+), 39 deletions(-) create mode 100644 test/script/basic/parser/assignmentExpr.js create mode 100644 test/script/basic/parser/assignmentExpr.js.EXPECTED create mode 100644 test/script/basic/parser/binaryExpr.js create mode 100644 test/script/basic/parser/binaryExpr.js.EXPECTED create mode 100644 test/script/basic/parser/breakStat.js create mode 100644 test/script/basic/parser/breakStat.js.EXPECTED create mode 100644 test/script/basic/parser/condExpr.js create mode 100644 test/script/basic/parser/condExpr.js.EXPECTED create mode 100644 test/script/basic/parser/continueStat.js create mode 100644 test/script/basic/parser/continueStat.js.EXPECTED create mode 100644 test/script/basic/parser/debuggerStat.js create mode 100644 test/script/basic/parser/debuggerStat.js.EXPECTED create mode 100644 test/script/basic/parser/functions.js create mode 100644 test/script/basic/parser/functions.js.EXPECTED create mode 100644 test/script/basic/parser/ifStat.js create mode 100644 test/script/basic/parser/ifStat.js.EXPECTED create mode 100644 test/script/basic/parser/labelledStat.js create mode 100644 test/script/basic/parser/labelledStat.js.EXPECTED create mode 100644 test/script/basic/parser/lhsExpr.js create mode 100644 test/script/basic/parser/lhsExpr.js.EXPECTED create mode 100644 test/script/basic/parser/loopStat.js create mode 100644 test/script/basic/parser/loopStat.js.EXPECTED create mode 100644 test/script/basic/parser/objectLitExpr.js create mode 100644 test/script/basic/parser/objectLitExpr.js.EXPECTED create mode 100644 test/script/basic/parser/parenExpr.js create mode 100644 test/script/basic/parser/parenExpr.js.EXPECTED create mode 100644 test/script/basic/parser/primaryExpr.js create mode 100644 test/script/basic/parser/primaryExpr.js.EXPECTED create mode 100644 test/script/basic/parser/returnStat.js create mode 100644 test/script/basic/parser/returnStat.js.EXPECTED create mode 100644 test/script/basic/parser/switchStat.js create mode 100644 test/script/basic/parser/switchStat.js.EXPECTED create mode 100644 test/script/basic/parser/throwStat.js create mode 100644 test/script/basic/parser/throwStat.js.EXPECTED create mode 100644 test/script/basic/parser/tryCatchStat.js create mode 100644 test/script/basic/parser/tryCatchStat.js.EXPECTED create mode 100644 test/script/basic/parser/unaryExpr.js create mode 100644 test/script/basic/parser/unaryExpr.js.EXPECTED create mode 100644 test/script/basic/parser/useStrict.js create mode 100644 test/script/basic/parser/useStrict.js.EXPECTED create mode 100644 test/script/basic/parser/util.js create mode 100644 test/script/basic/parser/varDecl.js create mode 100644 test/script/basic/parser/varDecl.js.EXPECTED create mode 100644 test/script/basic/parser/withStat.js create mode 100644 test/script/basic/parser/withStat.js.EXPECTED diff --git a/make/build.xml b/make/build.xml index 9a31be88..df655d59 100644 --- a/make/build.xml +++ b/make/build.xml @@ -264,6 +264,13 @@ grant codeBase "file:/${basedir}/test/script/basic/*" { permission java.util.PropertyPermission "nashorn.test.*", "read"; }; +grant codeBase "file:/${basedir}/test/script/basic/parser/*" { + permission java.io.FilePermission "${basedir}/test/script/-", "read"; + permission java.io.FilePermission "$${user.dir}", "read"; + permission java.util.PropertyPermission "user.dir", "read"; + permission java.util.PropertyPermission "nashorn.test.*", "read"; +}; + grant codeBase "file:/${basedir}/test/script/basic/JDK-8010946-privileged.js" { permission java.util.PropertyPermission "java.security.policy", "read"; }; diff --git a/src/jdk/nashorn/internal/ir/debug/JSONWriter.java b/src/jdk/nashorn/internal/ir/debug/JSONWriter.java index be4d49b4..dabc7e36 100644 --- a/src/jdk/nashorn/internal/ir/debug/JSONWriter.java +++ b/src/jdk/nashorn/internal/ir/debug/JSONWriter.java @@ -27,6 +27,7 @@ package jdk.nashorn.internal.ir.debug; import java.util.Arrays; import java.util.List; +import java.util.ArrayList; import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.ir.AccessNode; import jdk.nashorn.internal.ir.BinaryNode; @@ -197,10 +198,10 @@ public final class JSONWriter extends NodeVisitor { comma(); final IdentNode label = breakNode.getLabel(); + property("label"); if (label != null) { - property("label", label.getName()); + label.accept(this); } else { - property("label"); nullValue(); } @@ -256,13 +257,11 @@ public final class JSONWriter extends NodeVisitor { comma(); final Node guard = catchNode.getExceptionCondition(); - property("guard"); if (guard != null) { + property("guard"); guard.accept(this); - } else { - nullValue(); + comma(); } - comma(); property("body"); catchNode.getBody().accept(this); @@ -278,10 +277,10 @@ public final class JSONWriter extends NodeVisitor { comma(); final IdentNode label = continueNode.getLabel(); + property("label"); if (label != null) { - property("label", label.getName()); + label.accept(this); } else { - property("label"); nullValue(); } @@ -299,13 +298,20 @@ public final class JSONWriter extends NodeVisitor { @Override public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) { + // handle debugger statement + final Node expression = expressionStatement.getExpression(); + if (expression instanceof RuntimeNode) { + expression.accept(this); + return false; + } + enterDefault(expressionStatement); type("ExpressionStatement"); comma(); property("expression"); - expressionStatement.getExpression().accept(this); + expression.accept(this); return leave(); } @@ -388,13 +394,14 @@ public final class JSONWriter extends NodeVisitor { @Override public boolean enterFunctionNode(final FunctionNode functionNode) { - enterDefault(functionNode); - final boolean program = functionNode.isProgram(); - final String name; if (program) { - name = "Program"; - } else if (functionNode.isDeclared()) { + return emitProgram(functionNode); + } + + enterDefault(functionNode); + final String name; + if (functionNode.isDeclared()) { name = "FunctionDeclaration"; } else { name = "FunctionExpression"; @@ -402,24 +409,41 @@ public final class JSONWriter extends NodeVisitor { type(name); comma(); - if (! program) { - property("id"); - if (functionNode.isAnonymous()) { - nullValue(); - } else { - functionNode.getIdent().accept(this); - } - comma(); + property("id"); + if (functionNode.isAnonymous()) { + nullValue(); + } else { + functionNode.getIdent().accept(this); } + comma(); + + array("params", functionNode.getParameters()); + comma(); + + arrayStart("defaults"); + arrayEnd(); + comma(); property("rest"); nullValue(); comma(); - if (!program) { - array("params", functionNode.getParameters()); - comma(); - } + property("body"); + functionNode.getBody().accept(this); + comma(); + + property("generator", false); + comma(); + + property("expression", false); + + return leave(); + } + + private boolean emitProgram(final FunctionNode functionNode) { + enterDefault(functionNode); + type("Program"); + comma(); // body consists of nested functions and statements final List stats = functionNode.getBody().getStatements(); @@ -730,7 +754,31 @@ public final class JSONWriter extends NodeVisitor { tryNode.getBody().accept(this); comma(); - array("handlers", tryNode.getCatches()); + + final List catches = tryNode.getCatches(); + final List guarded = new ArrayList<>(); + CatchNode unguarded = null; + if (catches != null) { + for (Node n : catches) { + CatchNode cn = (CatchNode)n; + if (cn.getExceptionCondition() != null) { + guarded.add(cn); + } else { + assert unguarded == null: "too many unguarded?"; + unguarded = cn; + } + } + } + + array("guardedHandlers", guarded); + comma(); + + property("handler"); + if (unguarded != null) { + unguarded.accept(this); + } else { + nullValue(); + } comma(); property("finalizer"); @@ -760,8 +808,8 @@ public final class JSONWriter extends NodeVisitor { array("arguments", callNode.getArgs()); } else { - final boolean prefix; final String operator; + final boolean prefix; switch (tokenType) { case INCPOSTFIX: prefix = false; @@ -780,8 +828,9 @@ public final class JSONWriter extends NodeVisitor { prefix = true; break; default: - prefix = false; + prefix = true; operator = tokenType.getName(); + break; } type(unaryNode.isAssignment()? "UpdateExpression" : "UnaryExpression"); @@ -802,6 +851,14 @@ public final class JSONWriter extends NodeVisitor { @Override public boolean enterVarNode(final VarNode varNode) { + final Node init = varNode.getInit(); + if (init instanceof FunctionNode && ((FunctionNode)init).isDeclared()) { + // function declaration - don't emit VariableDeclaration instead + // just emit FunctionDeclaration using 'init' Node. + init.accept(this); + return false; + } + enterDefault(varNode); type("VariableDeclaration"); @@ -816,11 +873,11 @@ public final class JSONWriter extends NodeVisitor { type("VariableDeclarator"); comma(); - property("id", varNode.getName().toString()); + property("id"); + varNode.getName().accept(this); comma(); property("init"); - final Node init = varNode.getInit(); if (init != null) { init.accept(this); } else { @@ -855,7 +912,7 @@ public final class JSONWriter extends NodeVisitor { whileNode.getTest().accept(this); comma(); - property("block"); + property("body"); whileNode.getBody().accept(this); } @@ -894,23 +951,27 @@ public final class JSONWriter extends NodeVisitor { return buf.toString(); } - private void property(final String key, final String value) { + private void property(final String key, final String value, final boolean escape) { buf.append('"'); buf.append(key); buf.append("\":"); if (value != null) { - buf.append('"'); + if (escape) buf.append('"'); buf.append(value); - buf.append('"'); + if (escape) buf.append('"'); } } + private void property(final String key, final String value) { + property(key, value, true); + } + private void property(final String key, final boolean value) { - property(key, Boolean.toString(value)); + property(key, Boolean.toString(value), false); } private void property(final String key, final int value) { - property(key, Integer.toString(value)); + property(key, Integer.toString(value), false); } private void property(final String key) { diff --git a/test/script/basic/NASHORN-737.js b/test/script/basic/NASHORN-737.js index 44169d04..3db48918 100644 --- a/test/script/basic/NASHORN-737.js +++ b/test/script/basic/NASHORN-737.js @@ -30,4 +30,4 @@ load("nashorn:parser.js"); var ast = parse("label: while(true) break label;"); -print(JSON.stringify(ast)); +print(JSON.stringify(ast, null, " ")); diff --git a/test/script/basic/NASHORN-737.js.EXPECTED b/test/script/basic/NASHORN-737.js.EXPECTED index 8f828342..77c79657 100644 --- a/test/script/basic/NASHORN-737.js.EXPECTED +++ b/test/script/basic/NASHORN-737.js.EXPECTED @@ -1 +1,36 @@ -{"type":"Program","rest":null,"body":[{"type":"LabeledStatement","label":{"type":"Identifier","name":"label"},"body":{"type":"BlockStatement","body":[{"type":"WhileStatement","test":{"type":"Literal","value":true},"block":{"type":"BlockStatement","body":[{"type":"BreakStatement","label":"label"}]}}]}}]} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "label" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "label" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/test/script/basic/parser/assignmentExpr.js b/test/script/basic/parser/assignmentExpr.js new file mode 100644 index 00000000..231e19fd --- /dev/null +++ b/test/script/basic/parser/assignmentExpr.js @@ -0,0 +1,44 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check assignment e xyzpressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("xyz = 314"); +printParse("xyz += 314"); +printParse("xyz -= 314"); +printParse("xyz *= 314"); +printParse("xyz /= 314"); +printParse("xyz %= 314"); +printParse("xyz <<= 314"); +printParse("xyz >>= 314"); +printParse("xyz >>>= 314"); +printParse("xyz &= 314"); +printParse("xyz ^= 314"); +printParse("xyz |= 314"); diff --git a/test/script/basic/parser/assignmentExpr.js.EXPECTED b/test/script/basic/parser/assignmentExpr.js.EXPECTED new file mode 100644 index 00000000..da6793af --- /dev/null +++ b/test/script/basic/parser/assignmentExpr.js.EXPECTED @@ -0,0 +1,240 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "+=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "-=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "*=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "/=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "%=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "<<=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": ">>=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": ">>>=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "&=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "^=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "|=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} diff --git a/test/script/basic/parser/binaryExpr.js b/test/script/basic/parser/binaryExpr.js new file mode 100644 index 00000000..a2b761da --- /dev/null +++ b/test/script/basic/parser/binaryExpr.js @@ -0,0 +1,54 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check binary operators. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("a * b") +printParse("a / b"); +printParse("a % b"); +printParse("a + b"); +printParse("a - b"); +printParse("a << b"); +printParse("a >> b"); +printParse("a >>> b"); +printParse("a < b"); +printParse("a > b"); +printParse("a <= b"); +printParse("a >= b"); +printParse("a instanceof b"); +printParse("a == b"); +printParse("a != b"); +printParse("a === b"); +printParse("a !== b"); +printParse("a & b"); +printParse("a ^ b"); +printParse("a | b"); +printParse("a && b"); +printParse("a || b"); diff --git a/test/script/basic/parser/binaryExpr.js.EXPECTED b/test/script/basic/parser/binaryExpr.js.EXPECTED new file mode 100644 index 00000000..dd75f4b6 --- /dev/null +++ b/test/script/basic/parser/binaryExpr.js.EXPECTED @@ -0,0 +1,440 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "*", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "/", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "%", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "-", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<<", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">>", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">>>", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<=", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">=", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "instanceof", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "==", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "!=", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "===", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "!==", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "&", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "^", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "|", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "LogicalExpression", + "operator": "&&", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "LogicalExpression", + "operator": "||", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} diff --git a/test/script/basic/parser/breakStat.js b/test/script/basic/parser/breakStat.js new file mode 100644 index 00000000..1b16cc2c --- /dev/null +++ b/test/script/basic/parser/breakStat.js @@ -0,0 +1,35 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check 'break' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("while (true) { break; }"); +printParse("loop: { while (true) { break loop } }"); +printParse("loop: { for (;;) { break loop } }"); diff --git a/test/script/basic/parser/breakStat.js.EXPECTED b/test/script/basic/parser/breakStat.js.EXPECTED new file mode 100644 index 00000000..1d9fd079 --- /dev/null +++ b/test/script/basic/parser/breakStat.js.EXPECTED @@ -0,0 +1,92 @@ +{ + "type": "Program", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "loop" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "loop" + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "loop" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ForStatement", + "init": null, + "test": null, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "loop" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/test/script/basic/parser/condExpr.js b/test/script/basic/parser/condExpr.js new file mode 100644 index 00000000..3644ff35 --- /dev/null +++ b/test/script/basic/parser/condExpr.js @@ -0,0 +1,33 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check ternary operator. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("a? b : c"); diff --git a/test/script/basic/parser/condExpr.js.EXPECTED b/test/script/basic/parser/condExpr.js.EXPECTED new file mode 100644 index 00000000..75c486fa --- /dev/null +++ b/test/script/basic/parser/condExpr.js.EXPECTED @@ -0,0 +1,23 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ConditionalExpression", + "test": { + "type": "Identifier", + "name": "a" + }, + "consequent": { + "type": "Identifier", + "name": "b" + }, + "alternate": { + "type": "Identifier", + "name": "c" + } + } + } + ] +} diff --git a/test/script/basic/parser/continueStat.js b/test/script/basic/parser/continueStat.js new file mode 100644 index 00000000..22ddadd4 --- /dev/null +++ b/test/script/basic/parser/continueStat.js @@ -0,0 +1,35 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check 'continue' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("while (true) { continue; }"); +printParse("begin: { while (true) { continue begin; } }"); +printParse("start: { for(;;) { continue start; } }"); diff --git a/test/script/basic/parser/continueStat.js.EXPECTED b/test/script/basic/parser/continueStat.js.EXPECTED new file mode 100644 index 00000000..cfd3114d --- /dev/null +++ b/test/script/basic/parser/continueStat.js.EXPECTED @@ -0,0 +1,92 @@ +{ + "type": "Program", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ContinueStatement", + "label": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "begin" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ContinueStatement", + "label": { + "type": "Identifier", + "name": "begin" + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "start" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ForStatement", + "init": null, + "test": null, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ContinueStatement", + "label": { + "type": "Identifier", + "name": "start" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/test/script/basic/parser/debuggerStat.js b/test/script/basic/parser/debuggerStat.js new file mode 100644 index 00000000..60eab78f --- /dev/null +++ b/test/script/basic/parser/debuggerStat.js @@ -0,0 +1,33 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check debugger statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("debugger"); diff --git a/test/script/basic/parser/debuggerStat.js.EXPECTED b/test/script/basic/parser/debuggerStat.js.EXPECTED new file mode 100644 index 00000000..7b954fc3 --- /dev/null +++ b/test/script/basic/parser/debuggerStat.js.EXPECTED @@ -0,0 +1,8 @@ +{ + "type": "Program", + "body": [ + { + "type": "DebuggerStatement" + } + ] +} diff --git a/test/script/basic/parser/functions.js b/test/script/basic/parser/functions.js new file mode 100644 index 00000000..7b624b55 --- /dev/null +++ b/test/script/basic/parser/functions.js @@ -0,0 +1,39 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check 'function' statements and expressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("function hello() { print('hello') }") +printParse("function hello(a) { print(a) }") +printParse("function hello(a, b) { print(a, b) }") +printParse("var hello = function() { print('hello') };") +printParse("var hello = function hello() { print('hello') };") +printParse("(function(){})") +printParse("function test() { 'use strict' }"); diff --git a/test/script/basic/parser/functions.js.EXPECTED b/test/script/basic/parser/functions.js.EXPECTED new file mode 100644 index 00000000..59451d57 --- /dev/null +++ b/test/script/basic/parser/functions.js.EXPECTED @@ -0,0 +1,279 @@ +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [ + { + "type": "Identifier", + "name": "a" + } + ], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "hello" + }, + "init": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "hello" + }, + "init": { + "type": "FunctionExpression", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [] + }, + "generator": false, + "expression": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "test" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": "use strict" + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} diff --git a/test/script/basic/parser/ifStat.js b/test/script/basic/parser/ifStat.js new file mode 100644 index 00000000..5d156668 --- /dev/null +++ b/test/script/basic/parser/ifStat.js @@ -0,0 +1,34 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check 'if' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("if (js) { nashorn() }"); +printParse("if (js) { nashorn() } else { java() }"); diff --git a/test/script/basic/parser/ifStat.js.EXPECTED b/test/script/basic/parser/ifStat.js.EXPECTED new file mode 100644 index 00000000..3897dc14 --- /dev/null +++ b/test/script/basic/parser/ifStat.js.EXPECTED @@ -0,0 +1,73 @@ +{ + "type": "Program", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "js" + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "nashorn" + }, + "arguments": [] + } + } + ] + }, + "alternate": null + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "js" + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "nashorn" + }, + "arguments": [] + } + } + ] + }, + "alternate": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "java" + }, + "arguments": [] + } + } + ] + } + } + ] +} diff --git a/test/script/basic/parser/labelledStat.js b/test/script/basic/parser/labelledStat.js new file mode 100644 index 00000000..25829a4a --- /dev/null +++ b/test/script/basic/parser/labelledStat.js @@ -0,0 +1,34 @@ +/* + * 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. + * + * 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. + */ + +/** + * Test for labelled statements. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("begin: { for (;;) break begin }"); +printParse("begin: { while (true) break begin }"); diff --git a/test/script/basic/parser/labelledStat.js.EXPECTED b/test/script/basic/parser/labelledStat.js.EXPECTED new file mode 100644 index 00000000..fc5f37e8 --- /dev/null +++ b/test/script/basic/parser/labelledStat.js.EXPECTED @@ -0,0 +1,71 @@ +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "begin" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ForStatement", + "init": null, + "test": null, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "begin" + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "begin" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "begin" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/test/script/basic/parser/lhsExpr.js b/test/script/basic/parser/lhsExpr.js new file mode 100644 index 00000000..68f4d6c3 --- /dev/null +++ b/test/script/basic/parser/lhsExpr.js @@ -0,0 +1,47 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check left-hand-side expressions + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("a[3]"); +printParse("a[b]"); +printParse("a['foo']"); +printParse("obj.foo"); +printParse("obj.foo.bar"); +printParse("new Type"); +printParse("new Type()"); +printParse("new Type(a, 'hello')"); +printParse("new obj.Type"); +printParse("new obj.Type()"); +printParse("new obj.Type(a, 'hello')"); +printParse("foo()") +printParse("obj.foo()"); +printParse("foo(a,b)"); +printParse("obj.foo(a, b)"); diff --git a/test/script/basic/parser/lhsExpr.js.EXPECTED b/test/script/basic/parser/lhsExpr.js.EXPECTED new file mode 100644 index 00000000..e61c6c8f --- /dev/null +++ b/test/script/basic/parser/lhsExpr.js.EXPECTED @@ -0,0 +1,344 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a" + }, + "property": { + "type": "Literal", + "value": 3 + }, + "computed": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a" + }, + "property": { + "type": "Identifier", + "name": "b" + }, + "computed": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a" + }, + "property": { + "type": "Literal", + "value": "foo" + }, + "computed": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + }, + "property": { + "type": "Identifier", + "name": "bar" + }, + "computed": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "Type" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "Type" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "Type" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "Type" + }, + "computed": false + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "Type" + }, + "computed": false + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "Type" + }, + "computed": false + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ] + } + } + ] +} diff --git a/test/script/basic/parser/loopStat.js b/test/script/basic/parser/loopStat.js new file mode 100644 index 00000000..ba705568 --- /dev/null +++ b/test/script/basic/parser/loopStat.js @@ -0,0 +1,37 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests for loop statements. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("while(true) { print('hello') }") +printParse("do { print('hello') } while(true)") +printParse("for (i in obj) { print(obj[i]) }") +printParse("for each (i in obj) { print(i) }") +printParse("for (i = 0; i < 10; i++) { print(i) }") diff --git a/test/script/basic/parser/loopStat.js.EXPECTED b/test/script/basic/parser/loopStat.js.EXPECTED new file mode 100644 index 00000000..fd8ef838 --- /dev/null +++ b/test/script/basic/parser/loopStat.js.EXPECTED @@ -0,0 +1,212 @@ +{ + "type": "Program", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "DoWhileStatement", + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "test": { + "type": "Literal", + "value": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ForInStatement", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Identifier", + "name": "obj" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "i" + }, + "computed": true + } + ] + } + } + ] + }, + "each": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ForInStatement", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Identifier", + "name": "obj" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "i" + } + ] + } + } + ] + }, + "each": true + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ForStatement", + "init": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Literal", + "value": 0 + } + }, + "test": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Literal", + "value": 10 + } + }, + "update": { + "type": "UpdateExpression", + "operator": "++", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "i" + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "i" + } + ] + } + } + ] + } + } + ] +} diff --git a/test/script/basic/parser/objectLitExpr.js b/test/script/basic/parser/objectLitExpr.js new file mode 100644 index 00000000..bdecc7fa --- /dev/null +++ b/test/script/basic/parser/objectLitExpr.js @@ -0,0 +1,36 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check assignment e xyzpressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("obj = {}"); +printParse("p = { x: 10, y: 2 }"); +printParse("p = { 'x': 10, 'y': 2 }"); +printParse("p = { get x() { return xValue }, get y() { return yValue } }"); diff --git a/test/script/basic/parser/objectLitExpr.js.EXPECTED b/test/script/basic/parser/objectLitExpr.js.EXPECTED new file mode 100644 index 00000000..067c506a --- /dev/null +++ b/test/script/basic/parser/objectLitExpr.js.EXPECTED @@ -0,0 +1,189 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "obj" + }, + "right": { + "type": "ObjectExpression", + "properties": [] + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "p" + }, + "right": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "x" + }, + "value": { + "type": "Literal", + "value": 10 + }, + "kind": "init" + }, + { + "key": { + "type": "Identifier", + "name": "y" + }, + "value": { + "type": "Literal", + "value": 2 + }, + "kind": "init" + } + ] + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "p" + }, + "right": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Literal", + "value": "x" + }, + "value": { + "type": "Literal", + "value": 10 + }, + "kind": "init" + }, + { + "key": { + "type": "Literal", + "value": "y" + }, + "value": { + "type": "Literal", + "value": 2 + }, + "kind": "init" + } + ] + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "p" + }, + "right": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "x" + }, + "value": { + "type": "FunctionExpression", + "id": { + "type": "Identifier", + "name": "get x" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "xValue" + } + } + ] + }, + "generator": false, + "expression": false + }, + "kind": "get" + }, + { + "key": { + "type": "Identifier", + "name": "y" + }, + "value": { + "type": "FunctionExpression", + "id": { + "type": "Identifier", + "name": "get y" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "yValue" + } + } + ] + }, + "generator": false, + "expression": false + }, + "kind": "get" + } + ] + } + } + } + ] +} diff --git a/test/script/basic/parser/parenExpr.js b/test/script/basic/parser/parenExpr.js new file mode 100644 index 00000000..2d52a023 --- /dev/null +++ b/test/script/basic/parser/parenExpr.js @@ -0,0 +1,34 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests for parenthesis expressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("(2) + (1) + 4"); +printParse("3 + (7) << (5)"); diff --git a/test/script/basic/parser/parenExpr.js.EXPECTED b/test/script/basic/parser/parenExpr.js.EXPECTED new file mode 100644 index 00000000..1e4a2306 --- /dev/null +++ b/test/script/basic/parser/parenExpr.js.EXPECTED @@ -0,0 +1,56 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Literal", + "value": 2 + }, + "right": { + "type": "Literal", + "value": 1 + } + }, + "right": { + "type": "Literal", + "value": 4 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<<", + "left": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Literal", + "value": 3 + }, + "right": { + "type": "Literal", + "value": 7 + } + }, + "right": { + "type": "Literal", + "value": 5 + } + } + } + ] +} diff --git a/test/script/basic/parser/primaryExpr.js b/test/script/basic/parser/primaryExpr.js new file mode 100644 index 00000000..950c47f3 --- /dev/null +++ b/test/script/basic/parser/primaryExpr.js @@ -0,0 +1,45 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check primary expressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("this"); +printParse("foo"); +printParse("null"); +printParse("true"); +printParse("false"); +printParse("33"); +printParse("3.14"); +printParse("(10 + 3)*2"); +printParse("({})"); +printParse("({ x: 3 })"); +printParse("[]"); +printParse("[,,]"); +printParse("[4, 5, 5]"); diff --git a/test/script/basic/parser/primaryExpr.js.EXPECTED b/test/script/basic/parser/primaryExpr.js.EXPECTED new file mode 100644 index 00000000..fcb31d54 --- /dev/null +++ b/test/script/basic/parser/primaryExpr.js.EXPECTED @@ -0,0 +1,199 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ThisExpression" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Identifier", + "name": "foo" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": null + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": 33 + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": 3.14 + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "*", + "left": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Literal", + "value": 10 + }, + "right": { + "type": "Literal", + "value": 3 + } + }, + "right": { + "type": "Literal", + "value": 2 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ObjectExpression", + "properties": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "x" + }, + "value": { + "type": "Literal", + "value": 3 + }, + "kind": "init" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ArrayExpression", + "elements": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ArrayExpression", + "elements": [ + null, + null + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ArrayExpression", + "elements": [ + { + "type": "Literal", + "value": 4 + }, + { + "type": "Literal", + "value": 5 + }, + { + "type": "Literal", + "value": 5 + } + ] + } + } + ] +} diff --git a/test/script/basic/parser/returnStat.js b/test/script/basic/parser/returnStat.js new file mode 100644 index 00000000..741a2340 --- /dev/null +++ b/test/script/basic/parser/returnStat.js @@ -0,0 +1,35 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check 'return' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("(function() { return })"); +printParse("(function() { return res })"); +printParse("(function() { return foo() })"); diff --git a/test/script/basic/parser/returnStat.js.EXPECTED b/test/script/basic/parser/returnStat.js.EXPECTED new file mode 100644 index 00000000..149673c1 --- /dev/null +++ b/test/script/basic/parser/returnStat.js.EXPECTED @@ -0,0 +1,88 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": null + } + ] + }, + "generator": false, + "expression": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "res" + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo" + }, + "arguments": [] + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] +} diff --git a/test/script/basic/parser/switchStat.js b/test/script/basic/parser/switchStat.js new file mode 100644 index 00000000..6f0dd75e --- /dev/null +++ b/test/script/basic/parser/switchStat.js @@ -0,0 +1,35 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests for switch statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("switch (key) {}"); +printParse("switch (key) { case 2: hello(); break; }"); +printParse("switch (key) { case 4: hello(); break; case 2: world(); break; default: break }"); diff --git a/test/script/basic/parser/switchStat.js.EXPECTED b/test/script/basic/parser/switchStat.js.EXPECTED new file mode 100644 index 00000000..6de4ba48 --- /dev/null +++ b/test/script/basic/parser/switchStat.js.EXPECTED @@ -0,0 +1,123 @@ +{ + "type": "Program", + "body": [ + { + "type": "SwitchStatement", + "discriminant": { + "type": "Identifier", + "name": "key" + }, + "cases": [] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "SwitchStatement", + "discriminant": { + "type": "Identifier", + "name": "key" + }, + "cases": [ + { + "type": "SwitchCase", + "test": { + "type": "Literal", + "value": 2 + }, + "consequent": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "hello" + }, + "arguments": [] + } + }, + { + "type": "BreakStatement", + "label": null + } + ] + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "SwitchStatement", + "discriminant": { + "type": "Identifier", + "name": "key" + }, + "cases": [ + { + "type": "SwitchCase", + "test": { + "type": "Literal", + "value": 4 + }, + "consequent": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "hello" + }, + "arguments": [] + } + }, + { + "type": "BreakStatement", + "label": null + } + ] + }, + { + "type": "SwitchCase", + "test": { + "type": "Literal", + "value": 2 + }, + "consequent": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "world" + }, + "arguments": [] + } + }, + { + "type": "BreakStatement", + "label": null + } + ] + }, + { + "type": "SwitchCase", + "test": null, + "consequent": [ + { + "type": "BreakStatement", + "label": null + } + ] + } + ] + } + ] +} diff --git a/test/script/basic/parser/throwStat.js b/test/script/basic/parser/throwStat.js new file mode 100644 index 00000000..345e3b8c --- /dev/null +++ b/test/script/basic/parser/throwStat.js @@ -0,0 +1,37 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests for throw statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("throw err"); +printParse("throw 'wrong'"); +printParse("throw new TypeError"); +printParse("throw new TypeError('not an array')"); +printParse("throw { msg: 'wrong!' }"); diff --git a/test/script/basic/parser/throwStat.js.EXPECTED b/test/script/basic/parser/throwStat.js.EXPECTED new file mode 100644 index 00000000..d869cbda --- /dev/null +++ b/test/script/basic/parser/throwStat.js.EXPECTED @@ -0,0 +1,85 @@ +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "Identifier", + "name": "err" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "Literal", + "value": "wrong" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "TypeError" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "TypeError" + }, + "arguments": [ + { + "type": "Literal", + "value": "not an array" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "msg" + }, + "value": { + "type": "Literal", + "value": "wrong!" + }, + "kind": "init" + } + ] + } + } + ] +} diff --git a/test/script/basic/parser/tryCatchStat.js b/test/script/basic/parser/tryCatchStat.js new file mode 100644 index 00000000..de153133 --- /dev/null +++ b/test/script/basic/parser/tryCatchStat.js @@ -0,0 +1,38 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check try..catch statements. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("try { } catch (e) { }"); +printParse("try { } catch (e) { } finally {}"); +printParse("try { } finally {}"); +printParse("try { } catch (e) { handle() }"); +printParse("try { that() } catch (e) { handle() } finally { clean() }"); +printParse("try { that() } catch (e if e instanceof TypeError) { handle() } catch (e) { rest() }"); diff --git a/test/script/basic/parser/tryCatchStat.js.EXPECTED b/test/script/basic/parser/tryCatchStat.js.EXPECTED new file mode 100644 index 00000000..16075e15 --- /dev/null +++ b/test/script/basic/parser/tryCatchStat.js.EXPECTED @@ -0,0 +1,305 @@ +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [] + } + }, + "finalizer": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [] + } + }, + "finalizer": { + "type": "BlockStatement", + "body": [] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": null, + "finalizer": { + "type": "BlockStatement", + "body": [] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "handle" + }, + "arguments": [] + } + } + ] + } + }, + "finalizer": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "that" + }, + "arguments": [] + } + } + ] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "handle" + }, + "arguments": [] + } + } + ] + } + }, + "finalizer": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "clean" + }, + "arguments": [] + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "that" + }, + "arguments": [] + } + } + ] + }, + "guardedHandlers": [ + { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "guard": { + "type": "BinaryExpression", + "operator": "instanceof", + "left": { + "type": "Identifier", + "name": "e" + }, + "right": { + "type": "Identifier", + "name": "TypeError" + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "handle" + }, + "arguments": [] + } + } + ] + } + } + ], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "rest" + }, + "arguments": [] + } + } + ] + } + }, + "finalizer": null + } + ] + } + } + ] +} diff --git a/test/script/basic/parser/unaryExpr.js b/test/script/basic/parser/unaryExpr.js new file mode 100644 index 00000000..e21b55f3 --- /dev/null +++ b/test/script/basic/parser/unaryExpr.js @@ -0,0 +1,43 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check unary operators. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("x++"); +printParse("x--"); +printParse("delete x"); +printParse("void x"); +printParse("typeof x"); +printParse("++x"); +printParse("--x"); +printParse("+x"); +printParse("-x"); +printParse("~x"); +printParse("!x"); diff --git a/test/script/basic/parser/unaryExpr.js.EXPECTED b/test/script/basic/parser/unaryExpr.js.EXPECTED new file mode 100644 index 00000000..d7a9532b --- /dev/null +++ b/test/script/basic/parser/unaryExpr.js.EXPECTED @@ -0,0 +1,187 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "++", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "--", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "delete", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "void", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "typeof", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "++", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "--", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "+", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "-", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "~", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} diff --git a/test/script/basic/parser/useStrict.js b/test/script/basic/parser/useStrict.js new file mode 100644 index 00000000..4d1c7a94 --- /dev/null +++ b/test/script/basic/parser/useStrict.js @@ -0,0 +1,34 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check if statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("'use strict'"); +printParse("function f() { 'use strict' }"); diff --git a/test/script/basic/parser/useStrict.js.EXPECTED b/test/script/basic/parser/useStrict.js.EXPECTED new file mode 100644 index 00000000..870fbc24 --- /dev/null +++ b/test/script/basic/parser/useStrict.js.EXPECTED @@ -0,0 +1,41 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": "use strict" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "f" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": "use strict" + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} diff --git a/test/script/basic/parser/util.js b/test/script/basic/parser/util.js new file mode 100644 index 00000000..6170018b --- /dev/null +++ b/test/script/basic/parser/util.js @@ -0,0 +1,33 @@ +/* + * 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. + * + * 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. + */ + +/** + * @subtest + */ + +// utilitity for parser tests + +load("nashorn:parser.js"); +function printParse(code) { + print(JSON.stringify(parse(code), null, ' ')); +} diff --git a/test/script/basic/parser/varDecl.js b/test/script/basic/parser/varDecl.js new file mode 100644 index 00000000..e505761b --- /dev/null +++ b/test/script/basic/parser/varDecl.js @@ -0,0 +1,39 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests to check variable declarations. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +// no initialization +printParse("var a"); +printParse("var a, b"); + +// init single, multiple +printParse("var a = 'hello'"); +printParse("var a = 1, b = 2, c = 3"); diff --git a/test/script/basic/parser/varDecl.js.EXPECTED b/test/script/basic/parser/varDecl.js.EXPECTED new file mode 100644 index 00000000..96e71cf6 --- /dev/null +++ b/test/script/basic/parser/varDecl.js.EXPECTED @@ -0,0 +1,123 @@ +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": null + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": null + } + ] + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b" + }, + "init": null + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": { + "type": "Literal", + "value": "hello" + } + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": { + "type": "Literal", + "value": 1 + } + } + ] + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b" + }, + "init": { + "type": "Literal", + "value": 2 + } + } + ] + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "c" + }, + "init": { + "type": "Literal", + "value": 3 + } + } + ] + } + ] +} diff --git a/test/script/basic/parser/withStat.js b/test/script/basic/parser/withStat.js new file mode 100644 index 00000000..3f94c7f5 --- /dev/null +++ b/test/script/basic/parser/withStat.js @@ -0,0 +1,33 @@ +/* + * 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. + * + * 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. + */ + +/** + * Tests for 'with' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("with (scope) { x = y }"); diff --git a/test/script/basic/parser/withStat.js.EXPECTED b/test/script/basic/parser/withStat.js.EXPECTED new file mode 100644 index 00000000..46bea479 --- /dev/null +++ b/test/script/basic/parser/withStat.js.EXPECTED @@ -0,0 +1,32 @@ +{ + "type": "Program", + "body": [ + { + "type": "WithStatement", + "object": { + "type": "Identifier", + "name": "scope" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x" + }, + "right": { + "type": "Identifier", + "name": "y" + } + } + } + ] + } + } + ] +} -- cgit v1.2.3 From 0238832899f8eaa1bdf138c9e8914e4c425aa050 Mon Sep 17 00:00:00 2001 From: sundar Date: Fri, 13 Sep 2013 16:45:11 +0530 Subject: 8024619: JDBC java.sql.DriverManager is not usable from JS script Reviewed-by: jlaskey, lagergren, attila --- make/build.xml | 5 ++ src/jdk/nashorn/internal/runtime/Context.java | 17 +++-- .../nashorn/internal/runtime/NashornLoader.java | 30 +------- src/jdk/nashorn/internal/runtime/ScriptLoader.java | 31 ++++++++- .../nashorn/internal/runtime/StructureLoader.java | 27 ++------ test/script/basic/JDK-8024619.js | 46 +++++++++++++ test/src/META-INF/services/java.sql.Driver | 1 + test/src/jdk/nashorn/api/NashornSQLDriver.java | 79 ++++++++++++++++++++++ 8 files changed, 177 insertions(+), 59 deletions(-) create mode 100644 test/script/basic/JDK-8024619.js create mode 100644 test/src/META-INF/services/java.sql.Driver create mode 100644 test/src/jdk/nashorn/api/NashornSQLDriver.java diff --git a/make/build.xml b/make/build.xml index df655d59..73644a6b 100644 --- a/make/build.xml +++ b/make/build.xml @@ -230,6 +230,10 @@ + + + + @@ -238,6 +242,7 @@ + diff --git a/src/jdk/nashorn/internal/runtime/Context.java b/src/jdk/nashorn/internal/runtime/Context.java index 4651b508..7c69eb52 100644 --- a/src/jdk/nashorn/internal/runtime/Context.java +++ b/src/jdk/nashorn/internal/runtime/Context.java @@ -236,6 +236,10 @@ public final class Context { private static final ClassLoader myLoader = Context.class.getClassLoader(); private static final StructureLoader sharedLoader; + /*package-private*/ ClassLoader getSharedLoader() { + return sharedLoader; + } + private static AccessControlContext createNoPermAccCtxt() { return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) }); } @@ -254,7 +258,7 @@ public final class Context { sharedLoader = AccessController.doPrivileged(new PrivilegedAction() { @Override public StructureLoader run() { - return new StructureLoader(myLoader, null); + return new StructureLoader(myLoader); } }, CREATE_LOADER_ACC_CTXT); } @@ -599,7 +603,7 @@ public final class Context { * @throws ClassNotFoundException if structure class cannot be resolved */ public static Class forStructureClass(final String fullName) throws ClassNotFoundException { - if (System.getSecurityManager() != null && !NashornLoader.isStructureClass(fullName)) { + if (System.getSecurityManager() != null && !StructureLoader.isStructureClass(fullName)) { throw new ClassNotFoundException(fullName); } return Class.forName(fullName, true, sharedLoader); @@ -792,12 +796,11 @@ public final class Context { static Context fromClass(final Class clazz) { final ClassLoader loader = clazz.getClassLoader(); - Context context = null; - if (loader instanceof NashornLoader) { - context = ((NashornLoader)loader).getContext(); + if (loader instanceof ScriptLoader) { + return ((ScriptLoader)loader).getContext(); } - return (context != null) ? context : Context.getContextTrusted(); + return Context.getContextTrusted(); } private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) { @@ -899,7 +902,7 @@ public final class Context { new PrivilegedAction() { @Override public ScriptLoader run() { - return new ScriptLoader(sharedLoader, Context.this); + return new ScriptLoader(appLoader, Context.this); } }, CREATE_LOADER_ACC_CTXT); } diff --git a/src/jdk/nashorn/internal/runtime/NashornLoader.java b/src/jdk/nashorn/internal/runtime/NashornLoader.java index 4e349730..e7837013 100644 --- a/src/jdk/nashorn/internal/runtime/NashornLoader.java +++ b/src/jdk/nashorn/internal/runtime/NashornLoader.java @@ -38,10 +38,7 @@ import java.security.SecureClassLoader; import jdk.nashorn.tools.Shell; /** - * Superclass for Nashorn class loader classes. This stores Context - * instance as an instance field. The current context can be - * efficiently accessed from a given Class via it's ClassLoader. - * + * Superclass for Nashorn class loader classes. */ abstract class NashornLoader extends SecureClassLoader { private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects"; @@ -69,27 +66,8 @@ abstract class NashornLoader extends SecureClassLoader { }; } - private final Context context; - - final Context getContext() { - return context; - } - - NashornLoader(final ClassLoader parent, final Context context) { + NashornLoader(final ClassLoader parent) { super(parent); - this.context = context; - } - - - /** - * Called by subclass after package access check is done - * @param name name of the class to be loaded - * @param resolve whether the class should be resolved or not - * @return Class object - * @throws ClassNotFoundException if class cannot be loaded - */ - protected final Class loadClassTrusted(final String name, final boolean resolve) throws ClassNotFoundException { - return super.loadClass(name, resolve); } protected static void checkPackageAccess(final String name) { @@ -122,10 +100,6 @@ abstract class NashornLoader extends SecureClassLoader { return permCollection; } - static boolean isStructureClass(final String fullName) { - return fullName.startsWith(SCRIPTS_PKG); - } - /** * Create a secure URL class loader for the given classpath * @param classPath classpath for the loader to search from diff --git a/src/jdk/nashorn/internal/runtime/ScriptLoader.java b/src/jdk/nashorn/internal/runtime/ScriptLoader.java index 370faf31..736932ea 100644 --- a/src/jdk/nashorn/internal/runtime/ScriptLoader.java +++ b/src/jdk/nashorn/internal/runtime/ScriptLoader.java @@ -33,17 +33,42 @@ import java.security.ProtectionDomain; * */ final class ScriptLoader extends NashornLoader { + private static final String NASHORN_PKG_PREFIX = "jdk.nashorn.internal."; + + private final Context context; + + /*package-private*/ Context getContext() { + return context; + } + /** * Constructor. */ - ScriptLoader(final StructureLoader parent, final Context context) { - super(parent, context); + ScriptLoader(final ClassLoader parent, final Context context) { + super(parent); + this.context = context; } @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { checkPackageAccess(name); - return super.loadClassTrusted(name, resolve); + try { + return super.loadClass(name, resolve); + } catch (final ClassNotFoundException | SecurityException e) { + // We'll get ClassNotFoundException for Nashorn 'struct' classes. + // Also, we'll get SecurityException for jdk.nashorn.internal.* + // classes. So, load these using to context's 'shared' loader. + // All these classes start with "jdk.nashorn.internal." prefix. + try { + if (name.startsWith(NASHORN_PKG_PREFIX)) { + return context.getSharedLoader().loadClass(name); + } + } catch (final ClassNotFoundException ignored) { + } + + // throw the original exception from here + throw e; + } } // package-private and private stuff below this point diff --git a/src/jdk/nashorn/internal/runtime/StructureLoader.java b/src/jdk/nashorn/internal/runtime/StructureLoader.java index bdc40edd..41201cde 100644 --- a/src/jdk/nashorn/internal/runtime/StructureLoader.java +++ b/src/jdk/nashorn/internal/runtime/StructureLoader.java @@ -34,7 +34,6 @@ import jdk.nashorn.internal.codegen.ObjectClassGenerator; /** * Responsible for on the fly construction of structure classes. - * */ final class StructureLoader extends NashornLoader { private static final String JS_OBJECT_PREFIX_EXTERNAL = binaryName(SCRIPTS_PACKAGE) + '.' + JS_OBJECT_PREFIX.symbolName(); @@ -42,27 +41,17 @@ final class StructureLoader extends NashornLoader { /** * Constructor. */ - StructureLoader(final ClassLoader parent, final Context context) { - super(parent, context); + StructureLoader(final ClassLoader parent) { + super(parent); } - @Override - protected synchronized Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException { - // check the cache first - final Class loadedClass = findLoadedClass(name); - if (loadedClass != null) { - if (resolve) { - resolveClass(loadedClass); - } - return loadedClass; - } - - return super.loadClassTrusted(name, resolve); + static boolean isStructureClass(final String name) { + return name.startsWith(JS_OBJECT_PREFIX_EXTERNAL); } @Override protected Class findClass(final String name) throws ClassNotFoundException { - if (name.startsWith(JS_OBJECT_PREFIX_EXTERNAL)) { + if (isStructureClass(name)) { return generateClass(name, name.substring(JS_OBJECT_PREFIX_EXTERNAL.length())); } return super.findClass(name); @@ -75,11 +64,7 @@ final class StructureLoader extends NashornLoader { * @return Generated class. */ private Class generateClass(final String name, final String descriptor) { - Context context = getContext(); - - if (context == null) { - context = Context.getContextTrusted(); - } + final Context context = Context.getContextTrusted(); final byte[] code = new ObjectClassGenerator(context).generate(descriptor); return defineClass(name, code, 0, code.length, new ProtectionDomain(null, getPermissions(null))); diff --git a/test/script/basic/JDK-8024619.js b/test/script/basic/JDK-8024619.js new file mode 100644 index 00000000..064e0d7b --- /dev/null +++ b/test/script/basic/JDK-8024619.js @@ -0,0 +1,46 @@ +/* + * 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. + * + * 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-8024619: JDBC java.sql.DriverManager is not usable from JS script + * + * @test + * @run + */ + +var DriverManager = Java.type("java.sql.DriverManager"); +var e = DriverManager.getDrivers(); + +var driverFound = false; +// check for Nashorn SQL driver +while (e.hasMoreElements()) { + var driver = e.nextElement(); + if (driver.acceptsURL("jdbc:nashorn:")) { + driverFound = true; + break; + } +} + +if (! driverFound) { + fail("Nashorn JDBC Driver not found!"); +} diff --git a/test/src/META-INF/services/java.sql.Driver b/test/src/META-INF/services/java.sql.Driver new file mode 100644 index 00000000..295fe480 --- /dev/null +++ b/test/src/META-INF/services/java.sql.Driver @@ -0,0 +1 @@ +jdk.nashorn.api.NashornSQLDriver diff --git a/test/src/jdk/nashorn/api/NashornSQLDriver.java b/test/src/jdk/nashorn/api/NashornSQLDriver.java new file mode 100644 index 00000000..2987b948 --- /dev/null +++ b/test/src/jdk/nashorn/api/NashornSQLDriver.java @@ -0,0 +1,79 @@ +/* + * 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.api; + +import java.sql.*; +import java.util.Properties; +import java.util.logging.Logger; + +/** + * A dummy SQL driver for testing purpose. + */ +public final class NashornSQLDriver implements Driver { + static { + try { + DriverManager.registerDriver(new NashornSQLDriver(), null); + } catch (SQLException se) { + throw new RuntimeException(se); + } + } + + @Override + public boolean acceptsURL(String url) { + return url.startsWith("jdbc:nashorn:"); + } + + @Override + public Connection connect(String url, Properties info) { + throw new UnsupportedOperationException("I am a dummy!!"); + } + + @Override + public int getMajorVersion() { + return -1; + } + + @Override + public int getMinorVersion() { + return -1; + } + + @Override + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) { + return new DriverPropertyInfo[0]; + } + + @Override + public boolean jdbcCompliant() { + // no way! + return false; + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + throw new SQLFeatureNotSupportedException(); + } +} -- cgit v1.2.3 From baafce737ca84ffa4cf397b548618c9f0a1aa97e Mon Sep 17 00:00:00 2001 From: sundar Date: Mon, 16 Sep 2013 15:08:36 +0530 Subject: 8024847: Java.to should accept mirror and external JSObjects as array-like objects as well Reviewed-by: hannesw, attila, lagergren --- src/jdk/nashorn/internal/objects/NativeJava.java | 10 +- src/jdk/nashorn/internal/runtime/ECMAErrors.java | 1 - .../internal/runtime/JSObjectListAdapter.java | 56 +++++++++++ src/jdk/nashorn/internal/runtime/JSType.java | 60 ++++++++++++ src/jdk/nashorn/internal/runtime/ListAdapter.java | 105 ++++++++++++--------- .../internal/runtime/ScriptObjectListAdapter.java | 54 +++++++++++ .../nashorn/internal/runtime/arrays/ArrayData.java | 18 +--- test/script/basic/JDK-8024847.js | 102 ++++++++++++++++++++ test/script/basic/JDK-8024847.js.EXPECTED | 12 +++ 9 files changed, 352 insertions(+), 66 deletions(-) create mode 100644 src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java create mode 100644 src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java create mode 100644 test/script/basic/JDK-8024847.js create mode 100644 test/script/basic/JDK-8024847.js.EXPECTED diff --git a/src/jdk/nashorn/internal/objects/NativeJava.java b/src/jdk/nashorn/internal/objects/NativeJava.java index 011fd8bf..5e9ac83d 100644 --- a/src/jdk/nashorn/internal/objects/NativeJava.java +++ b/src/jdk/nashorn/internal/objects/NativeJava.java @@ -34,6 +34,7 @@ import java.util.Deque; import java.util.List; import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.support.TypeUtilities; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.ScriptClass; @@ -43,6 +44,7 @@ import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ListAdapter; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory; @@ -288,7 +290,9 @@ public final class NativeJava { return null; } - Global.checkObject(obj); + if (!(obj instanceof ScriptObject) && !(obj instanceof JSObject)) { + throw typeError("not.an.object", ScriptRuntime.safeToString(obj)); + } final Class targetClass; if(objType == UNDEFINED) { @@ -304,11 +308,11 @@ public final class NativeJava { } if(targetClass.isArray()) { - return ((ScriptObject)obj).getArray().asArrayOfType(targetClass.getComponentType()); + return JSType.toJavaArray(obj, targetClass.getComponentType()); } if(targetClass == List.class || targetClass == Deque.class) { - return new ListAdapter((ScriptObject)obj); + return ListAdapter.create(obj); } throw typeError("unsupported.java.to.type", targetClass.getName()); diff --git a/src/jdk/nashorn/internal/runtime/ECMAErrors.java b/src/jdk/nashorn/internal/runtime/ECMAErrors.java index 5b608f4b..0ff843a4 100644 --- a/src/jdk/nashorn/internal/runtime/ECMAErrors.java +++ b/src/jdk/nashorn/internal/runtime/ECMAErrors.java @@ -28,7 +28,6 @@ package jdk.nashorn.internal.runtime; import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; - import jdk.nashorn.api.scripting.NashornException; import jdk.nashorn.internal.scripts.JS; diff --git a/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java b/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java new file mode 100644 index 00000000..3c430b29 --- /dev/null +++ b/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java @@ -0,0 +1,56 @@ +/* + * 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.runtime; + +import jdk.nashorn.api.scripting.JSObject; + +/** + * A ListAdapter that can wraps a JSObject. + */ +public final class JSObjectListAdapter extends ListAdapter { + /** + * Creates a new list wrapper for the specified JSObject. + * @param obj JSOcript the object to wrap + */ + public JSObjectListAdapter(final JSObject obj) { + super(obj); + } + + @Override + public int size() { + return JSType.toInt32(((JSObject)obj).getMember("length")); + } + + @Override + protected Object getAt(int index) { + return ((JSObject)obj).getSlot(index); + } + + @Override + protected void setAt(int index, Object element) { + ((JSObject)obj).setSlot(index, element); + } +} diff --git a/src/jdk/nashorn/internal/runtime/JSType.java b/src/jdk/nashorn/internal/runtime/JSType.java index 6098eb27..93f0835b 100644 --- a/src/jdk/nashorn/internal/runtime/JSType.java +++ b/src/jdk/nashorn/internal/runtime/JSType.java @@ -28,10 +28,14 @@ package jdk.nashorn.internal.runtime; import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.lang.reflect.Array; import jdk.internal.dynalink.beans.StaticClass; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.parser.Lexer; +import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator; import jdk.nashorn.internal.runtime.linker.Bootstrap; /** @@ -859,6 +863,53 @@ public enum JSType { return ((GlobalObject)global).wrapAsObject(obj); } + /** + * Script object to Java array conversion. + * + * @param obj script object to be converted to Java array + * @param componentType component type of the destination array required + * @return converted Java array + */ + public static Object toJavaArray(final Object obj, final Class componentType) { + if (obj instanceof ScriptObject) { + return convertArray(((ScriptObject)obj).getArray().asObjectArray(), componentType); + } else if (obj instanceof JSObject) { + final ArrayLikeIterator itr = ArrayLikeIterator.arrayLikeIterator(obj); + final int len = (int) itr.getLength(); + final Object[] res = new Object[len]; + int idx = 0; + while (itr.hasNext()) { + res[idx++] = itr.next(); + } + return convertArray(res, componentType); + } else { + throw new IllegalArgumentException("not a script object"); + } + } + + /** + * Java array to java array conversion - but using type conversions implemented by linker. + * + * @param src source array + * @param componentType component type of the destination array required + * @return converted Java array + */ + public static Object convertArray(final Object[] src, final Class componentType) { + final int l = src.length; + final Object dst = Array.newInstance(componentType, l); + final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType); + try { + for (int i = 0; i < src.length; i++) { + Array.set(dst, i, invoke(converter, src[i])); + } + } catch (final RuntimeException | Error e) { + throw e; + } catch (final Throwable t) { + throw new RuntimeException(t); + } + return dst; + } + /** * Check if an object is null or undefined * @@ -964,4 +1015,13 @@ public enum JSType { return Double.NaN; } + private static Object invoke(final MethodHandle mh, final Object arg) { + try { + return mh.invoke(arg); + } catch (final RuntimeException | Error e) { + throw e; + } catch (final Throwable t) { + throw new RuntimeException(t); + } + } } diff --git a/src/jdk/nashorn/internal/runtime/ListAdapter.java b/src/jdk/nashorn/internal/runtime/ListAdapter.java index ae6d7446..41d34600 100644 --- a/src/jdk/nashorn/internal/runtime/ListAdapter.java +++ b/src/jdk/nashorn/internal/runtime/ListAdapter.java @@ -32,6 +32,7 @@ import java.util.ListIterator; import java.util.NoSuchElementException; import java.util.RandomAccess; import java.util.concurrent.Callable; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.InvokeByName; @@ -48,7 +49,7 @@ import jdk.nashorn.internal.runtime.linker.InvokeByName; * operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and * {@code pop}. */ -public final class ListAdapter extends AbstractList implements RandomAccess, Deque { +public abstract class ListAdapter extends AbstractList implements RandomAccess, Deque { // These add to the back and front of the list private static final Object PUSH = new Object(); private static InvokeByName getPUSH() { @@ -56,7 +57,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("push", ScriptObject.class, void.class, Object.class); + return new InvokeByName("push", Object.class, void.class, Object.class); } }); } @@ -67,7 +68,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("unshift", ScriptObject.class, void.class, Object.class); + return new InvokeByName("unshift", Object.class, void.class, Object.class); } }); } @@ -79,7 +80,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("pop", ScriptObject.class, Object.class); + return new InvokeByName("pop", Object.class, Object.class); } }); } @@ -90,7 +91,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("shift", ScriptObject.class, Object.class); + return new InvokeByName("shift", Object.class, Object.class); } }); } @@ -102,7 +103,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class, Object.class); + return new InvokeByName("splice", Object.class, void.class, int.class, int.class, Object.class); } }); } @@ -113,40 +114,52 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class); + return new InvokeByName("splice", Object.class, void.class, int.class, int.class); } }); } - private final ScriptObject obj; + protected final Object obj; - /** - * Creates a new list wrapper for the specified script object. - * @param obj script the object to wrap - */ - public ListAdapter(ScriptObject obj) { + // allow subclasses only in this package + ListAdapter(Object obj) { this.obj = obj; } - @Override - public int size() { - return JSType.toInt32(obj.getLength()); + /** + * Factory to create a ListAdapter for a given script object. + * + * @param obj script object to wrap as a ListAdapter + * @return A ListAdapter wrapper object + */ + public static ListAdapter create(final Object obj) { + if (obj instanceof ScriptObject) { + return new ScriptObjectListAdapter((ScriptObject)obj); + } else if (obj instanceof JSObject) { + return new JSObjectListAdapter((JSObject)obj); + } else { + throw new IllegalArgumentException("ScriptObject or JSObject expected"); + } } @Override - public Object get(int index) { + public final Object get(int index) { checkRange(index); - return obj.get(index); + return getAt(index); } + protected abstract Object getAt(final int index); + @Override public Object set(int index, Object element) { checkRange(index); - final Object prevValue = get(index); - obj.set(index, element, false); + final Object prevValue = getAt(index); + setAt(index, element); return prevValue; } + protected abstract void setAt(int index, Object element); + private void checkRange(int index) { if(index < 0 || index >= size()) { throw invalidIndex(index); @@ -154,18 +167,18 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public void push(Object e) { + public final void push(Object e) { addFirst(e); } @Override - public boolean add(Object e) { + public final boolean add(Object e) { addLast(e); return true; } @Override - public void addFirst(Object e) { + public final void addFirst(Object e) { try { final InvokeByName unshiftInvoker = getUNSHIFT(); final Object fn = unshiftInvoker.getGetter().invokeExact(obj); @@ -179,7 +192,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public void addLast(Object e) { + public final void addLast(Object e) { try { final InvokeByName pushInvoker = getPUSH(); final Object fn = pushInvoker.getGetter().invokeExact(obj); @@ -193,7 +206,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public void add(int index, Object e) { + public final void add(int index, Object e) { try { if(index < 0) { throw invalidIndex(index); @@ -229,40 +242,40 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public boolean offer(Object e) { + public final boolean offer(Object e) { return offerLast(e); } @Override - public boolean offerFirst(Object e) { + public final boolean offerFirst(Object e) { addFirst(e); return true; } @Override - public boolean offerLast(Object e) { + public final boolean offerLast(Object e) { addLast(e); return true; } @Override - public Object pop() { + public final Object pop() { return removeFirst(); } @Override - public Object remove() { + public final Object remove() { return removeFirst(); } @Override - public Object removeFirst() { + public final Object removeFirst() { checkNonEmpty(); return invokeShift(); } @Override - public Object removeLast() { + public final Object removeLast() { checkNonEmpty(); return invokePop(); } @@ -274,7 +287,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public Object remove(int index) { + public final Object remove(int index) { if(index < 0) { throw invalidIndex(index); } else if (index == 0) { @@ -320,7 +333,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - protected void removeRange(int fromIndex, int toIndex) { + protected final void removeRange(int fromIndex, int toIndex) { invokeSpliceRemove(fromIndex, toIndex - fromIndex); } @@ -338,54 +351,54 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public Object poll() { + public final Object poll() { return pollFirst(); } @Override - public Object pollFirst() { + public final Object pollFirst() { return isEmpty() ? null : invokeShift(); } @Override - public Object pollLast() { + public final Object pollLast() { return isEmpty() ? null : invokePop(); } @Override - public Object peek() { + public final Object peek() { return peekFirst(); } @Override - public Object peekFirst() { + public final Object peekFirst() { return isEmpty() ? null : get(0); } @Override - public Object peekLast() { + public final Object peekLast() { return isEmpty() ? null : get(size() - 1); } @Override - public Object element() { + public final Object element() { return getFirst(); } @Override - public Object getFirst() { + public final Object getFirst() { checkNonEmpty(); return get(0); } @Override - public Object getLast() { + public final Object getLast() { checkNonEmpty(); return get(size() - 1); } @Override - public Iterator descendingIterator() { + public final Iterator descendingIterator() { final ListIterator it = listIterator(size()); return new Iterator() { @Override @@ -406,12 +419,12 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public boolean removeFirstOccurrence(Object o) { + public final boolean removeFirstOccurrence(Object o) { return removeOccurrence(o, iterator()); } @Override - public boolean removeLastOccurrence(Object o) { + public final boolean removeLastOccurrence(Object o) { return removeOccurrence(o, descendingIterator()); } diff --git a/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java b/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java new file mode 100644 index 00000000..4fe2dc40 --- /dev/null +++ b/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java @@ -0,0 +1,54 @@ +/* + * 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.runtime; + +/** + * A ListAdapter that can wrap a ScriptObject. + */ +public final class ScriptObjectListAdapter extends ListAdapter { + /** + * Creates a new list wrapper for the specified ScriptObject. + * @param obj script the object to wrap + */ + public ScriptObjectListAdapter(final ScriptObject obj) { + super(obj); + } + + @Override + public int size() { + return JSType.toInt32(((ScriptObject)obj).getLength()); + } + + @Override + protected Object getAt(int index) { + return ((ScriptObject)obj).get(index); + } + + @Override + protected void setAt(int index, Object element) { + ((ScriptObject)obj).set(index, element, false); + } +} diff --git a/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java b/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java index 1278d49f..ca4adb62 100644 --- a/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java @@ -26,10 +26,9 @@ package jdk.nashorn.internal.runtime.arrays; import java.lang.invoke.MethodHandle; -import java.lang.reflect.Array; import jdk.nashorn.internal.runtime.GlobalObject; +import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.PropertyDescriptor; -import jdk.nashorn.internal.runtime.linker.Bootstrap; /** * ArrayData - abstraction for wrapping array elements @@ -204,20 +203,7 @@ public abstract class ArrayData { * @return and array of the given type */ public Object asArrayOfType(final Class componentType) { - final Object[] src = asObjectArray(); - final int l = src.length; - final Object dst = Array.newInstance(componentType, l); - final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType); - try { - for (int i = 0; i < src.length; i++) { - Array.set(dst, i, invoke(converter, src[i])); - } - } catch (final RuntimeException | Error e) { - throw e; - } catch (final Throwable t) { - throw new RuntimeException(t); - } - return dst; + return JSType.convertArray(asObjectArray(), componentType); } /** diff --git a/test/script/basic/JDK-8024847.js b/test/script/basic/JDK-8024847.js new file mode 100644 index 00000000..4a671ecd --- /dev/null +++ b/test/script/basic/JDK-8024847.js @@ -0,0 +1,102 @@ +/* + * 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. + * + * 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-8024847: Java.to should accept mirror and external JSObjects as array-like objects as well + * + * @test + * @run + */ + +var global = loadWithNewGlobal({ name: "test", script:"this" }); +var arr = new global.Array(2, 4, 6, 8); +var jarr = Java.to(arr, "int[]"); +for (var i in jarr) { + print(jarr[i]); +} + +arr = null; +jarr = null; + +// external JSObjects +var JSObject = Java.type("jdk.nashorn.api.scripting.JSObject"); +var arr = new JSObject() { + getMember: function(name) { + return name == "length"? 4 : undefined; + }, + + hasMember: function(name) { + return name == "length"; + }, + + getSlot: function(idx) { + return idx*idx; + }, + + hasSlot: function(idx) { + return true; + } +}; + +var jarr = Java.to(arr, "int[]"); +for (var i in jarr) { + print(jarr[i]); +} + +arr = null; +jarr = null; + +// List conversion +var arr = global.Array("hello", "world"); +var jlist = Java.to(arr, java.util.List); +print(jlist instanceof java.util.List); +print(jlist); + +arr = null; +jlist = null; + +// external JSObject +var __array__ = [ "nashorn", "js" ]; + +var obj = new JSObject() { + + hasMember: function(name) { + return name in __array__; + }, + + hasSlot: function(idx) { + return idx in __array__; + }, + + getMember: function(name) { + return __array__[name]; + }, + + getSlot: function(idx) { + return __array__[idx]; + } +} + +var jlist = Java.to(obj, java.util.List); +print(jlist instanceof java.util.List); +print(jlist); diff --git a/test/script/basic/JDK-8024847.js.EXPECTED b/test/script/basic/JDK-8024847.js.EXPECTED new file mode 100644 index 00000000..015183a0 --- /dev/null +++ b/test/script/basic/JDK-8024847.js.EXPECTED @@ -0,0 +1,12 @@ +2 +4 +6 +8 +0 +1 +4 +9 +true +[hello, world] +true +[nashorn, js] -- cgit v1.2.3 From ba3175e455da7429c89b9af959366f9069b041f6 Mon Sep 17 00:00:00 2001 From: attila Date: Mon, 16 Sep 2013 14:44:20 +0200 Subject: 8024846: keep separate internal arguments variable Reviewed-by: lagergren, sundar --- src/jdk/nashorn/internal/codegen/Attr.java | 89 ++++++++++++++-------- .../internal/codegen/CompilerConstants.java | 8 +- src/jdk/nashorn/internal/parser/Parser.java | 21 +++-- test/script/basic/JDK-8024846.js | 37 +++++++++ 4 files changed, 115 insertions(+), 40 deletions(-) create mode 100644 test/script/basic/JDK-8024846.js diff --git a/src/jdk/nashorn/internal/codegen/Attr.java b/src/jdk/nashorn/internal/codegen/Attr.java index 88e904dc..813d3fc9 100644 --- a/src/jdk/nashorn/internal/codegen/Attr.java +++ b/src/jdk/nashorn/internal/codegen/Attr.java @@ -26,6 +26,7 @@ package jdk.nashorn.internal.codegen; import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; +import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR; import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE; import static jdk.nashorn.internal.codegen.CompilerConstants.EXCEPTION_PREFIX; import static jdk.nashorn.internal.codegen.CompilerConstants.ITERATOR_PREFIX; @@ -172,7 +173,9 @@ final class Attr extends NodeOperatorVisitor { initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL); if (functionNode.needsArguments()) { initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED); - addLocalDef(ARGUMENTS.symbolName()); + final String argumentsName = ARGUMENTS_VAR.symbolName(); + newType(defineSymbol(body, argumentsName, IS_VAR | IS_ALWAYS_DEFINED), Type.typeFor(ARGUMENTS_VAR.type())); + addLocalDef(argumentsName); } } @@ -491,30 +494,29 @@ final class Attr extends NodeOperatorVisitor { objectifySymbols(body); } - if (body.getFlag(Block.NEEDS_SELF_SYMBOL)) { - final IdentNode callee = compilerConstant(CALLEE); - VarNode selfInit = - new VarNode( - newFunctionNode.getLineNumber(), - newFunctionNode.getToken(), - newFunctionNode.getFinish(), - newFunctionNode.getIdent(), - callee); - - LOG.info("Accepting self symbol init ", selfInit, " for ", newFunctionNode.getName()); - - final List newStatements = new ArrayList<>(); - assert callee.getSymbol() != null && callee.getSymbol().hasSlot(); + List syntheticInitializers = null; - final IdentNode name = selfInit.getName(); - final Symbol nameSymbol = body.getExistingSymbol(name.getName()); - - assert nameSymbol != null; + if (body.getFlag(Block.NEEDS_SELF_SYMBOL)) { + syntheticInitializers = new ArrayList<>(2); + LOG.info("Accepting self symbol init for ", newFunctionNode.getName()); + // "var fn = :callee" + syntheticInitializers.add(createSyntheticInitializer(newFunctionNode.getIdent(), CALLEE, newFunctionNode)); + } - selfInit = selfInit.setName((IdentNode)name.setSymbol(lc, nameSymbol)); + if(newFunctionNode.needsArguments()) { + if(syntheticInitializers == null) { + syntheticInitializers = new ArrayList<>(1); + } + // "var arguments = :arguments" + syntheticInitializers.add(createSyntheticInitializer(createImplicitIdentifier(ARGUMENTS_VAR.symbolName()), + ARGUMENTS, newFunctionNode)); + } - newStatements.add(selfInit); - newStatements.addAll(body.getStatements()); + if(syntheticInitializers != null) { + final List stmts = body.getStatements(); + final List newStatements = new ArrayList<>(stmts.size() + syntheticInitializers.size()); + newStatements.addAll(syntheticInitializers); + newStatements.addAll(stmts); newFunctionNode = newFunctionNode.setBody(lc, body.setStatements(lc, newStatements)); } @@ -533,6 +535,28 @@ final class Attr extends NodeOperatorVisitor { return newFunctionNode; } + /** + * 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 + * expressions as well as for assignment of {@code :arguments} to {@code arguments}. + * + * @param name the ident node identifying the variable to initialize + * @param initConstant the compiler constant it is initialized to + * @param fn the function node the assignment is for + * @return a var node with the appropriate assignment + */ + private VarNode createSyntheticInitializer(final IdentNode name, final CompilerConstants initConstant, final FunctionNode fn) { + final IdentNode init = compilerConstant(initConstant); + assert init.getSymbol() != null && init.getSymbol().hasSlot(); + + VarNode synthVar = new VarNode(fn.getLineNumber(), fn.getToken(), fn.getFinish(), name, init); + + final Symbol nameSymbol = fn.getBody().getExistingSymbol(name.getName()); + assert nameSymbol != null; + + return synthVar.setName((IdentNode)name.setSymbol(lc, nameSymbol)); + } + @Override public Node leaveCONVERT(final UnaryNode unaryNode) { assert false : "There should be no convert operators in IR during Attribution"; @@ -974,15 +998,18 @@ final class Attr extends NodeOperatorVisitor { } private IdentNode compilerConstant(CompilerConstants cc) { - final FunctionNode functionNode = lc.getCurrentFunction(); - return (IdentNode) - new IdentNode( - functionNode.getToken(), - functionNode.getFinish(), - cc.symbolName()). - setSymbol( - lc, - functionNode.compilerConstant(cc)); + return (IdentNode)createImplicitIdentifier(cc.symbolName()).setSymbol(lc, lc.getCurrentFunction().compilerConstant(cc)); + } + + /** + * Creates an ident node for an implicit identifier within the function (one not declared in the script source + * code). These identifiers are defined with function's token and finish. + * @param name the name of the identifier + * @return an ident node representing the implicit identifier. + */ + private IdentNode createImplicitIdentifier(final String name) { + final FunctionNode fn = lc.getCurrentFunction(); + return new IdentNode(fn.getToken(), fn.getFinish(), name); } @Override diff --git a/src/jdk/nashorn/internal/codegen/CompilerConstants.java b/src/jdk/nashorn/internal/codegen/CompilerConstants.java index 5207fbce..fb347c75 100644 --- a/src/jdk/nashorn/internal/codegen/CompilerConstants.java +++ b/src/jdk/nashorn/internal/codegen/CompilerConstants.java @@ -102,8 +102,12 @@ public enum CompilerConstants { /** the varargs variable when necessary */ VARARGS(":varargs", Object[].class), - /** the arguments vector when necessary and the slot */ - ARGUMENTS("arguments", ScriptObject.class, 2), + /** the arguments variable (visible to function body). Initially set to ARGUMENTS, but can be reassigned by code in + * the function body.*/ + ARGUMENTS_VAR("arguments", Object.class), + + /** the internal arguments object, when necessary (not visible to scripts, can't be reassigned). */ + ARGUMENTS(":arguments", ScriptObject.class), /** prefix for iterators for for (x in ...) */ ITERATOR_PREFIX(":i", Iterator.class), diff --git a/src/jdk/nashorn/internal/parser/Parser.java b/src/jdk/nashorn/internal/parser/Parser.java index ea01f598..d0519171 100644 --- a/src/jdk/nashorn/internal/parser/Parser.java +++ b/src/jdk/nashorn/internal/parser/Parser.java @@ -25,7 +25,6 @@ package jdk.nashorn.internal.parser; -import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL; import static jdk.nashorn.internal.codegen.CompilerConstants.FUNCTION_PREFIX; import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT; @@ -115,6 +114,8 @@ import jdk.nashorn.internal.runtime.Timing; * Builds the IR. */ public class Parser extends AbstractParser { + private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName(); + /** Current script environment. */ private final ScriptEnvironment env; @@ -511,13 +512,19 @@ loop: * @param ident Referenced property. */ private void detectSpecialProperty(final IdentNode ident) { - final String name = ident.getName(); - - if (ARGUMENTS.symbolName().equals(name)) { + if (isArguments(ident)) { lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_ARGUMENTS); } } + private static boolean isArguments(final String name) { + return ARGUMENTS_NAME.equals(name); + } + + private static boolean isArguments(final IdentNode ident) { + return isArguments(ident.getName()); + } + /** * Tells whether a IdentNode can be used as L-value of an assignment * @@ -2449,7 +2456,7 @@ loop: } else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.WARNING) { warning(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here.warn"), functionToken); } - if (ARGUMENTS.symbolName().equals(name.getName())) { + if (isArguments(name)) { lc.setFlag(lc.getCurrentFunction(), FunctionNode.DEFINES_ARGUMENTS); } } @@ -2468,7 +2475,7 @@ loop: final IdentNode parameter = parameters.get(i); String parameterName = parameter.getName(); - if (ARGUMENTS.symbolName().equals(parameterName)) { + if (isArguments(parameterName)) { functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS); } @@ -2486,7 +2493,7 @@ loop: parametersSet.add(parameterName); } } else if (arity == 1) { - if (ARGUMENTS.symbolName().equals(parameters.get(0).getName())) { + if (isArguments(parameters.get(0))) { functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS); } } diff --git a/test/script/basic/JDK-8024846.js b/test/script/basic/JDK-8024846.js new file mode 100644 index 00000000..ccdf8fcc --- /dev/null +++ b/test/script/basic/JDK-8024846.js @@ -0,0 +1,37 @@ +/* + * 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. + * + * 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-8024846: keep separate internal arguments variable + * + * @test + */ + +function f() { print(arguments); } + +function func(obj) { + var arguments = obj; + for (var i in arguments) { + } + return obj; +} -- cgit v1.2.3