This commit is contained in:
Lana Steuck 2015-06-18 10:24:14 -07:00
commit c9e37d0dcb
37 changed files with 909 additions and 245 deletions

View File

@ -152,6 +152,7 @@ public class ConstructorGenerator extends ClassGenerator {
}
if (constructor != null) {
initPrototype(mi);
final int arity = constructor.getArity();
if (arity != MemberInfo.DEFAULT_ARITY) {
mi.loadThis();
@ -193,6 +194,7 @@ public class ConstructorGenerator extends ClassGenerator {
}
private void initFunctionFields(final MethodGenerator mi) {
assert memberCount > 0;
for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
if (!memInfo.isConstructorFunction()) {
continue;
@ -204,37 +206,39 @@ public class ConstructorGenerator extends ClassGenerator {
}
private void initDataFields(final MethodGenerator mi) {
for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
if (!memInfo.isConstructorProperty() || memInfo.isFinal()) {
continue;
}
final Object value = memInfo.getValue();
if (value != null) {
mi.loadThis();
mi.loadLiteral(value);
mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc());
} else if (!memInfo.getInitClass().isEmpty()) {
final String clazz = memInfo.getInitClass();
mi.loadThis();
mi.newObject(clazz);
mi.dup();
mi.invokeSpecial(clazz, INIT, DEFAULT_INIT_DESC);
mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc());
}
assert memberCount > 0;
for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
if (!memInfo.isConstructorProperty() || memInfo.isFinal()) {
continue;
}
final Object value = memInfo.getValue();
if (value != null) {
mi.loadThis();
mi.loadLiteral(value);
mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc());
} else if (!memInfo.getInitClass().isEmpty()) {
final String clazz = memInfo.getInitClass();
mi.loadThis();
mi.newObject(clazz);
mi.dup();
mi.invokeSpecial(clazz, INIT, DEFAULT_INIT_DESC);
mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc());
}
}
}
if (constructor != null) {
mi.loadThis();
final String protoName = scriptClassInfo.getPrototypeClassName();
mi.newObject(protoName);
mi.dup();
mi.invokeSpecial(protoName, INIT, DEFAULT_INIT_DESC);
mi.dup();
mi.loadThis();
mi.invokeStatic(PROTOTYPEOBJECT_TYPE, PROTOTYPEOBJECT_SETCONSTRUCTOR,
PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC);
mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETPROTOTYPE, SCRIPTFUNCTION_SETPROTOTYPE_DESC);
}
private void initPrototype(final MethodGenerator mi) {
assert constructor != null;
mi.loadThis();
final String protoName = scriptClassInfo.getPrototypeClassName();
mi.newObject(protoName);
mi.dup();
mi.invokeSpecial(protoName, INIT, DEFAULT_INIT_DESC);
mi.dup();
mi.loadThis();
mi.invokeStatic(PROTOTYPEOBJECT_TYPE, PROTOTYPEOBJECT_SETCONSTRUCTOR,
PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC);
mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETPROTOTYPE, SCRIPTFUNCTION_SETPROTOTYPE_DESC);
}
/**

View File

@ -140,7 +140,7 @@ public class Main {
String simpleName = inFile.getName();
simpleName = simpleName.substring(0, simpleName.indexOf(".class"));
if (sci.getPrototypeMemberCount() > 0) {
if (sci.isPrototypeNeeded()) {
// generate prototype class
final PrototypeGenerator protGen = new PrototypeGenerator(sci);
buf = protGen.getClassBytes();
@ -152,7 +152,7 @@ public class Main {
}
}
if (sci.getConstructorMemberCount() > 0 || sci.getConstructor() != null) {
if (sci.isConstructorNeeded()) {
// generate constructor class
final ConstructorGenerator consGen = new ConstructorGenerator(sci);
buf = consGen.getClassBytes();

View File

@ -126,10 +126,42 @@ public final class ScriptClassInfo {
return Collections.unmodifiableList(res);
}
boolean isConstructorNeeded() {
// Constructor class generation is needed if we one or
// more constructor properties are defined or @Constructor
// is defined in the class.
for (final MemberInfo memInfo : members) {
if (memInfo.getKind() == Kind.CONSTRUCTOR ||
memInfo.getWhere() == Where.CONSTRUCTOR) {
return true;
}
}
return false;
}
boolean isPrototypeNeeded() {
// Prototype class generation is needed if we have atleast one
// prototype property or @Constructor defined in the class.
for (final MemberInfo memInfo : members) {
if (memInfo.getWhere() == Where.PROTOTYPE || memInfo.isConstructor()) {
return true;
}
}
return false;
}
int getPrototypeMemberCount() {
int count = 0;
for (final MemberInfo memInfo : members) {
if (memInfo.getWhere() == Where.PROTOTYPE || memInfo.isConstructor()) {
switch (memInfo.getKind()) {
case SETTER:
case SPECIALIZED_FUNCTION:
// SETTER was counted when GETTER was encountered.
// SPECIALIZED_FUNCTION was counted as FUNCTION already.
continue;
}
if (memInfo.getWhere() == Where.PROTOTYPE) {
count++;
}
}
@ -139,6 +171,16 @@ public final class ScriptClassInfo {
int getConstructorMemberCount() {
int count = 0;
for (final MemberInfo memInfo : members) {
switch (memInfo.getKind()) {
case CONSTRUCTOR:
case SETTER:
case SPECIALIZED_FUNCTION:
// SETTER was counted when GETTER was encountered.
// Constructor and constructor SpecializedFunctions
// are not added as members and so not counted.
continue;
}
if (memInfo.getWhere() == Where.CONSTRUCTOR) {
count++;
}
@ -149,6 +191,14 @@ public final class ScriptClassInfo {
int getInstancePropertyCount() {
int count = 0;
for (final MemberInfo memInfo : members) {
switch (memInfo.getKind()) {
case SETTER:
case SPECIALIZED_FUNCTION:
// SETTER was counted when GETTER was encountered.
// SPECIALIZED_FUNCTION was counted as FUNCTION already.
continue;
}
if (memInfo.getWhere() == Where.INSTANCE) {
count++;
}

View File

@ -288,9 +288,7 @@ public class ScriptClassInfoCollector extends ClassVisitor {
where = Where.PROTOTYPE;
break;
case SPECIALIZED_FUNCTION:
if (isSpecializedConstructor) {
where = Where.CONSTRUCTOR;
}
where = isSpecializedConstructor? Where.CONSTRUCTOR : Where.PROTOTYPE;
//fallthru
default:
break;

View File

@ -63,5 +63,3 @@ function fields(jobj) {
}
}
}
undefined;

View File

@ -172,7 +172,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
return Context.getContext();
}
}, GET_CONTEXT_ACC_CTXT);
return wrapLikeMe(context.eval(global, s, sobj, null, false));
return wrapLikeMe(context.eval(global, s, sobj, null));
}
});
}

View File

@ -103,7 +103,7 @@ public final class Compiler implements Loggable {
private final CodeInstaller<ScriptEnvironment> installer;
/** logger for compiler, trampolines, splits and related code generation events
/** logger for compiler, trampolines and related code generation events
* that affect classes */
private final DebugLogger log;

