Fri, 23 Aug 2013 16:44:02 +0530
Merge
1.1 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Mon Aug 19 19:37:29 2013 +0530 1.2 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Fri Aug 23 16:44:02 2013 +0530 1.3 @@ -55,6 +55,7 @@ 1.4 import javax.script.ScriptEngine; 1.5 import javax.script.ScriptEngineFactory; 1.6 import javax.script.ScriptException; 1.7 +import javax.script.SimpleBindings; 1.8 import jdk.nashorn.internal.runtime.Context; 1.9 import jdk.nashorn.internal.runtime.ErrorManager; 1.10 import jdk.nashorn.internal.runtime.GlobalObject; 1.11 @@ -74,6 +75,12 @@ 1.12 */ 1.13 1.14 public final class NashornScriptEngine extends AbstractScriptEngine implements Compilable, Invocable { 1.15 + /** 1.16 + * Key used to associate Nashorn global object mirror with arbitrary Bindings instance. 1.17 + */ 1.18 + public static final String NASHORN_GLOBAL = "nashorn.global"; 1.19 + 1.20 + // commonly used access control context objects 1.21 private static AccessControlContext createPermAccCtxt(final String permName) { 1.22 final Permissions perms = new Permissions(); 1.23 perms.add(new RuntimePermission(permName)); 1.24 @@ -83,16 +90,23 @@ 1.25 private static final AccessControlContext CREATE_CONTEXT_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_CONTEXT); 1.26 private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_GLOBAL); 1.27 1.28 + // the factory that created this engine 1.29 private final ScriptEngineFactory factory; 1.30 + // underlying nashorn Context - 1:1 with engine instance 1.31 private final Context nashornContext; 1.32 + // do we want to share single Nashorn global instance across ENGINE_SCOPEs? 1.33 + private final boolean _global_per_engine; 1.34 + // This is the initial default Nashorn global object. 1.35 + // This is used as "shared" global if above option is true. 1.36 private final ScriptObject global; 1.37 - // initialized bit late to be made 'final'. Property object for "context" 1.38 - // property of global object 1.39 - private Property contextProperty; 1.40 + // initialized bit late to be made 'final'. 1.41 + // Property object for "context" property of global object. 1.42 + private volatile Property contextProperty; 1.43 1.44 // default options passed to Nashorn Options object 1.45 private static final String[] DEFAULT_OPTIONS = new String[] { "-scripting", "-doe" }; 1.46 1.47 + // Nashorn script engine error message management 1.48 private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages"; 1.49 1.50 private static final ResourceBundle MESSAGES_BUNDLE; 1.51 @@ -100,6 +114,7 @@ 1.52 MESSAGES_BUNDLE = ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault()); 1.53 } 1.54 1.55 + // helper to get Nashorn script engine error message 1.56 private static String getMessage(final String msgId, final String... args) { 1.57 try { 1.58 return new MessageFormat(MESSAGES_BUNDLE.getString(msgId)).format(args); 1.59 @@ -108,6 +123,30 @@ 1.60 } 1.61 } 1.62 1.63 + // load engine.js and return content as a char[] 1.64 + private static char[] loadEngineJSSource() { 1.65 + final String script = "resources/engine.js"; 1.66 + try { 1.67 + final InputStream is = AccessController.doPrivileged( 1.68 + new PrivilegedExceptionAction<InputStream>() { 1.69 + @Override 1.70 + public InputStream run() throws Exception { 1.71 + final URL url = NashornScriptEngine.class.getResource(script); 1.72 + return url.openStream(); 1.73 + } 1.74 + }); 1.75 + return Source.readFully(new InputStreamReader(is)); 1.76 + } catch (final PrivilegedActionException | IOException e) { 1.77 + if (Context.DEBUG) { 1.78 + e.printStackTrace(); 1.79 + } 1.80 + throw new RuntimeException(e); 1.81 + } 1.82 + } 1.83 + 1.84 + // Source object for engine.js 1.85 + private static final Source ENGINE_SCRIPT_SRC = new Source(NashornException.ENGINE_SCRIPT_SOURCE_NAME, loadEngineJSSource()); 1.86 + 1.87 NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) { 1.88 this(factory, DEFAULT_OPTIONS, appLoader); 1.89 } 1.90 @@ -134,20 +173,13 @@ 1.91 } 1.92 }, CREATE_CONTEXT_ACC_CTXT); 1.93 1.94 + // cache this option that is used often 1.95 + this._global_per_engine = nashornContext.getEnv()._global_per_engine; 1.96 + 1.97 // create new global object 1.98 - this.global = createNashornGlobal(); 1.99 - // set the default engine scope for the default context 1.100 + this.global = createNashornGlobal(context); 1.101 + // set the default ENGINE_SCOPE object for the default context 1.102 context.setBindings(new ScriptObjectMirror(global, global), ScriptContext.ENGINE_SCOPE); 1.103 - 1.104 - // evaluate engine initial script 1.105 - try { 1.106 - evalEngineScript(); 1.107 - } catch (final ScriptException e) { 1.108 - if (Context.DEBUG) { 1.109 - e.printStackTrace(); 1.110 - } 1.111 - throw new RuntimeException(e); 1.112 - } 1.113 } 1.114 1.115 @Override 1.116 @@ -176,8 +208,13 @@ 1.117 1.118 @Override 1.119 public Bindings createBindings() { 1.120 - final ScriptObject newGlobal = createNashornGlobal(); 1.121 - return new ScriptObjectMirror(newGlobal, newGlobal); 1.122 + if (_global_per_engine) { 1.123 + // just create normal SimpleBindings. 1.124 + // We use same 'global' for all Bindings. 1.125 + return new SimpleBindings(); 1.126 + } else { 1.127 + return createGlobalMirror(null); 1.128 + } 1.129 } 1.130 1.131 // Compilable methods 1.132 @@ -213,6 +250,48 @@ 1.133 return invokeImpl(thiz, name, args); 1.134 } 1.135 1.136 + @Override 1.137 + public <T> T getInterface(final Class<T> clazz) { 1.138 + return getInterfaceInner(null, clazz); 1.139 + } 1.140 + 1.141 + @Override 1.142 + public <T> T getInterface(final Object thiz, final Class<T> clazz) { 1.143 + if (thiz == null) { 1.144 + throw new IllegalArgumentException(getMessage("thiz.cannot.be.null")); 1.145 + } 1.146 + return getInterfaceInner(thiz, clazz); 1.147 + } 1.148 + 1.149 + // These are called from the "engine.js" script 1.150 + 1.151 + /** 1.152 + * This hook is used to search js global variables exposed from Java code. 1.153 + * 1.154 + * @param self 'this' passed from the script 1.155 + * @param ctxt current ScriptContext in which name is searched 1.156 + * @param name name of the variable searched 1.157 + * @return the value of the named variable 1.158 + */ 1.159 + public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) { 1.160 + if (ctxt != null) { 1.161 + final int scope = ctxt.getAttributesScope(name); 1.162 + final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt); 1.163 + if (scope != -1) { 1.164 + return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal); 1.165 + } 1.166 + 1.167 + if (self == UNDEFINED) { 1.168 + // scope access and so throw ReferenceError 1.169 + throw referenceError(ctxtGlobal, "not.defined", name); 1.170 + } 1.171 + } 1.172 + 1.173 + return UNDEFINED; 1.174 + } 1.175 + 1.176 + // Implementation only below this point 1.177 + 1.178 private <T> T getInterfaceInner(final Object thiz, final Class<T> clazz) { 1.179 if (clazz == null || !clazz.isInterface()) { 1.180 throw new IllegalArgumentException(getMessage("interface.class.expected")); 1.181 @@ -280,58 +359,56 @@ 1.182 } 1.183 } 1.184 1.185 - @Override 1.186 - public <T> T getInterface(final Class<T> clazz) { 1.187 - return getInterfaceInner(null, clazz); 1.188 + // Retrieve nashorn Global object for a given ScriptContext object 1.189 + private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) { 1.190 + if (_global_per_engine) { 1.191 + // shared single global object for all ENGINE_SCOPE Bindings 1.192 + return global; 1.193 + } 1.194 + 1.195 + final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE); 1.196 + // is this Nashorn's own Bindings implementation? 1.197 + if (bindings instanceof ScriptObjectMirror) { 1.198 + final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)bindings); 1.199 + if (sobj != null) { 1.200 + return sobj; 1.201 + } 1.202 + } 1.203 + 1.204 + // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it! 1.205 + Object scope = bindings.get(NASHORN_GLOBAL); 1.206 + if (scope instanceof ScriptObjectMirror) { 1.207 + final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)scope); 1.208 + if (sobj != null) { 1.209 + return sobj; 1.210 + } 1.211 + } 1.212 + 1.213 + // We didn't find associated nashorn global mirror in the Bindings given! 1.214 + // Create new global instance mirror and associate with the Bindings. 1.215 + final ScriptObjectMirror mirror = createGlobalMirror(ctxt); 1.216 + bindings.put(NASHORN_GLOBAL, mirror); 1.217 + return mirror.getScriptObject(); 1.218 } 1.219 1.220 - @Override 1.221 - public <T> T getInterface(final Object thiz, final Class<T> clazz) { 1.222 - if (thiz == null) { 1.223 - throw new IllegalArgumentException(getMessage("thiz.cannot.be.null")); 1.224 + // Retrieve nashorn Global object from a given ScriptObjectMirror 1.225 + private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) { 1.226 + ScriptObject sobj = mirror.getScriptObject(); 1.227 + if (sobj instanceof GlobalObject && sobj.isOfContext(nashornContext)) { 1.228 + return sobj; 1.229 } 1.230 - return getInterfaceInner(thiz, clazz); 1.231 + 1.232 + return null; 1.233 } 1.234 1.235 - // These are called from the "engine.js" script 1.236 - 1.237 - /** 1.238 - * This hook is used to search js global variables exposed from Java code. 1.239 - * 1.240 - * @param self 'this' passed from the script 1.241 - * @param ctxt current ScriptContext in which name is searched 1.242 - * @param name name of the variable searched 1.243 - * @return the value of the named variable 1.244 - */ 1.245 - public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) { 1.246 - final int scope = ctxt.getAttributesScope(name); 1.247 - final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt); 1.248 - if (scope != -1) { 1.249 - return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal); 1.250 - } 1.251 - 1.252 - if (self == UNDEFINED) { 1.253 - // scope access and so throw ReferenceError 1.254 - throw referenceError(ctxtGlobal, "not.defined", name); 1.255 - } 1.256 - 1.257 - return UNDEFINED; 1.258 + // Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object 1.259 + private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) { 1.260 + final ScriptObject newGlobal = createNashornGlobal(ctxt); 1.261 + return new ScriptObjectMirror(newGlobal, newGlobal); 1.262 } 1.263 1.264 - private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) { 1.265 - final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE); 1.266 - if (bindings instanceof ScriptObjectMirror) { 1.267 - ScriptObject sobj = ((ScriptObjectMirror)bindings).getScriptObject(); 1.268 - if (sobj instanceof GlobalObject) { 1.269 - return sobj; 1.270 - } 1.271 - } 1.272 - 1.273 - // didn't find global object from context given - return the engine-wide global 1.274 - return global; 1.275 - } 1.276 - 1.277 - private ScriptObject createNashornGlobal() { 1.278 + // Create a new Nashorn Global object 1.279 + private ScriptObject createNashornGlobal(final ScriptContext ctxt) { 1.280 final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() { 1.281 @Override 1.282 public ScriptObject run() { 1.283 @@ -352,7 +429,7 @@ 1.284 // current ScriptContext exposed as "context" 1.285 // "context" is non-writable from script - but script engine still 1.286 // needs to set it and so save the context Property object 1.287 - contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, UNDEFINED); 1.288 + contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, null); 1.289 // current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as 1.290 // NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property 1.291 // in the Global of a Context we just created - both the Context and the Global were just created and can not be 1.292 @@ -362,38 +439,17 @@ 1.293 newGlobal.addOwnProperty("arguments", Property.NOT_ENUMERABLE, UNDEFINED); 1.294 // file name default is null 1.295 newGlobal.addOwnProperty(ScriptEngine.FILENAME, Property.NOT_ENUMERABLE, null); 1.296 + // evaluate engine.js initialization script this new global object 1.297 + try { 1.298 + evalImpl(compileImpl(ENGINE_SCRIPT_SRC, newGlobal), ctxt, newGlobal); 1.299 + } catch (final ScriptException exp) { 1.300 + throw new RuntimeException(exp); 1.301 + } 1.302 return newGlobal; 1.303 } 1.304 1.305 - private void evalEngineScript() throws ScriptException { 1.306 - final String script = "resources/engine.js"; 1.307 - final String name = NashornException.ENGINE_SCRIPT_SOURCE_NAME; 1.308 - try { 1.309 - final InputStream is = AccessController.doPrivileged( 1.310 - new PrivilegedExceptionAction<InputStream>() { 1.311 - @Override 1.312 - public InputStream run() throws Exception { 1.313 - final URL url = NashornScriptEngine.class.getResource(script); 1.314 - return url.openStream(); 1.315 - } 1.316 - }); 1.317 - put(ScriptEngine.FILENAME, name); 1.318 - try (final InputStreamReader isr = new InputStreamReader(is)) { 1.319 - eval(isr); 1.320 - } 1.321 - } catch (final PrivilegedActionException | IOException e) { 1.322 - if (Context.DEBUG) { 1.323 - e.printStackTrace(); 1.324 - } 1.325 - throw new ScriptException(e); 1.326 - } finally { 1.327 - put(ScriptEngine.FILENAME, null); 1.328 - } 1.329 - } 1.330 - 1.331 - // scripts should see "context" and "engine" as variables 1.332 - private void setContextVariables(final ScriptContext ctxt) { 1.333 - final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt); 1.334 + // scripts should see "context" and "engine" as variables in the given global object 1.335 + private void setContextVariables(final ScriptObject ctxtGlobal, final ScriptContext ctxt) { 1.336 // set "context" global variable via contextProperty - because this 1.337 // property is non-writable 1.338 contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false); 1.339 @@ -402,8 +458,10 @@ 1.340 args = ScriptRuntime.EMPTY_ARRAY; 1.341 } 1.342 // if no arguments passed, expose it 1.343 - args = ((GlobalObject)ctxtGlobal).wrapAsObject(args); 1.344 - ctxtGlobal.set("arguments", args, false); 1.345 + if (! (args instanceof ScriptObject)) { 1.346 + args = ((GlobalObject)ctxtGlobal).wrapAsObject(args); 1.347 + ctxtGlobal.set("arguments", args, false); 1.348 + } 1.349 } 1.350 1.351 private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException { 1.352 @@ -456,18 +514,24 @@ 1.353 } 1.354 1.355 private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException { 1.356 + return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt)); 1.357 + } 1.358 + 1.359 + private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final ScriptObject ctxtGlobal) throws ScriptException { 1.360 if (script == null) { 1.361 return null; 1.362 } 1.363 final ScriptObject oldGlobal = Context.getGlobal(); 1.364 - final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt); 1.365 final boolean globalChanged = (oldGlobal != ctxtGlobal); 1.366 try { 1.367 if (globalChanged) { 1.368 Context.setGlobal(ctxtGlobal); 1.369 } 1.370 1.371 - setContextVariables(ctxt); 1.372 + // set ScriptContext variables if ctxt is non-null 1.373 + if (ctxt != null) { 1.374 + setContextVariables(ctxtGlobal, ctxt); 1.375 + } 1.376 return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal)); 1.377 } catch (final Exception e) { 1.378 throwAsScriptException(e); 1.379 @@ -517,15 +581,18 @@ 1.380 } 1.381 1.382 private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException { 1.383 + return compileImpl(source, getNashornGlobalFrom(ctxt)); 1.384 + } 1.385 + 1.386 + private ScriptFunction compileImpl(final Source source, final ScriptObject newGlobal) throws ScriptException { 1.387 final ScriptObject oldGlobal = Context.getGlobal(); 1.388 - final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt); 1.389 - final boolean globalChanged = (oldGlobal != ctxtGlobal); 1.390 + final boolean globalChanged = (oldGlobal != newGlobal); 1.391 try { 1.392 if (globalChanged) { 1.393 - Context.setGlobal(ctxtGlobal); 1.394 + Context.setGlobal(newGlobal); 1.395 } 1.396 1.397 - return nashornContext.compileScript(source, ctxtGlobal); 1.398 + return nashornContext.compileScript(source, newGlobal); 1.399 } catch (final Exception e) { 1.400 throwAsScriptException(e); 1.401 throw new AssertionError("should not reach here");
2.1 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Mon Aug 19 19:37:29 2013 +0530 2.2 +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Fri Aug 23 16:44:02 2013 +0530 2.3 @@ -99,12 +99,14 @@ 2.4 } 2.5 2.6 final Object val = functionName == null? sobj : sobj.get(functionName); 2.7 - if (! (val instanceof ScriptFunction)) { 2.8 - throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : "")); 2.9 + if (val instanceof ScriptFunction) { 2.10 + final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; 2.11 + return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); 2.12 + } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { 2.13 + return ((ScriptObjectMirror)val).call(null, args); 2.14 } 2.15 2.16 - final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; 2.17 - return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); 2.18 + throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : "")); 2.19 } catch (final RuntimeException | Error e) { 2.20 throw e; 2.21 } catch (final Throwable t) { 2.22 @@ -127,12 +129,14 @@ 2.23 } 2.24 2.25 final Object val = functionName == null? sobj : sobj.get(functionName); 2.26 - if (! (val instanceof ScriptFunction)) { 2.27 - throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : "")); 2.28 + if (val instanceof ScriptFunction) { 2.29 + final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; 2.30 + return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global); 2.31 + } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { 2.32 + return ((ScriptObjectMirror)val).newObject(null, args); 2.33 } 2.34 2.35 - final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; 2.36 - return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global); 2.37 + throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : "")); 2.38 } catch (final RuntimeException | Error e) { 2.39 throw e; 2.40 } catch (final Throwable t) { 2.41 @@ -374,6 +378,19 @@ 2.42 } 2.43 2.44 /** 2.45 + * Set the __proto__ of this object. 2.46 + * @param proto new proto for this object 2.47 + */ 2.48 + public void setProto(final Object proto) { 2.49 + inGlobal(new Callable<Void>() { 2.50 + @Override public Void call() { 2.51 + sobj.setProtoCheck(unwrap(proto, global)); 2.52 + return null; 2.53 + } 2.54 + }); 2.55 + } 2.56 + 2.57 + /** 2.58 * ECMA 8.12.1 [[GetOwnProperty]] (P) 2.59 * 2.60 * @param key property key
3.1 --- a/src/jdk/nashorn/api/scripting/resources/engine.js Mon Aug 19 19:37:29 2013 +0530 3.2 +++ b/src/jdk/nashorn/api/scripting/resources/engine.js Fri Aug 23 16:44:02 2013 +0530 3.3 @@ -23,10 +23,9 @@ 3.4 3.5 /** 3.6 * This script file is executed by script engine at the construction 3.7 - * of the engine. The functions here assume global variables "context" 3.8 - * of type javax.script.ScriptContext and "engine" of the type 3.9 + * of the every new Global object. The functions here assume global variables 3.10 + * "context" of type javax.script.ScriptContext and "engine" of the type 3.11 * jdk.nashorn.api.scripting.NashornScriptEngine. 3.12 - * 3.13 **/ 3.14 3.15 Object.defineProperty(this, "__noSuchProperty__", { 3.16 @@ -40,7 +39,7 @@ 3.17 }); 3.18 3.19 function print() { 3.20 - var writer = context.getWriter(); 3.21 + var writer = context != null? context.writer : engine.context.writer; 3.22 if (! (writer instanceof java.io.PrintWriter)) { 3.23 writer = new java.io.PrintWriter(writer); 3.24 }
4.1 --- a/src/jdk/nashorn/internal/codegen/Attr.java Mon Aug 19 19:37:29 2013 +0530 4.2 +++ b/src/jdk/nashorn/internal/codegen/Attr.java Fri Aug 23 16:44:02 2013 +0530 4.3 @@ -543,8 +543,6 @@ 4.4 public Node leaveIdentNode(final IdentNode identNode) { 4.5 final String name = identNode.getName(); 4.6 4.7 - start(identNode); 4.8 - 4.9 if (identNode.isPropertyName()) { 4.10 // assign a pseudo symbol to property name 4.11 final Symbol pseudoSymbol = pseudoSymbol(name); 4.12 @@ -1850,9 +1848,10 @@ 4.13 append("] "). 4.14 append(printNode ? node.toString() : ""). 4.15 append(" in '"). 4.16 - append(lc.getCurrentFunction().getName()); 4.17 + append(lc.getCurrentFunction().getName()). 4.18 + append('\''); 4.19 4.20 - if(node instanceof Expression) { 4.21 + if (node instanceof Expression) { 4.22 final Symbol symbol = ((Expression)node).getSymbol(); 4.23 if (symbol == null) { 4.24 sb.append(" <NO SYMBOL>");
5.1 --- a/src/jdk/nashorn/internal/objects/NativeJava.java Mon Aug 19 19:37:29 2013 +0530 5.2 +++ b/src/jdk/nashorn/internal/objects/NativeJava.java Fri Aug 23 16:44:02 2013 +0530 5.3 @@ -32,7 +32,6 @@ 5.4 import java.util.Collection; 5.5 import java.util.Deque; 5.6 import java.util.List; 5.7 - 5.8 import jdk.internal.dynalink.beans.StaticClass; 5.9 import jdk.internal.dynalink.support.TypeUtilities; 5.10 import jdk.nashorn.internal.objects.annotations.Attribute; 5.11 @@ -44,6 +43,7 @@ 5.12 import jdk.nashorn.internal.runtime.ListAdapter; 5.13 import jdk.nashorn.internal.runtime.PropertyMap; 5.14 import jdk.nashorn.internal.runtime.ScriptObject; 5.15 +import jdk.nashorn.internal.runtime.linker.Bootstrap; 5.16 import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory; 5.17 5.18 /** 5.19 @@ -539,4 +539,25 @@ 5.20 } 5.21 return JavaAdapterFactory.getAdapterClassFor(stypes, classOverrides); 5.22 } 5.23 + 5.24 + /** 5.25 + * When given an object created using {@code Java.extend()} or equivalent mechanism (that is, any JavaScript-to-Java 5.26 + * adapter), returns an object that can be used to invoke superclass methods on that object. E.g.: 5.27 + * <pre> 5.28 + * var cw = new FilterWriterAdapter(sw) { 5.29 + * write: function(s, off, len) { 5.30 + * s = capitalize(s, off, len) 5.31 + * cw_super.write(s, 0, s.length()) 5.32 + * } 5.33 + * } 5.34 + * var cw_super = Java.super(cw) 5.35 + * </pre> 5.36 + * @param self the {@code Java} object itself - not used. 5.37 + * @param adapter the original Java adapter instance for which the super adapter is created. 5.38 + * @return a super adapter for the original adapter 5.39 + */ 5.40 + @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR, name="super") 5.41 + public static Object _super(final Object self, final Object adapter) { 5.42 + return Bootstrap.createSuperAdapter(adapter); 5.43 + } 5.44 }
6.1 --- a/src/jdk/nashorn/internal/objects/NativeObject.java Mon Aug 19 19:37:29 2013 +0530 6.2 +++ b/src/jdk/nashorn/internal/objects/NativeObject.java Fri Aug 23 16:44:02 2013 +0530 6.3 @@ -125,6 +125,28 @@ 6.4 } 6.5 6.6 /** 6.7 + * Nashorn extension: Object.setPrototypeOf ( O, proto ) 6.8 + * Also found in ES6 draft specification. 6.9 + * 6.10 + * @param self self reference 6.11 + * @param obj object to set prototype for 6.12 + * @param proto prototype object to be used 6.13 + * @return object whose prototype is set 6.14 + */ 6.15 + @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 6.16 + public static Object setPrototypeOf(final Object self, final Object obj, final Object proto) { 6.17 + if (obj instanceof ScriptObject) { 6.18 + ((ScriptObject)obj).setProtoCheck(proto); 6.19 + return obj; 6.20 + } else if (obj instanceof ScriptObjectMirror) { 6.21 + ((ScriptObjectMirror)obj).setProto(proto); 6.22 + return obj; 6.23 + } 6.24 + 6.25 + throw notAnObject(obj); 6.26 + } 6.27 + 6.28 + /** 6.29 * ECMA 15.2.3.3 Object.getOwnPropertyDescriptor ( O, P ) 6.30 * 6.31 * @param self self reference 6.32 @@ -184,7 +206,7 @@ 6.33 // FIXME: should we create a proper object with correct number of 6.34 // properties? 6.35 final ScriptObject newObj = Global.newEmptyInstance(); 6.36 - newObj.setProtoCheck(proto); 6.37 + newObj.setProto((ScriptObject)proto); 6.38 if (props != UNDEFINED) { 6.39 NativeObject.defineProperties(self, newObj, props); 6.40 }
7.1 --- a/src/jdk/nashorn/internal/runtime/Context.java Mon Aug 19 19:37:29 2013 +0530 7.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java Fri Aug 23 16:44:02 2013 +0530 7.3 @@ -91,6 +91,11 @@ 7.4 */ 7.5 public static final String NASHORN_JAVA_REFLECTION = "nashorn.JavaReflection"; 7.6 7.7 + /* Force DebuggerSupport to be loaded. */ 7.8 + static { 7.9 + DebuggerSupport.FORCELOAD = true; 7.10 + } 7.11 + 7.12 /** 7.13 * ContextCodeInstaller that has the privilege of installing classes in the Context. 7.14 * Can only be instantiated from inside the context and is opaque to other classes
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/jdk/nashorn/internal/runtime/DebuggerSupport.java Fri Aug 23 16:44:02 2013 +0530 8.3 @@ -0,0 +1,310 @@ 8.4 +/* 8.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General License version 2 only, as 8.10 + * published by the Free Software Foundation. Oracle designates this 8.11 + * particular file as subject to the "Classpath" exception as provided 8.12 + * by Oracle in the LICENSE file that accompanied this code. 8.13 + * 8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General License 8.17 + * version 2 for more details (a copy is included in the LICENSE file that 8.18 + * accompanied this code). 8.19 + * 8.20 + * You should have received a copy of the GNU General License version 8.21 + * 2 along with this work; if not, write to the Free Software Foundation, 8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.23 + * 8.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.25 + * or visit www.oracle.com if you need additional information or have any 8.26 + * questions. 8.27 + */ 8.28 + 8.29 +package jdk.nashorn.internal.runtime; 8.30 + 8.31 +import java.util.HashSet; 8.32 +import java.util.Set; 8.33 + 8.34 +/** 8.35 + * This class provides support for external debuggers. Its primary purpose is 8.36 + * is to simplify the debugger tasks and provide better performance. 8.37 + */ 8.38 +final class DebuggerSupport { 8.39 + /** 8.40 + * Hook to force the loading of the DebuggerSupport class so that it is 8.41 + * available to external debuggers. 8.42 + */ 8.43 + static boolean FORCELOAD = true; 8.44 + 8.45 + static { 8.46 + /** 8.47 + * Hook to force the loading of the DebuggerValueDesc class so that it is 8.48 + * available to external debuggers. 8.49 + */ 8.50 + DebuggerValueDesc forceLoad = new DebuggerValueDesc(null, false, null, null); 8.51 + } 8.52 + 8.53 + /** This class is used to send a bulk description of a value. */ 8.54 + static class DebuggerValueDesc { 8.55 + /** Property key (or index) or field name. */ 8.56 + final String key; 8.57 + 8.58 + /** If the value is expandable. */ 8.59 + final boolean expandable; 8.60 + 8.61 + /** Property or field value as object. */ 8.62 + final Object valueAsObject; 8.63 + 8.64 + /** Property or field value as string. */ 8.65 + final String valueAsString; 8.66 + 8.67 + DebuggerValueDesc(final String key, final boolean expandable, final Object valueAsObject, final String valueAsString) { 8.68 + this.key = key; 8.69 + this.expandable = expandable; 8.70 + this.valueAsObject = valueAsObject; 8.71 + this.valueAsString = valueAsString; 8.72 + } 8.73 + } 8.74 + 8.75 + /** 8.76 + * Return the current context global. 8.77 + * @return context global. 8.78 + */ 8.79 + static Object getGlobal() { 8.80 + return Context.getGlobalTrusted(); 8.81 + } 8.82 + 8.83 + /** 8.84 + * This method returns a bulk description of an object's properties. 8.85 + * @param object Script object to be displayed by the debugger. 8.86 + * @param all true if to include non-enumerable values. 8.87 + * @return An array of DebuggerValueDesc. 8.88 + */ 8.89 + static DebuggerValueDesc[] valueInfos(final Object object, final boolean all) { 8.90 + assert object instanceof ScriptObject; 8.91 + return getDebuggerValueDescs((ScriptObject)object, all, new HashSet<>()); 8.92 + } 8.93 + 8.94 + /** 8.95 + * This method returns a debugger description of the value. 8.96 + * @param name Name of value (property name). 8.97 + * @param value Data value. 8.98 + * @param all true if to include non-enumerable values. 8.99 + * @return A DebuggerValueDesc. 8.100 + */ 8.101 + static DebuggerValueDesc valueInfo(final String name, final Object value, final boolean all) { 8.102 + return valueInfo(name, value, all, new HashSet<>()); 8.103 + } 8.104 + 8.105 + /** 8.106 + * This method returns a debugger description of the value. 8.107 + * @param name Name of value (property name). 8.108 + * @param value Data value. 8.109 + * @param all true if to include non-enumerable values. 8.110 + * @param duplicates Duplication set to avoid cycles. 8.111 + * @return A DebuggerValueDesc. 8.112 + */ 8.113 + private static DebuggerValueDesc valueInfo(final String name, final Object value, final boolean all, final Set<Object> duplicates) { 8.114 + if (value instanceof ScriptObject && !(value instanceof ScriptFunction)) { 8.115 + final ScriptObject object = (ScriptObject)value; 8.116 + return new DebuggerValueDesc(name, !object.isEmpty(), value, objectAsString(object, all, duplicates)); 8.117 + } else { 8.118 + return new DebuggerValueDesc(name, false, value, valueAsString(value)); 8.119 + } 8.120 + } 8.121 + 8.122 + /** 8.123 + * Generate the descriptions for an object's properties. 8.124 + * @param object Object to introspect. 8.125 + * @param all true if to include non-enumerable values. 8.126 + * @param duplicates Duplication set to avoid cycles. 8.127 + * @return An array of DebuggerValueDesc. 8.128 + */ 8.129 + private static DebuggerValueDesc[] getDebuggerValueDescs(final ScriptObject object, final boolean all, final Set<Object> duplicates) { 8.130 + if (duplicates.contains(object)) { 8.131 + return null; 8.132 + } 8.133 + 8.134 + duplicates.add(object); 8.135 + 8.136 + final String[] keys = object.getOwnKeys(all); 8.137 + final DebuggerValueDesc[] descs = new DebuggerValueDesc[keys.length]; 8.138 + 8.139 + for (int i = 0; i < keys.length; i++) { 8.140 + final String key = keys[i]; 8.141 + descs[i] = valueInfo(key, object.get(key), true, duplicates); 8.142 + } 8.143 + 8.144 + duplicates.remove(object); 8.145 + 8.146 + return descs; 8.147 + } 8.148 + 8.149 + /** 8.150 + * Generate a string representation of a Script object. 8.151 + * @param object Script object to represent. 8.152 + * @param all true if to include non-enumerable values. 8.153 + * @param duplicates Duplication set to avoid cycles. 8.154 + * @return String representation. 8.155 + */ 8.156 + private static String objectAsString(final ScriptObject object, final boolean all, final Set<Object> duplicates) { 8.157 + final StringBuilder sb = new StringBuilder(); 8.158 + 8.159 + if (ScriptObject.isArray(object)) { 8.160 + sb.append('['); 8.161 + final long length = object.getLong("length"); 8.162 + 8.163 + for (long i = 0; i < length; i++) { 8.164 + if (object.has(i)) { 8.165 + final Object valueAsObject = object.get(i); 8.166 + final boolean isUndefined = JSType.of(valueAsObject) == JSType.UNDEFINED; 8.167 + 8.168 + if (isUndefined) { 8.169 + if (i != 0) { 8.170 + sb.append(","); 8.171 + } 8.172 + } else { 8.173 + if (i != 0) { 8.174 + sb.append(", "); 8.175 + } 8.176 + 8.177 + if (valueAsObject instanceof ScriptObject && !(valueAsObject instanceof ScriptFunction)) { 8.178 + final String objectString = objectAsString((ScriptObject)valueAsObject, true, duplicates); 8.179 + sb.append(objectString != null ? objectString : "{...}"); 8.180 + } else { 8.181 + sb.append(valueAsString(valueAsObject)); 8.182 + } 8.183 + } 8.184 + } else { 8.185 + if (i != 0) { 8.186 + sb.append(','); 8.187 + } 8.188 + } 8.189 + } 8.190 + 8.191 + sb.append(']'); 8.192 + } else { 8.193 + sb.append('{'); 8.194 + final DebuggerValueDesc[] descs = getDebuggerValueDescs(object, all, duplicates); 8.195 + 8.196 + if (descs != null) { 8.197 + for (int i = 0; i < descs.length; i++) { 8.198 + if (i != 0) { 8.199 + sb.append(", "); 8.200 + } 8.201 + 8.202 + final String valueAsString = descs[i].valueAsString; 8.203 + sb.append(descs[i].key); 8.204 + sb.append(": "); 8.205 + sb.append(descs[i].valueAsString); 8.206 + } 8.207 + } 8.208 + 8.209 + sb.append('}'); 8.210 + } 8.211 + 8.212 + return sb.toString(); 8.213 + } 8.214 + 8.215 + /** 8.216 + * This method returns a string representation of a value. 8.217 + * @param value Arbitrary value to be displayed by the debugger. 8.218 + * @return A string representation of the value or an array of DebuggerValueDesc. 8.219 + */ 8.220 + private static String valueAsString(final Object value) { 8.221 + final JSType type = JSType.of(value); 8.222 + 8.223 + switch (type) { 8.224 + case BOOLEAN: 8.225 + return value.toString(); 8.226 + 8.227 + case STRING: 8.228 + return escape((String)value); 8.229 + 8.230 + case NUMBER: 8.231 + return JSType.toString(((Number)value).doubleValue()); 8.232 + 8.233 + case NULL: 8.234 + return "null"; 8.235 + 8.236 + case UNDEFINED: 8.237 + return "undefined"; 8.238 + 8.239 + case OBJECT: 8.240 + return ScriptRuntime.safeToString(value); 8.241 + 8.242 + case FUNCTION: 8.243 + if (value instanceof ScriptFunction) { 8.244 + return ((ScriptFunction)value).toSource(); 8.245 + } else { 8.246 + return value.toString(); 8.247 + } 8.248 + 8.249 + default: 8.250 + return value.toString(); 8.251 + } 8.252 + } 8.253 + 8.254 + /** 8.255 + * Escape a string into a form that can be parsed by JavaScript. 8.256 + * @param value String to be escaped. 8.257 + * @return Escaped string. 8.258 + */ 8.259 + private static String escape(final String value) { 8.260 + final StringBuilder sb = new StringBuilder(); 8.261 + 8.262 + sb.append("\""); 8.263 + 8.264 + for (final char ch : value.toCharArray()) { 8.265 + switch (ch) { 8.266 + case '\\': 8.267 + sb.append("\\\\"); 8.268 + break; 8.269 + case '"': 8.270 + sb.append("\\\""); 8.271 + break; 8.272 + case '\'': 8.273 + sb.append("\\\'"); 8.274 + break; 8.275 + case '\b': 8.276 + sb.append("\\b"); 8.277 + break; 8.278 + case '\f': 8.279 + sb.append("\\f"); 8.280 + break; 8.281 + case '\n': 8.282 + sb.append("\\n"); 8.283 + break; 8.284 + case '\r': 8.285 + sb.append("\\r"); 8.286 + break; 8.287 + case '\t': 8.288 + sb.append("\\t"); 8.289 + break; 8.290 + default: 8.291 + if (ch < ' ' || ch >= 0xFF) { 8.292 + sb.append("\\u"); 8.293 + 8.294 + final String hex = Integer.toHexString(ch); 8.295 + for (int i = hex.length(); i < 4; i++) { 8.296 + sb.append('0'); 8.297 + } 8.298 + sb.append(hex); 8.299 + } else { 8.300 + sb.append(ch); 8.301 + } 8.302 + 8.303 + break; 8.304 + } 8.305 + } 8.306 + 8.307 + sb.append("\""); 8.308 + 8.309 + return sb.toString(); 8.310 + } 8.311 +} 8.312 + 8.313 +
9.1 --- a/src/jdk/nashorn/internal/runtime/JSType.java Mon Aug 19 19:37:29 2013 +0530 9.2 +++ b/src/jdk/nashorn/internal/runtime/JSType.java Fri Aug 23 16:44:02 2013 +0530 9.3 @@ -30,11 +30,10 @@ 9.4 9.5 import java.lang.invoke.MethodHandles; 9.6 import java.util.Locale; 9.7 -import jdk.internal.dynalink.beans.BeansLinker; 9.8 import jdk.internal.dynalink.beans.StaticClass; 9.9 -import jdk.nashorn.api.scripting.ScriptObjectMirror; 9.10 import jdk.nashorn.internal.codegen.CompilerConstants.Call; 9.11 import jdk.nashorn.internal.parser.Lexer; 9.12 +import jdk.nashorn.internal.runtime.linker.Bootstrap; 9.13 9.14 /** 9.15 * Representation for ECMAScript types - this maps directly to the ECMA script standard 9.16 @@ -148,22 +147,10 @@ 9.17 return JSType.STRING; 9.18 } 9.19 9.20 - if (obj instanceof ScriptObject) { 9.21 - return (obj instanceof ScriptFunction) ? JSType.FUNCTION : JSType.OBJECT; 9.22 - } 9.23 - 9.24 - if (obj instanceof StaticClass) { 9.25 + if (Bootstrap.isCallable(obj)) { 9.26 return JSType.FUNCTION; 9.27 } 9.28 9.29 - if (BeansLinker.isDynamicMethod(obj)) { 9.30 - return JSType.FUNCTION; 9.31 - } 9.32 - 9.33 - if (obj instanceof ScriptObjectMirror) { 9.34 - return ((ScriptObjectMirror)obj).isFunction()? JSType.FUNCTION : JSType.OBJECT; 9.35 - } 9.36 - 9.37 return JSType.OBJECT; 9.38 } 9.39
10.1 --- a/src/jdk/nashorn/internal/runtime/PropertyListener.java Mon Aug 19 19:37:29 2013 +0530 10.2 +++ b/src/jdk/nashorn/internal/runtime/PropertyListener.java Fri Aug 23 16:44:02 2013 +0530 10.3 @@ -54,4 +54,13 @@ 10.4 * 10.5 */ 10.6 public void propertyModified(ScriptObject object, Property oldProp, Property newProp); 10.7 + 10.8 + /** 10.9 + * Given object's __proto__ has changed. 10.10 + * 10.11 + * @param object object whose __proto__ has changed. 10.12 + * @param oldProto old __proto__ 10.13 + * @param newProto new __proto__ 10.14 + */ 10.15 + public void protoChanged(ScriptObject object, ScriptObject oldProto, ScriptObject newProto); 10.16 }
11.1 --- a/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java Mon Aug 19 19:37:29 2013 +0530 11.2 +++ b/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java Fri Aug 23 16:44:02 2013 +0530 11.3 @@ -140,6 +140,21 @@ 11.4 } 11.5 } 11.6 11.7 + /** 11.8 + * This method can be called to notify __proto__ modification to this object's listeners. 11.9 + * 11.10 + * @param object The ScriptObject whose __proto__ was changed. 11.11 + * @param oldProto old __proto__ 11.12 + * @param newProto new __proto__ 11.13 + */ 11.14 + protected synchronized final void notifyProtoChanged(final ScriptObject object, final ScriptObject oldProto, final ScriptObject newProto) { 11.15 + if (listeners != null) { 11.16 + for (PropertyListener listener : listeners.keySet()) { 11.17 + listener.protoChanged(object, oldProto, newProto); 11.18 + } 11.19 + } 11.20 + } 11.21 + 11.22 // PropertyListener methods 11.23 11.24 @Override 11.25 @@ -156,4 +171,9 @@ 11.26 public final void propertyModified(final ScriptObject object, final Property oldProp, final Property newProp) { 11.27 notifyPropertyModified(object, oldProp, newProp); 11.28 } 11.29 + 11.30 + @Override 11.31 + public final void protoChanged(final ScriptObject object, final ScriptObject oldProto, final ScriptObject newProto) { 11.32 + notifyProtoChanged(object, oldProto, newProto); 11.33 + } 11.34 }
12.1 --- a/src/jdk/nashorn/internal/runtime/PropertyMap.java Mon Aug 19 19:37:29 2013 +0530 12.2 +++ b/src/jdk/nashorn/internal/runtime/PropertyMap.java Fri Aug 23 16:44:02 2013 +0530 12.3 @@ -230,7 +230,7 @@ 12.4 } 12.5 12.6 /** 12.7 - * Indicate that a prototype property hash changed. 12.8 + * Indicate that a prototype property has changed. 12.9 * 12.10 * @param property {@link Property} to invalidate. 12.11 */ 12.12 @@ -251,6 +251,18 @@ 12.13 } 12.14 12.15 /** 12.16 + * Indicate that proto itself has changed in hierachy somewhere. 12.17 + */ 12.18 + private void invalidateAllProtoGetSwitchPoints() { 12.19 + assert !isShared() : "proto invalidation on a shared PropertyMap"; 12.20 + 12.21 + if (protoGetSwitches != null) { 12.22 + final Collection<SwitchPoint> sws = protoGetSwitches.values(); 12.23 + SwitchPoint.invalidateAll(sws.toArray(new SwitchPoint[sws.size()])); 12.24 + } 12.25 + } 12.26 + 12.27 + /** 12.28 * Add a property to the map, re-binding its getters and setters, 12.29 * if available, to a given receiver. This is typically the global scope. See 12.30 * {@link ScriptObject#addBoundProperties(ScriptObject)} 12.31 @@ -878,6 +890,15 @@ 12.32 invalidateProtoGetSwitchPoint(oldProp); 12.33 } 12.34 12.35 + @Override 12.36 + public void protoChanged(final ScriptObject object, final ScriptObject oldProto, final ScriptObject newProto) { 12.37 + // We may walk and invalidate SwitchPoints for properties inherited 12.38 + // from 'object' or it's old proto chain. But, it may not be worth it. 12.39 + // For example, a new proto may have a user defined getter/setter for 12.40 + // a data property down the chain. So, invalidating all is better. 12.41 + invalidateAllProtoGetSwitchPoints(); 12.42 + } 12.43 + 12.44 /* 12.45 * Debugging and statistics. 12.46 */
13.1 --- a/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Mon Aug 19 19:37:29 2013 +0530 13.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Fri Aug 23 16:44:02 2013 +0530 13.3 @@ -86,6 +86,9 @@ 13.4 /** Launch using as fx application */ 13.5 public final boolean _fx; 13.6 13.7 + /** Use single Global instance per jsr223 engine instance. */ 13.8 + public final boolean _global_per_engine; 13.9 + 13.10 /** 13.11 * Behavior when encountering a function declaration in a lexical context where only statements are acceptable 13.12 * (function declarations are source elements, but not statements). 13.13 @@ -128,9 +131,6 @@ 13.14 /** Do not support typed arrays. */ 13.15 public final boolean _no_typed_arrays; 13.16 13.17 - /** Package to which generated class files are added */ 13.18 - public final String _package; 13.19 - 13.20 /** Only parse the source code, do not compile */ 13.21 public final boolean _parse_only; 13.22 13.23 @@ -211,12 +211,12 @@ 13.24 _function_statement = FunctionStatementBehavior.ACCEPT; 13.25 } 13.26 _fx = options.getBoolean("fx"); 13.27 + _global_per_engine = options.getBoolean("global.per.engine"); 13.28 _lazy_compilation = options.getBoolean("lazy.compilation"); 13.29 _loader_per_compile = options.getBoolean("loader.per.compile"); 13.30 _no_java = options.getBoolean("no.java"); 13.31 _no_syntax_extensions = options.getBoolean("no.syntax.extensions"); 13.32 _no_typed_arrays = options.getBoolean("no.typed.arrays"); 13.33 - _package = options.getString("package"); 13.34 _parse_only = options.getBoolean("parse.only"); 13.35 _print_ast = options.getBoolean("print.ast"); 13.36 _print_lower_ast = options.getBoolean("print.lower.ast");
14.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Aug 19 19:37:29 2013 +0530 14.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Aug 23 16:44:02 2013 +0530 14.3 @@ -1008,10 +1008,6 @@ 14.4 return getMap().findProperty(key); 14.5 } 14.6 14.7 - static String convertKey(final Object key) { 14.8 - return (key instanceof String) ? (String)key : JSType.toString(key); 14.9 - } 14.10 - 14.11 /** 14.12 * Overridden by {@link jdk.nashorn.internal.objects.NativeArguments} class (internal use.) 14.13 * Used for argument access in a vararg function using parameter name. 14.14 @@ -1129,6 +1125,9 @@ 14.15 proto = newProto; 14.16 14.17 if (isPrototype()) { 14.18 + // tell listeners that my __proto__ has been changed 14.19 + notifyProtoChanged(this, oldProto, newProto); 14.20 + 14.21 if (oldProto != null) { 14.22 oldProto.removePropertyListener(this); 14.23 } 14.24 @@ -1144,7 +1143,19 @@ 14.25 * @param newProto Prototype to set. 14.26 */ 14.27 public final void setProtoCheck(final Object newProto) { 14.28 + if (!isExtensible()) { 14.29 + throw typeError("__proto__.set.non.extensible", ScriptRuntime.safeToString(this)); 14.30 + } 14.31 + 14.32 if (newProto == null || newProto instanceof ScriptObject) { 14.33 + // check for circularity 14.34 + ScriptObject proto = (ScriptObject)newProto; 14.35 + while (proto != null) { 14.36 + if (proto == this) { 14.37 + throw typeError("circular.__proto__.set", ScriptRuntime.safeToString(this)); 14.38 + } 14.39 + proto = proto.getProto(); 14.40 + } 14.41 setProto((ScriptObject)newProto); 14.42 } else { 14.43 final ScriptObject global = Context.getGlobalTrusted(); 14.44 @@ -2359,7 +2370,7 @@ 14.45 return array.getInt(index); 14.46 } 14.47 14.48 - return getInt(index, convertKey(key)); 14.49 + return getInt(index, JSType.toString(key)); 14.50 } 14.51 14.52 @Override 14.53 @@ -2371,7 +2382,7 @@ 14.54 return array.getInt(index); 14.55 } 14.56 14.57 - return getInt(index, convertKey(key)); 14.58 + return getInt(index, JSType.toString(key)); 14.59 } 14.60 14.61 @Override 14.62 @@ -2383,7 +2394,7 @@ 14.63 return array.getInt(index); 14.64 } 14.65 14.66 - return getInt(index, convertKey(key)); 14.67 + return getInt(index, JSType.toString(key)); 14.68 } 14.69 14.70 @Override 14.71 @@ -2394,7 +2405,7 @@ 14.72 return array.getInt(key); 14.73 } 14.74 14.75 - return getInt(key, convertKey(key)); 14.76 + return getInt(key, JSType.toString(key)); 14.77 } 14.78 14.79 private long getLong(final int index, final String key) { 14.80 @@ -2436,7 +2447,7 @@ 14.81 return array.getLong(index); 14.82 } 14.83 14.84 - return getLong(index, convertKey(key)); 14.85 + return getLong(index, JSType.toString(key)); 14.86 } 14.87 14.88 @Override 14.89 @@ -2448,7 +2459,7 @@ 14.90 return array.getLong(index); 14.91 } 14.92 14.93 - return getLong(index, convertKey(key)); 14.94 + return getLong(index, JSType.toString(key)); 14.95 } 14.96 14.97 @Override 14.98 @@ -2460,7 +2471,7 @@ 14.99 return array.getLong(index); 14.100 } 14.101 14.102 - return getLong(index, convertKey(key)); 14.103 + return getLong(index, JSType.toString(key)); 14.104 } 14.105 14.106 @Override 14.107 @@ -2471,7 +2482,7 @@ 14.108 return array.getLong(key); 14.109 } 14.110 14.111 - return getLong(key, convertKey(key)); 14.112 + return getLong(key, JSType.toString(key)); 14.113 } 14.114 14.115 private double getDouble(final int index, final String key) { 14.116 @@ -2513,7 +2524,7 @@ 14.117 return array.getDouble(index); 14.118 } 14.119 14.120 - return getDouble(index, convertKey(key)); 14.121 + return getDouble(index, JSType.toString(key)); 14.122 } 14.123 14.124 @Override 14.125 @@ -2525,7 +2536,7 @@ 14.126 return array.getDouble(index); 14.127 } 14.128 14.129 - return getDouble(index, convertKey(key)); 14.130 + return getDouble(index, JSType.toString(key)); 14.131 } 14.132 14.133 @Override 14.134 @@ -2537,7 +2548,7 @@ 14.135 return array.getDouble(index); 14.136 } 14.137 14.138 - return getDouble(index, convertKey(key)); 14.139 + return getDouble(index, JSType.toString(key)); 14.140 } 14.141 14.142 @Override 14.143 @@ -2548,7 +2559,7 @@ 14.144 return array.getDouble(key); 14.145 } 14.146 14.147 - return getDouble(key, convertKey(key)); 14.148 + return getDouble(key, JSType.toString(key)); 14.149 } 14.150 14.151 private Object get(final int index, final String key) { 14.152 @@ -2590,7 +2601,7 @@ 14.153 return array.getObject(index); 14.154 } 14.155 14.156 - return get(index, convertKey(key)); 14.157 + return get(index, JSType.toString(key)); 14.158 } 14.159 14.160 @Override 14.161 @@ -2602,7 +2613,7 @@ 14.162 return array.getObject(index); 14.163 } 14.164 14.165 - return get(index, convertKey(key)); 14.166 + return get(index, JSType.toString(key)); 14.167 } 14.168 14.169 @Override 14.170 @@ -2614,7 +2625,7 @@ 14.171 return array.getObject(index); 14.172 } 14.173 14.174 - return get(index, convertKey(key)); 14.175 + return get(index, JSType.toString(key)); 14.176 } 14.177 14.178 @Override 14.179 @@ -2625,7 +2636,7 @@ 14.180 return array.getObject(key); 14.181 } 14.182 14.183 - return get(key, convertKey(key)); 14.184 + return get(key, JSType.toString(key)); 14.185 } 14.186 14.187 /** 14.188 @@ -2640,7 +2651,7 @@ 14.189 final long longIndex = index & JSType.MAX_UINT; 14.190 14.191 if (!getArray().has(index)) { 14.192 - final String key = convertKey(longIndex); 14.193 + final String key = JSType.toString(longIndex); 14.194 final FindProperty find = findProperty(key, true); 14.195 14.196 if (find != null) { 14.197 @@ -2786,7 +2797,7 @@ 14.198 return; 14.199 } 14.200 14.201 - final String propName = convertKey(key); 14.202 + final String propName = JSType.toString(key); 14.203 final FindProperty find = findProperty(propName, true); 14.204 14.205 setObject(find, strict, propName, value); 14.206 @@ -3008,7 +3019,7 @@ 14.207 } 14.208 } 14.209 14.210 - final FindProperty find = findProperty(convertKey(key), true); 14.211 + final FindProperty find = findProperty(JSType.toString(key), true); 14.212 14.213 return find != null; 14.214 } 14.215 @@ -3025,7 +3036,7 @@ 14.216 } 14.217 } 14.218 14.219 - final FindProperty find = findProperty(convertKey(key), true); 14.220 + final FindProperty find = findProperty(JSType.toString(key), true); 14.221 14.222 return find != null; 14.223 } 14.224 @@ -3042,7 +3053,7 @@ 14.225 } 14.226 } 14.227 14.228 - final FindProperty find = findProperty(convertKey(key), true); 14.229 + final FindProperty find = findProperty(JSType.toString(key), true); 14.230 14.231 return find != null; 14.232 } 14.233 @@ -3059,7 +3070,7 @@ 14.234 } 14.235 } 14.236 14.237 - final FindProperty find = findProperty(convertKey(key), true); 14.238 + final FindProperty find = findProperty(JSType.toString(key), true); 14.239 14.240 return find != null; 14.241 } 14.242 @@ -3072,7 +3083,7 @@ 14.243 return true; 14.244 } 14.245 14.246 - final FindProperty find = findProperty(convertKey(key), false); 14.247 + final FindProperty find = findProperty(JSType.toString(key), false); 14.248 14.249 return find != null; 14.250 } 14.251 @@ -3085,7 +3096,7 @@ 14.252 return true; 14.253 } 14.254 14.255 - final FindProperty find = findProperty(convertKey(key), false); 14.256 + final FindProperty find = findProperty(JSType.toString(key), false); 14.257 14.258 return find != null; 14.259 } 14.260 @@ -3098,7 +3109,7 @@ 14.261 return true; 14.262 } 14.263 14.264 - final FindProperty find = findProperty(convertKey(key), false); 14.265 + final FindProperty find = findProperty(JSType.toString(key), false); 14.266 14.267 return find != null; 14.268 } 14.269 @@ -3111,7 +3122,7 @@ 14.270 return true; 14.271 } 14.272 14.273 - final FindProperty find = findProperty(convertKey(key), false); 14.274 + final FindProperty find = findProperty(JSType.toString(key), false); 14.275 14.276 return find != null; 14.277 } 14.278 @@ -3181,7 +3192,7 @@ 14.279 } 14.280 14.281 private boolean deleteObject(final Object key, final boolean strict) { 14.282 - final String propName = convertKey(key); 14.283 + final String propName = JSType.toString(key); 14.284 final FindProperty find = findProperty(propName, false); 14.285 14.286 if (find == null) {
15.1 --- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Mon Aug 19 19:37:29 2013 +0530 15.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Fri Aug 23 16:44:02 2013 +0530 15.3 @@ -37,7 +37,9 @@ 15.4 import java.lang.reflect.Array; 15.5 import java.util.Collections; 15.6 import java.util.Iterator; 15.7 +import java.util.List; 15.8 import java.util.Locale; 15.9 +import java.util.Map; 15.10 import java.util.NoSuchElementException; 15.11 import java.util.Objects; 15.12 import jdk.internal.dynalink.beans.StaticClass; 15.13 @@ -221,49 +223,71 @@ 15.14 } 15.15 15.16 /** 15.17 - * Used to determine property iterator used in for in. 15.18 - * @param obj Object to iterate on. 15.19 - * @return Iterator. 15.20 + * Returns an iterator over property identifiers used in the {@code for...in} statement. Note that the ECMAScript 15.21 + * 5.1 specification, chapter 12.6.4. uses the terminology "property names", which seems to imply that the property 15.22 + * identifiers are expected to be strings, but this is not actually spelled out anywhere, and Nashorn will in some 15.23 + * cases deviate from this. Namely, we guarantee to always return an iterator over {@link String} values for any 15.24 + * built-in JavaScript object. We will however return an iterator over {@link Integer} objects for native Java 15.25 + * arrays and {@link List} objects, as well as arbitrary objects representing keys of a {@link Map}. Therefore, the 15.26 + * expression {@code typeof i} within a {@code for(i in obj)} statement can return something other than 15.27 + * {@code string} when iterating over native Java arrays, {@code List}, and {@code Map} objects. 15.28 + * @param obj object to iterate on. 15.29 + * @return iterator over the object's property names. 15.30 */ 15.31 - public static Iterator<String> toPropertyIterator(final Object obj) { 15.32 + public static Iterator<?> toPropertyIterator(final Object obj) { 15.33 if (obj instanceof ScriptObject) { 15.34 return ((ScriptObject)obj).propertyIterator(); 15.35 } 15.36 15.37 if (obj != null && obj.getClass().isArray()) { 15.38 - final int length = Array.getLength(obj); 15.39 - 15.40 - return new Iterator<String>() { 15.41 - private int index = 0; 15.42 - 15.43 - @Override 15.44 - public boolean hasNext() { 15.45 - return index < length; 15.46 - } 15.47 - 15.48 - @Override 15.49 - public String next() { 15.50 - return "" + index++; //TODO numeric property iterator? 15.51 - } 15.52 - 15.53 - @Override 15.54 - public void remove() { 15.55 - throw new UnsupportedOperationException(); 15.56 - } 15.57 - }; 15.58 + return new RangeIterator(Array.getLength(obj)); 15.59 } 15.60 15.61 if (obj instanceof ScriptObjectMirror) { 15.62 return ((ScriptObjectMirror)obj).keySet().iterator(); 15.63 } 15.64 15.65 + if (obj instanceof List) { 15.66 + return new RangeIterator(((List<?>)obj).size()); 15.67 + } 15.68 + 15.69 + if (obj instanceof Map) { 15.70 + return ((Map<?,?>)obj).keySet().iterator(); 15.71 + } 15.72 + 15.73 return Collections.emptyIterator(); 15.74 } 15.75 15.76 + private static final class RangeIterator implements Iterator<Integer> { 15.77 + private final int length; 15.78 + private int index; 15.79 + 15.80 + RangeIterator(int length) { 15.81 + this.length = length; 15.82 + } 15.83 + 15.84 + @Override 15.85 + public boolean hasNext() { 15.86 + return index < length; 15.87 + } 15.88 + 15.89 + @Override 15.90 + public Integer next() { 15.91 + return index++; 15.92 + } 15.93 + 15.94 + @Override 15.95 + public void remove() { 15.96 + throw new UnsupportedOperationException(); 15.97 + } 15.98 + } 15.99 + 15.100 /** 15.101 - * Used to determine property value iterator used in for each in. 15.102 - * @param obj Object to iterate on. 15.103 - * @return Iterator. 15.104 + * Returns an iterator over property values used in the {@code for each...in} statement. Aside from built-in JS 15.105 + * objects, it also operates on Java arrays, any {@link Iterable}, as well as on {@link Map} objects, iterating over 15.106 + * map values. 15.107 + * @param obj object to iterate on. 15.108 + * @return iterator over the object's property values. 15.109 */ 15.110 public static Iterator<?> toValueIterator(final Object obj) { 15.111 if (obj instanceof ScriptObject) { 15.112 @@ -301,6 +325,10 @@ 15.113 return ((ScriptObjectMirror)obj).values().iterator(); 15.114 } 15.115 15.116 + if (obj instanceof Map) { 15.117 + return ((Map<?,?>)obj).values().iterator(); 15.118 + } 15.119 + 15.120 if (obj instanceof Iterable) { 15.121 return ((Iterable<?>)obj).iterator(); 15.122 }
16.1 --- a/src/jdk/nashorn/internal/runtime/WithObject.java Mon Aug 19 19:37:29 2013 +0530 16.2 +++ b/src/jdk/nashorn/internal/runtime/WithObject.java Fri Aug 23 16:44:02 2013 +0530 16.3 @@ -73,7 +73,7 @@ 16.4 public boolean delete(final Object key, final boolean strict) { 16.5 if (expression instanceof ScriptObject) { 16.6 final ScriptObject self = (ScriptObject)expression; 16.7 - final String propName = ScriptObject.convertKey(key); 16.8 + final String propName = JSType.toString(key); 16.9 16.10 final FindProperty find = self.findProperty(propName, true); 16.11
17.1 --- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Mon Aug 19 19:37:29 2013 +0530 17.2 +++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Fri Aug 23 16:44:02 2013 +0530 17.3 @@ -36,6 +36,7 @@ 17.4 import jdk.internal.dynalink.DynamicLinker; 17.5 import jdk.internal.dynalink.DynamicLinkerFactory; 17.6 import jdk.internal.dynalink.beans.BeansLinker; 17.7 +import jdk.internal.dynalink.beans.StaticClass; 17.8 import jdk.internal.dynalink.linker.GuardedInvocation; 17.9 import jdk.internal.dynalink.linker.LinkerServices; 17.10 import jdk.nashorn.api.scripting.ScriptObjectMirror; 17.11 @@ -61,7 +62,7 @@ 17.12 static { 17.13 final DynamicLinkerFactory factory = new DynamicLinkerFactory(); 17.14 factory.setPrioritizedLinkers(new NashornLinker(), new NashornPrimitiveLinker(), new NashornStaticClassLinker(), 17.15 - new BoundDynamicMethodLinker(), new JSObjectLinker(), new ReflectionCheckLinker()); 17.16 + new BoundDynamicMethodLinker(), new JavaSuperAdapterLinker(), new JSObjectLinker(), new ReflectionCheckLinker()); 17.17 factory.setFallbackLinkers(new BeansLinker(), new NashornBottomLinker()); 17.18 factory.setSyncOnRelink(true); 17.19 final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1); 17.20 @@ -88,7 +89,8 @@ 17.21 return obj instanceof ScriptFunction || 17.22 ((obj instanceof ScriptObjectMirror) && ((ScriptObjectMirror)obj).isFunction()) || 17.23 isDynamicMethod(obj) || 17.24 - isFunctionalInterfaceObject(obj); 17.25 + isFunctionalInterfaceObject(obj) || 17.26 + obj instanceof StaticClass; 17.27 } 17.28 17.29 /** 17.30 @@ -262,6 +264,16 @@ 17.31 } 17.32 17.33 /** 17.34 + * Creates a super-adapter for an adapter, that is, an adapter to the adapter that allows invocation of superclass 17.35 + * methods on it. 17.36 + * @param adapter the original adapter 17.37 + * @return a new adapter that can be used to invoke super methods on the original adapter. 17.38 + */ 17.39 + public static Object createSuperAdapter(final Object adapter) { 17.40 + return new JavaSuperAdapter(adapter); 17.41 + } 17.42 + 17.43 + /** 17.44 * If the given class is a reflection-specific class (anything in {@code java.lang.reflect} and 17.45 * {@code java.lang.invoke} package, as well a {@link Class} and any subclass of {@link ClassLoader}) and there is 17.46 * a security manager in the system, then it checks the {@code nashorn.JavaReflection} {@code RuntimePermission}.
18.1 --- a/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java Mon Aug 19 19:37:29 2013 +0530 18.2 +++ b/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java Fri Aug 23 16:44:02 2013 +0530 18.3 @@ -67,11 +67,12 @@ 18.4 // BeansLinker. 18.5 final CallSiteDescriptor descriptor = linkRequest.getCallSiteDescriptor(); 18.6 final MethodType type = descriptor.getMethodType(); 18.7 + final Class<?> dynamicMethodClass = dynamicMethod.getClass(); 18.8 final CallSiteDescriptor newDescriptor = descriptor.changeMethodType( 18.9 - type.changeParameterType(0, dynamicMethod.getClass()).changeParameterType(1, boundThis.getClass())); 18.10 + type.changeParameterType(0, dynamicMethodClass).changeParameterType(1, boundThis.getClass())); 18.11 18.12 // Delegate to BeansLinker 18.13 - final GuardedInvocation inv = BeansLinker.getLinkerForClass(dynamicMethod.getClass()).getGuardedInvocation( 18.14 + final GuardedInvocation inv = BeansLinker.getLinkerForClass(dynamicMethodClass).getGuardedInvocation( 18.15 linkRequest.replaceArguments(newDescriptor, args), linkerServices); 18.16 if(inv == null) { 18.17 return null;
19.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Mon Aug 19 19:37:29 2013 +0530 19.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Fri Aug 23 16:44:02 2013 +0530 19.3 @@ -173,6 +173,9 @@ 19.4 private static final String CLASS_INIT = "<clinit>"; 19.5 private static final String STATIC_GLOBAL_FIELD_NAME = "staticGlobal"; 19.6 19.7 + // Method name prefix for invoking super-methods 19.8 + static final String SUPER_PREFIX = "super$"; 19.9 + 19.10 /** 19.11 * Collection of methods we never override: Object.clone(), Object.finalize(). 19.12 */ 19.13 @@ -240,6 +243,7 @@ 19.14 } 19.15 generateConstructors(); 19.16 generateMethods(); 19.17 + generateSuperMethods(); 19.18 // } 19.19 cw.visitEnd(); 19.20 } 19.21 @@ -507,6 +511,10 @@ 19.22 19.23 private static void endInitMethod(final InstructionAdapter mv) { 19.24 mv.visitInsn(RETURN); 19.25 + endMethod(mv); 19.26 + } 19.27 + 19.28 + private static void endMethod(final InstructionAdapter mv) { 19.29 mv.visitMaxs(0, 0); 19.30 mv.visitEnd(); 19.31 } 19.32 @@ -603,13 +611,8 @@ 19.33 */ 19.34 private void generateMethod(final MethodInfo mi) { 19.35 final Method method = mi.method; 19.36 - final int mod = method.getModifiers(); 19.37 - final int access = ACC_PUBLIC | (method.isVarArgs() ? ACC_VARARGS : 0); 19.38 final Class<?>[] exceptions = method.getExceptionTypes(); 19.39 - final String[] exceptionNames = new String[exceptions.length]; 19.40 - for (int i = 0; i < exceptions.length; ++i) { 19.41 - exceptionNames[i] = Type.getInternalName(exceptions[i]); 19.42 - } 19.43 + final String[] exceptionNames = getExceptionNames(exceptions); 19.44 final MethodType type = mi.type; 19.45 final String methodDesc = type.toMethodDescriptorString(); 19.46 final String name = mi.getName(); 19.47 @@ -617,14 +620,8 @@ 19.48 final Type asmType = Type.getMethodType(methodDesc); 19.49 final Type[] asmArgTypes = asmType.getArgumentTypes(); 19.50 19.51 - // Determine the first index for a local variable 19.52 - int nextLocalVar = 1; // this 19.53 - for(final Type t: asmArgTypes) { 19.54 - nextLocalVar += t.getSize(); 19.55 - } 19.56 - 19.57 - final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(access, name, methodDesc, null, 19.58 - exceptionNames)); 19.59 + final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(getAccessModifiers(method), name, 19.60 + methodDesc, null, exceptionNames)); 19.61 mv.visitCode(); 19.62 19.63 final Label instanceHandleDefined = new Label(); 19.64 @@ -646,7 +643,7 @@ 19.65 } 19.66 19.67 // No handle is available, fall back to default behavior 19.68 - if(Modifier.isAbstract(mod)) { 19.69 + if(Modifier.isAbstract(method.getModifiers())) { 19.70 // If the super method is abstract, throw an exception 19.71 mv.anew(UNSUPPORTED_OPERATION_TYPE); 19.72 mv.dup(); 19.73 @@ -654,14 +651,7 @@ 19.74 mv.athrow(); 19.75 } else { 19.76 // If the super method is not abstract, delegate to it. 19.77 - mv.visitVarInsn(ALOAD, 0); 19.78 - int nextParam = 1; 19.79 - for(final Type t: asmArgTypes) { 19.80 - mv.load(nextParam, t); 19.81 - nextParam += t.getSize(); 19.82 - } 19.83 - mv.invokespecial(superClassName, name, methodDesc); 19.84 - mv.areturn(asmReturnType); 19.85 + emitSuperCall(mv, name, methodDesc); 19.86 } 19.87 19.88 final Label setupGlobal = new Label(); 19.89 @@ -685,6 +675,12 @@ 19.90 // stack: [creatingGlobal, someHandle] 19.91 mv.visitLabel(setupGlobal); 19.92 19.93 + // Determine the first index for a local variable 19.94 + int nextLocalVar = 1; // "this" is at 0 19.95 + for(final Type t: asmArgTypes) { 19.96 + nextLocalVar += t.getSize(); 19.97 + } 19.98 + // Set our local variable indices 19.99 final int currentGlobalVar = nextLocalVar++; 19.100 final int globalsDifferVar = nextLocalVar++; 19.101 19.102 @@ -775,8 +771,7 @@ 19.103 } 19.104 mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, throwableHandler, THROWABLE_TYPE_NAME); 19.105 } 19.106 - mv.visitMaxs(0, 0); 19.107 - mv.visitEnd(); 19.108 + endMethod(mv); 19.109 } 19.110 19.111 /** 19.112 @@ -817,6 +812,53 @@ 19.113 return false; 19.114 } 19.115 19.116 + private void generateSuperMethods() { 19.117 + for(final MethodInfo mi: methodInfos) { 19.118 + if(!Modifier.isAbstract(mi.method.getModifiers())) { 19.119 + generateSuperMethod(mi); 19.120 + } 19.121 + } 19.122 + } 19.123 + 19.124 + private void generateSuperMethod(MethodInfo mi) { 19.125 + final Method method = mi.method; 19.126 + 19.127 + final String methodDesc = mi.type.toMethodDescriptorString(); 19.128 + final String name = mi.getName(); 19.129 + 19.130 + final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(getAccessModifiers(method), 19.131 + SUPER_PREFIX + name, methodDesc, null, getExceptionNames(method.getExceptionTypes()))); 19.132 + mv.visitCode(); 19.133 + 19.134 + emitSuperCall(mv, name, methodDesc); 19.135 + 19.136 + endMethod(mv); 19.137 + } 19.138 + 19.139 + private void emitSuperCall(final InstructionAdapter mv, final String name, final String methodDesc) { 19.140 + mv.visitVarInsn(ALOAD, 0); 19.141 + int nextParam = 1; 19.142 + final Type methodType = Type.getMethodType(methodDesc); 19.143 + for(final Type t: methodType.getArgumentTypes()) { 19.144 + mv.load(nextParam, t); 19.145 + nextParam += t.getSize(); 19.146 + } 19.147 + mv.invokespecial(superClassName, name, methodDesc); 19.148 + mv.areturn(methodType.getReturnType()); 19.149 + } 19.150 + 19.151 + private static String[] getExceptionNames(final Class<?>[] exceptions) { 19.152 + final String[] exceptionNames = new String[exceptions.length]; 19.153 + for (int i = 0; i < exceptions.length; ++i) { 19.154 + exceptionNames[i] = Type.getInternalName(exceptions[i]); 19.155 + } 19.156 + return exceptionNames; 19.157 + } 19.158 + 19.159 + private static int getAccessModifiers(final Method method) { 19.160 + return ACC_PUBLIC | (method.isVarArgs() ? ACC_VARARGS : 0); 19.161 + } 19.162 + 19.163 /** 19.164 * Gathers methods that can be implemented or overridden from the specified type into this factory's 19.165 * {@link #methodInfos} set. It will add all non-final, non-static methods that are either public or protected from
20.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Mon Aug 19 19:37:29 2013 +0530 20.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Fri Aug 23 16:44:02 2013 +0530 20.3 @@ -34,7 +34,6 @@ 20.4 import java.security.PrivilegedAction; 20.5 import java.security.ProtectionDomain; 20.6 import java.security.SecureClassLoader; 20.7 - 20.8 import jdk.internal.dynalink.beans.StaticClass; 20.9 20.10 /**
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapter.java Fri Aug 23 16:44:02 2013 +0530 21.3 @@ -0,0 +1,44 @@ 21.4 +/* 21.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.7 + * 21.8 + * This code is free software; you can redistribute it and/or modify it 21.9 + * under the terms of the GNU General Public License version 2 only, as 21.10 + * published by the Free Software Foundation. Oracle designates this 21.11 + * particular file as subject to the "Classpath" exception as provided 21.12 + * by Oracle in the LICENSE file that accompanied this code. 21.13 + * 21.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 21.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21.17 + * version 2 for more details (a copy is included in the LICENSE file that 21.18 + * accompanied this code). 21.19 + * 21.20 + * You should have received a copy of the GNU General Public License version 21.21 + * 2 along with this work; if not, write to the Free Software Foundation, 21.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21.23 + * 21.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21.25 + * or visit www.oracle.com if you need additional information or have any 21.26 + * questions. 21.27 + */ 21.28 + 21.29 +package jdk.nashorn.internal.runtime.linker; 21.30 + 21.31 +/** 21.32 + * Represents a an adapter for invoking superclass methods on an adapter instance generated by 21.33 + * {@link JavaAdapterBytecodeGenerator}. Note that objects of this class are just wrappers around the adapter instances, 21.34 + * without any behavior. All the behavior is defined in the {@code JavaSuperAdapterLinker}. 21.35 + */ 21.36 +class JavaSuperAdapter { 21.37 + private final Object adapter; 21.38 + 21.39 + JavaSuperAdapter(final Object adapter) { 21.40 + adapter.getClass(); // NPE check 21.41 + this.adapter = adapter; 21.42 + } 21.43 + 21.44 + public Object getAdapter() { 21.45 + return adapter; 21.46 + } 21.47 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java Fri Aug 23 16:44:02 2013 +0530 22.3 @@ -0,0 +1,180 @@ 22.4 +/* 22.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.7 + * 22.8 + * This code is free software; you can redistribute it and/or modify it 22.9 + * under the terms of the GNU General Public License version 2 only, as 22.10 + * published by the Free Software Foundation. Oracle designates this 22.11 + * particular file as subject to the "Classpath" exception as provided 22.12 + * by Oracle in the LICENSE file that accompanied this code. 22.13 + * 22.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 22.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 22.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 22.17 + * version 2 for more details (a copy is included in the LICENSE file that 22.18 + * accompanied this code). 22.19 + * 22.20 + * You should have received a copy of the GNU General Public License version 22.21 + * 2 along with this work; if not, write to the Free Software Foundation, 22.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22.23 + * 22.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22.25 + * or visit www.oracle.com if you need additional information or have any 22.26 + * questions. 22.27 + */ 22.28 + 22.29 +package jdk.nashorn.internal.runtime.linker; 22.30 + 22.31 +import static jdk.nashorn.internal.lookup.Lookup.EMPTY_GETTER; 22.32 +import static jdk.nashorn.internal.runtime.linker.JavaAdapterBytecodeGenerator.SUPER_PREFIX; 22.33 + 22.34 +import java.lang.invoke.MethodHandle; 22.35 +import java.lang.invoke.MethodHandles; 22.36 +import java.lang.invoke.MethodType; 22.37 +import jdk.internal.dynalink.CallSiteDescriptor; 22.38 +import jdk.internal.dynalink.beans.BeansLinker; 22.39 +import jdk.internal.dynalink.linker.GuardedInvocation; 22.40 +import jdk.internal.dynalink.linker.LinkRequest; 22.41 +import jdk.internal.dynalink.linker.LinkerServices; 22.42 +import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; 22.43 +import jdk.internal.dynalink.support.CallSiteDescriptorFactory; 22.44 +import jdk.internal.dynalink.support.Lookup; 22.45 +import jdk.nashorn.internal.runtime.ScriptRuntime; 22.46 + 22.47 +/** 22.48 + * A linker for instances of {@link JavaSuperAdapter}. Only links {@code getMethod} calls, by forwarding them to the 22.49 + * bean linker for the adapter class and prepending {@code super$} to method names. 22.50 + * 22.51 + */ 22.52 +final class JavaSuperAdapterLinker implements TypeBasedGuardingDynamicLinker { 22.53 + private static final String GET_METHOD = "getMethod"; 22.54 + private static final String DYN_GET_METHOD = "dyn:" + GET_METHOD; 22.55 + private static final String DYN_GET_METHOD_FIXED = DYN_GET_METHOD + ":" + SUPER_PREFIX; 22.56 + 22.57 + private static final MethodHandle ADD_PREFIX_TO_METHOD_NAME; 22.58 + private static final MethodHandle BIND_DYNAMIC_METHOD; 22.59 + private static final MethodHandle GET_ADAPTER; 22.60 + private static final MethodHandle IS_ADAPTER_OF_CLASS; 22.61 + 22.62 + static { 22.63 + final Lookup lookup = new Lookup(MethodHandles.lookup()); 22.64 + ADD_PREFIX_TO_METHOD_NAME = lookup.findOwnStatic("addPrefixToMethodName", Object.class, Object.class); 22.65 + BIND_DYNAMIC_METHOD = lookup.findOwnStatic("bindDynamicMethod", Object.class, Object.class, Object.class); 22.66 + GET_ADAPTER = lookup.findVirtual(JavaSuperAdapter.class, "getAdapter", MethodType.methodType(Object.class)); 22.67 + IS_ADAPTER_OF_CLASS = lookup.findOwnStatic("isAdapterOfClass", boolean.class, Class.class, Object.class); 22.68 + } 22.69 + 22.70 + @Override 22.71 + public boolean canLinkType(final Class<?> type) { 22.72 + return type == JavaSuperAdapter.class; 22.73 + } 22.74 + 22.75 + @Override 22.76 + public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) 22.77 + throws Exception { 22.78 + final Object objSuperAdapter = linkRequest.getReceiver(); 22.79 + if(!(objSuperAdapter instanceof JavaSuperAdapter)) { 22.80 + return null; 22.81 + } 22.82 + 22.83 + final CallSiteDescriptor descriptor = linkRequest.getCallSiteDescriptor(); 22.84 + if(!CallSiteDescriptorFactory.tokenizeOperators(descriptor).contains(GET_METHOD)) { 22.85 + // We only handle getMethod 22.86 + return null; 22.87 + } 22.88 + 22.89 + final Object adapter = ((JavaSuperAdapter)objSuperAdapter).getAdapter(); 22.90 + 22.91 + // Replace argument (javaSuperAdapter, ...) => (adapter, ...) when delegating to BeansLinker 22.92 + final Object[] args = linkRequest.getArguments(); 22.93 + args[0] = adapter; 22.94 + 22.95 + // Use R(T0, ...) => R(adapter.class, ...) call site type when delegating to BeansLinker. 22.96 + final MethodType type = descriptor.getMethodType(); 22.97 + final Class<?> adapterClass = adapter.getClass(); 22.98 + final boolean hasFixedName = descriptor.getNameTokenCount() > 2; 22.99 + final String opName = hasFixedName ? (DYN_GET_METHOD_FIXED + descriptor.getNameToken( 22.100 + CallSiteDescriptor.NAME_OPERAND)) : DYN_GET_METHOD; 22.101 + 22.102 + final CallSiteDescriptor newDescriptor = NashornCallSiteDescriptor.get(descriptor.getLookup(), opName, 22.103 + type.changeParameterType(0, adapterClass), 0); 22.104 + 22.105 + // Delegate to BeansLinker 22.106 + final GuardedInvocation guardedInv = BeansLinker.getLinkerForClass(adapterClass).getGuardedInvocation( 22.107 + linkRequest.replaceArguments(newDescriptor, args), linkerServices); 22.108 + 22.109 + final MethodHandle guard = IS_ADAPTER_OF_CLASS.bindTo(adapterClass); 22.110 + if(guardedInv == null) { 22.111 + // Short circuit the lookup here for non-existent methods by linking an empty getter. If we just returned 22.112 + // null instead, BeansLinker would find final methods on the JavaSuperAdapter instead: getClass() and 22.113 + // wait(). 22.114 + return new GuardedInvocation(MethodHandles.dropArguments(EMPTY_GETTER, 1,type.parameterList().subList(1, 22.115 + type.parameterCount())), guard).asType(descriptor); 22.116 + } 22.117 + 22.118 + final MethodHandle invocation = guardedInv.getInvocation(); 22.119 + final MethodType invType = invocation.type(); 22.120 + // For invocation typed R(T0, ...) create a dynamic method binder of type R(R, T0) 22.121 + final MethodHandle typedBinder = BIND_DYNAMIC_METHOD.asType(MethodType.methodType(invType.returnType(), 22.122 + invType.returnType(), invType.parameterType(0))); 22.123 + // For invocation typed R(T0, T1, ...) create a dynamic method binder of type R(R, T0, T1, ...) 22.124 + final MethodHandle droppingBinder = MethodHandles.dropArguments(typedBinder, 2, 22.125 + invType.parameterList().subList(1, invType.parameterCount())); 22.126 + // Finally, fold the invocation into the binder to produce a method handle that will bind every returned 22.127 + // DynamicMethod object from dyn:getMethod calls to the actual receiver 22.128 + // R(R(T0, T1, ...), T0, T1, ...) 22.129 + final MethodHandle bindingInvocation = MethodHandles.foldArguments(droppingBinder, invocation); 22.130 + 22.131 + final MethodHandle typedGetAdapter = asFilterType(GET_ADAPTER, 0, invType, type); 22.132 + final MethodHandle adaptedInvocation; 22.133 + if(hasFixedName) { 22.134 + adaptedInvocation = MethodHandles.filterArguments(bindingInvocation, 0, typedGetAdapter); 22.135 + } else { 22.136 + // Add a filter that'll prepend "super$" to each name passed to the variable-name "dyn:getMethod". 22.137 + final MethodHandle typedAddPrefix = asFilterType(ADD_PREFIX_TO_METHOD_NAME, 1, invType, type); 22.138 + adaptedInvocation = MethodHandles.filterArguments(bindingInvocation, 0, typedGetAdapter, typedAddPrefix); 22.139 + } 22.140 + 22.141 + return guardedInv.replaceMethods(adaptedInvocation, guard).asType(descriptor); 22.142 + } 22.143 + 22.144 + /** 22.145 + * Adapts the type of a method handle used as a filter in a position from a source method type to a target method type. 22.146 + * @param filter the filter method handle 22.147 + * @param pos the position in the argument list that it's filtering 22.148 + * @param targetType the target method type for filtering 22.149 + * @param sourceType the source method type for filtering 22.150 + * @return a type adapted filter 22.151 + */ 22.152 + private static MethodHandle asFilterType(final MethodHandle filter, int pos, MethodType targetType, MethodType sourceType) { 22.153 + return filter.asType(MethodType.methodType(targetType.parameterType(pos), sourceType.parameterType(pos))); 22.154 + } 22.155 + 22.156 + @SuppressWarnings("unused") 22.157 + private static Object addPrefixToMethodName(final Object name) { 22.158 + return SUPER_PREFIX.concat(String.valueOf(name)); 22.159 + } 22.160 + 22.161 + /** 22.162 + * Used to transform the return value of getMethod; transform a {@code DynamicMethod} into a 22.163 + * {@code BoundDynamicMethod} while also accounting for the possibility of a non-existent method. 22.164 + * @param dynamicMethod the dynamic method to bind 22.165 + * @param boundThis the adapter underlying a super adapter, to which the dynamic method is bound. 22.166 + * @return a dynamic method bound to the adapter instance. 22.167 + */ 22.168 + @SuppressWarnings("unused") 22.169 + private static Object bindDynamicMethod(final Object dynamicMethod, final Object boundThis) { 22.170 + return dynamicMethod == null ? ScriptRuntime.UNDEFINED : Bootstrap.bindDynamicMethod(dynamicMethod, boundThis); 22.171 + } 22.172 + 22.173 + /** 22.174 + * Used as the guard of linkages, as the receiver is not guaranteed to be a JavaSuperAdapter. 22.175 + * @param clazz the class the receiver's adapter is tested against. 22.176 + * @param obj receiver 22.177 + * @return true if the receiver is a super adapter, and its underlying adapter is of the specified class 22.178 + */ 22.179 + @SuppressWarnings("unused") 22.180 + private static boolean isAdapterOfClass(Class<?> clazz, Object obj) { 22.181 + return obj instanceof JavaSuperAdapter && clazz == (((JavaSuperAdapter)obj).getAdapter()).getClass(); 22.182 + } 22.183 +}
23.1 --- a/src/jdk/nashorn/internal/runtime/regexp/RegExp.java Mon Aug 19 19:37:29 2013 +0530 23.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/RegExp.java Fri Aug 23 16:44:02 2013 +0530 23.3 @@ -60,7 +60,7 @@ 23.4 * @param flags the flags string 23.5 */ 23.6 protected RegExp(final String source, final String flags) { 23.7 - this.source = source; 23.8 + this.source = source.length() == 0 ? "(?:)" : source; 23.9 for (int i = 0; i < flags.length(); i++) { 23.10 final char ch = flags.charAt(i); 23.11 switch (ch) {
24.1 --- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties Mon Aug 19 19:37:29 2013 +0530 24.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties Fri Aug 23 16:44:02 2013 +0530 24.3 @@ -94,6 +94,8 @@ 24.4 type.error.cant.redefine.property=Cannot redefine property "{0}" of {1} 24.5 type.error.property.not.writable="{0}" is not a writable property of {1} 24.6 type.error.object.non.extensible=Cannot add new property "{0}" to non-extensible {1} 24.7 +type.error.__proto__.set.non.extensible=Cannot set __proto__ of non-extensible {0} 24.8 +type.error.circular.__proto__.set=Cannot create__proto__ cycle for {0} 24.9 24.10 # miscellaneous 24.11 type.error.regex.cant.supply.flags=Cannot supply flags when constructing one RegExp from another
25.1 --- a/src/jdk/nashorn/internal/runtime/resources/Options.properties Mon Aug 19 19:37:29 2013 +0530 25.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Options.properties Fri Aug 23 16:44:02 2013 +0530 25.3 @@ -157,6 +157,14 @@ 25.4 default=false \ 25.5 } 25.6 25.7 +nashorn.option.global.per.engine = { \ 25.8 + name="--global-per-engine", \ 25.9 + desc="Use single Global instance per script engine instance.", \ 25.10 + is_undocumented=true, \ 25.11 + type=Boolean, \ 25.12 + default=false \ 25.13 +} 25.14 + 25.15 nashorn.option.log = { \ 25.16 name="--log", \ 25.17 is_undocumented=true, \ 25.18 @@ -216,15 +224,6 @@ 25.19 default=false \ 25.20 } 25.21 25.22 -nashorn.option.package = { \ 25.23 - name="--package", \ 25.24 - is_undocumented=true, \ 25.25 - desc="Package to which generated .class files are added.", \ 25.26 - params="<package>", \ 25.27 - type=String, \ 25.28 - default="" \ 25.29 -} 25.30 - 25.31 nashorn.option.parse.only = { \ 25.32 name="--parse-only", \ 25.33 is_undocumented=true, \
26.1 --- a/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Mon Aug 19 19:37:29 2013 +0530 26.2 +++ b/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Fri Aug 23 16:44:02 2013 +0530 26.3 @@ -144,7 +144,7 @@ 26.4 return Object.getPrototypeOf(this); 26.5 }, 26.6 set: function(x) { 26.7 - throw new TypeError("__proto__ set not supported"); 26.8 + Object.setPrototypeOf(this, x); 26.9 } 26.10 }); 26.11
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/test/script/basic/JDK-8022903.js Fri Aug 23 16:44:02 2013 +0530 27.3 @@ -0,0 +1,55 @@ 27.4 +/* 27.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 27.7 + * 27.8 + * This code is free software; you can redistribute it and/or modify it 27.9 + * under the terms of the GNU General Public License version 2 only, as 27.10 + * published by the Free Software Foundation. 27.11 + * 27.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 27.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 27.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 27.15 + * version 2 for more details (a copy is included in the LICENSE file that 27.16 + * accompanied this code). 27.17 + * 27.18 + * You should have received a copy of the GNU General Public License version 27.19 + * 2 along with this work; if not, write to the Free Software Foundation, 27.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 27.21 + * 27.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 27.23 + * or visit www.oracle.com if you need additional information or have any 27.24 + * questions. 27.25 + */ 27.26 + 27.27 +/** 27.28 + * JDK-8022903: Enhance for-in and for-each for Lists and Maps 27.29 + * 27.30 + * @test 27.31 + * @run 27.32 + */ 27.33 + 27.34 +var colors = new java.util.ArrayList() 27.35 +colors.add("red") 27.36 +colors.add("purple") 27.37 +colors.add("pink") 27.38 + 27.39 +for(var index in colors) { 27.40 + print("colors[" + index + "]=" + colors[index]) 27.41 +} 27.42 + 27.43 +for each(var color in colors) { 27.44 + print(color) 27.45 +} 27.46 + 27.47 +var capitals = new java.util.LinkedHashMap() 27.48 +capitals.Sweden = "Stockholm" 27.49 +capitals.Hungary = "Budapet" 27.50 +capitals.Croatia = "Zagreb" 27.51 + 27.52 +for(var key in capitals) { 27.53 + print("capital of " + key + " is " + capitals[key]) 27.54 +} 27.55 + 27.56 +for each(var capital in capitals) { 27.57 + print(capital) 27.58 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/test/script/basic/JDK-8022903.js.EXPECTED Fri Aug 23 16:44:02 2013 +0530 28.3 @@ -0,0 +1,12 @@ 28.4 +colors[0]=red 28.5 +colors[1]=purple 28.6 +colors[2]=pink 28.7 +red 28.8 +purple 28.9 +pink 28.10 +capital of Sweden is Stockholm 28.11 +capital of Hungary is Budapet 28.12 +capital of Croatia is Zagreb 28.13 +Stockholm 28.14 +Budapet 28.15 +Zagreb
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/test/script/basic/JDK-8023368.js Fri Aug 23 16:44:02 2013 +0530 29.3 @@ -0,0 +1,73 @@ 29.4 +/* 29.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.7 + * 29.8 + * This code is free software; you can redistribute it and/or modify it 29.9 + * under the terms of the GNU General Public License version 2 only, as 29.10 + * published by the Free Software Foundation. 29.11 + * 29.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 29.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 29.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 29.15 + * version 2 for more details (a copy is included in the LICENSE file that 29.16 + * accompanied this code). 29.17 + * 29.18 + * You should have received a copy of the GNU General Public License version 29.19 + * 2 along with this work; if not, write to the Free Software Foundation, 29.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 29.21 + * 29.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 29.23 + * or visit www.oracle.com if you need additional information or have any 29.24 + * questions. 29.25 + */ 29.26 + 29.27 +/** 29.28 + * JDK-8023368: Instance __proto__ property should exist and be writable. 29.29 + * 29.30 + * @test 29.31 + * @run 29.32 + */ 29.33 + 29.34 +load("nashorn:mozilla_compat.js"); 29.35 + 29.36 +// function to force same callsites 29.37 +function check(obj) { 29.38 + print(obj.func()); 29.39 + print(obj.x); 29.40 + print(obj.toString()); 29.41 +} 29.42 + 29.43 +function Func() { 29.44 +} 29.45 + 29.46 +Func.prototype.func = function() { 29.47 + return "Func.prototype.func"; 29.48 +} 29.49 + 29.50 +Func.prototype.x = "hello"; 29.51 + 29.52 +var obj = new Func(); 29.53 +var obj2 = Object.create(obj); 29.54 + 29.55 +// check direct and indirect __proto__ change 29.56 +check(obj); 29.57 +check(obj2); 29.58 +obj.__proto__ = { 29.59 + func: function() { 29.60 + return "obj.__proto__.func @ " + __LINE__; 29.61 + }, 29.62 + x: 344 29.63 +}; 29.64 + 29.65 +check(obj); 29.66 +check(obj2); 29.67 + 29.68 +// check indirect (1 and 2 levels) __proto__ function change 29.69 +obj.__proto__.__proto__ = { 29.70 + toString: function() { 29.71 + return "new object.toString"; 29.72 + } 29.73 +}; 29.74 + 29.75 +check(obj); 29.76 +check(obj2);
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/test/script/basic/JDK-8023368.js.EXPECTED Fri Aug 23 16:44:02 2013 +0530 30.3 @@ -0,0 +1,18 @@ 30.4 +Func.prototype.func 30.5 +hello 30.6 +[object Object] 30.7 +Func.prototype.func 30.8 +hello 30.9 +[object Object] 30.10 +obj.__proto__.func @ 57 30.11 +344 30.12 +[object Object] 30.13 +obj.__proto__.func @ 57 30.14 +344 30.15 +[object Object] 30.16 +obj.__proto__.func @ 57 30.17 +344 30.18 +new object.toString 30.19 +obj.__proto__.func @ 57 30.20 +344 30.21 +new object.toString
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/test/script/basic/JDK-8023368_2.js Fri Aug 23 16:44:02 2013 +0530 31.3 @@ -0,0 +1,73 @@ 31.4 +/* 31.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.7 + * 31.8 + * This code is free software; you can redistribute it and/or modify it 31.9 + * under the terms of the GNU General Public License version 2 only, as 31.10 + * published by the Free Software Foundation. 31.11 + * 31.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 31.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 31.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 31.15 + * version 2 for more details (a copy is included in the LICENSE file that 31.16 + * accompanied this code). 31.17 + * 31.18 + * You should have received a copy of the GNU General Public License version 31.19 + * 2 along with this work; if not, write to the Free Software Foundation, 31.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 31.21 + * 31.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 31.23 + * or visit www.oracle.com if you need additional information or have any 31.24 + * questions. 31.25 + */ 31.26 + 31.27 +/** 31.28 + * JDK-8023368: Instance __proto__ property should exist and be writable. 31.29 + * 31.30 + * @test 31.31 + * @run 31.32 + */ 31.33 + 31.34 +// check Object.setPrototypeOf extension rather than using __proto__ 31.35 + 31.36 +// function to force same callsites 31.37 +function check(obj) { 31.38 + print(obj.func()); 31.39 + print(obj.x); 31.40 + print(obj.toString()); 31.41 +} 31.42 + 31.43 +function Func() { 31.44 +} 31.45 + 31.46 +Func.prototype.func = function() { 31.47 + return "Func.prototype.func"; 31.48 +} 31.49 + 31.50 +Func.prototype.x = "hello"; 31.51 + 31.52 +var obj = new Func(); 31.53 +var obj2 = Object.create(obj); 31.54 + 31.55 +// check direct and indirect __proto__ change 31.56 +check(obj); 31.57 +check(obj2); 31.58 +Object.setPrototypeOf(obj, { 31.59 + func: function() { 31.60 + return "obj.__proto__.func @ " + __LINE__; 31.61 + }, 31.62 + x: 344 31.63 +}); 31.64 + 31.65 +check(obj); 31.66 +check(obj2); 31.67 + 31.68 +// check indirect (1 and 2 levels) __proto__ function change 31.69 +Object.setPrototypeOf(Object.getPrototypeOf(obj), { 31.70 + toString: function() { 31.71 + return "new object.toString"; 31.72 + } 31.73 +}); 31.74 + 31.75 +check(obj); 31.76 +check(obj2);
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/test/script/basic/JDK-8023368_2.js.EXPECTED Fri Aug 23 16:44:02 2013 +0530 32.3 @@ -0,0 +1,18 @@ 32.4 +Func.prototype.func 32.5 +hello 32.6 +[object Object] 32.7 +Func.prototype.func 32.8 +hello 32.9 +[object Object] 32.10 +obj.__proto__.func @ 57 32.11 +344 32.12 +[object Object] 32.13 +obj.__proto__.func @ 57 32.14 +344 32.15 +[object Object] 32.16 +obj.__proto__.func @ 57 32.17 +344 32.18 +new object.toString 32.19 +obj.__proto__.func @ 57 32.20 +344 32.21 +new object.toString
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/test/script/basic/JDK-8023373.js Fri Aug 23 16:44:02 2013 +0530 33.3 @@ -0,0 +1,84 @@ 33.4 +/* 33.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.7 + * 33.8 + * This code is free software; you can redistribute it and/or modify it 33.9 + * under the terms of the GNU General Public License version 2 only, as 33.10 + * published by the Free Software Foundation. 33.11 + * 33.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 33.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 33.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 33.15 + * version 2 for more details (a copy is included in the LICENSE file that 33.16 + * accompanied this code). 33.17 + * 33.18 + * You should have received a copy of the GNU General Public License version 33.19 + * 2 along with this work; if not, write to the Free Software Foundation, 33.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 33.21 + * 33.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 33.23 + * or visit www.oracle.com if you need additional information or have any 33.24 + * questions. 33.25 + */ 33.26 + 33.27 +/** 33.28 + * JDK-8023373: allow super invocation for adapters 33.29 + * 33.30 + * @test 33.31 + * @run 33.32 + */ 33.33 + 33.34 +var CharArray = Java.type("char[]") 33.35 +var jString = Java.type("java.lang.String") 33.36 +var Character = Java.type("java.lang.Character") 33.37 + 33.38 +function capitalize(s) { 33.39 + if(s instanceof CharArray) { 33.40 + return new jString(s).toUpperCase() 33.41 + } 33.42 + if(s instanceof jString) { 33.43 + return s.toUpperCase() 33.44 + } 33.45 + return Character.toUpperCase(s) // must be int 33.46 +} 33.47 + 33.48 +var sw = new (Java.type("java.io.StringWriter")) 33.49 + 33.50 +var FilterWriterAdapter = Java.extend(Java.type("java.io.FilterWriter")) 33.51 + 33.52 +var cw = new FilterWriterAdapter(sw) { 33.53 + write: function(s, off, len) { 33.54 + s = capitalize(s) 33.55 + // Must handle overloads by arity 33.56 + if(off === undefined) { 33.57 + cw.super$write(s, 0, s.length()) 33.58 + } else if (typeof s === "string") { 33.59 + cw.super$write(s, off, len) 33.60 + } 33.61 + } 33.62 +} 33.63 + 33.64 +cw.write("abcd") 33.65 +cw.write("e".charAt(0)) 33.66 +cw.write("fgh".toCharArray()) 33.67 +cw.write("**ijk**", 2, 3) 33.68 +cw.write("***lmno**".toCharArray(), 3, 4) 33.69 +cw.flush() 33.70 +print(sw) 33.71 + 33.72 +// Can invoke super for Object methods 33.73 +print("cw has super hashCode(): " + (typeof cw.super$hashCode === "function")) 33.74 +print("cw has super equals(): " + (typeof cw.super$equals === "function")) 33.75 +// Can't invoke super for final methods 33.76 +print("cw has no super getClass(): " + (typeof cw.super$getClass === "undefined")) 33.77 +print("cw has no super wait(): " + (typeof cw.super$wait === "undefined")) 33.78 + 33.79 +var r = new (Java.type("java.lang.Runnable"))(function() {}) 33.80 +// Can't invoke super for abstract methods 33.81 +print("r has no super run(): " + (typeof r.super$run === "undefined")) 33.82 +// Interfaces can also invoke super Object methods 33.83 +print("r has super hashCode(): " + (typeof r.super$hashCode === "function")) 33.84 +print("r has super equals(): " + (typeof r.super$equals === "function")) 33.85 +// But still can't invoke final methods 33.86 +print("r has no super getClass(): " + (typeof r.super$getClass === "undefined")) 33.87 +print("r has no super wait(): " + (typeof r.super$wait === "undefined"))
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/test/script/basic/JDK-8023373.js.EXPECTED Fri Aug 23 16:44:02 2013 +0530 34.3 @@ -0,0 +1,10 @@ 34.4 +ABCDEFGHIJKLMNO 34.5 +cw has super hashCode(): true 34.6 +cw has super equals(): true 34.7 +cw has no super getClass(): true 34.8 +cw has no super wait(): true 34.9 +r has no super run(): true 34.10 +r has super hashCode(): true 34.11 +r has super equals(): true 34.12 +r has no super getClass(): true 34.13 +r has no super wait(): true
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/test/script/basic/JDK-8023531.js Fri Aug 23 16:44:02 2013 +0530 35.3 @@ -0,0 +1,106 @@ 35.4 +/* 35.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 35.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 35.7 + * 35.8 + * This code is free software; you can redistribute it and/or modify it 35.9 + * under the terms of the GNU General Public License version 2 only, as 35.10 + * published by the Free Software Foundation. 35.11 + * 35.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 35.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 35.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 35.15 + * version 2 for more details (a copy is included in the LICENSE file that 35.16 + * accompanied this code). 35.17 + * 35.18 + * You should have received a copy of the GNU General Public License version 35.19 + * 2 along with this work; if not, write to the Free Software Foundation, 35.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 35.21 + * 35.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 35.23 + * or visit www.oracle.com if you need additional information or have any 35.24 + * questions. 35.25 + */ 35.26 + 35.27 +/** 35.28 + * JDK-8023531: new RegExp('').toString() should return '/(?:)/' 35.29 + * 35.30 + * @test 35.31 + * @run 35.32 + */ 35.33 + 35.34 +if (new RegExp("").toString() !== "/(?:)/") { 35.35 + throw new Error(); 35.36 +} else if (!(new RegExp("").test(""))) { 35.37 + throw new Error(); 35.38 +} 35.39 + 35.40 +if (new RegExp("", "g").toString() !== "/(?:)/g") { 35.41 + throw new Error(); 35.42 +} else if (!(new RegExp("", "g").test(""))) { 35.43 + throw new Error(); 35.44 +} 35.45 + 35.46 +if (new RegExp("", "i").toString() !== "/(?:)/i") { 35.47 + throw new Error(); 35.48 +} else if (!(new RegExp("", "i").test(""))) { 35.49 + throw new Error(); 35.50 +} 35.51 + 35.52 +if (new RegExp("", "m").toString() !== "/(?:)/m") { 35.53 + throw new Error(); 35.54 +} else if (!(new RegExp("", "m").test(""))) { 35.55 + throw new Error(); 35.56 +} 35.57 + 35.58 +if (RegExp("").toString() !== "/(?:)/") { 35.59 + throw new Error(); 35.60 +} else if (!RegExp("").test("")) { 35.61 + throw new Error(); 35.62 +} 35.63 + 35.64 +if (RegExp("", "g").toString() !== "/(?:)/g") { 35.65 + throw new Error(); 35.66 +} else if (!RegExp("", "g").test("")) { 35.67 + throw new Error(); 35.68 +} 35.69 + 35.70 +if (RegExp("", "i").toString() !== "/(?:)/i") { 35.71 + throw new Error(); 35.72 +} else if (!RegExp("", "i").test("")) { 35.73 + throw new Error(); 35.74 +} 35.75 + 35.76 +if (RegExp("", "m").toString() !== "/(?:)/m") { 35.77 + throw new Error(); 35.78 +} else if (!RegExp("", "m").test("")) { 35.79 + throw new Error(); 35.80 +} 35.81 + 35.82 +var re = /abc/; 35.83 +re.compile(""); 35.84 +if (re.toString() !== "/(?:)/") { 35.85 + throw new Error(); 35.86 +} else if (!re.test("")) { 35.87 + throw new Error(); 35.88 +} 35.89 + 35.90 +re.compile("", "g"); 35.91 +if (re.toString() !== "/(?:)/g") { 35.92 + throw new Error(); 35.93 +} else if (!re.test("")) { 35.94 + throw new Error(); 35.95 +} 35.96 + 35.97 +re.compile("", "i"); 35.98 +if (re.toString() !== "/(?:)/i") { 35.99 + throw new Error(); 35.100 +} else if (!re.test("")) { 35.101 + throw new Error(); 35.102 +} 35.103 + 35.104 +re.compile("", "m"); 35.105 +if (re.toString() !== "/(?:)/m") { 35.106 + throw new Error(); 35.107 +} else if (!re.test("")) { 35.108 + throw new Error(); 35.109 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/test/script/basic/JDK-8023551.js Fri Aug 23 16:44:02 2013 +0530 36.3 @@ -0,0 +1,42 @@ 36.4 +/* 36.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 36.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 36.7 + * 36.8 + * This code is free software; you can redistribute it and/or modify it 36.9 + * under the terms of the GNU General Public License version 2 only, as 36.10 + * published by the Free Software Foundation. 36.11 + * 36.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 36.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 36.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 36.15 + * version 2 for more details (a copy is included in the LICENSE file that 36.16 + * accompanied this code). 36.17 + * 36.18 + * You should have received a copy of the GNU General Public License version 36.19 + * 2 along with this work; if not, write to the Free Software Foundation, 36.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 36.21 + * 36.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 36.23 + * or visit www.oracle.com if you need additional information or have any 36.24 + * questions. 36.25 + */ 36.26 + 36.27 +/** 36.28 + * JDK-8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction 36.29 + * 36.30 + * @test 36.31 + * @run 36.32 + */ 36.33 + 36.34 +var m = new javax.script.ScriptEngineManager(); 36.35 +var e = m.getEngineByName("nashorn"); 36.36 + 36.37 +function func(x) { 36.38 + print("func: " + x); 36.39 +} 36.40 + 36.41 +e.put("func", func); 36.42 +e.invokeFunction("func", "hello"); 36.43 + 36.44 +var obj = e.eval("({ foo: func })"); 36.45 +e.invokeMethod(obj, "foo", "world");
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/test/script/basic/JDK-8023551.js.EXPECTED Fri Aug 23 16:44:02 2013 +0530 37.3 @@ -0,0 +1,2 @@ 37.4 +func: hello 37.5 +func: world
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/test/script/basic/JDK-8023630.js Fri Aug 23 16:44:02 2013 +0530 38.3 @@ -0,0 +1,94 @@ 38.4 +/* 38.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 38.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 38.7 + * 38.8 + * This code is free software; you can redistribute it and/or modify it 38.9 + * under the terms of the GNU General Public License version 2 only, as 38.10 + * published by the Free Software Foundation. 38.11 + * 38.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 38.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 38.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 38.15 + * version 2 for more details (a copy is included in the LICENSE file that 38.16 + * accompanied this code). 38.17 + * 38.18 + * You should have received a copy of the GNU General Public License version 38.19 + * 2 along with this work; if not, write to the Free Software Foundation, 38.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 38.21 + * 38.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 38.23 + * or visit www.oracle.com if you need additional information or have any 38.24 + * questions. 38.25 + */ 38.26 + 38.27 +/** 38.28 + * JDK-8023630: Implement Java.super() as the preferred way to call super methods 38.29 + * 38.30 + * @test 38.31 + * @run 38.32 + */ 38.33 + 38.34 +var CharArray = Java.type("char[]") 38.35 +var jString = Java.type("java.lang.String") 38.36 +var Character = Java.type("java.lang.Character") 38.37 + 38.38 +function capitalize(s) { 38.39 + if(s instanceof CharArray) { 38.40 + return new jString(s).toUpperCase() 38.41 + } 38.42 + if(s instanceof jString) { 38.43 + return s.toUpperCase() 38.44 + } 38.45 + return Character.toUpperCase(s) // must be int 38.46 +} 38.47 + 38.48 +var sw = new (Java.type("java.io.StringWriter")) 38.49 + 38.50 +var FilterWriterAdapter = Java.extend(Java.type("java.io.FilterWriter")) 38.51 + 38.52 +var cw = new FilterWriterAdapter(sw) { 38.53 + write: function(s, off, len) { 38.54 + s = capitalize(s) 38.55 + // Must handle overloads by arity 38.56 + if(off === undefined) { 38.57 + cw_super.write(s, 0, s.length()) 38.58 + } else if (typeof s === "string") { 38.59 + cw_super.write(s, off, len) 38.60 + } 38.61 + } 38.62 +} 38.63 +var cw_super = Java.super(cw) 38.64 + 38.65 +cw.write("abcd") 38.66 +cw.write("e".charAt(0)) 38.67 +cw.write("fgh".toCharArray()) 38.68 +cw.write("**ijk**", 2, 3) 38.69 +cw.write("***lmno**".toCharArray(), 3, 4) 38.70 +cw.flush() 38.71 +print(sw) 38.72 + 38.73 +// Can invoke super for Object methods 38.74 +print("cw_super has hashCode(): " + (typeof cw_super.hashCode === "function")) 38.75 +print("cw_super has super equals(): " + (typeof cw_super.equals === "function")) 38.76 +// Can't invoke super for final methods 38.77 +print("cw_super has no getClass(): " + (typeof cw_super.getClass === "undefined")) 38.78 +print("cw_super has no wait(): " + (typeof cw_super.wait === "undefined")) 38.79 + 38.80 +var r = new (Java.type("java.lang.Runnable"))(function() {}) 38.81 +var r_super = Java.super(r) 38.82 + 38.83 +// Can't invoke super for abstract methods 38.84 +print("r_super has no run(): " + (typeof r_super.run === "undefined")) 38.85 +// Interfaces can also invoke super Object methods 38.86 +print("r_super has hashCode(): " + (typeof r_super.hashCode === "function")) 38.87 +print("r_super has equals(): " + (typeof r_super.equals === "function")) 38.88 +// But still can't invoke final methods 38.89 +print("r_super has no getClass(): " + (typeof r_super.getClass === "undefined")) 38.90 +print("r_super has no wait(): " + (typeof r_super.wait === "undefined")) 38.91 + 38.92 +var name = "write" 38.93 +print("cw_super can access write through [] getter: " + (typeof cw_super[name] === "function")) 38.94 +var name = "hashCode" 38.95 +print("cw_super can access hashCode through [] getter: " + (typeof cw_super[name] === "function")) 38.96 +var name = "getClass" 38.97 +print("cw_super can not access getClass through [] getter: " + (typeof cw_super[name] === "undefined"))
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/test/script/basic/JDK-8023630.js.EXPECTED Fri Aug 23 16:44:02 2013 +0530 39.3 @@ -0,0 +1,13 @@ 39.4 +ABCDEFGHIJKLMNO 39.5 +cw_super has hashCode(): true 39.6 +cw_super has super equals(): true 39.7 +cw_super has no getClass(): true 39.8 +cw_super has no wait(): true 39.9 +r_super has no run(): true 39.10 +r_super has hashCode(): true 39.11 +r_super has equals(): true 39.12 +r_super has no getClass(): true 39.13 +r_super has no wait(): true 39.14 +cw_super can access write through [] getter: true 39.15 +cw_super can access hashCode through [] getter: true 39.16 +cw_super can not access getClass through [] getter: true
40.1 --- a/test/script/basic/NASHORN-397.js Mon Aug 19 19:37:29 2013 +0530 40.2 +++ b/test/script/basic/NASHORN-397.js Fri Aug 23 16:44:02 2013 +0530 40.3 @@ -35,7 +35,10 @@ 40.4 fail("typeof(5).x is not 'number'"); 40.5 } 40.6 40.7 -if (typeof (java.lang.System.out) != 'object') { 40.8 +// It is function because PrintStream implements Closeable, which is 40.9 +// marked with @FunctionalInterface. Yes, this means calling a stream 40.10 +// like "stream()" closes it. 40.11 +if (typeof (java.lang.System.out) != 'function') { 40.12 fail("typeof java.lang.System.out is not 'object'"); 40.13 } 40.14
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/test/script/basic/circular_proto.js Fri Aug 23 16:44:02 2013 +0530 41.3 @@ -0,0 +1,46 @@ 41.4 +/* 41.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 41.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41.7 + * 41.8 + * This code is free software; you can redistribute it and/or modify it 41.9 + * under the terms of the GNU General Public License version 2 only, as 41.10 + * published by the Free Software Foundation. 41.11 + * 41.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 41.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 41.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 41.15 + * version 2 for more details (a copy is included in the LICENSE file that 41.16 + * accompanied this code). 41.17 + * 41.18 + * You should have received a copy of the GNU General Public License version 41.19 + * 2 along with this work; if not, write to the Free Software Foundation, 41.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 41.21 + * 41.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 41.23 + * or visit www.oracle.com if you need additional information or have any 41.24 + * questions. 41.25 + */ 41.26 + 41.27 +/** 41.28 + * JDK-8023368: Instance __proto__ property should exist and be writable. 41.29 + * 41.30 + * @test 41.31 + * @run 41.32 + */ 41.33 + 41.34 +// check that we cannot create __proto__ cycle 41.35 +load("nashorn:mozilla_compat.js"); 41.36 + 41.37 +var obj = {}; 41.38 +var obj2 = Object.create(obj); 41.39 + 41.40 +// attempt to create __proto__ cycle 41.41 +try { 41.42 + obj.__proto__ = obj2; 41.43 + fail("Should have thrown TypeError"); 41.44 +} catch (e) { 41.45 + if (! (e instanceof TypeError)) { 41.46 + fail("Expected TypeError, got " + e); 41.47 + } 41.48 + print(e); 41.49 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/test/script/basic/circular_proto.js.EXPECTED Fri Aug 23 16:44:02 2013 +0530 42.3 @@ -0,0 +1,1 @@ 42.4 +TypeError: Cannot create__proto__ cycle for [object Object]
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/test/script/basic/mirror_proto_assign.js Fri Aug 23 16:44:02 2013 +0530 43.3 @@ -0,0 +1,52 @@ 43.4 +/* 43.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 43.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 43.7 + * 43.8 + * This code is free software; you can redistribute it and/or modify it 43.9 + * under the terms of the GNU General Public License version 2 only, as 43.10 + * published by the Free Software Foundation. 43.11 + * 43.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 43.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 43.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 43.15 + * version 2 for more details (a copy is included in the LICENSE file that 43.16 + * accompanied this code). 43.17 + * 43.18 + * You should have received a copy of the GNU General Public License version 43.19 + * 2 along with this work; if not, write to the Free Software Foundation, 43.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 43.21 + * 43.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 43.23 + * or visit www.oracle.com if you need additional information or have any 43.24 + * questions. 43.25 + */ 43.26 + 43.27 +/** 43.28 + * JDK-8023368: Instance __proto__ property should exist and be writable. 43.29 + * 43.30 + * @test 43.31 + * @run 43.32 + */ 43.33 + 43.34 +// check that Object.setPrototypeOf works for mirror objects as well. 43.35 + 43.36 +var global = loadWithNewGlobal({ 43.37 + name: "test", 43.38 + script: "var obj = {}; this" 43.39 +}); 43.40 + 43.41 +var proto = global.eval("({ foo: 323 })"); 43.42 + 43.43 +Object.setPrototypeOf(global.obj, proto); 43.44 + 43.45 +function func(obj) { 43.46 + // check proto inherited value 43.47 + print("obj.foo = " + obj.foo); 43.48 +} 43.49 + 43.50 +func(global.obj); 43.51 + 43.52 +var newProto = global.eval("({ foo: 'hello' })"); 43.53 +Object.setPrototypeOf(global.obj, newProto); 43.54 + 43.55 +func(global.obj);
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/test/script/basic/mirror_proto_assign.js.EXPECTED Fri Aug 23 16:44:02 2013 +0530 44.3 @@ -0,0 +1,2 @@ 44.4 +obj.foo = 323 44.5 +obj.foo = hello
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/test/script/basic/nonextensible_proto_assign.js Fri Aug 23 16:44:02 2013 +0530 45.3 @@ -0,0 +1,44 @@ 45.4 +/* 45.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 45.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 45.7 + * 45.8 + * This code is free software; you can redistribute it and/or modify it 45.9 + * under the terms of the GNU General Public License version 2 only, as 45.10 + * published by the Free Software Foundation. 45.11 + * 45.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 45.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 45.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 45.15 + * version 2 for more details (a copy is included in the LICENSE file that 45.16 + * accompanied this code). 45.17 + * 45.18 + * You should have received a copy of the GNU General Public License version 45.19 + * 2 along with this work; if not, write to the Free Software Foundation, 45.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 45.21 + * 45.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 45.23 + * or visit www.oracle.com if you need additional information or have any 45.24 + * questions. 45.25 + */ 45.26 + 45.27 +/** 45.28 + * JDK-8023368: Instance __proto__ property should exist and be writable. 45.29 + * 45.30 + * @test 45.31 + * @run 45.32 + */ 45.33 + 45.34 +load("nashorn:mozilla_compat.js") 45.35 + 45.36 +// check that we cannot assign to __proto__ of a non-extensible object 45.37 +try { 45.38 + var obj = {} 45.39 + Object.preventExtensions(obj); 45.40 + obj.__proto__ = { }; 45.41 + fail("Should have thrown TypeError"); 45.42 +} catch (e) { 45.43 + if (! (e instanceof TypeError)) { 45.44 + fail("Expected TypeError, got " + e); 45.45 + } 45.46 + print(e); 45.47 +}
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/test/script/basic/nonextensible_proto_assign.js.EXPECTED Fri Aug 23 16:44:02 2013 +0530 46.3 @@ -0,0 +1,1 @@ 46.4 +TypeError: Cannot set __proto__ of non-extensible [object Object]
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/test/src/jdk/nashorn/api/scripting/InvocableTest.java Fri Aug 23 16:44:02 2013 +0530 47.3 @@ -0,0 +1,525 @@ 47.4 +/* 47.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 47.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 47.7 + * 47.8 + * This code is free software; you can redistribute it and/or modify it 47.9 + * under the terms of the GNU General Public License version 2 only, as 47.10 + * published by the Free Software Foundation. Oracle designates this 47.11 + * particular file as subject to the "Classpath" exception as provided 47.12 + * by Oracle in the LICENSE file that accompanied this code. 47.13 + * 47.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 47.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 47.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 47.17 + * version 2 for more details (a copy is included in the LICENSE file that 47.18 + * accompanied this code). 47.19 + * 47.20 + * You should have received a copy of the GNU General Public License version 47.21 + * 2 along with this work; if not, write to the Free Software Foundation, 47.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 47.23 + * 47.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 47.25 + * or visit www.oracle.com if you need additional information or have any 47.26 + * questions. 47.27 + */ 47.28 + 47.29 +package jdk.nashorn.api.scripting; 47.30 + 47.31 +import java.util.Objects; 47.32 +import javax.script.Invocable; 47.33 +import javax.script.ScriptContext; 47.34 +import javax.script.ScriptEngine; 47.35 +import javax.script.ScriptEngineManager; 47.36 +import javax.script.ScriptException; 47.37 +import javax.script.SimpleScriptContext; 47.38 +import org.testng.Assert; 47.39 +import static org.testng.Assert.assertEquals; 47.40 +import static org.testng.Assert.fail; 47.41 +import org.testng.annotations.Test; 47.42 + 47.43 +/** 47.44 + * Tests for javax.script.Invocable implementation of nashorn. 47.45 + */ 47.46 +public class InvocableTest { 47.47 + 47.48 + private void log(String msg) { 47.49 + org.testng.Reporter.log(msg, true); 47.50 + } 47.51 + 47.52 + @Test 47.53 + public void invokeMethodTest() { 47.54 + final ScriptEngineManager m = new ScriptEngineManager(); 47.55 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.56 + 47.57 + try { 47.58 + e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();"); 47.59 + final Object obj = e.get("myExample"); 47.60 + final Object res = ((Invocable) e).invokeMethod(obj, "hello"); 47.61 + assertEquals(res, "Hello World!"); 47.62 + } catch (final Exception exp) { 47.63 + exp.printStackTrace(); 47.64 + fail(exp.getMessage()); 47.65 + } 47.66 + } 47.67 + 47.68 + @Test 47.69 + /** 47.70 + * Check that we can call invokeMethod on an object that we got by 47.71 + * evaluating script with different Context set. 47.72 + */ 47.73 + public void invokeMethodDifferentContextTest() { 47.74 + ScriptEngineManager m = new ScriptEngineManager(); 47.75 + ScriptEngine e = m.getEngineByName("nashorn"); 47.76 + 47.77 + try { 47.78 + // define an object with method on it 47.79 + Object obj = e.eval("({ hello: function() { return 'Hello World!'; } })"); 47.80 + 47.81 + final ScriptContext ctxt = new SimpleScriptContext(); 47.82 + ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 47.83 + e.setContext(ctxt); 47.84 + 47.85 + // invoke 'func' on obj - but with current script context changed 47.86 + final Object res = ((Invocable) e).invokeMethod(obj, "hello"); 47.87 + assertEquals(res, "Hello World!"); 47.88 + } catch (final Exception exp) { 47.89 + exp.printStackTrace(); 47.90 + fail(exp.getMessage()); 47.91 + } 47.92 + } 47.93 + 47.94 + @Test 47.95 + /** 47.96 + * Check that invokeMethod throws NPE on null method name. 47.97 + */ 47.98 + public void invokeMethodNullNameTest() { 47.99 + final ScriptEngineManager m = new ScriptEngineManager(); 47.100 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.101 + 47.102 + try { 47.103 + final Object obj = e.eval("({})"); 47.104 + final Object res = ((Invocable) e).invokeMethod(obj, null); 47.105 + fail("should have thrown NPE"); 47.106 + } catch (final Exception exp) { 47.107 + if (!(exp instanceof NullPointerException)) { 47.108 + exp.printStackTrace(); 47.109 + fail(exp.getMessage()); 47.110 + } 47.111 + } 47.112 + } 47.113 + 47.114 + @Test 47.115 + /** 47.116 + * Check that invokeMethod throws NoSuchMethodException on missing method. 47.117 + */ 47.118 + public void invokeMethodMissingTest() { 47.119 + final ScriptEngineManager m = new ScriptEngineManager(); 47.120 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.121 + 47.122 + try { 47.123 + final Object obj = e.eval("({})"); 47.124 + final Object res = ((Invocable) e).invokeMethod(obj, "nonExistentMethod"); 47.125 + fail("should have thrown NoSuchMethodException"); 47.126 + } catch (final Exception exp) { 47.127 + if (!(exp instanceof NoSuchMethodException)) { 47.128 + exp.printStackTrace(); 47.129 + fail(exp.getMessage()); 47.130 + } 47.131 + } 47.132 + } 47.133 + 47.134 + @Test 47.135 + /** 47.136 + * Check that calling method on non-script object 'thiz' results in 47.137 + * IllegalArgumentException. 47.138 + */ 47.139 + public void invokeMethodNonScriptObjectThizTest() { 47.140 + final ScriptEngineManager m = new ScriptEngineManager(); 47.141 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.142 + 47.143 + try { 47.144 + ((Invocable) e).invokeMethod(new Object(), "toString"); 47.145 + fail("should have thrown IllegalArgumentException"); 47.146 + } catch (final Exception exp) { 47.147 + if (!(exp instanceof IllegalArgumentException)) { 47.148 + exp.printStackTrace(); 47.149 + fail(exp.getMessage()); 47.150 + } 47.151 + } 47.152 + } 47.153 + 47.154 + @Test 47.155 + /** 47.156 + * Check that calling method on null 'thiz' results in 47.157 + * IllegalArgumentException. 47.158 + */ 47.159 + public void invokeMethodNullThizTest() { 47.160 + final ScriptEngineManager m = new ScriptEngineManager(); 47.161 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.162 + 47.163 + try { 47.164 + ((Invocable) e).invokeMethod(null, "toString"); 47.165 + fail("should have thrown IllegalArgumentException"); 47.166 + } catch (final Exception exp) { 47.167 + if (!(exp instanceof IllegalArgumentException)) { 47.168 + exp.printStackTrace(); 47.169 + fail(exp.getMessage()); 47.170 + } 47.171 + } 47.172 + } 47.173 + 47.174 + @Test 47.175 + /** 47.176 + * Check that calling method on mirror created by another engine results in 47.177 + * IllegalArgumentException. 47.178 + */ 47.179 + public void invokeMethodMixEnginesTest() { 47.180 + final ScriptEngineManager m = new ScriptEngineManager(); 47.181 + final ScriptEngine engine1 = m.getEngineByName("nashorn"); 47.182 + final ScriptEngine engine2 = m.getEngineByName("nashorn"); 47.183 + 47.184 + try { 47.185 + Object obj = engine1.eval("({ run: function() {} })"); 47.186 + // pass object from engine1 to engine2 as 'thiz' for invokeMethod 47.187 + ((Invocable) engine2).invokeMethod(obj, "run"); 47.188 + fail("should have thrown IllegalArgumentException"); 47.189 + } catch (final Exception exp) { 47.190 + if (!(exp instanceof IllegalArgumentException)) { 47.191 + exp.printStackTrace(); 47.192 + fail(exp.getMessage()); 47.193 + } 47.194 + } 47.195 + } 47.196 + 47.197 + @Test 47.198 + public void getInterfaceTest() { 47.199 + final ScriptEngineManager m = new ScriptEngineManager(); 47.200 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.201 + final Invocable inv = (Invocable) e; 47.202 + 47.203 + // try to get interface from global functions 47.204 + try { 47.205 + e.eval("function run() { print('run'); };"); 47.206 + final Runnable runnable = inv.getInterface(Runnable.class); 47.207 + runnable.run(); 47.208 + } catch (final Exception exp) { 47.209 + exp.printStackTrace(); 47.210 + fail(exp.getMessage()); 47.211 + } 47.212 + 47.213 + // try interface on specific script object 47.214 + try { 47.215 + e.eval("var obj = { run: function() { print('run from obj'); } };"); 47.216 + Object obj = e.get("obj"); 47.217 + final Runnable runnable = inv.getInterface(obj, Runnable.class); 47.218 + runnable.run(); 47.219 + } catch (final Exception exp) { 47.220 + exp.printStackTrace(); 47.221 + fail(exp.getMessage()); 47.222 + } 47.223 + } 47.224 + 47.225 + public interface Foo { 47.226 + 47.227 + public void bar(); 47.228 + } 47.229 + 47.230 + public interface Foo2 extends Foo { 47.231 + 47.232 + public void bar2(); 47.233 + } 47.234 + 47.235 + @Test 47.236 + public void getInterfaceMissingTest() { 47.237 + final ScriptEngineManager manager = new ScriptEngineManager(); 47.238 + final ScriptEngine engine = manager.getEngineByName("nashorn"); 47.239 + 47.240 + // don't define any function. 47.241 + try { 47.242 + engine.eval(""); 47.243 + } catch (final Exception exp) { 47.244 + exp.printStackTrace(); 47.245 + fail(exp.getMessage()); 47.246 + } 47.247 + 47.248 + Runnable runnable = ((Invocable) engine).getInterface(Runnable.class); 47.249 + if (runnable != null) { 47.250 + fail("runnable is not null!"); 47.251 + } 47.252 + 47.253 + // now define "run" 47.254 + try { 47.255 + engine.eval("function run() { print('this is run function'); }"); 47.256 + } catch (final Exception exp) { 47.257 + exp.printStackTrace(); 47.258 + fail(exp.getMessage()); 47.259 + } 47.260 + runnable = ((Invocable) engine).getInterface(Runnable.class); 47.261 + // should not return null now! 47.262 + runnable.run(); 47.263 + 47.264 + // define only one method of "Foo2" 47.265 + try { 47.266 + engine.eval("function bar() { print('bar function'); }"); 47.267 + } catch (final Exception exp) { 47.268 + exp.printStackTrace(); 47.269 + fail(exp.getMessage()); 47.270 + } 47.271 + 47.272 + Foo2 foo2 = ((Invocable) engine).getInterface(Foo2.class); 47.273 + if (foo2 != null) { 47.274 + throw new RuntimeException("foo2 is not null!"); 47.275 + } 47.276 + 47.277 + // now define other method of "Foo2" 47.278 + try { 47.279 + engine.eval("function bar2() { print('bar2 function'); }"); 47.280 + } catch (final Exception exp) { 47.281 + exp.printStackTrace(); 47.282 + fail(exp.getMessage()); 47.283 + } 47.284 + foo2 = ((Invocable) engine).getInterface(Foo2.class); 47.285 + foo2.bar(); 47.286 + foo2.bar2(); 47.287 + } 47.288 + 47.289 + @Test 47.290 + /** 47.291 + * Try passing non-interface Class object for interface implementation. 47.292 + */ 47.293 + public void getNonInterfaceGetInterfaceTest() { 47.294 + final ScriptEngineManager manager = new ScriptEngineManager(); 47.295 + final ScriptEngine engine = manager.getEngineByName("nashorn"); 47.296 + try { 47.297 + log(Objects.toString(((Invocable) engine).getInterface(Object.class))); 47.298 + fail("Should have thrown IllegalArgumentException"); 47.299 + } catch (final Exception exp) { 47.300 + if (!(exp instanceof IllegalArgumentException)) { 47.301 + fail("IllegalArgumentException expected, got " + exp); 47.302 + } 47.303 + } 47.304 + } 47.305 + 47.306 + @Test 47.307 + /** 47.308 + * Check that we can get interface out of a script object even after 47.309 + * switching to use different ScriptContext. 47.310 + */ 47.311 + public void getInterfaceDifferentContext() { 47.312 + ScriptEngineManager m = new ScriptEngineManager(); 47.313 + ScriptEngine e = m.getEngineByName("nashorn"); 47.314 + try { 47.315 + Object obj = e.eval("({ run: function() { } })"); 47.316 + 47.317 + // change script context 47.318 + ScriptContext ctxt = new SimpleScriptContext(); 47.319 + ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 47.320 + e.setContext(ctxt); 47.321 + 47.322 + Runnable r = ((Invocable) e).getInterface(obj, Runnable.class); 47.323 + r.run(); 47.324 + } catch (final Exception exp) { 47.325 + exp.printStackTrace(); 47.326 + fail(exp.getMessage()); 47.327 + } 47.328 + } 47.329 + 47.330 + @Test 47.331 + /** 47.332 + * Check that getInterface on non-script object 'thiz' results in 47.333 + * IllegalArgumentException. 47.334 + */ 47.335 + public void getInterfaceNonScriptObjectThizTest() { 47.336 + final ScriptEngineManager m = new ScriptEngineManager(); 47.337 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.338 + 47.339 + try { 47.340 + ((Invocable) e).getInterface(new Object(), Runnable.class); 47.341 + fail("should have thrown IllegalArgumentException"); 47.342 + } catch (final Exception exp) { 47.343 + if (!(exp instanceof IllegalArgumentException)) { 47.344 + exp.printStackTrace(); 47.345 + fail(exp.getMessage()); 47.346 + } 47.347 + } 47.348 + } 47.349 + 47.350 + @Test 47.351 + /** 47.352 + * Check that getInterface on null 'thiz' results in 47.353 + * IllegalArgumentException. 47.354 + */ 47.355 + public void getInterfaceNullThizTest() { 47.356 + final ScriptEngineManager m = new ScriptEngineManager(); 47.357 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.358 + 47.359 + try { 47.360 + ((Invocable) e).getInterface(null, Runnable.class); 47.361 + fail("should have thrown IllegalArgumentException"); 47.362 + } catch (final Exception exp) { 47.363 + if (!(exp instanceof IllegalArgumentException)) { 47.364 + exp.printStackTrace(); 47.365 + fail(exp.getMessage()); 47.366 + } 47.367 + } 47.368 + } 47.369 + 47.370 + @Test 47.371 + /** 47.372 + * Check that calling getInterface on mirror created by another engine 47.373 + * results in IllegalArgumentException. 47.374 + */ 47.375 + public void getInterfaceMixEnginesTest() { 47.376 + final ScriptEngineManager m = new ScriptEngineManager(); 47.377 + final ScriptEngine engine1 = m.getEngineByName("nashorn"); 47.378 + final ScriptEngine engine2 = m.getEngineByName("nashorn"); 47.379 + 47.380 + try { 47.381 + Object obj = engine1.eval("({ run: function() {} })"); 47.382 + // pass object from engine1 to engine2 as 'thiz' for getInterface 47.383 + ((Invocable) engine2).getInterface(obj, Runnable.class); 47.384 + fail("should have thrown IllegalArgumentException"); 47.385 + } catch (final Exception exp) { 47.386 + if (!(exp instanceof IllegalArgumentException)) { 47.387 + exp.printStackTrace(); 47.388 + fail(exp.getMessage()); 47.389 + } 47.390 + } 47.391 + } 47.392 + 47.393 + @Test 47.394 + /** 47.395 + * check that null function name results in NPE. 47.396 + */ 47.397 + public void invokeFunctionNullNameTest() { 47.398 + final ScriptEngineManager m = new ScriptEngineManager(); 47.399 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.400 + 47.401 + try { 47.402 + final Object res = ((Invocable) e).invokeFunction(null); 47.403 + fail("should have thrown NPE"); 47.404 + } catch (final Exception exp) { 47.405 + if (!(exp instanceof NullPointerException)) { 47.406 + exp.printStackTrace(); 47.407 + fail(exp.getMessage()); 47.408 + } 47.409 + } 47.410 + } 47.411 + 47.412 + @Test 47.413 + /** 47.414 + * Check that attempt to call missing function results in 47.415 + * NoSuchMethodException. 47.416 + */ 47.417 + public void invokeFunctionMissingTest() { 47.418 + final ScriptEngineManager m = new ScriptEngineManager(); 47.419 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.420 + 47.421 + try { 47.422 + final Object res = ((Invocable) e).invokeFunction("NonExistentFunc"); 47.423 + fail("should have thrown NoSuchMethodException"); 47.424 + } catch (final Exception exp) { 47.425 + if (!(exp instanceof NoSuchMethodException)) { 47.426 + exp.printStackTrace(); 47.427 + fail(exp.getMessage()); 47.428 + } 47.429 + } 47.430 + } 47.431 + 47.432 + @Test 47.433 + /** 47.434 + * Check that invokeFunction calls functions only from current context's 47.435 + * Bindings. 47.436 + */ 47.437 + public void invokeFunctionDifferentContextTest() { 47.438 + ScriptEngineManager m = new ScriptEngineManager(); 47.439 + ScriptEngine e = m.getEngineByName("nashorn"); 47.440 + 47.441 + try { 47.442 + // define an object with method on it 47.443 + Object obj = e.eval("function hello() { return 'Hello World!'; }"); 47.444 + final ScriptContext ctxt = new SimpleScriptContext(); 47.445 + ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 47.446 + // change engine's current context 47.447 + e.setContext(ctxt); 47.448 + 47.449 + ((Invocable) e).invokeFunction("hello"); // no 'hello' in new context! 47.450 + fail("should have thrown NoSuchMethodException"); 47.451 + } catch (final Exception exp) { 47.452 + if (!(exp instanceof NoSuchMethodException)) { 47.453 + exp.printStackTrace(); 47.454 + fail(exp.getMessage()); 47.455 + } 47.456 + } 47.457 + } 47.458 + 47.459 + @Test 47.460 + public void invokeFunctionExceptionTest() { 47.461 + final ScriptEngineManager m = new ScriptEngineManager(); 47.462 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.463 + try { 47.464 + e.eval("function func() { throw new TypeError(); }"); 47.465 + } catch (final Throwable t) { 47.466 + t.printStackTrace(); 47.467 + fail(t.getMessage()); 47.468 + } 47.469 + 47.470 + try { 47.471 + ((Invocable) e).invokeFunction("func"); 47.472 + fail("should have thrown exception"); 47.473 + } catch (final ScriptException se) { 47.474 + // ECMA TypeError property wrapped as a ScriptException 47.475 + log("got " + se + " as expected"); 47.476 + } catch (final Throwable t) { 47.477 + t.printStackTrace(); 47.478 + fail(t.getMessage()); 47.479 + } 47.480 + } 47.481 + 47.482 + @Test 47.483 + public void invokeMethodExceptionTest() { 47.484 + final ScriptEngineManager m = new ScriptEngineManager(); 47.485 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.486 + try { 47.487 + e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }"); 47.488 + } catch (final Throwable t) { 47.489 + t.printStackTrace(); 47.490 + fail(t.getMessage()); 47.491 + } 47.492 + 47.493 + try { 47.494 + final Object sobj = e.get("sobj"); 47.495 + ((Invocable) e).invokeMethod(sobj, "foo"); 47.496 + fail("should have thrown exception"); 47.497 + } catch (final ScriptException se) { 47.498 + // ECMA TypeError property wrapped as a ScriptException 47.499 + log("got " + se + " as expected"); 47.500 + } catch (final Throwable t) { 47.501 + t.printStackTrace(); 47.502 + fail(t.getMessage()); 47.503 + } 47.504 + } 47.505 + 47.506 + @Test 47.507 + /** 47.508 + * Tests whether invocation of a JavaScript method through a variable arity 47.509 + * Java method will pass the vararg array. Both non-vararg and vararg 47.510 + * JavaScript methods are tested. 47.511 + * 47.512 + * @throws ScriptException 47.513 + */ 47.514 + public void variableArityInterfaceTest() throws ScriptException { 47.515 + final ScriptEngineManager m = new ScriptEngineManager(); 47.516 + final ScriptEngine e = m.getEngineByName("nashorn"); 47.517 + e.eval( 47.518 + "function test1(i, strings) {" 47.519 + + " return 'i == ' + i + ', strings instanceof java.lang.String[] == ' + (strings instanceof Java.type('java.lang.String[]')) + ', strings == ' + java.util.Arrays.toString(strings)" 47.520 + + "}" 47.521 + + "function test2() {" 47.522 + + " return 'arguments[0] == ' + arguments[0] + ', arguments[1] instanceof java.lang.String[] == ' + (arguments[1] instanceof Java.type('java.lang.String[]')) + ', arguments[1] == ' + java.util.Arrays.toString(arguments[1])" 47.523 + + "}"); 47.524 + final VariableArityTestInterface itf = ((Invocable) e).getInterface(VariableArityTestInterface.class); 47.525 + Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]"); 47.526 + Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]"); 47.527 + } 47.528 +}
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/test/src/jdk/nashorn/api/scripting/ScopeTest.java Fri Aug 23 16:44:02 2013 +0530 48.3 @@ -0,0 +1,248 @@ 48.4 +/* 48.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 48.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 48.7 + * 48.8 + * This code is free software; you can redistribute it and/or modify it 48.9 + * under the terms of the GNU General Public License version 2 only, as 48.10 + * published by the Free Software Foundation. Oracle designates this 48.11 + * particular file as subject to the "Classpath" exception as provided 48.12 + * by Oracle in the LICENSE file that accompanied this code. 48.13 + * 48.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 48.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 48.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 48.17 + * version 2 for more details (a copy is included in the LICENSE file that 48.18 + * accompanied this code). 48.19 + * 48.20 + * You should have received a copy of the GNU General Public License version 48.21 + * 2 along with this work; if not, write to the Free Software Foundation, 48.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 48.23 + * 48.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 48.25 + * or visit www.oracle.com if you need additional information or have any 48.26 + * questions. 48.27 + */ 48.28 +package jdk.nashorn.api.scripting; 48.29 + 48.30 +import javax.script.Bindings; 48.31 +import javax.script.ScriptContext; 48.32 +import javax.script.ScriptEngine; 48.33 +import javax.script.ScriptEngineManager; 48.34 +import javax.script.ScriptException; 48.35 +import javax.script.SimpleBindings; 48.36 +import javax.script.SimpleScriptContext; 48.37 +import org.testng.Assert; 48.38 +import static org.testng.Assert.assertEquals; 48.39 +import static org.testng.Assert.assertNotNull; 48.40 +import static org.testng.Assert.assertTrue; 48.41 +import static org.testng.Assert.fail; 48.42 +import org.testng.annotations.Test; 48.43 + 48.44 +/** 48.45 + * Tests for jsr223 Bindings "scope" (engine, global scopes) 48.46 + */ 48.47 +public class ScopeTest { 48.48 + 48.49 + @Test 48.50 + public void createBindingsTest() { 48.51 + final ScriptEngineManager m = new ScriptEngineManager(); 48.52 + final ScriptEngine e = m.getEngineByName("nashorn"); 48.53 + Bindings b = e.createBindings(); 48.54 + b.put("foo", 42.0); 48.55 + Object res = null; 48.56 + try { 48.57 + res = e.eval("foo == 42.0", b); 48.58 + } catch (final ScriptException | NullPointerException se) { 48.59 + se.printStackTrace(); 48.60 + fail(se.getMessage()); 48.61 + } 48.62 + 48.63 + assertEquals(res, Boolean.TRUE); 48.64 + } 48.65 + 48.66 + @Test 48.67 + public void engineScopeTest() { 48.68 + final ScriptEngineManager m = new ScriptEngineManager(); 48.69 + final ScriptEngine e = m.getEngineByName("nashorn"); 48.70 + Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE); 48.71 + 48.72 + // check few ECMA standard built-in global properties 48.73 + assertNotNull(engineScope.get("Object")); 48.74 + assertNotNull(engineScope.get("TypeError")); 48.75 + assertNotNull(engineScope.get("eval")); 48.76 + 48.77 + // can access via ScriptEngine.get as well 48.78 + assertNotNull(e.get("Object")); 48.79 + assertNotNull(e.get("TypeError")); 48.80 + assertNotNull(e.get("eval")); 48.81 + 48.82 + // Access by either way should return same object 48.83 + assertEquals(engineScope.get("Array"), e.get("Array")); 48.84 + assertEquals(engineScope.get("EvalError"), e.get("EvalError")); 48.85 + assertEquals(engineScope.get("undefined"), e.get("undefined")); 48.86 + 48.87 + // try exposing a new variable from scope 48.88 + engineScope.put("myVar", "foo"); 48.89 + try { 48.90 + assertEquals(e.eval("myVar"), "foo"); 48.91 + } catch (final ScriptException se) { 48.92 + se.printStackTrace(); 48.93 + fail(se.getMessage()); 48.94 + } 48.95 + 48.96 + // update "myVar" in script an check the value from scope 48.97 + try { 48.98 + e.eval("myVar = 'nashorn';"); 48.99 + } catch (final ScriptException se) { 48.100 + se.printStackTrace(); 48.101 + fail(se.getMessage()); 48.102 + } 48.103 + 48.104 + // now check modified value from scope and engine 48.105 + assertEquals(engineScope.get("myVar"), "nashorn"); 48.106 + assertEquals(e.get("myVar"), "nashorn"); 48.107 + } 48.108 + 48.109 + @Test 48.110 + public void multiGlobalTest() { 48.111 + final ScriptEngineManager m = new ScriptEngineManager(); 48.112 + final ScriptEngine e = m.getEngineByName("nashorn"); 48.113 + final Bindings b = e.createBindings(); 48.114 + final ScriptContext newCtxt = new SimpleScriptContext(); 48.115 + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); 48.116 + 48.117 + try { 48.118 + Object obj1 = e.eval("Object"); 48.119 + Object obj2 = e.eval("Object", newCtxt); 48.120 + Assert.assertNotEquals(obj1, obj2); 48.121 + Assert.assertNotNull(obj1); 48.122 + Assert.assertNotNull(obj2); 48.123 + Assert.assertEquals(obj1.toString(), obj2.toString()); 48.124 + 48.125 + e.eval("x = 'hello'"); 48.126 + e.eval("x = 'world'", newCtxt); 48.127 + Object x1 = e.getContext().getAttribute("x"); 48.128 + Object x2 = newCtxt.getAttribute("x"); 48.129 + Assert.assertNotEquals(x1, x2); 48.130 + Assert.assertEquals(x1, "hello"); 48.131 + Assert.assertEquals(x2, "world"); 48.132 + 48.133 + x1 = e.eval("x"); 48.134 + x2 = e.eval("x", newCtxt); 48.135 + Assert.assertNotEquals(x1, x2); 48.136 + Assert.assertEquals(x1, "hello"); 48.137 + Assert.assertEquals(x2, "world"); 48.138 + 48.139 + final ScriptContext origCtxt = e.getContext(); 48.140 + e.setContext(newCtxt); 48.141 + e.eval("y = new Object()"); 48.142 + e.eval("y = new Object()", origCtxt); 48.143 + 48.144 + Object y1 = origCtxt.getAttribute("y"); 48.145 + Object y2 = newCtxt.getAttribute("y"); 48.146 + Assert.assertNotEquals(y1, y2); 48.147 + Assert.assertNotEquals(e.eval("y"), e.eval("y", origCtxt)); 48.148 + Assert.assertEquals("[object Object]", y1.toString()); 48.149 + Assert.assertEquals("[object Object]", y2.toString()); 48.150 + } catch (final ScriptException se) { 48.151 + se.printStackTrace(); 48.152 + fail(se.getMessage()); 48.153 + } 48.154 + } 48.155 + 48.156 + @Test 48.157 + public void userEngineScopeBindingsTest() throws ScriptException { 48.158 + final ScriptEngineManager m = new ScriptEngineManager(); 48.159 + final ScriptEngine e = m.getEngineByName("nashorn"); 48.160 + e.eval("function func() {}"); 48.161 + 48.162 + final ScriptContext newContext = new SimpleScriptContext(); 48.163 + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 48.164 + // we are using a new bindings - so it should have 'func' defined 48.165 + Object value = e.eval("typeof func", newContext); 48.166 + assertTrue(value.equals("undefined")); 48.167 + } 48.168 + 48.169 + @Test 48.170 + public void userEngineScopeBindingsNoLeakTest() throws ScriptException { 48.171 + final ScriptEngineManager m = new ScriptEngineManager(); 48.172 + final ScriptEngine e = m.getEngineByName("nashorn"); 48.173 + final ScriptContext newContext = new SimpleScriptContext(); 48.174 + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 48.175 + e.eval("function foo() {}", newContext); 48.176 + 48.177 + // in the default context's ENGINE_SCOPE, 'foo' shouldn't exist 48.178 + assertTrue(e.eval("typeof foo").equals("undefined")); 48.179 + } 48.180 + 48.181 + @Test 48.182 + public void userEngineScopeBindingsRetentionTest() throws ScriptException { 48.183 + final ScriptEngineManager m = new ScriptEngineManager(); 48.184 + final ScriptEngine e = m.getEngineByName("nashorn"); 48.185 + final ScriptContext newContext = new SimpleScriptContext(); 48.186 + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 48.187 + e.eval("function foo() {}", newContext); 48.188 + 48.189 + // definition retained with user's ENGINE_SCOPE Binding 48.190 + assertTrue(e.eval("typeof foo", newContext).equals("function")); 48.191 + 48.192 + final Bindings oldBindings = newContext.getBindings(ScriptContext.ENGINE_SCOPE); 48.193 + // but not in another ENGINE_SCOPE binding 48.194 + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 48.195 + assertTrue(e.eval("typeof foo", newContext).equals("undefined")); 48.196 + 48.197 + // restore ENGINE_SCOPE and check again 48.198 + newContext.setBindings(oldBindings, ScriptContext.ENGINE_SCOPE); 48.199 + assertTrue(e.eval("typeof foo", newContext).equals("function")); 48.200 + } 48.201 + 48.202 + @Test 48.203 + // check that engine.js definitions are visible in all new global instances 48.204 + public void checkBuiltinsInNewBindingsTest() throws ScriptException { 48.205 + final ScriptEngineManager m = new ScriptEngineManager(); 48.206 + final ScriptEngine e = m.getEngineByName("nashorn"); 48.207 + 48.208 + // check default global instance has engine.js definitions 48.209 + final Bindings g = (Bindings) e.eval("this"); 48.210 + Object value = g.get("__noSuchProperty__"); 48.211 + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); 48.212 + value = g.get("print"); 48.213 + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); 48.214 + 48.215 + // check new global instance created has engine.js definitions 48.216 + Bindings b = e.createBindings(); 48.217 + value = b.get("__noSuchProperty__"); 48.218 + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); 48.219 + value = b.get("print"); 48.220 + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); 48.221 + 48.222 + // put a mapping into GLOBAL_SCOPE 48.223 + final Bindings globalScope = e.getContext().getBindings(ScriptContext.GLOBAL_SCOPE); 48.224 + globalScope.put("x", "hello"); 48.225 + 48.226 + // GLOBAL_SCOPE mapping should be visible from default ScriptContext eval 48.227 + assertTrue(e.eval("x").equals("hello")); 48.228 + 48.229 + final ScriptContext ctx = new SimpleScriptContext(); 48.230 + ctx.setBindings(globalScope, ScriptContext.GLOBAL_SCOPE); 48.231 + ctx.setBindings(b, ScriptContext.ENGINE_SCOPE); 48.232 + 48.233 + // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval 48.234 + assertTrue(e.eval("x", ctx).equals("hello")); 48.235 + 48.236 + // try some arbitray Bindings for ENGINE_SCOPE 48.237 + Bindings sb = new SimpleBindings(); 48.238 + ctx.setBindings(sb, ScriptContext.ENGINE_SCOPE); 48.239 + 48.240 + // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval 48.241 + assertTrue(e.eval("x", ctx).equals("hello")); 48.242 + 48.243 + // engine.js builtins are still defined even with arbitrary Bindings 48.244 + assertTrue(e.eval("typeof print", ctx).equals("function")); 48.245 + assertTrue(e.eval("typeof __noSuchProperty__", ctx).equals("function")); 48.246 + 48.247 + // ENGINE_SCOPE definition should 'hide' GLOBAL_SCOPE definition 48.248 + sb.put("x", "newX"); 48.249 + assertTrue(e.eval("x", ctx).equals("newX")); 48.250 + } 48.251 +}
49.1 --- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Mon Aug 19 19:37:29 2013 +0530 49.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Fri Aug 23 16:44:02 2013 +0530 49.3 @@ -26,7 +26,6 @@ 49.4 package jdk.nashorn.api.scripting; 49.5 49.6 import static org.testng.Assert.assertEquals; 49.7 -import static org.testng.Assert.assertFalse; 49.8 import static org.testng.Assert.assertNotNull; 49.9 import static org.testng.Assert.assertTrue; 49.10 import static org.testng.Assert.fail; 49.11 @@ -34,21 +33,13 @@ 49.12 import java.io.StringReader; 49.13 import java.io.StringWriter; 49.14 import java.lang.reflect.Method; 49.15 -import java.util.HashMap; 49.16 -import java.util.Map; 49.17 -import java.util.Objects; 49.18 import java.util.concurrent.Callable; 49.19 -import javax.script.Bindings; 49.20 import javax.script.Compilable; 49.21 import javax.script.CompiledScript; 49.22 -import javax.script.Invocable; 49.23 -import javax.script.ScriptContext; 49.24 import javax.script.ScriptEngine; 49.25 import javax.script.ScriptEngineFactory; 49.26 import javax.script.ScriptEngineManager; 49.27 import javax.script.ScriptException; 49.28 -import javax.script.SimpleScriptContext; 49.29 -import org.testng.Assert; 49.30 import org.testng.annotations.Test; 49.31 49.32 /** 49.33 @@ -239,214 +230,6 @@ 49.34 } 49.35 49.36 @Test 49.37 - public void createBindingsTest() { 49.38 - final ScriptEngineManager m = new ScriptEngineManager(); 49.39 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.40 - Bindings b = e.createBindings(); 49.41 - b.put("foo", 42.0); 49.42 - Object res = null; 49.43 - try { 49.44 - res = e.eval("foo == 42.0", b); 49.45 - } catch (final ScriptException | NullPointerException se) { 49.46 - se.printStackTrace(); 49.47 - fail(se.getMessage()); 49.48 - } 49.49 - 49.50 - assertEquals(res, Boolean.TRUE); 49.51 - } 49.52 - 49.53 - @Test 49.54 - public void getInterfaceTest() { 49.55 - final ScriptEngineManager m = new ScriptEngineManager(); 49.56 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.57 - final Invocable inv = (Invocable)e; 49.58 - 49.59 - // try to get interface from global functions 49.60 - try { 49.61 - e.eval("function run() { print('run'); };"); 49.62 - final Runnable runnable = inv.getInterface(Runnable.class); 49.63 - runnable.run(); 49.64 - } catch (final Exception exp) { 49.65 - exp.printStackTrace(); 49.66 - fail(exp.getMessage()); 49.67 - } 49.68 - 49.69 - // try interface on specific script object 49.70 - try { 49.71 - e.eval("var obj = { run: function() { print('run from obj'); } };"); 49.72 - Object obj = e.get("obj"); 49.73 - final Runnable runnable = inv.getInterface(obj, Runnable.class); 49.74 - runnable.run(); 49.75 - } catch (final Exception exp) { 49.76 - exp.printStackTrace(); 49.77 - fail(exp.getMessage()); 49.78 - } 49.79 - } 49.80 - 49.81 - public interface Foo { 49.82 - public void bar(); 49.83 - } 49.84 - 49.85 - public interface Foo2 extends Foo { 49.86 - public void bar2(); 49.87 - } 49.88 - 49.89 - @Test 49.90 - public void getInterfaceMissingTest() { 49.91 - final ScriptEngineManager manager = new ScriptEngineManager(); 49.92 - final ScriptEngine engine = manager.getEngineByName("nashorn"); 49.93 - 49.94 - // don't define any function. 49.95 - try { 49.96 - engine.eval(""); 49.97 - } catch (final Exception exp) { 49.98 - exp.printStackTrace(); 49.99 - fail(exp.getMessage()); 49.100 - } 49.101 - 49.102 - Runnable runnable = ((Invocable)engine).getInterface(Runnable.class); 49.103 - if (runnable != null) { 49.104 - fail("runnable is not null!"); 49.105 - } 49.106 - 49.107 - // now define "run" 49.108 - try { 49.109 - engine.eval("function run() { print('this is run function'); }"); 49.110 - } catch (final Exception exp) { 49.111 - exp.printStackTrace(); 49.112 - fail(exp.getMessage()); 49.113 - } 49.114 - runnable = ((Invocable)engine).getInterface(Runnable.class); 49.115 - // should not return null now! 49.116 - runnable.run(); 49.117 - 49.118 - // define only one method of "Foo2" 49.119 - try { 49.120 - engine.eval("function bar() { print('bar function'); }"); 49.121 - } catch (final Exception exp) { 49.122 - exp.printStackTrace(); 49.123 - fail(exp.getMessage()); 49.124 - } 49.125 - 49.126 - Foo2 foo2 = ((Invocable)engine).getInterface(Foo2.class); 49.127 - if (foo2 != null) { 49.128 - throw new RuntimeException("foo2 is not null!"); 49.129 - } 49.130 - 49.131 - // now define other method of "Foo2" 49.132 - try { 49.133 - engine.eval("function bar2() { print('bar2 function'); }"); 49.134 - } catch (final Exception exp) { 49.135 - exp.printStackTrace(); 49.136 - fail(exp.getMessage()); 49.137 - } 49.138 - foo2 = ((Invocable)engine).getInterface(Foo2.class); 49.139 - foo2.bar(); 49.140 - foo2.bar2(); 49.141 - } 49.142 - 49.143 - @Test 49.144 - /** 49.145 - * Try passing non-interface Class object for interface implementation. 49.146 - */ 49.147 - public void getNonInterfaceGetInterfaceTest() { 49.148 - final ScriptEngineManager manager = new ScriptEngineManager(); 49.149 - final ScriptEngine engine = manager.getEngineByName("nashorn"); 49.150 - try { 49.151 - log(Objects.toString(((Invocable)engine).getInterface(Object.class))); 49.152 - fail("Should have thrown IllegalArgumentException"); 49.153 - } catch (final Exception exp) { 49.154 - if (! (exp instanceof IllegalArgumentException)) { 49.155 - fail("IllegalArgumentException expected, got " + exp); 49.156 - } 49.157 - } 49.158 - } 49.159 - 49.160 - @Test 49.161 - /** 49.162 - * Check that we can get interface out of a script object even after 49.163 - * switching to use different ScriptContext. 49.164 - */ 49.165 - public void getInterfaceDifferentContext() { 49.166 - ScriptEngineManager m = new ScriptEngineManager(); 49.167 - ScriptEngine e = m.getEngineByName("nashorn"); 49.168 - try { 49.169 - Object obj = e.eval("({ run: function() { } })"); 49.170 - 49.171 - // change script context 49.172 - ScriptContext ctxt = new SimpleScriptContext(); 49.173 - ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 49.174 - e.setContext(ctxt); 49.175 - 49.176 - Runnable r = ((Invocable)e).getInterface(obj, Runnable.class); 49.177 - r.run(); 49.178 - }catch (final Exception exp) { 49.179 - exp.printStackTrace(); 49.180 - fail(exp.getMessage()); 49.181 - } 49.182 - } 49.183 - 49.184 - @Test 49.185 - /** 49.186 - * Check that getInterface on non-script object 'thiz' results in IllegalArgumentException. 49.187 - */ 49.188 - public void getInterfaceNonScriptObjectThizTest() { 49.189 - final ScriptEngineManager m = new ScriptEngineManager(); 49.190 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.191 - 49.192 - try { 49.193 - ((Invocable)e).getInterface(new Object(), Runnable.class); 49.194 - fail("should have thrown IllegalArgumentException"); 49.195 - } catch (final Exception exp) { 49.196 - if (! (exp instanceof IllegalArgumentException)) { 49.197 - exp.printStackTrace(); 49.198 - fail(exp.getMessage()); 49.199 - } 49.200 - } 49.201 - } 49.202 - 49.203 - @Test 49.204 - /** 49.205 - * Check that getInterface on null 'thiz' results in IllegalArgumentException. 49.206 - */ 49.207 - public void getInterfaceNullThizTest() { 49.208 - final ScriptEngineManager m = new ScriptEngineManager(); 49.209 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.210 - 49.211 - try { 49.212 - ((Invocable)e).getInterface(null, Runnable.class); 49.213 - fail("should have thrown IllegalArgumentException"); 49.214 - } catch (final Exception exp) { 49.215 - if (! (exp instanceof IllegalArgumentException)) { 49.216 - exp.printStackTrace(); 49.217 - fail(exp.getMessage()); 49.218 - } 49.219 - } 49.220 - } 49.221 - 49.222 - @Test 49.223 - /** 49.224 - * Check that calling getInterface on mirror created by another engine results in IllegalArgumentException. 49.225 - */ 49.226 - public void getInterfaceMixEnginesTest() { 49.227 - final ScriptEngineManager m = new ScriptEngineManager(); 49.228 - final ScriptEngine engine1 = m.getEngineByName("nashorn"); 49.229 - final ScriptEngine engine2 = m.getEngineByName("nashorn"); 49.230 - 49.231 - try { 49.232 - Object obj = engine1.eval("({ run: function() {} })"); 49.233 - // pass object from engine1 to engine2 as 'thiz' for getInterface 49.234 - ((Invocable)engine2).getInterface(obj, Runnable.class); 49.235 - fail("should have thrown IllegalArgumentException"); 49.236 - } catch (final Exception exp) { 49.237 - if (! (exp instanceof IllegalArgumentException)) { 49.238 - exp.printStackTrace(); 49.239 - fail(exp.getMessage()); 49.240 - } 49.241 - } 49.242 - } 49.243 - 49.244 - @Test 49.245 public void accessGlobalTest() { 49.246 final ScriptEngineManager m = new ScriptEngineManager(); 49.247 final ScriptEngine e = m.getEngineByName("nashorn"); 49.248 @@ -621,88 +404,6 @@ 49.249 assertEquals(sw.toString().replaceAll("\r", ""), "hello world\n"); 49.250 } 49.251 49.252 - @SuppressWarnings("unchecked") 49.253 - @Test 49.254 - public void reflectionTest() throws ScriptException { 49.255 - final ScriptEngineManager m = new ScriptEngineManager(); 49.256 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.257 - 49.258 - e.eval("var obj = { x: 344, y: 'nashorn' }"); 49.259 - 49.260 - int count = 0; 49.261 - Map<Object, Object> map = (Map<Object, Object>)e.get("obj"); 49.262 - assertFalse(map.isEmpty()); 49.263 - assertTrue(map.keySet().contains("x")); 49.264 - assertTrue(map.containsKey("x")); 49.265 - assertTrue(map.values().contains("nashorn")); 49.266 - assertTrue(map.containsValue("nashorn")); 49.267 - for (final Map.Entry<?, ?> ex : map.entrySet()) { 49.268 - final Object key = ex.getKey(); 49.269 - if (key.equals("x")) { 49.270 - assertTrue(344 == ((Number)ex.getValue()).doubleValue()); 49.271 - count++; 49.272 - } else if (key.equals("y")) { 49.273 - assertEquals(ex.getValue(), "nashorn"); 49.274 - count++; 49.275 - } 49.276 - } 49.277 - assertEquals(2, count); 49.278 - assertEquals(2, map.size()); 49.279 - 49.280 - // add property 49.281 - map.put("z", "hello"); 49.282 - assertEquals(e.eval("obj.z"), "hello"); 49.283 - assertEquals(map.get("z"), "hello"); 49.284 - assertTrue(map.keySet().contains("z")); 49.285 - assertTrue(map.containsKey("z")); 49.286 - assertTrue(map.values().contains("hello")); 49.287 - assertTrue(map.containsValue("hello")); 49.288 - assertEquals(map.size(), 3); 49.289 - 49.290 - final Map<Object, Object> newMap = new HashMap<>(); 49.291 - newMap.put("foo", 23.0); 49.292 - newMap.put("bar", true); 49.293 - map.putAll(newMap); 49.294 - 49.295 - assertEquals(e.eval("obj.foo"), 23.0); 49.296 - assertEquals(e.eval("obj.bar"), true); 49.297 - 49.298 - // remove using map method 49.299 - map.remove("foo"); 49.300 - assertEquals(e.eval("typeof obj.foo"), "undefined"); 49.301 - 49.302 - count = 0; 49.303 - e.eval("var arr = [ true, 'hello' ]"); 49.304 - map = (Map<Object, Object>)e.get("arr"); 49.305 - assertFalse(map.isEmpty()); 49.306 - assertTrue(map.containsKey("length")); 49.307 - assertTrue(map.containsValue("hello")); 49.308 - for (final Map.Entry<?, ?> ex : map.entrySet()) { 49.309 - final Object key = ex.getKey(); 49.310 - if (key.equals("0")) { 49.311 - assertEquals(ex.getValue(), Boolean.TRUE); 49.312 - count++; 49.313 - } else if (key.equals("1")) { 49.314 - assertEquals(ex.getValue(), "hello"); 49.315 - count++; 49.316 - } 49.317 - } 49.318 - assertEquals(count, 2); 49.319 - assertEquals(map.size(), 2); 49.320 - 49.321 - // add element 49.322 - map.put("2", "world"); 49.323 - assertEquals(map.get("2"), "world"); 49.324 - assertEquals(map.size(), 3); 49.325 - 49.326 - // remove all 49.327 - map.clear(); 49.328 - assertTrue(map.isEmpty()); 49.329 - assertEquals(e.eval("typeof arr[0]"), "undefined"); 49.330 - assertEquals(e.eval("typeof arr[1]"), "undefined"); 49.331 - assertEquals(e.eval("typeof arr[2]"), "undefined"); 49.332 - } 49.333 - 49.334 @Test 49.335 public void redefineEchoTest() { 49.336 final ScriptEngineManager m = new ScriptEngineManager(); 49.337 @@ -715,150 +416,6 @@ 49.338 fail(exp.getMessage()); 49.339 } 49.340 } 49.341 - 49.342 - @Test 49.343 - public void invokeMethodTest() { 49.344 - final ScriptEngineManager m = new ScriptEngineManager(); 49.345 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.346 - 49.347 - try { 49.348 - e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();"); 49.349 - final Object obj = e.get("myExample"); 49.350 - final Object res = ((Invocable)e).invokeMethod(obj, "hello"); 49.351 - assertEquals(res, "Hello World!"); 49.352 - } catch (final Exception exp) { 49.353 - exp.printStackTrace(); 49.354 - fail(exp.getMessage()); 49.355 - } 49.356 - } 49.357 - 49.358 - @Test 49.359 - /** 49.360 - * Check that we can call invokeMethod on an object that we got by evaluating 49.361 - * script with different Context set. 49.362 - */ 49.363 - public void invokeMethodDifferentContextTest() { 49.364 - ScriptEngineManager m = new ScriptEngineManager(); 49.365 - ScriptEngine e = m.getEngineByName("nashorn"); 49.366 - 49.367 - try { 49.368 - // define an object with method on it 49.369 - Object obj = e.eval("({ hello: function() { return 'Hello World!'; } })"); 49.370 - 49.371 - final ScriptContext ctxt = new SimpleScriptContext(); 49.372 - ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 49.373 - e.setContext(ctxt); 49.374 - 49.375 - // invoke 'func' on obj - but with current script context changed 49.376 - final Object res = ((Invocable)e).invokeMethod(obj, "hello"); 49.377 - assertEquals(res, "Hello World!"); 49.378 - } catch (final Exception exp) { 49.379 - exp.printStackTrace(); 49.380 - fail(exp.getMessage()); 49.381 - } 49.382 - } 49.383 - 49.384 - @Test 49.385 - /** 49.386 - * Check that invokeMethod throws NPE on null method name. 49.387 - */ 49.388 - public void invokeMethodNullNameTest() { 49.389 - final ScriptEngineManager m = new ScriptEngineManager(); 49.390 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.391 - 49.392 - try { 49.393 - final Object obj = e.eval("({})"); 49.394 - final Object res = ((Invocable)e).invokeMethod(obj, null); 49.395 - fail("should have thrown NPE"); 49.396 - } catch (final Exception exp) { 49.397 - if (! (exp instanceof NullPointerException)) { 49.398 - exp.printStackTrace(); 49.399 - fail(exp.getMessage()); 49.400 - } 49.401 - } 49.402 - } 49.403 - 49.404 - @Test 49.405 - /** 49.406 - * Check that invokeMethod throws NoSuchMethodException on missing method. 49.407 - */ 49.408 - public void invokeMethodMissingTest() { 49.409 - final ScriptEngineManager m = new ScriptEngineManager(); 49.410 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.411 - 49.412 - try { 49.413 - final Object obj = e.eval("({})"); 49.414 - final Object res = ((Invocable)e).invokeMethod(obj, "nonExistentMethod"); 49.415 - fail("should have thrown NoSuchMethodException"); 49.416 - } catch (final Exception exp) { 49.417 - if (! (exp instanceof NoSuchMethodException)) { 49.418 - exp.printStackTrace(); 49.419 - fail(exp.getMessage()); 49.420 - } 49.421 - } 49.422 - } 49.423 - 49.424 - @Test 49.425 - /** 49.426 - * Check that calling method on non-script object 'thiz' results in IllegalArgumentException. 49.427 - */ 49.428 - public void invokeMethodNonScriptObjectThizTest() { 49.429 - final ScriptEngineManager m = new ScriptEngineManager(); 49.430 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.431 - 49.432 - try { 49.433 - ((Invocable)e).invokeMethod(new Object(), "toString"); 49.434 - fail("should have thrown IllegalArgumentException"); 49.435 - } catch (final Exception exp) { 49.436 - if (! (exp instanceof IllegalArgumentException)) { 49.437 - exp.printStackTrace(); 49.438 - fail(exp.getMessage()); 49.439 - } 49.440 - } 49.441 - } 49.442 - 49.443 - @Test 49.444 - /** 49.445 - * Check that calling method on null 'thiz' results in IllegalArgumentException. 49.446 - */ 49.447 - public void invokeMethodNullThizTest() { 49.448 - final ScriptEngineManager m = new ScriptEngineManager(); 49.449 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.450 - 49.451 - try { 49.452 - ((Invocable)e).invokeMethod(null, "toString"); 49.453 - fail("should have thrown IllegalArgumentException"); 49.454 - } catch (final Exception exp) { 49.455 - if (! (exp instanceof IllegalArgumentException)) { 49.456 - exp.printStackTrace(); 49.457 - fail(exp.getMessage()); 49.458 - } 49.459 - } 49.460 - } 49.461 - 49.462 - 49.463 - @Test 49.464 - /** 49.465 - * Check that calling method on mirror created by another engine results in IllegalArgumentException. 49.466 - */ 49.467 - public void invokeMethodMixEnginesTest() { 49.468 - final ScriptEngineManager m = new ScriptEngineManager(); 49.469 - final ScriptEngine engine1 = m.getEngineByName("nashorn"); 49.470 - final ScriptEngine engine2 = m.getEngineByName("nashorn"); 49.471 - 49.472 - try { 49.473 - Object obj = engine1.eval("({ run: function() {} })"); 49.474 - // pass object from engine1 to engine2 as 'thiz' for invokeMethod 49.475 - ((Invocable)engine2).invokeMethod(obj, "run"); 49.476 - fail("should have thrown IllegalArgumentException"); 49.477 - } catch (final Exception exp) { 49.478 - if (! (exp instanceof IllegalArgumentException)) { 49.479 - exp.printStackTrace(); 49.480 - fail(exp.getMessage()); 49.481 - } 49.482 - } 49.483 - } 49.484 - 49.485 @Test 49.486 public void noEnumerablePropertiesTest() { 49.487 final ScriptEngineManager m = new ScriptEngineManager(); 49.488 @@ -920,308 +477,6 @@ 49.489 } 49.490 49.491 @Test 49.492 - public void jsobjectTest() { 49.493 - final ScriptEngineManager m = new ScriptEngineManager(); 49.494 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.495 - try { 49.496 - e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }"); 49.497 - JSObject obj = (JSObject) e.get("obj"); 49.498 - 49.499 - // try basic get on existing properties 49.500 - if (! obj.getMember("bar").equals("hello")) { 49.501 - fail("obj.bar != 'hello'"); 49.502 - } 49.503 - 49.504 - if (! obj.getSlot(1).equals("world")) { 49.505 - fail("obj[1] != 'world'"); 49.506 - } 49.507 - 49.508 - if (! obj.call("func", new Object[0]).equals("hello")) { 49.509 - fail("obj.call('func') != 'hello'"); 49.510 - } 49.511 - 49.512 - // try setting properties 49.513 - obj.setMember("bar", "new-bar"); 49.514 - obj.setSlot(1, "new-element-1"); 49.515 - if (! obj.getMember("bar").equals("new-bar")) { 49.516 - fail("obj.bar != 'new-bar'"); 49.517 - } 49.518 - 49.519 - if (! obj.getSlot(1).equals("new-element-1")) { 49.520 - fail("obj[1] != 'new-element-1'"); 49.521 - } 49.522 - 49.523 - // try adding properties 49.524 - obj.setMember("prop", "prop-value"); 49.525 - obj.setSlot(12, "element-12"); 49.526 - if (! obj.getMember("prop").equals("prop-value")) { 49.527 - fail("obj.prop != 'prop-value'"); 49.528 - } 49.529 - 49.530 - if (! obj.getSlot(12).equals("element-12")) { 49.531 - fail("obj[12] != 'element-12'"); 49.532 - } 49.533 - 49.534 - // delete properties 49.535 - obj.removeMember("prop"); 49.536 - if ("prop-value".equals(obj.getMember("prop"))) { 49.537 - fail("obj.prop is not deleted!"); 49.538 - } 49.539 - 49.540 - // Simple eval tests 49.541 - assertEquals(obj.eval("typeof Object"), "function"); 49.542 - assertEquals(obj.eval("'nashorn'.substring(3)"), "horn"); 49.543 - } catch (final Exception exp) { 49.544 - exp.printStackTrace(); 49.545 - fail(exp.getMessage()); 49.546 - } 49.547 - } 49.548 - 49.549 - @Test 49.550 - /** 49.551 - * check that null function name results in NPE. 49.552 - */ 49.553 - public void invokeFunctionNullNameTest() { 49.554 - final ScriptEngineManager m = new ScriptEngineManager(); 49.555 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.556 - 49.557 - try { 49.558 - final Object res = ((Invocable)e).invokeFunction(null); 49.559 - fail("should have thrown NPE"); 49.560 - } catch (final Exception exp) { 49.561 - if (! (exp instanceof NullPointerException)) { 49.562 - exp.printStackTrace(); 49.563 - fail(exp.getMessage()); 49.564 - } 49.565 - } 49.566 - } 49.567 - 49.568 - @Test 49.569 - /** 49.570 - * Check that attempt to call missing function results in NoSuchMethodException. 49.571 - */ 49.572 - public void invokeFunctionMissingTest() { 49.573 - final ScriptEngineManager m = new ScriptEngineManager(); 49.574 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.575 - 49.576 - try { 49.577 - final Object res = ((Invocable)e).invokeFunction("NonExistentFunc"); 49.578 - fail("should have thrown NoSuchMethodException"); 49.579 - } catch (final Exception exp) { 49.580 - if (! (exp instanceof NoSuchMethodException)) { 49.581 - exp.printStackTrace(); 49.582 - fail(exp.getMessage()); 49.583 - } 49.584 - } 49.585 - } 49.586 - 49.587 - @Test 49.588 - /** 49.589 - * Check that invokeFunction calls functions only from current context's Bindings. 49.590 - */ 49.591 - public void invokeFunctionDifferentContextTest() { 49.592 - ScriptEngineManager m = new ScriptEngineManager(); 49.593 - ScriptEngine e = m.getEngineByName("nashorn"); 49.594 - 49.595 - try { 49.596 - // define an object with method on it 49.597 - Object obj = e.eval("function hello() { return 'Hello World!'; }"); 49.598 - final ScriptContext ctxt = new SimpleScriptContext(); 49.599 - ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 49.600 - // change engine's current context 49.601 - e.setContext(ctxt); 49.602 - 49.603 - ((Invocable)e).invokeFunction("hello"); // no 'hello' in new context! 49.604 - fail("should have thrown NoSuchMethodException"); 49.605 - } catch (final Exception exp) { 49.606 - if (! (exp instanceof NoSuchMethodException)) { 49.607 - exp.printStackTrace(); 49.608 - fail(exp.getMessage()); 49.609 - } 49.610 - } 49.611 - } 49.612 - 49.613 - @Test 49.614 - public void invokeFunctionExceptionTest() { 49.615 - final ScriptEngineManager m = new ScriptEngineManager(); 49.616 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.617 - try { 49.618 - e.eval("function func() { throw new TypeError(); }"); 49.619 - } catch (final Throwable t) { 49.620 - t.printStackTrace(); 49.621 - fail(t.getMessage()); 49.622 - } 49.623 - 49.624 - try { 49.625 - ((Invocable)e).invokeFunction("func"); 49.626 - fail("should have thrown exception"); 49.627 - } catch (final ScriptException se) { 49.628 - // ECMA TypeError property wrapped as a ScriptException 49.629 - log("got " + se + " as expected"); 49.630 - } catch (final Throwable t) { 49.631 - t.printStackTrace(); 49.632 - fail(t.getMessage()); 49.633 - } 49.634 - } 49.635 - 49.636 - @Test 49.637 - public void invokeMethodExceptionTest() { 49.638 - final ScriptEngineManager m = new ScriptEngineManager(); 49.639 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.640 - try { 49.641 - e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }"); 49.642 - } catch (final Throwable t) { 49.643 - t.printStackTrace(); 49.644 - fail(t.getMessage()); 49.645 - } 49.646 - 49.647 - try { 49.648 - final Object sobj = e.get("sobj"); 49.649 - ((Invocable)e).invokeMethod(sobj, "foo"); 49.650 - fail("should have thrown exception"); 49.651 - } catch (final ScriptException se) { 49.652 - // ECMA TypeError property wrapped as a ScriptException 49.653 - log("got " + se + " as expected"); 49.654 - } catch (final Throwable t) { 49.655 - t.printStackTrace(); 49.656 - fail(t.getMessage()); 49.657 - } 49.658 - } 49.659 - 49.660 - @Test 49.661 - public void scriptObjectMirrorToStringTest() { 49.662 - final ScriptEngineManager m = new ScriptEngineManager(); 49.663 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.664 - try { 49.665 - Object obj = e.eval("new TypeError('wrong type')"); 49.666 - assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value"); 49.667 - } catch (final Throwable t) { 49.668 - t.printStackTrace(); 49.669 - fail(t.getMessage()); 49.670 - } 49.671 - 49.672 - try { 49.673 - Object obj = e.eval("function func() { print('hello'); }"); 49.674 - assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value"); 49.675 - } catch (final Throwable t) { 49.676 - t.printStackTrace(); 49.677 - fail(t.getMessage()); 49.678 - } 49.679 - } 49.680 - 49.681 - @Test 49.682 - public void engineScopeTest() { 49.683 - final ScriptEngineManager m = new ScriptEngineManager(); 49.684 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.685 - Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE); 49.686 - 49.687 - // check few ECMA standard built-in global properties 49.688 - assertNotNull(engineScope.get("Object")); 49.689 - assertNotNull(engineScope.get("TypeError")); 49.690 - assertNotNull(engineScope.get("eval")); 49.691 - 49.692 - // can access via ScriptEngine.get as well 49.693 - assertNotNull(e.get("Object")); 49.694 - assertNotNull(e.get("TypeError")); 49.695 - assertNotNull(e.get("eval")); 49.696 - 49.697 - // Access by either way should return same object 49.698 - assertEquals(engineScope.get("Array"), e.get("Array")); 49.699 - assertEquals(engineScope.get("EvalError"), e.get("EvalError")); 49.700 - assertEquals(engineScope.get("undefined"), e.get("undefined")); 49.701 - 49.702 - // try exposing a new variable from scope 49.703 - engineScope.put("myVar", "foo"); 49.704 - try { 49.705 - assertEquals(e.eval("myVar"), "foo"); 49.706 - } catch (final ScriptException se) { 49.707 - se.printStackTrace(); 49.708 - fail(se.getMessage()); 49.709 - } 49.710 - 49.711 - // update "myVar" in script an check the value from scope 49.712 - try { 49.713 - e.eval("myVar = 'nashorn';"); 49.714 - } catch (final ScriptException se) { 49.715 - se.printStackTrace(); 49.716 - fail(se.getMessage()); 49.717 - } 49.718 - 49.719 - // now check modified value from scope and engine 49.720 - assertEquals(engineScope.get("myVar"), "nashorn"); 49.721 - assertEquals(e.get("myVar"), "nashorn"); 49.722 - } 49.723 - 49.724 - @Test 49.725 - public void multiGlobalTest() { 49.726 - final ScriptEngineManager m = new ScriptEngineManager(); 49.727 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.728 - final Bindings b = e.createBindings(); 49.729 - final ScriptContext newCtxt = new SimpleScriptContext(); 49.730 - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); 49.731 - 49.732 - try { 49.733 - Object obj1 = e.eval("Object"); 49.734 - Object obj2 = e.eval("Object", newCtxt); 49.735 - Assert.assertNotEquals(obj1, obj2); 49.736 - Assert.assertNotNull(obj1); 49.737 - Assert.assertNotNull(obj2); 49.738 - Assert.assertEquals(obj1.toString(), obj2.toString()); 49.739 - 49.740 - e.eval("x = 'hello'"); 49.741 - e.eval("x = 'world'", newCtxt); 49.742 - Object x1 = e.getContext().getAttribute("x"); 49.743 - Object x2 = newCtxt.getAttribute("x"); 49.744 - Assert.assertNotEquals(x1, x2); 49.745 - Assert.assertEquals(x1, "hello"); 49.746 - Assert.assertEquals(x2, "world"); 49.747 - 49.748 - x1 = e.eval("x"); 49.749 - x2 = e.eval("x", newCtxt); 49.750 - Assert.assertNotEquals(x1, x2); 49.751 - Assert.assertEquals(x1, "hello"); 49.752 - Assert.assertEquals(x2, "world"); 49.753 - 49.754 - final ScriptContext origCtxt = e.getContext(); 49.755 - e.setContext(newCtxt); 49.756 - e.eval("y = new Object()"); 49.757 - e.eval("y = new Object()", origCtxt); 49.758 - 49.759 - Object y1 = origCtxt.getAttribute("y"); 49.760 - Object y2 = newCtxt.getAttribute("y"); 49.761 - Assert.assertNotEquals(y1, y2); 49.762 - Assert.assertNotEquals(e.eval("y"), e.eval("y", origCtxt)); 49.763 - Assert.assertEquals("[object Object]", y1.toString()); 49.764 - Assert.assertEquals("[object Object]", y2.toString()); 49.765 - } catch (final ScriptException se) { 49.766 - se.printStackTrace(); 49.767 - fail(se.getMessage()); 49.768 - } 49.769 - } 49.770 - 49.771 - @Test 49.772 - /** 49.773 - * Tests whether invocation of a JavaScript method through a variable arity Java method will pass the vararg array. 49.774 - * Both non-vararg and vararg JavaScript methods are tested. 49.775 - * @throws ScriptException 49.776 - */ 49.777 - public void variableArityInterfaceTest() throws ScriptException { 49.778 - final ScriptEngineManager m = new ScriptEngineManager(); 49.779 - final ScriptEngine e = m.getEngineByName("nashorn"); 49.780 - e.eval( 49.781 - "function test1(i, strings) {" + 49.782 - " return 'i == ' + i + ', strings instanceof java.lang.String[] == ' + (strings instanceof Java.type('java.lang.String[]')) + ', strings == ' + java.util.Arrays.toString(strings)" + 49.783 - "}" + 49.784 - "function test2() {" + 49.785 - " return 'arguments[0] == ' + arguments[0] + ', arguments[1] instanceof java.lang.String[] == ' + (arguments[1] instanceof Java.type('java.lang.String[]')) + ', arguments[1] == ' + java.util.Arrays.toString(arguments[1])" + 49.786 - "}" 49.787 - ); 49.788 - final VariableArityTestInterface itf = ((Invocable)e).getInterface(VariableArityTestInterface.class); 49.789 - Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]"); 49.790 - Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]"); 49.791 - } 49.792 - 49.793 - @Test 49.794 // check that print function prints arg followed by newline char 49.795 public void printTest() { 49.796 final ScriptEngineManager m = new ScriptEngineManager();
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Fri Aug 23 16:44:02 2013 +0530 50.3 @@ -0,0 +1,230 @@ 50.4 +/* 50.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 50.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 50.7 + * 50.8 + * This code is free software; you can redistribute it and/or modify it 50.9 + * under the terms of the GNU General Public License version 2 only, as 50.10 + * published by the Free Software Foundation. Oracle designates this 50.11 + * particular file as subject to the "Classpath" exception as provided 50.12 + * by Oracle in the LICENSE file that accompanied this code. 50.13 + * 50.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 50.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 50.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 50.17 + * version 2 for more details (a copy is included in the LICENSE file that 50.18 + * accompanied this code). 50.19 + * 50.20 + * You should have received a copy of the GNU General Public License version 50.21 + * 2 along with this work; if not, write to the Free Software Foundation, 50.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 50.23 + * 50.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 50.25 + * or visit www.oracle.com if you need additional information or have any 50.26 + * questions. 50.27 + */ 50.28 + 50.29 +package jdk.nashorn.api.scripting; 50.30 + 50.31 +import java.util.HashMap; 50.32 +import java.util.Map; 50.33 +import javax.script.ScriptEngine; 50.34 +import javax.script.ScriptEngineManager; 50.35 +import javax.script.ScriptException; 50.36 +import static org.testng.Assert.assertEquals; 50.37 +import static org.testng.Assert.assertFalse; 50.38 +import static org.testng.Assert.assertTrue; 50.39 +import static org.testng.Assert.fail; 50.40 +import org.testng.annotations.Test; 50.41 + 50.42 +/** 50.43 + * Tests to check jdk.nashorn.api.scripting.ScriptObjectMirror API. 50.44 + */ 50.45 +public class ScriptObjectMirrorTest { 50.46 + 50.47 + @SuppressWarnings("unchecked") 50.48 + @Test 50.49 + public void reflectionTest() throws ScriptException { 50.50 + final ScriptEngineManager m = new ScriptEngineManager(); 50.51 + final ScriptEngine e = m.getEngineByName("nashorn"); 50.52 + 50.53 + e.eval("var obj = { x: 344, y: 'nashorn' }"); 50.54 + 50.55 + int count = 0; 50.56 + Map<Object, Object> map = (Map<Object, Object>) e.get("obj"); 50.57 + assertFalse(map.isEmpty()); 50.58 + assertTrue(map.keySet().contains("x")); 50.59 + assertTrue(map.containsKey("x")); 50.60 + assertTrue(map.values().contains("nashorn")); 50.61 + assertTrue(map.containsValue("nashorn")); 50.62 + for (final Map.Entry<?, ?> ex : map.entrySet()) { 50.63 + final Object key = ex.getKey(); 50.64 + if (key.equals("x")) { 50.65 + assertTrue(344 == ((Number) ex.getValue()).doubleValue()); 50.66 + count++; 50.67 + } else if (key.equals("y")) { 50.68 + assertEquals(ex.getValue(), "nashorn"); 50.69 + count++; 50.70 + } 50.71 + } 50.72 + assertEquals(2, count); 50.73 + assertEquals(2, map.size()); 50.74 + 50.75 + // add property 50.76 + map.put("z", "hello"); 50.77 + assertEquals(e.eval("obj.z"), "hello"); 50.78 + assertEquals(map.get("z"), "hello"); 50.79 + assertTrue(map.keySet().contains("z")); 50.80 + assertTrue(map.containsKey("z")); 50.81 + assertTrue(map.values().contains("hello")); 50.82 + assertTrue(map.containsValue("hello")); 50.83 + assertEquals(map.size(), 3); 50.84 + 50.85 + final Map<Object, Object> newMap = new HashMap<>(); 50.86 + newMap.put("foo", 23.0); 50.87 + newMap.put("bar", true); 50.88 + map.putAll(newMap); 50.89 + 50.90 + assertEquals(e.eval("obj.foo"), 23.0); 50.91 + assertEquals(e.eval("obj.bar"), true); 50.92 + 50.93 + // remove using map method 50.94 + map.remove("foo"); 50.95 + assertEquals(e.eval("typeof obj.foo"), "undefined"); 50.96 + 50.97 + count = 0; 50.98 + e.eval("var arr = [ true, 'hello' ]"); 50.99 + map = (Map<Object, Object>) e.get("arr"); 50.100 + assertFalse(map.isEmpty()); 50.101 + assertTrue(map.containsKey("length")); 50.102 + assertTrue(map.containsValue("hello")); 50.103 + for (final Map.Entry<?, ?> ex : map.entrySet()) { 50.104 + final Object key = ex.getKey(); 50.105 + if (key.equals("0")) { 50.106 + assertEquals(ex.getValue(), Boolean.TRUE); 50.107 + count++; 50.108 + } else if (key.equals("1")) { 50.109 + assertEquals(ex.getValue(), "hello"); 50.110 + count++; 50.111 + } 50.112 + } 50.113 + assertEquals(count, 2); 50.114 + assertEquals(map.size(), 2); 50.115 + 50.116 + // add element 50.117 + map.put("2", "world"); 50.118 + assertEquals(map.get("2"), "world"); 50.119 + assertEquals(map.size(), 3); 50.120 + 50.121 + // remove all 50.122 + map.clear(); 50.123 + assertTrue(map.isEmpty()); 50.124 + assertEquals(e.eval("typeof arr[0]"), "undefined"); 50.125 + assertEquals(e.eval("typeof arr[1]"), "undefined"); 50.126 + assertEquals(e.eval("typeof arr[2]"), "undefined"); 50.127 + } 50.128 + 50.129 + @Test 50.130 + public void jsobjectTest() { 50.131 + final ScriptEngineManager m = new ScriptEngineManager(); 50.132 + final ScriptEngine e = m.getEngineByName("nashorn"); 50.133 + try { 50.134 + e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }"); 50.135 + JSObject obj = (JSObject) e.get("obj"); 50.136 + 50.137 + // try basic get on existing properties 50.138 + if (!obj.getMember("bar").equals("hello")) { 50.139 + fail("obj.bar != 'hello'"); 50.140 + } 50.141 + 50.142 + if (!obj.getSlot(1).equals("world")) { 50.143 + fail("obj[1] != 'world'"); 50.144 + } 50.145 + 50.146 + if (!obj.call("func", new Object[0]).equals("hello")) { 50.147 + fail("obj.call('func') != 'hello'"); 50.148 + } 50.149 + 50.150 + // try setting properties 50.151 + obj.setMember("bar", "new-bar"); 50.152 + obj.setSlot(1, "new-element-1"); 50.153 + if (!obj.getMember("bar").equals("new-bar")) { 50.154 + fail("obj.bar != 'new-bar'"); 50.155 + } 50.156 + 50.157 + if (!obj.getSlot(1).equals("new-element-1")) { 50.158 + fail("obj[1] != 'new-element-1'"); 50.159 + } 50.160 + 50.161 + // try adding properties 50.162 + obj.setMember("prop", "prop-value"); 50.163 + obj.setSlot(12, "element-12"); 50.164 + if (!obj.getMember("prop").equals("prop-value")) { 50.165 + fail("obj.prop != 'prop-value'"); 50.166 + } 50.167 + 50.168 + if (!obj.getSlot(12).equals("element-12")) { 50.169 + fail("obj[12] != 'element-12'"); 50.170 + } 50.171 + 50.172 + // delete properties 50.173 + obj.removeMember("prop"); 50.174 + if ("prop-value".equals(obj.getMember("prop"))) { 50.175 + fail("obj.prop is not deleted!"); 50.176 + } 50.177 + 50.178 + // Simple eval tests 50.179 + assertEquals(obj.eval("typeof Object"), "function"); 50.180 + assertEquals(obj.eval("'nashorn'.substring(3)"), "horn"); 50.181 + } catch (final Exception exp) { 50.182 + exp.printStackTrace(); 50.183 + fail(exp.getMessage()); 50.184 + } 50.185 + } 50.186 + 50.187 + @Test 50.188 + public void scriptObjectMirrorToStringTest() { 50.189 + final ScriptEngineManager m = new ScriptEngineManager(); 50.190 + final ScriptEngine e = m.getEngineByName("nashorn"); 50.191 + try { 50.192 + Object obj = e.eval("new TypeError('wrong type')"); 50.193 + assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value"); 50.194 + } catch (final Throwable t) { 50.195 + t.printStackTrace(); 50.196 + fail(t.getMessage()); 50.197 + } 50.198 + 50.199 + try { 50.200 + Object obj = e.eval("function func() { print('hello'); }"); 50.201 + assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value"); 50.202 + } catch (final Throwable t) { 50.203 + t.printStackTrace(); 50.204 + fail(t.getMessage()); 50.205 + } 50.206 + } 50.207 + 50.208 + @Test 50.209 + public void mirrorNewObjectGlobalFunctionTest() throws ScriptException { 50.210 + final ScriptEngineManager m = new ScriptEngineManager(); 50.211 + final ScriptEngine e = m.getEngineByName("nashorn"); 50.212 + final ScriptEngine e2 = m.getEngineByName("nashorn"); 50.213 + 50.214 + e.eval("function func() {}"); 50.215 + e2.put("foo", e.get("func")); 50.216 + final Object e2global = e2.eval("this"); 50.217 + final Object newObj = ((ScriptObjectMirror) e2global).newObject("foo"); 50.218 + assertTrue(newObj instanceof ScriptObjectMirror); 50.219 + } 50.220 + 50.221 + @Test 50.222 + public void mirrorNewObjectInstanceFunctionTest() throws ScriptException { 50.223 + final ScriptEngineManager m = new ScriptEngineManager(); 50.224 + final ScriptEngine e = m.getEngineByName("nashorn"); 50.225 + final ScriptEngine e2 = m.getEngineByName("nashorn"); 50.226 + 50.227 + e.eval("function func() {}"); 50.228 + e2.put("func", e.get("func")); 50.229 + final Object e2obj = e2.eval("({ foo: func })"); 50.230 + final Object newObj = ((ScriptObjectMirror) e2obj).newObject("foo"); 50.231 + assertTrue(newObj instanceof ScriptObjectMirror); 50.232 + } 50.233 +}
51.1 --- a/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Mon Aug 19 19:37:29 2013 +0530 51.2 +++ b/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Fri Aug 23 16:44:02 2013 +0530 51.3 @@ -32,7 +32,10 @@ 51.4 import javax.script.ScriptEngine; 51.5 import javax.script.ScriptEngineFactory; 51.6 import javax.script.ScriptEngineManager; 51.7 +import javax.script.ScriptContext; 51.8 import javax.script.ScriptException; 51.9 +import javax.script.SimpleBindings; 51.10 +import javax.script.SimpleScriptContext; 51.11 import jdk.nashorn.api.scripting.NashornScriptEngineFactory; 51.12 import org.testng.annotations.Test; 51.13 51.14 @@ -196,4 +199,25 @@ 51.15 } 51.16 fail("Cannot find nashorn factory!"); 51.17 } 51.18 + 51.19 + @Test 51.20 + public void globalPerEngineTest() throws ScriptException { 51.21 + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); 51.22 + final String[] options = new String[] { "--global-per-engine" }; 51.23 + final ScriptEngine e = fac.getScriptEngine(options); 51.24 + 51.25 + e.eval("function foo() {}"); 51.26 + 51.27 + final ScriptContext newCtx = new SimpleScriptContext(); 51.28 + newCtx.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 51.29 + 51.30 + // all global definitions shared and so 'foo' should be 51.31 + // visible in new Bindings as well. 51.32 + assertTrue(e.eval("typeof foo", newCtx).equals("function")); 51.33 + 51.34 + e.eval("function bar() {}", newCtx); 51.35 + 51.36 + // bar should be visible in default context 51.37 + assertTrue(e.eval("typeof bar").equals("function")); 51.38 + } 51.39 }