View File

@ -30,6 +30,8 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import jdk.nashorn.internal.runtime.PropertyMap;
/**
@ -120,7 +122,7 @@ final class ConstantData {
private final int hashCode;
public PropertyMapWrapper(final PropertyMap map) {
this.hashCode = Arrays.hashCode(map.getProperties());
this.hashCode = Arrays.hashCode(map.getProperties()) + 31 * Objects.hashCode(map.getClassName());
this.propertyMap = map;
}
@ -131,8 +133,13 @@ final class ConstantData {
@Override
public boolean equals(final Object other) {
return other instanceof PropertyMapWrapper &&
Arrays.equals(propertyMap.getProperties(), ((PropertyMapWrapper) other).propertyMap.getProperties());
if (!(other instanceof PropertyMapWrapper)) {
return false;
}
final PropertyMap otherMap = ((PropertyMapWrapper) other).propertyMap;
return propertyMap == otherMap
|| (Arrays.equals(propertyMap.getProperties(), otherMap.getProperties())
&& Objects.equals(propertyMap.getClassName(), otherMap.getClassName()));
}
}

View File

@ -584,7 +584,9 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Lo
@Override
public Node leaveVarNode(final VarNode varNode) {
addStatement(varNode);
if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION) && lc.getCurrentFunction().isProgram()) {
if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION)
&& lc.getCurrentFunction().isProgram()
&& ((FunctionNode) varNode.getInit()).isAnonymous()) {
new ExpressionStatement(varNode.getLineNumber(), varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this);
}
return varNode;

View File

@ -42,13 +42,17 @@ import jdk.nashorn.internal.ir.Node;
import jdk.nashorn.internal.ir.SplitNode;
import jdk.nashorn.internal.ir.Statement;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Loggable;
import jdk.nashorn.internal.runtime.logging.Logger;
import jdk.nashorn.internal.runtime.options.Options;
/**
* Split the IR into smaller compile units.
*/
final class Splitter extends NodeVisitor<LexicalContext> {
@Logger(name="splitter")
final class Splitter extends NodeVisitor<LexicalContext> implements Loggable {
/** Current compiler. */
private final Compiler compiler;
@ -78,7 +82,17 @@ final class Splitter extends NodeVisitor<LexicalContext> {
this.compiler = compiler;
this.outermost = functionNode;
this.outermostCompileUnit = outermostCompileUnit;
this.log = compiler.getLogger();
this.log = initLogger(compiler.getContext());
}
@Override
public DebugLogger initLogger(final Context context) {
return context.getLogger(this.getClass());
}
@Override
public DebugLogger getLogger() {
return log;
}
/**
@ -89,7 +103,7 @@ final class Splitter extends NodeVisitor<LexicalContext> {
FunctionNode split(final FunctionNode fn, final boolean top) {
FunctionNode functionNode = fn;
log.finest("Initiating split of '", functionNode.getName(), "'");
log.fine("Initiating split of '", functionNode.getName(), "'");
long weight = WeighNodes.weigh(functionNode);
@ -98,7 +112,7 @@ final class Splitter extends NodeVisitor<LexicalContext> {
assert lc.isEmpty() : "LexicalContext not empty";
if (weight >= SPLIT_THRESHOLD) {
log.finest("Splitting '", functionNode.getName(), "' as its weight ", weight, " exceeds split threshold ", SPLIT_THRESHOLD);
log.info("Splitting '", functionNode.getName(), "' as its weight ", weight, " exceeds split threshold ", SPLIT_THRESHOLD);
functionNode = (FunctionNode)functionNode.accept(this);
if (functionNode.isSplit()) {

View File

@ -23,31 +23,6 @@
* questions.
*/
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.nashorn.internal.codegen.types;
import static jdk.internal.org.objectweb.asm.Opcodes.I2D;

View File

@ -87,7 +87,7 @@ import jdk.nashorn.tools.ShellFunctions;
* Representation of global scope.
*/
@ScriptClass("Global")
public final class Global extends ScriptObject implements Scope {
public final class Global extends Scope {
// Placeholder value used in place of a location property (__FILE__, __DIR__, __LINE__)
private static final Object LOCATION_PROPERTY_PLACEHOLDER = new Object();
private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
@ -906,9 +906,6 @@ public final class Global extends ScriptObject implements Scope {
*/
private ScriptFunction typeErrorThrower;
// Flag to indicate that a split method issued a return statement
private int splitState = -1;
// Used to store the last RegExp result to support deprecated RegExp constructor properties
private RegExpResult lastRegExpResult;
@ -995,7 +992,6 @@ public final class Global extends ScriptObject implements Scope {
public Global(final Context context) {
super(checkAndGetMap(context));
this.context = context;
this.setIsScope();
this.lexicalScope = context.getEnv()._es6 ? new LexicalScope(this) : null;
}
@ -1451,7 +1447,7 @@ public final class Global extends ScriptObject implements Scope {
* @return the result of eval
*/
public static Object eval(final Object self, final Object str) {
return directEval(self, str, UNDEFINED, UNDEFINED, false);
return directEval(self, str, Global.instanceFrom(self), UNDEFINED, false);
}
/**
@ -1461,7 +1457,7 @@ public final class Global extends ScriptObject implements Scope {
* @param str Evaluated code
* @param callThis "this" to be passed to the evaluated code
* @param location location of the eval call
* @param strict is eval called a strict mode code?
* @param strict is eval called from a strict mode code?
*
* @return the return value of the eval
*
@ -1502,26 +1498,53 @@ public final class Global extends ScriptObject implements Scope {
}
/**
* Global load implementation - Nashorn extension
* Global load implementation - Nashorn extension.
*
* @param self scope
* @param source source to load
* <p>
* load builtin loads the given script. Script source can be a URL or a File
* or a script object with name and script properties. Evaluated code gets
* global object "this" and uses global object as scope for evaluation.
* </p>
* <p>
* If self is undefined or null or global, then global object is used
* as scope as well as "this" for the evaluated code. If self is any other
* object, then it is indirect load call. With indirect load call, the
* properties of scope are available to evaluated script as variables. Also,
* global scope properties are accessible. Any var, function definition in
* evaluated script goes into an object that is not accessible to user scripts.
* </p>
* Thus the indirect load call is equivalent to the following:
* <pre>
* <code>
* (function (scope, source) {
* with(scope) {
* eval(&lt;script_from_source&gt;);
* }
* })(self, source);
* </code>
* </pre>
*
* @return result of load (undefined)
* @param self scope to use for the script evaluation
* @param source script source
*
* @return result of load (may be undefined)
*
* @throws IOException if source could not be read
*/
public static Object load(final Object self, final Object source) throws IOException {
final Global global = Global.instanceFrom(self);
final ScriptObject scope = self instanceof ScriptObject ? (ScriptObject)self : global;
return global.getContext().load(scope, source);
return global.getContext().load(self, source);
}
/**
* Global loadWithNewGlobal implementation - Nashorn extension
* Global loadWithNewGlobal implementation - Nashorn extension.
*
* @param self scope
* @param args from plus (optional) arguments to be passed to the loaded script
* loadWithNewGlobal builtin loads the given script from a URL or a File
* or a script object with name and script properties. Evaluated code gets
* new global object "this" and uses that new global object as scope for evaluation.
*
* @param self self This value is ignored by this function
* @param args optional arguments to be passed to the loaded script
*
* @return result of load (may be undefined)
*
@ -2327,26 +2350,6 @@ public final class Global extends ScriptObject implements Scope {
}
}
/**
* Get the current split state.
*
* @return current split state
*/
@Override
public int getSplitState() {
return splitState;
}
/**
* Set the current split state.
*
* @param state current split state
*/
@Override
public void setSplitState(final int state) {
splitState = state;
}
/**
* Return the ES6 global scope for lexically declared bindings.
* @return the ES6 lexical global scope.

View File

@ -37,6 +37,7 @@ import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.PropertyListeners;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.Scope;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
@ -245,7 +246,7 @@ public final class NativeDebug extends ScriptObject {
final PrintWriter out = Context.getCurrentErr();
out.println("ScriptObject count " + ScriptObject.getCount());
out.println("Scope count " + ScriptObject.getScopeCount());
out.println("Scope count " + Scope.getCount());
out.println("ScriptObject listeners added " + PropertyListeners.getListenersAdded());
out.println("ScriptObject listeners removed " + PropertyListeners.getListenersRemoved());
out.println("ScriptFunction constructor calls " + ScriptFunction.getConstructorCount());

View File

@ -279,8 +279,8 @@ public final class NativeFunction {
sb.append("})");
final Global global = Global.instance();
return (ScriptFunction)Global.directEval(global, sb.toString(), global, "<function>", global.isStrictContext());
final Context context = global.getContext();
return (ScriptFunction)context.eval(global, sb.toString(), global, "<function>");
}
private static void checkFunctionParameters(final String params) {

View File

@ -459,6 +459,19 @@ public abstract class AbstractParser {
if (kind == TokenKind.KEYWORD || kind == TokenKind.FUTURE || kind == TokenKind.FUTURESTRICT) {
return true;
}
// only literals allowed are null, false and true
if (kind == TokenKind.LITERAL) {
switch (type) {
case FALSE:
case NULL:
case TRUE:
return true;
default:
return false;
}
}
// Fake out identifier.
final long identToken = Token.recast(token, IDENT);
// Get IDENT.

View File

@ -668,12 +668,11 @@ public final class Context {
* @param string Evaluated code as a String
* @param callThis "this" to be passed to the evaluated code
* @param location location of the eval call
* @param strict is this {@code eval} call from a strict mode code?
* @return the return value of the {@code eval}
*/
public Object eval(final ScriptObject initialScope, final String string,
final Object callThis, final Object location, final boolean strict) {
return eval(initialScope, string, callThis, location, strict, false);
final Object callThis, final Object location) {
return eval(initialScope, string, callThis, location, false, false);
}
/**
@ -692,14 +691,16 @@ public final class Context {
final Object callThis, final Object location, final boolean strict, final boolean evalCall) {
final String file = location == UNDEFINED || location == null ? "<eval>" : location.toString();
final Source source = sourceFor(file, string, evalCall);
final boolean directEval = location != UNDEFINED; // is this direct 'eval' call or indirectly invoked eval?
// is this direct 'eval' builtin call?
final boolean directEval = evalCall && (location != UNDEFINED);
final Global global = Context.getGlobal();
ScriptObject scope = initialScope;
// ECMA section 10.1.1 point 2 says eval code is strict if it begins
// with "use strict" directive or eval direct call itself is made
// from from strict mode code. We are passed with caller's strict mode.
boolean strictFlag = directEval && strict;
// Nashorn extension: any 'eval' is unconditionally strict when -strict is specified.
boolean strictFlag = strict || this._strict;
Class<?> clazz = null;
try {
@ -723,16 +724,8 @@ public final class Context {
// In strict mode, eval does not instantiate variables and functions
// in the caller's environment. A new environment is created!
if (strictFlag) {
// Create a new scope object
final ScriptObject strictEvalScope = global.newObject();
// bless it as a "scope"
strictEvalScope.setIsScope();
// set given scope to be it's proto so that eval can still
// access caller environment vars in the new environment.
strictEvalScope.setProto(scope);
scope = strictEvalScope;
// Create a new scope object with given scope as its prototype
scope = newScope(scope);
}
final ScriptFunction func = getProgramFunction(clazz, scope);
@ -740,12 +733,17 @@ public final class Context {
if (directEval) {
evalThis = (callThis != UNDEFINED && callThis != null) || strictFlag ? callThis : global;
} else {
evalThis = global;
// either indirect evalCall or non-eval (Function, engine.eval, ScriptObjectMirror.eval..)
evalThis = callThis;
}
return ScriptRuntime.apply(func, evalThis);
}
private static ScriptObject newScope(final ScriptObject callerScope) {
return new Scope(callerScope, PropertyMap.newMap(Scope.class));
}
private static Source loadInternal(final String srcStr, final String prefix, final String resourcePath) {
if (srcStr.startsWith(prefix)) {
final String resource = resourcePath + srcStr.substring(prefix.length());
@ -779,7 +777,7 @@ public final class Context {
*
* @throws IOException if source cannot be found or loaded
*/
public Object load(final ScriptObject scope, final Object from) throws IOException {
public Object load(final Object scope, final Object from) throws IOException {
final Object src = from instanceof ConsString ? from.toString() : from;
Source source = null;
@ -831,7 +829,42 @@ public final class Context {
}
if (source != null) {
return evaluateSource(source, scope, scope);
if (scope instanceof ScriptObject && ((ScriptObject)scope).isScope()) {
final ScriptObject sobj = (ScriptObject)scope;
// passed object is a script object
// Global is the only user accessible scope ScriptObject
assert sobj.isGlobal() : "non-Global scope object!!";
return evaluateSource(source, sobj, sobj);
} else if (scope == null || scope == UNDEFINED) {
// undefined or null scope. Use current global instance.
final Global global = getGlobal();
return evaluateSource(source, global, global);
} else {
/*
* Arbitrary object passed for scope.
* Indirect load that is equivalent to:
*
* (function(scope, source) {
* with (scope) {
* eval(<script_from_source>);
* }
* })(scope, source);
*/
final Global global = getGlobal();
// Create a new object. This is where all declarations
// (var, function) from the evaluated code go.
// make global to be its __proto__ so that global
// definitions are accessible to the evaluated code.
final ScriptObject evalScope = newScope(global);
// finally, make a WithObject around user supplied scope object
// so that it's properties are accessible as variables.
final ScriptObject withObj = ScriptRuntime.openWith(evalScope, scope);
// evaluate given source with 'withObj' as scope
// but use global object as "this".
return evaluateSource(source, withObj, global);
}
}
throw typeError("cant.load.script", ScriptRuntime.safeToString(from));

View File

@ -156,7 +156,7 @@ final class DebuggerSupport {
final Context context = global.getContext();
try {
return context.eval(initialScope, string, callThis, ScriptRuntime.UNDEFINED, false);
return context.eval(initialScope, string, callThis, ScriptRuntime.UNDEFINED);
} catch (final Throwable ex) {
return returnException ? ex : null;
}

View File

@ -35,17 +35,12 @@ package jdk.nashorn.internal.runtime;
*
* The constructor of this class is responsible for any function prologue
* involving the scope.
*
* TODO see NASHORN-715.
*/
public class FunctionScope extends ScriptObject implements Scope {
public class FunctionScope extends Scope {
/** Area to store scope arguments. (public for access from scripts.) */
public final ScriptObject arguments;
/** Flag to indicate that a split method issued a return statement */
private int splitState = -1;
/**
* Constructor
*
@ -56,7 +51,6 @@ public class FunctionScope extends ScriptObject implements Scope {
public FunctionScope(final PropertyMap map, final ScriptObject callerScope, final ScriptObject arguments) {
super(callerScope, map);
this.arguments = arguments;
setIsScope();
}
/**
@ -68,7 +62,6 @@ public class FunctionScope extends ScriptObject implements Scope {
public FunctionScope(final PropertyMap map, final ScriptObject callerScope) {
super(callerScope, map);
this.arguments = null;
setIsScope();
}
/**
@ -82,23 +75,4 @@ public class FunctionScope extends ScriptObject implements Scope {
super(map, primitiveSpill, objectSpill);
this.arguments = null;
}
/**
* Get the current split state.
* @return current split state
*/
@Override
public int getSplitState() {
return splitState;
}
/**
* Set the current split state.
* @param state current split state
*/
@Override
public void setSplitState(final int state) {
splitState = state;
}
}

View File

@ -596,6 +596,15 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
return properties.getProperties();
}
/**
* Return the name of the class of objects using this property map.
*
* @return class name of owner objects.
*/
public String getClassName() {
return className;
}
/**
* Prevents the map from having additional properties.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,30 +25,105 @@
package jdk.nashorn.internal.runtime;
import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup;
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
import jdk.nashorn.internal.codegen.CompilerConstants;
/**
* Interface implemented by {@link ScriptObject}s that act as scope.
* A {@link ScriptObject} subclass for objects that act as scope.
*/
public interface Scope {
public class Scope extends ScriptObject {
/* This is used to store return state of split functions. */
private int splitState = -1;
/** This is updated only in debug mode - counts number of {@code ScriptObject} instances created that are scope */
private static int count;
/** Method handle that points to {@link Scope#getSplitState}. */
public static final CompilerConstants.Call GET_SPLIT_STATE = interfaceCallNoLookup(Scope.class, "getSplitState", int.class);
public static final CompilerConstants.Call GET_SPLIT_STATE = virtualCallNoLookup(Scope.class, "getSplitState", int.class);
/** Method handle that points to {@link Scope#setSplitState(int)}. */
public static final CompilerConstants.Call SET_SPLIT_STATE = interfaceCallNoLookup(Scope.class, "setSplitState", void.class, int.class);
public static final CompilerConstants.Call SET_SPLIT_STATE = virtualCallNoLookup(Scope.class, "setSplitState", void.class, int.class);
/**
* Constructor
*
* @param map initial property map
*/
public Scope(final PropertyMap map) {
super(map);
if (Context.DEBUG) {
count++;
}
}
/**
* Constructor
*
* @param proto parent scope
* @param map initial property map
*/
public Scope(final ScriptObject proto, final PropertyMap map) {
super(proto, map);
if (Context.DEBUG) {
count++;
}
}
/**
* Constructor
*
* @param map property map
* @param primitiveSpill primitive spill array
* @param objectSpill reference spill array
*/
public Scope(final PropertyMap map, final long[] primitiveSpill, final Object[] objectSpill) {
super(map, primitiveSpill, objectSpill);
if (Context.DEBUG) {
count++;
}
}
@Override
public boolean isScope() {
return true;
}
@Override
boolean hasWithScope() {
for (ScriptObject obj = this; obj != null; obj = obj.getProto()) {
if (obj instanceof WithObject) {
return true;
}
}
return false;
}
/**
* Get the scope's split method state.
* @return the current state
*
* @return current split state
*/
public int getSplitState();
public int getSplitState() {
return splitState;
}
/**
* Set the scope's split method state.
* @param state the new state.
*
* @param state current split state
*/
public void setSplitState(int state);
public void setSplitState(final int state) {
splitState = state;
}
/**
* Get number of {@code Scope} instances created. If not running in debug
* mode this is always 0.
*
* @return number of scope ScriptObjects created
*/
public static int getScopeCount() {
return count;
}
}

View File

@ -109,20 +109,17 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
/** Search fall back routine name for "no such property" */
public static final String NO_SUCH_PROPERTY_NAME = "__noSuchProperty__";
/** Per ScriptObject flag - is this a scope object? */
public static final int IS_SCOPE = 1 << 0;
/** Per ScriptObject flag - is this an array object? */
public static final int IS_ARRAY = 1 << 1;
public static final int IS_ARRAY = 1 << 0;
/** Per ScriptObject flag - is this an arguments object? */
public static final int IS_ARGUMENTS = 1 << 2;
public static final int IS_ARGUMENTS = 1 << 1;
/** Is length property not-writable? */
public static final int IS_LENGTH_NOT_WRITABLE = 1 << 3;
public static final int IS_LENGTH_NOT_WRITABLE = 1 << 2;
/** Is this a builtin object? */
public static final int IS_BUILTIN = 1 << 4;
public static final int IS_BUILTIN = 1 << 3;
/**
* Spill growth rate - by how many elements does {@link ScriptObject#primitiveSpill} and
@ -395,14 +392,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return has(VALUE) || has(WRITABLE);
}
/**
* ECMA 8.10.3 IsGenericDescriptor ( Desc )
* @return true if this has a descriptor describing an {@link AccessorPropertyDescriptor} or {@link DataPropertyDescriptor}
*/
public final boolean isGenericDescriptor() {
return isAccessorDescriptor() || isDataDescriptor();
}
/**
* ECMA 8.10.5 ToPropertyDescriptor ( Obj )
*
@ -1630,23 +1619,12 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return getMap().isFrozen();
}
/**
* Flag this ScriptObject as scope
*/
public final void setIsScope() {
if (Context.DEBUG) {
scopeCount++;
}
flags |= IS_SCOPE;
}
/**
* Check whether this ScriptObject is scope
* @return true if scope
*/
public final boolean isScope() {
return (flags & IS_SCOPE) != 0;
public boolean isScope() {
return false;
}
/**
@ -1921,14 +1899,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
* Test whether this object contains in its prototype chain or is itself a with-object.
* @return true if a with-object was found
*/
final boolean hasWithScope() {
if (isScope()) {
for (ScriptObject obj = this; obj != null; obj = obj.getProto()) {
if (obj instanceof WithObject) {
return true;
}
}
}
boolean hasWithScope() {
return false;
}
@ -3817,9 +3788,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
/** This is updated only in debug mode - counts number of {@code ScriptObject} instances created */
private static int count;
/** This is updated only in debug mode - counts number of {@code ScriptObject} instances created that are scope */
private static int scopeCount;
/**
* Get number of {@code ScriptObject} instances created. If not running in debug
* mode this is always 0
@ -3829,15 +3797,4 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
public static int getCount() {
return count;
}
/**
* Get number of scope {@code ScriptObject} instances created. If not running in debug
* mode this is always 0
*
* @return number of scope ScriptObjects created
*/
public static int getScopeCount() {
return scopeCount;
}
}

View File

@ -373,9 +373,9 @@ public final class ScriptRuntime {
* @return prototype object after merge
*/
public static ScriptObject mergeScope(final ScriptObject scope) {
final ScriptObject global = scope.getProto();
global.addBoundProperties(scope);
return global;
final ScriptObject parentScope = scope.getProto();
parentScope.addBoundProperties(scope);
return parentScope;
}
/**

View File

@ -44,7 +44,7 @@ import jdk.nashorn.internal.runtime.linker.NashornGuards;
* This class supports the handling of scope in a with body.
*
*/
public final class WithObject extends ScriptObject implements Scope {
public final class WithObject extends Scope {
private static final MethodHandle WITHEXPRESSIONGUARD = findOwnMH("withExpressionGuard", boolean.class, Object.class, PropertyMap.class, SwitchPoint.class);
private static final MethodHandle WITHEXPRESSIONFILTER = findOwnMH("withFilterExpression", Object.class, Object.class);
private static final MethodHandle WITHSCOPEFILTER = findOwnMH("withFilterScope", Object.class, Object.class);
@ -62,7 +62,6 @@ public final class WithObject extends ScriptObject implements Scope {
*/
WithObject(final ScriptObject scope, final ScriptObject expression) {
super(scope, null);
setIsScope();
this.expression = expression;
}
@ -224,29 +223,33 @@ public final class WithObject extends ScriptObject implements Scope {
@Override
public void setSplitState(final int state) {
getNonWithParent().setSplitState(state);
((Scope) getNonWithParent()).setSplitState(state);
}
@Override
public int getSplitState() {
return getNonWithParent().getSplitState();
return ((Scope) getNonWithParent()).getSplitState();
}
@Override
public void addBoundProperties(final ScriptObject source, final Property[] properties) {
// Declared variables in nested eval go to first normal (non-with) parent scope.
getNonWithParent().addBoundProperties(source, properties);
}
/**
* Get first parent scope that is not an instance of WithObject.
*/
private Scope getNonWithParent() {
ScriptObject proto = getParentScope();
private ScriptObject getNonWithParent() {
ScriptObject proto = getProto();
while (proto != null && proto instanceof WithObject) {
proto = ((WithObject)proto).getParentScope();
proto = proto.getProto();
}
assert proto instanceof Scope : "with scope without parent scope";
return (Scope) proto;
return proto;
}
private static GuardedInvocation fixReceiverType(final GuardedInvocation link, final MethodHandle filter) {
// The receiver may be an Object or a ScriptObject.
final MethodType invType = link.getInvocation().type();
@ -380,14 +383,6 @@ public final class WithObject extends ScriptObject implements Scope {
return expression;
}
/**
* Get the parent scope for this {@code WithObject}
* @return the parent scope
*/
public ScriptObject getParentScope() {
return getProto();
}
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
return MH.findStatic(MethodHandles.lookup(), WithObject.class, name, MH.type(rtype, types));
}

View File

@ -439,7 +439,7 @@ public class Shell {
}
try {
final Object res = context.eval(global, source, global, "<shell>", env._strict);
final Object res = context.eval(global, source, global, "<shell>");
if (res != ScriptRuntime.UNDEFINED) {
err.println(JSType.toString(res));
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8087211: Indirect evals should be strict with -strict option
*
* @test
* @run
* @option -strict
*/
var global = this;
try {
// indirect eval call.
global.eval("x = 34;");
throw new Error("should have thrown ReferenceError");
} catch (e if e instanceof ReferenceError) {
}
function teststrict() {
"use strict";
// strict caller, indirect eval.
global.eval('public = 1;');
}
try {
teststrict();
throw new Error("should have thrown SyntaxError");
} catch (e if e instanceof SyntaxError) {
}
function testnonstrict() {
// non strict caller, indirect eval.
global.eval('public = 1;');
}
try {
testnonstrict();
throw new Error("should have thrown SyntaxError");
} catch (e if e instanceof SyntaxError) {
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8087211: Indirect evals should be strict with -strict option
* Make sure without -strict option, indirect evals are not strict.
*
* @test
* @run
*/
var global = this;
// indirect eval call.
global.eval("x = 34;");
function teststrict() {
"use strict";
// strict caller, indirect eval.
global.eval('public = 1;');
}
teststrict();
function testnonstrict() {
// non strict caller, indirect eval.
global.eval('public = 1;');
}
testnonstrict();

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8087312: PropertyMapWrapper.equals should compare className
*
* @test
* @run
* @fork
* @option -Dnashorn.debug=true
*/
function createObject(type) {
// we want to make sure two different object literals with the same keys and types share the same property map.
if (type) {
return {
a: "a",
b: 1,
c: 0.1
}
} else {
return {
a: "x",
b: 10,
c: 3.4
}
}
}
var o1 = createObject(false);
var o2 = createObject(true);
Assert.assertTrue(Debug.map(o1) === Debug.map(o2));

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8098546: eval within a 'with' leaks definitions into global scope
*
* @test
* @run
*/
function func() {
var obj = { foo: 344 };
with (obj) {
eval("var x = foo + 3");
}
Assert.assertTrue(obj.x === undefined);
Assert.assertTrue(x === 347);
}
func();
// x should be undefined here
Assert.assertTrue(typeof x === "undefined");

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8098578: Global scope is not accessible with indirect load call
*
* @test
* @run
*/
var obj = { foo: 343 };
var global = this;
var x = 434;
// indirect load call
var res = load.call(obj, {
name: "t.js",
// global is accessible. All declarations go into
// intermediate inaccessible scope. "this" is global
// User's passed object's properties are accessible
// as variables.
script: "foo -= 300; var bar = x; Assert.assertTrue(bar == 434); function func() {}; this"
})
// 'this' for the evaluated code is global
Assert.assertTrue(res === global);
// properties of passed object are accessible in evaluated code
Assert.assertTrue(obj.foo == 43);
// vars, functions definined in evaluated code don't go into passed object
Assert.assertTrue(typeof obj.bar == "undefined");
Assert.assertTrue(typeof obj.func == "undefined");
// vars, functions definined in evaluated code don't go leak into global
Assert.assertTrue(typeof bar == "undefined");
Assert.assertTrue(typeof func == "undefined");
Assert.assertTrue(typeof foo == "undefined");
var res = load.call(undefined, {
name: "t1.js",
// still global is accessible and 'this' is global
script: "Assert.assertTrue(x == 434); this"
});
// indirect load with 'undefined' this is same as as direct load
// or load on global itself.
Assert.assertTrue(res === global);
// indirect load with 'undefined' this is same as as direct load
// or load on global itself.
var res = load.call(null, {
name: "t2.js",
// still global is accessible and 'this' is global
script: "Assert.assertTrue(x == 434); this"
});
Assert.assertTrue(res === global);
// indirect load with mirror object
var mirror = loadWithNewGlobal({
name: "t3.js",
script: "({ foo: 'hello', x: Math.PI })"
});
var res = load.call(mirror, {
name: "t4.js",
script: "Assert.assertTrue(foo == 'hello'); Assert.assertTrue(x == Math.PI); this"
});
Assert.assertTrue(res === global);
// indirect load on non-script object, non-mirror results in TypeError
function tryLoad(obj) {
try {
load.call(obj, {
name: "t5.js", script: "this"
});
throw new Error("should thrown TypeError for: " + obj);
} catch (e if TypeError) {}
}
tryLoad("hello");
tryLoad(Math.E);
tryLoad(true);
tryLoad(false);
// indirect load of a large script
load.call({}, __DIR__ + "JDK-8098807-payload.js");

View File

@ -0,0 +1,157 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8098807: Strict eval throws ClassCastException with large scripts
*
* @subtest
*/
function f() {}
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8098807: Strict eval throws ClassCastException with large scripts
*
* @test
* @run
* @option -scripting
*/
"use strict";
var path = __DIR__ + "JDK-8098807-payload.js"
var source = readFully(path);
eval(source);

View File

@ -59,10 +59,14 @@ if (!(str1 === str2)){
print("Scoping OK");
var f = eval("function cookie() { print('sweet and crunchy!'); } function cake() { print('moist and delicious!'); }");
// According to the spec, evaluation of function declarations should not return a value,
// but we return values of anonymous function declarations (Nashorn extension).
var e = eval("function cookie() { print('sweet and crunchy!'); } function cake() { print('moist and delicious!'); }");
print(e);
var f = eval("function cookie() { print('sweet and crunchy!'); } function() { print('moist and delicious!'); }");
print(f);
f();
var g = eval("function cake() { print('moist and delicious!'); } function cookie() { print('sweet and crunchy!'); }");
var g = eval("function cake() { print('moist and delicious!'); } function() { print('sweet and crunchy!'); }");
print(g);
g();

View File

@ -5,7 +5,8 @@ undefined
undefined
hello
Scoping OK
function cake() { print('moist and delicious!'); }
undefined
function() { print('moist and delicious!'); }
moist and delicious!
function cookie() { print('sweet and crunchy!'); }
function() { print('sweet and crunchy!'); }
sweet and crunchy!

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8098847: obj."prop" and obj.'prop' should result in SyntaxError
*
* @test/compile-error
*/
var obj = { "prop": 45 };
obj."prop" = "hello";
obj.'prop' = "hello";

View File

@ -0,0 +1,6 @@
test/script/error/JDK-8098847.js:32:5 Expected ident but found prop
obj."prop" = "hello";
^
test/script/error/JDK-8098847.js:33:5 Expected ident but found prop
obj.'prop' = "hello";
^

View File

@ -97,12 +97,14 @@ public class JSONCompatibleTest {
assertEquals(x2.get("1"), 5);
}
@SuppressWarnings("unchecked")
private static List<Object> asList(final Object obj) {
assertJSObject(obj);
Assert.assertTrue(obj instanceof List);
return (List)obj;
}
@SuppressWarnings("unchecked")
private static Map<String, Object> asMap(final Object obj) {
assertJSObject(obj);
Assert.assertTrue(obj instanceof Map);

View File

@ -204,7 +204,7 @@ public class ScriptObjectMirrorTest {
}
try {
final Object obj = e.eval("function func() { print('hello'); }");
final Object obj = e.eval("(function func() { print('hello'); })");
assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value");
} catch (final Throwable t) {
t.printStackTrace();