{
/** Right hand side argument. */
- private final Node rhs;
+ private final Expression rhs;
/**
* Constructor
@@ -49,7 +50,7 @@
* @param token token
* @param rhs expression
*/
- public UnaryNode(final long token, final Node rhs) {
+ public UnaryNode(final long token, final Expression rhs) {
this(token, Math.min(rhs.getStart(), Token.descPosition(token)), Math.max(Token.descPosition(token) + Token.descLength(token), rhs.getFinish()), rhs);
}
@@ -61,13 +62,13 @@
* @param finish finish
* @param rhs expression
*/
- public UnaryNode(final long token, final int start, final int finish, final Node rhs) {
+ public UnaryNode(final long token, final int start, final int finish, final Expression rhs) {
super(token, start, finish);
this.rhs = rhs;
}
- private UnaryNode(final UnaryNode unaryNode, final Node rhs) {
+ private UnaryNode(final UnaryNode unaryNode, final Expression rhs) {
super(unaryNode);
this.rhs = rhs;
}
@@ -101,17 +102,17 @@
}
@Override
- public Node getAssignmentDest() {
+ public Expression getAssignmentDest() {
return isAssignment() ? rhs() : null;
}
@Override
- public Node setAssignmentDest(Node n) {
+ public UnaryNode setAssignmentDest(Expression n) {
return setRHS(n);
}
@Override
- public Node getAssignmentSource() {
+ public Expression getAssignmentSource() {
return getAssignmentDest();
}
@@ -122,7 +123,7 @@
@Override
public Node accept(final NodeVisitor extends LexicalContext> visitor) {
if (visitor.enterUnaryNode(this)) {
- return visitor.leaveUnaryNode(setRHS(rhs.accept(visitor)));
+ return visitor.leaveUnaryNode(setRHS((Expression)rhs.accept(visitor)));
}
return this;
@@ -130,6 +131,22 @@
@Override
public void toString(final StringBuilder sb) {
+ toString(sb, new Runnable() {
+ @Override
+ public void run() {
+ sb.append(rhs().toString());
+ }
+ });
+ }
+
+ /**
+ * Creates the string representation of this unary node, delegating the creation of the string representation of its
+ * operand to a specified runnable.
+ * @param sb the string builder to use
+ * @param rhsStringBuilder the runnable that appends the string representation of the operand to the string builder
+ * when invoked.
+ */
+ public void toString(final StringBuilder sb, final Runnable rhsStringBuilder) {
final TokenType type = tokenType();
final String name = type.getName();
final boolean isPostfix = type == DECPOSTFIX || type == INCPOSTFIX;
@@ -161,7 +178,7 @@
if (rhsParen) {
sb.append('(');
}
- rhs().toString(sb);
+ rhsStringBuilder.run();
if (rhsParen) {
sb.append(')');
}
@@ -189,7 +206,7 @@
*
* @return right hand side or expression node
*/
- public Node rhs() {
+ public Expression rhs() {
return rhs;
}
@@ -202,7 +219,7 @@
* @param rhs right hand side or expression node
* @return a node equivalent to this one except for the requested change.
*/
- public UnaryNode setRHS(final Node rhs) {
+ public UnaryNode setRHS(final Expression rhs) {
if (this.rhs == rhs) {
return this;
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/ir/VarNode.java
--- a/nashorn/src/jdk/nashorn/internal/ir/VarNode.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/ir/VarNode.java Fri Jul 12 20:12:29 2013 +0530
@@ -37,7 +37,7 @@
private final IdentNode name;
/** Initialization expression. */
- private final Node init;
+ private final Expression init;
/** Is this a var statement (as opposed to a "var" in a for loop statement) */
private final int flags;
@@ -59,11 +59,11 @@
* @param name name of variable
* @param init init node or null if just a declaration
*/
- public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Node init) {
+ public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Expression init) {
this(lineNumber, token, finish, name, init, IS_STATEMENT);
}
- private VarNode(final VarNode varNode, final IdentNode name, final Node init, final int flags) {
+ private VarNode(final VarNode varNode, final IdentNode name, final Expression init, final int flags) {
super(varNode);
this.name = init == null ? name : name.setIsInitializedHere();
this.init = init;
@@ -80,7 +80,7 @@
* @param init init node or null if just a declaration
* @param flags flags
*/
- public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Node init, final int flags) {
+ public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Expression init, final int flags) {
super(lineNumber, token, finish);
this.name = init == null ? name : name.setIsInitializedHere();
@@ -99,12 +99,12 @@
}
@Override
- public Node setAssignmentDest(IdentNode n) {
+ public VarNode setAssignmentDest(IdentNode n) {
return setName(n);
}
@Override
- public Node getAssignmentSource() {
+ public Expression getAssignmentSource() {
return isAssignment() ? getInit() : null;
}
@@ -123,9 +123,9 @@
@Override
public Node accept(final NodeVisitor extends LexicalContext> visitor) {
if (visitor.enterVarNode(this)) {
- final IdentNode newName = (IdentNode)name.accept(visitor);
- final Node newInit = init == null ? null : init.accept(visitor);
- final VarNode newThis;
+ final IdentNode newName = (IdentNode)name.accept(visitor);
+ final Expression newInit = init == null ? null : (Expression)init.accept(visitor);
+ final VarNode newThis;
if (name != newName || init != newInit) {
newThis = new VarNode(this, newName, newInit, flags);
} else {
@@ -151,7 +151,7 @@
* If this is an assignment of the form {@code var x = init;}, get the init part.
* @return the expression to initialize the variable to, null if just a declaration
*/
- public Node getInit() {
+ public Expression getInit() {
return init;
}
@@ -160,7 +160,7 @@
* @param init new initialization expression
* @return a node equivalent to this one except for the requested change.
*/
- public VarNode setInit(final Node init) {
+ public VarNode setInit(final Expression init) {
if (this.init == init) {
return this;
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/ir/WhileNode.java
--- a/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java Fri Jul 12 20:12:29 2013 +0530
@@ -59,7 +59,7 @@
* @param body body
* @param controlFlowEscapes control flow escapes?
*/
- protected WhileNode(final WhileNode whileNode, final Node test, final Block body, final boolean controlFlowEscapes) {
+ protected WhileNode(final WhileNode whileNode, final Expression test, final Block body, final boolean controlFlowEscapes) {
super(whileNode, test, body, controlFlowEscapes);
this.isDoWhile = whileNode.isDoWhile;
}
@@ -75,28 +75,28 @@
}
@Override
- protected Node accept(final LexicalContext lc, final NodeVisitor extends LexicalContext> visitor) {
+ public Node accept(final LexicalContext lc, final NodeVisitor extends LexicalContext> visitor) {
if (visitor.enterWhileNode(this)) {
if (isDoWhile()) {
return visitor.leaveWhileNode(
- setTest(lc, test.accept(visitor)).
+ setTest(lc, (Expression)test.accept(visitor)).
setBody(lc, (Block)body.accept(visitor)));
}
return visitor.leaveWhileNode(
setBody(lc, (Block)body.accept(visitor)).
- setTest(lc, test.accept(visitor)));
+ setTest(lc, (Expression)test.accept(visitor)));
}
return this;
}
@Override
- public Node getTest() {
+ public Expression getTest() {
return test;
}
@Override
- public WhileNode setTest(final LexicalContext lc, final Node test) {
+ public WhileNode setTest(final LexicalContext lc, final Expression test) {
if (this.test == test) {
return this;
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/ir/WithNode.java
--- a/nashorn/src/jdk/nashorn/internal/ir/WithNode.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/ir/WithNode.java Fri Jul 12 20:12:29 2013 +0530
@@ -32,9 +32,9 @@
* IR representation for {@code with} statements.
*/
@Immutable
-public final class WithNode extends LexicalContextNode {
+public final class WithNode extends LexicalContextStatement {
/** This expression. */
- private final Node expression;
+ private final Expression expression;
/** Statements. */
private final Block body;
@@ -52,7 +52,7 @@
this.body = null;
}
- private WithNode(final WithNode node, final Node expression, final Block body) {
+ private WithNode(final WithNode node, final Expression expression, final Block body) {
super(node);
this.expression = expression;
this.body = body;
@@ -67,7 +67,7 @@
public Node accept(final LexicalContext lc, final NodeVisitor extends LexicalContext> visitor) {
if (visitor.enterWithNode(this)) {
return visitor.leaveWithNode(
- setExpression(lc, expression.accept(visitor)).
+ setExpression(lc, (Expression)expression.accept(visitor)).
setBody(lc, (Block)body.accept(visitor)));
}
return this;
@@ -110,7 +110,7 @@
* Get the expression of this WithNode
* @return the expression
*/
- public Node getExpression() {
+ public Expression getExpression() {
return expression;
}
@@ -120,7 +120,7 @@
* @param expression new expression
* @return new or same withnode
*/
- public WithNode setExpression(final LexicalContext lc, final Node expression) {
+ public WithNode setExpression(final LexicalContext lc, final Expression expression) {
if (this.expression == expression) {
return this;
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java
--- a/nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java Fri Jul 12 20:12:29 2013 +0530
@@ -33,10 +33,11 @@
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
-
import jdk.nashorn.internal.ir.BinaryNode;
import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.Expression;
import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.Symbol;
import jdk.nashorn.internal.ir.TernaryNode;
import jdk.nashorn.internal.ir.annotations.Ignore;
import jdk.nashorn.internal.ir.annotations.Reference;
@@ -111,8 +112,15 @@
type = "ref: " + type;
}
type += "@" + Debug.id(node);
- if (node.getSymbol() != null) {
- type += "#" + node.getSymbol();
+ final Symbol symbol;
+ if(node instanceof Expression) {
+ symbol = ((Expression)node).getSymbol();
+ } else {
+ symbol = null;
+ }
+
+ if (symbol != null) {
+ type += "#" + symbol;
}
if (node instanceof Block && ((Block)node).needsScope()) {
@@ -135,8 +143,8 @@
status += " Goto ";
}
- if (node.getSymbol() != null) {
- status += node.getSymbol();
+ if (symbol != null) {
+ status += symbol;
}
status = status.trim();
@@ -144,8 +152,8 @@
status = " [" + status + "]";
}
- if (node.getSymbol() != null) {
- String tname = node.getType().toString();
+ if (symbol != null) {
+ String tname = ((Expression)node).getType().toString();
if (tname.indexOf('.') != -1) {
tname = tname.substring(tname.lastIndexOf('.') + 1, tname.length());
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java
--- a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java Fri Jul 12 20:12:29 2013 +0530
@@ -27,18 +27,18 @@
import java.util.Arrays;
import java.util.List;
-
import jdk.nashorn.internal.codegen.CompilerConstants;
import jdk.nashorn.internal.ir.AccessNode;
import jdk.nashorn.internal.ir.BinaryNode;
import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.BlockStatement;
import jdk.nashorn.internal.ir.BreakNode;
import jdk.nashorn.internal.ir.CallNode;
import jdk.nashorn.internal.ir.CaseNode;
import jdk.nashorn.internal.ir.CatchNode;
import jdk.nashorn.internal.ir.ContinueNode;
import jdk.nashorn.internal.ir.EmptyNode;
-import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.ExpressionStatement;
import jdk.nashorn.internal.ir.ForNode;
import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.IdentNode;
@@ -298,14 +298,27 @@
}
@Override
- public boolean enterExecuteNode(final ExecuteNode executeNode) {
- enterDefault(executeNode);
+ public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
+ enterDefault(expressionStatement);
type("ExpressionStatement");
comma();
property("expression");
- executeNode.getExpression().accept(this);
+ expressionStatement.getExpression().accept(this);
+
+ return leave();
+ }
+
+ @Override
+ public boolean enterBlockStatement(BlockStatement blockStatement) {
+ enterDefault(blockStatement);
+
+ type("BlockStatement");
+ comma();
+
+ property("block");
+ blockStatement.getBlock().accept(this);
return leave();
}
@@ -680,15 +693,15 @@
comma();
property("test");
- ternaryNode.lhs().accept(this);
+ ternaryNode.getTest().accept(this);
comma();
property("consequent");
- ternaryNode.rhs().accept(this);
+ ternaryNode.getTrueExpression().accept(this);
comma();
property("alternate");
- ternaryNode.third().accept(this);
+ ternaryNode.getFalseExpression().accept(this);
return leave();
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java
--- a/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java Fri Jul 12 20:12:29 2013 +0530
@@ -26,12 +26,11 @@
package jdk.nashorn.internal.ir.debug;
import java.util.List;
-
import jdk.nashorn.internal.ir.BinaryNode;
import jdk.nashorn.internal.ir.Block;
import jdk.nashorn.internal.ir.CaseNode;
import jdk.nashorn.internal.ir.CatchNode;
-import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.ExpressionStatement;
import jdk.nashorn.internal.ir.ForNode;
import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.IfNode;
@@ -41,8 +40,8 @@
import jdk.nashorn.internal.ir.SplitNode;
import jdk.nashorn.internal.ir.Statement;
import jdk.nashorn.internal.ir.SwitchNode;
-import jdk.nashorn.internal.ir.Symbol;
import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
import jdk.nashorn.internal.ir.VarNode;
import jdk.nashorn.internal.ir.WhileNode;
import jdk.nashorn.internal.ir.WithNode;
@@ -167,14 +166,6 @@
continue;
}
- final Symbol symbol = statement.getSymbol();
-
- if (symbol != null) {
- sb.append(" [");
- sb.append(symbol.toString());
- sb.append(']');
- }
-
int lastIndex = sb.length() - 1;
char lastChar = sb.charAt(lastIndex);
while (Character.isWhitespace(lastChar) && lastIndex >= 0) {
@@ -215,8 +206,19 @@
}
@Override
- public boolean enterExecuteNode(final ExecuteNode executeNode) {
- executeNode.getExpression().accept(this);
+ public boolean enterUnaryNode(final UnaryNode unaryNode) {
+ unaryNode.toString(sb, new Runnable() {
+ @Override
+ public void run() {
+ unaryNode.rhs().accept(PrintVisitor.this);
+ }
+ });
+ return false;
+ }
+
+ @Override
+ public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
+ expressionStatement.getExpression().accept(this);
return false;
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java
--- a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Fri Jul 12 20:12:29 2013 +0530
@@ -1263,6 +1263,4 @@
public Node leaveSUB(final BinaryNode binaryNode) {
return leaveDefault(binaryNode);
}
-
-
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java
--- a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java Fri Jul 12 20:12:29 2013 +0530
@@ -28,13 +28,14 @@
import jdk.nashorn.internal.ir.AccessNode;
import jdk.nashorn.internal.ir.BinaryNode;
import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.BlockStatement;
import jdk.nashorn.internal.ir.BreakNode;
import jdk.nashorn.internal.ir.CallNode;
import jdk.nashorn.internal.ir.CaseNode;
import jdk.nashorn.internal.ir.CatchNode;
import jdk.nashorn.internal.ir.ContinueNode;
import jdk.nashorn.internal.ir.EmptyNode;
-import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.ExpressionStatement;
import jdk.nashorn.internal.ir.ForNode;
import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.IdentNode;
@@ -308,23 +309,43 @@
}
/**
- * Callback for entering an ExecuteNode
+ * Callback for entering an ExpressionStatement
*
- * @param executeNode the node
+ * @param expressionStatement the node
* @return true if traversal should continue and node children be traversed, false otherwise
*/
- public boolean enterExecuteNode(final ExecuteNode executeNode) {
- return enterDefault(executeNode);
+ public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
+ return enterDefault(expressionStatement);
}
/**
- * Callback for leaving an ExecuteNode
+ * Callback for leaving an ExpressionStatement
*
- * @param executeNode the node
+ * @param expressionStatement the node
* @return processed node, which will replace the original one, or the original node
*/
- public Node leaveExecuteNode(final ExecuteNode executeNode) {
- return leaveDefault(executeNode);
+ public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) {
+ return leaveDefault(expressionStatement);
+ }
+
+ /**
+ * Callback for entering a BlockStatement
+ *
+ * @param blockStatement the node
+ * @return true if traversal should continue and node children be traversed, false otherwise
+ */
+ public boolean enterBlockStatement(final BlockStatement blockStatement) {
+ return enterDefault(blockStatement);
+ }
+
+ /**
+ * Callback for leaving a BlockStatement
+ *
+ * @param blockStatement the node
+ * @return processed node, which will replace the original one, or the original node
+ */
+ public Node leaveBlockStatement(final BlockStatement blockStatement) {
+ return leaveDefault(blockStatement);
}
/**
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/lookup/Lookup.java
--- a/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java Fri Jul 12 20:12:29 2013 +0530
@@ -32,8 +32,6 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import jdk.nashorn.internal.runtime.JSType;
-import jdk.nashorn.internal.runtime.Property;
-import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptRuntime;
/**
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java Fri Jul 12 20:12:29 2013 +0530
@@ -179,6 +179,9 @@
/**
* Returns the property listener count for a script object
+ *
+ * @param self self reference
+ * @param obj script object whose listener count is returned
* @return listener count
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Fri Jul 12 20:12:29 2013 +0530
@@ -622,12 +622,15 @@
case "getMethod":
final FindProperty find = adaptee.findProperty(__call__, true);
if (find != null) {
- final ScriptFunctionImpl func = (ScriptFunctionImpl)getObjectValue(find);
- // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
- // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
- return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
- func.makeBoundFunction(this, new Object[] { name })), 0, Object.class),
- adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), __call__), testJSAdaptor(adaptee, null, null, null));
+ final Object value = getObjectValue(find);
+ if (value instanceof ScriptFunction) {
+ final ScriptFunctionImpl func = (ScriptFunctionImpl)value;
+ // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
+ // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
+ return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
+ func.makeBoundFunction(this, new Object[] { name })), 0, Object.class),
+ adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), __call__), testJSAdaptor(adaptee, null, null, null));
+ }
}
throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
default:
@@ -687,16 +690,19 @@
final MethodType type = desc.getMethodType();
if (findData != null) {
final String name = desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null;
- final ScriptFunction func = (ScriptFunction)getObjectValue(findData);
+ final Object value = getObjectValue(findData);
+ if (value instanceof ScriptFunction) {
+ final ScriptFunction func = (ScriptFunction)value;
- final MethodHandle methodHandle = getCallMethodHandle(findData, type,
+ final MethodHandle methodHandle = getCallMethodHandle(findData, type,
useName ? name : null);
- if (methodHandle != null) {
- return new GuardedInvocation(
- methodHandle,
- adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), hook),
- testJSAdaptor(adaptee, findData.getGetter(Object.class), findData.getOwner(), func));
- }
+ if (methodHandle != null) {
+ return new GuardedInvocation(
+ methodHandle,
+ adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), hook),
+ testJSAdaptor(adaptee, findData.getGetter(Object.class), findData.getOwner(), func));
+ }
+ }
}
switch (hook) {
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java Fri Jul 12 20:12:29 2013 +0530
@@ -48,7 +48,6 @@
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
/**
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java Fri Jul 12 20:12:29 2013 +0530
@@ -27,18 +27,24 @@
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.lang.invoke.MethodHandle;
+import java.util.ArrayList;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.AccessorProperty;
import jdk.nashorn.internal.runtime.ECMAException;
import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.InvokeByName;
/**
@@ -471,4 +477,114 @@
return false;
}
+
+ /**
+ * Nashorn extension: Object.bindProperties
+ *
+ * Binds the source object's properties to the target object. Binding
+ * properties allows two-way read/write for the properties of the source object.
+ *
+ * Example:
+ *
+ * var obj = { x: 34, y: 100 };
+ * var foo = {}
+ *
+ * // bind properties of "obj" to "foo" object
+ * Object.bindProperties(foo, obj);
+ *
+ * // now, we can access/write on 'foo' properties
+ * print(foo.x); // prints obj.x which is 34
+ *
+ * // update obj.x via foo.x
+ * foo.x = "hello";
+ * print(obj.x); // prints "hello" now
+ *
+ * obj.x = 42; // foo.x also becomes 42
+ * print(foo.x); // prints 42
+ *
+ *
+ * The source object bound can be a ScriptObject or a ScriptOjectMirror.
+ * null or undefined source object results in TypeError being thrown.
+ *
+ * Example:
+ *
+ * var obj = loadWithNewGlobal({
+ * name: "test",
+ * script: "obj = { x: 33, y: 'hello' }"
+ * });
+ *
+ * // bind 'obj's properties to global scope 'this'
+ * Object.bindProperties(this, obj);
+ * print(x); // prints 33
+ * print(y); // prints "hello"
+ * x = Math.PI; // changes obj.x to Math.PI
+ * print(obj.x); // prints Math.PI
+ *
+ *
+ * Limitations of property binding:
+ *
+ * - Only enumerable, immediate (not proto inherited) properties of the source object are bound.
+ *
- If the target object already contains a property called "foo", the source's "foo" is skipped (not bound).
+ *
- Properties added to the source object after binding to the target are not bound.
+ *
- Property configuration changes on the source object (or on the target) is not propagated.
+ *
- Delete of property on the target (or the source) is not propagated -
+ * only the property value is set to 'undefined' if the property happens to be a data property.
+ *
+ *
+ * It is recommended that the bound properties be treated as non-configurable
+ * properties to avoid surprises.
+ *
+ *
+ * @param self self reference
+ * @param target the target object to which the source object's properties are bound
+ * @param source the source object whose properties are bound to the target
+ * @return the target object after property binding
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+ public static Object bindProperties(final Object self, final Object target, final Object source) {
+ // target object has to be a ScriptObject
+ Global.checkObject(target);
+ // check null or undefined source object
+ Global.checkObjectCoercible(source);
+
+ final ScriptObject targetObj = (ScriptObject)target;
+
+ if (source instanceof ScriptObject) {
+ final ScriptObject sourceObj = (ScriptObject)source;
+ final Property[] properties = sourceObj.getMap().getProperties();
+
+ // filter non-enumerable properties
+ final ArrayList propList = new ArrayList<>();
+ for (Property prop : properties) {
+ if (prop.isEnumerable()) {
+ propList.add(prop);
+ }
+ }
+
+ if (! propList.isEmpty()) {
+ targetObj.addBoundProperties(sourceObj, propList.toArray(new Property[propList.size()]));
+ }
+ } else if (source instanceof ScriptObjectMirror) {
+ // get enumerable, immediate properties of mirror
+ final ScriptObjectMirror mirror = (ScriptObjectMirror)source;
+ final String[] keys = mirror.getOwnKeys(false);
+ if (keys.length == 0) {
+ // nothing to bind
+ return target;
+ }
+
+ // make accessor properties using dynamic invoker getters and setters
+ final AccessorProperty[] props = new AccessorProperty[keys.length];
+ for (int idx = 0; idx < keys.length; idx++) {
+ final String name = keys[idx];
+ final MethodHandle getter = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getElem:" + name, Object.class, ScriptObjectMirror.class);
+ final MethodHandle setter = Bootstrap.createDynamicInvoker("dyn:setProp|setElem:" + name, Object.class, ScriptObjectMirror.class, Object.class);
+ props[idx] = (AccessorProperty.create(name, 0, getter, setter));
+ }
+
+ targetObj.addBoundProperties(source, props);
+ }
+
+ return target;
+ }
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
--- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Fri Jul 12 20:12:29 2013 +0530
@@ -212,10 +212,10 @@
// Instance of this class is used as global anonymous function which
// serves as Function.prototype object.
private static class AnonymousFunction extends ScriptFunctionImpl {
- private static final PropertyMap map$ = PropertyMap.newMap().setIsShared();
+ private static final PropertyMap anonmap$ = PropertyMap.newMap().setIsShared();
static PropertyMap getInitialMap() {
- return map$;
+ return anonmap$;
}
AnonymousFunction(final Global global) {
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/parser/JSONParser.java
--- a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java Fri Jul 12 20:12:29 2013 +0530
@@ -35,6 +35,7 @@
import java.util.ArrayList;
import java.util.List;
+import jdk.nashorn.internal.ir.Expression;
import jdk.nashorn.internal.ir.LiteralNode;
import jdk.nashorn.internal.ir.Node;
import jdk.nashorn.internal.ir.ObjectNode;
@@ -274,7 +275,7 @@
* Parse a JSON literal from the token stream
* @return the JSON literal as a Node
*/
- private Node jsonLiteral() {
+ private Expression jsonLiteral() {
final long literalToken = token;
switch (type) {
@@ -326,7 +327,7 @@
* Parse an array literal from the token stream
* @return the array literal as a Node
*/
- private Node arrayLiteral() {
+ private LiteralNode arrayLiteral() {
// Unlike JavaScript array literals, elison is not permitted in JSON.
// Capture LBRACKET token.
@@ -334,9 +335,9 @@
// LBRACKET tested in caller.
next();
- Node result = null;
+ LiteralNode result = null;
// Prepare to accummulating elements.
- final List elements = new ArrayList<>();
+ final List elements = new ArrayList<>();
loop:
while (true) {
@@ -368,7 +369,7 @@
* Parse an object literal from the token stream
* @return the object literal as a Node
*/
- private Node objectLiteral() {
+ private ObjectNode objectLiteral() {
// Capture LBRACE token.
final long objectToken = token;
// LBRACE tested in caller.
@@ -423,7 +424,7 @@
if (name != null) {
expect(COLON);
- final Node value = jsonLiteral();
+ final Expression value = jsonLiteral();
return new PropertyNode(propertyToken, value.getFinish(), name, value, null, null);
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/parser/Lexer.java
--- a/nashorn/src/jdk/nashorn/internal/parser/Lexer.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/parser/Lexer.java Fri Jul 12 20:12:29 2013 +0530
@@ -546,14 +546,27 @@
}
/**
+ * interface to receive line information for multi-line literals.
+ */
+ protected interface LineInfoReceiver {
+ /**
+ * Receives line information
+ * @param line last line number
+ * @param linePosition position of last line
+ */
+ public void lineInfo(int line, int linePosition);
+ }
+
+ /**
* Check whether the given token represents the beginning of a literal. If so scan
* the literal and return true, otherwise return false.
*
* @param token the token.
* @param startTokenType the token type.
+ * @parasm lir LineInfoReceiver that receives line info for multi-line string literals.
* @return True if a literal beginning with startToken was found and scanned.
*/
- protected boolean scanLiteral(final long token, final TokenType startTokenType) {
+ protected boolean scanLiteral(final long token, final TokenType startTokenType, final LineInfoReceiver lir) {
// Check if it can be a literal.
if (!canStartLiteral(startTokenType)) {
return false;
@@ -569,7 +582,7 @@
return scanRegEx();
} else if (ch0 == '<') {
if (ch1 == '<') {
- return scanHereString();
+ return scanHereString(lir);
} else if (Character.isJavaIdentifierStart(ch1)) {
return scanXMLLiteral();
}
@@ -1417,7 +1430,7 @@
*
* @return TRUE if is a here string.
*/
- private boolean scanHereString() {
+ private boolean scanHereString(final LineInfoReceiver lir) {
assert ch0 == '<' && ch1 == '<';
if (scripting) {
// Record beginning of here string.
@@ -1446,7 +1459,13 @@
// Record rest of line.
final State restState = saveState();
+ // keep line number updated
+ int lastLine = line;
+ int lastLinePosition = linePosition;
+
skipLine(false);
+ lastLine++;
+ lastLinePosition = position;
restState.setLimit(position);
// Record beginning of string.
@@ -1463,9 +1482,14 @@
}
skipLine(false);
+ lastLine++;
+ lastLinePosition = position;
stringEnd = position;
}
+ // notify last line information
+ lir.lineInfo(lastLine, lastLinePosition);
+
// Record end of string.
stringState.setLimit(stringEnd);
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/parser/Parser.java
--- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java Fri Jul 12 20:12:29 2013 +0530
@@ -54,6 +54,7 @@
import static jdk.nashorn.internal.parser.TokenType.WHILE;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -66,6 +67,7 @@
import jdk.nashorn.internal.ir.BinaryNode;
import jdk.nashorn.internal.ir.Block;
import jdk.nashorn.internal.ir.BlockLexicalContext;
+import jdk.nashorn.internal.ir.BlockStatement;
import jdk.nashorn.internal.ir.BreakNode;
import jdk.nashorn.internal.ir.BreakableNode;
import jdk.nashorn.internal.ir.CallNode;
@@ -73,7 +75,8 @@
import jdk.nashorn.internal.ir.CatchNode;
import jdk.nashorn.internal.ir.ContinueNode;
import jdk.nashorn.internal.ir.EmptyNode;
-import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.Expression;
+import jdk.nashorn.internal.ir.ExpressionStatement;
import jdk.nashorn.internal.ir.ForNode;
import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
@@ -127,6 +130,9 @@
private static final DebugLogger LOG = new DebugLogger("parser");
+ /** to receive line information from Lexer when scanning multine literals. */
+ protected final Lexer.LineInfoReceiver lineInfoReceiver;
+
/**
* Constructor
*
@@ -151,6 +157,19 @@
this.env = env;
this.namespace = new Namespace(env.getNamespace());
this.scripting = env._scripting;
+ if (this.scripting) {
+ this.lineInfoReceiver = new Lexer.LineInfoReceiver() {
+ @Override
+ public void lineInfo(final int line, final int linePosition) {
+ // update the parser maintained line information
+ Parser.this.line = line;
+ Parser.this.linePosition = linePosition;
+ }
+ };
+ } else {
+ // non-scripting mode script can't have multi-line literals
+ this.lineInfoReceiver = null;
+ }
}
/**
@@ -350,7 +369,7 @@
* @return New block.
*/
private Block newBlock() {
- return lc.push(new Block(line, token, Token.descPosition(token)));
+ return lc.push(new Block(token, Token.descPosition(token)));
}
/**
@@ -516,7 +535,7 @@
* @param rhs Right hand side expression.
* @return Verified expression.
*/
- private Node verifyAssignment(final long op, final Node lhs, final Node rhs) {
+ private Expression verifyAssignment(final long op, final Expression lhs, final Expression rhs) {
final TokenType opType = Token.descType(op);
switch (opType) {
@@ -562,7 +581,7 @@
* @param isPostfix Prefix or postfix.
* @return Reduced expression.
*/
- private static Node incDecExpression(final long firstToken, final TokenType tokenType, final Node expression, final boolean isPostfix) {
+ private static UnaryNode incDecExpression(final long firstToken, final TokenType tokenType, final Expression expression, final boolean isPostfix) {
if (isPostfix) {
return new UnaryNode(Token.recast(firstToken, tokenType == DECPREFIX ? DECPOSTFIX : INCPOSTFIX), expression.getStart(), Token.descPosition(firstToken) + Token.descLength(firstToken), expression);
}
@@ -622,8 +641,8 @@
* @return Directive value if the given statement is a directive
*/
private String getDirective(final Node stmt) {
- if (stmt instanceof ExecuteNode) {
- final Node expr = ((ExecuteNode)stmt).getExpression();
+ if (stmt instanceof ExpressionStatement) {
+ final Node expr = ((ExpressionStatement)stmt).getExpression();
if (expr instanceof LiteralNode) {
final LiteralNode> lit = (LiteralNode>)expr;
final long litToken = lit.getToken();
@@ -836,9 +855,7 @@
* Parse a statement block.
*/
private void block() {
- final Block newBlock = getBlock(true);
- // Force block execution.
- appendStatement(new ExecuteNode(newBlock.getLineNumber(), newBlock.getToken(), finish, newBlock));
+ appendStatement(new BlockStatement(line, getBlock(true)));
}
/**
@@ -921,7 +938,7 @@
verifyStrictIdent(name, "variable name");
// Assume no init.
- Node init = null;
+ Expression init = null;
// Look for initializer assignment.
if (type == ASSIGN) {
@@ -985,20 +1002,20 @@
final long expressionToken = token;
// Get expression and add as statement.
- final Node expression = expression();
-
- ExecuteNode executeNode = null;
+ final Expression expression = expression();
+
+ ExpressionStatement expressionStatement = null;
if (expression != null) {
- executeNode = new ExecuteNode(expressionLine, expressionToken, finish, expression);
- appendStatement(executeNode);
+ expressionStatement = new ExpressionStatement(expressionLine, expressionToken, finish, expression);
+ appendStatement(expressionStatement);
} else {
expect(null);
}
endOfLine();
- if (executeNode != null) {
- executeNode.setFinish(finish);
+ if (expressionStatement != null) {
+ expressionStatement.setFinish(finish);
lc.getCurrentBlock().setFinish(finish);
}
}
@@ -1020,7 +1037,7 @@
next();
expect(LPAREN);
- final Node test = expression();
+ final Expression test = expression();
expect(RPAREN);
final Block pass = getStatement();
@@ -1049,8 +1066,6 @@
// Create FOR node, capturing FOR token.
ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, null, null, null, ForNode.IS_FOR);
- // Set up new block for scope of vars. Captures first token.
- Block outer = newBlock();
lc.push(forNode);
try {
@@ -1076,7 +1091,7 @@
case SEMICOLON:
break;
default:
- final Node expression = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
+ final Expression expression = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
forNode = forNode.setInit(lc, expression);
break;
}
@@ -1148,15 +1163,11 @@
final Block body = getStatement();
forNode = forNode.setBody(lc, body);
forNode.setFinish(body.getFinish());
- outer.setFinish(body.getFinish());
appendStatement(forNode);
} finally {
lc.pop(forNode);
- outer = restoreBlock(outer);
}
-
- appendStatement(new ExecuteNode(outer.getLineNumber(), outer.getToken(), outer.getFinish(), outer));
}
/**
@@ -1364,7 +1375,7 @@
// RETURN tested in caller.
nextOrEOL();
- Node expression = null;
+ Expression expression = null;
// SEMICOLON or expression.
switch (type) {
@@ -1400,7 +1411,7 @@
// YIELD tested in caller.
nextOrEOL();
- Node expression = null;
+ Expression expression = null;
// SEMICOLON or expression.
switch (type) {
@@ -1502,7 +1513,7 @@
while (type != RBRACE) {
// Prepare for next case.
- Node caseExpression = null;
+ Expression caseExpression = null;
final long caseToken = token;
switch (type) {
@@ -1595,7 +1606,7 @@
// THROW tested in caller.
nextOrEOL();
- Node expression = null;
+ Expression expression = null;
// SEMICOLON or expression.
switch (type) {
@@ -1643,6 +1654,7 @@
next();
// Container block needed to act as target for labeled break statements
+ final int startLine = line;
Block outer = newBlock();
// Create try.
@@ -1662,11 +1674,13 @@
verifyStrictIdent(exception, "catch argument");
// Check for conditional catch.
- Node ifExpression = null;
+ final Expression ifExpression;
if (type == IF) {
next();
// Get the exception condition.
ifExpression = expression();
+ } else {
+ ifExpression = null;
}
expect(RPAREN);
@@ -1713,7 +1727,7 @@
outer = restoreBlock(outer);
}
- appendStatement(new ExecuteNode(outer.getLineNumber(), outer.getToken(), outer.getFinish(), outer));
+ appendStatement(new BlockStatement(startLine, outer));
}
/**
@@ -1731,7 +1745,7 @@
// DEBUGGER tested in caller.
next();
endOfLine();
- appendStatement(new ExecuteNode(debuggerLine, debuggerToken, finish, new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList())));
+ appendStatement(new ExpressionStatement(debuggerLine, debuggerToken, finish, new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList())));
}
/**
@@ -1749,7 +1763,7 @@
* @return Expression node.
*/
@SuppressWarnings("fallthrough")
- private Node primaryExpression() {
+ private Expression primaryExpression() {
// Capture first token.
final int primaryLine = line;
final long primaryToken = token;
@@ -1796,7 +1810,7 @@
case LPAREN:
next();
- final Node expression = expression();
+ final Expression expression = expression();
expect(RPAREN);
@@ -1804,7 +1818,7 @@
default:
// In this context some operator tokens mark the start of a literal.
- if (lexer.scanLiteral(primaryToken, type)) {
+ if (lexer.scanLiteral(primaryToken, type, lineInfoReceiver)) {
next();
return getLiteral();
}
@@ -1823,17 +1837,16 @@
* @param primaryToken Original string token.
* @return callNode to $EXEC.
*/
- Node execString(final int primaryLine, final long primaryToken) {
+ CallNode execString(final int primaryLine, final long primaryToken) {
// Synthesize an ident to call $EXEC.
final IdentNode execIdent = new IdentNode(primaryToken, finish, ScriptingFunctions.EXEC_NAME);
// Skip over EXECSTRING.
next();
// Set up argument list for call.
- final List arguments = new ArrayList<>();
// Skip beginning of edit string expression.
expect(LBRACE);
// Add the following expression to arguments.
- arguments.add(expression());
+ final List arguments = Collections.singletonList(expression());
// Skip ending of edit string expression.
expect(RBRACE);
@@ -1860,14 +1873,14 @@
* Parse array literal.
* @return Expression node.
*/
- private Node arrayLiteral() {
+ private LiteralNode arrayLiteral() {
// Capture LBRACKET token.
final long arrayToken = token;
// LBRACKET tested in caller.
next();
// Prepare to accummulating elements.
- final List elements = new ArrayList<>();
+ final List elements = new ArrayList<>();
// Track elisions.
boolean elision = true;
loop:
@@ -1895,7 +1908,7 @@
throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
}
// Add expression element.
- final Node expression = assignmentExpression(false);
+ final Expression expression = assignmentExpression(false);
if (expression != null) {
elements.add(expression);
@@ -1925,7 +1938,7 @@
* Parse an object literal.
* @return Expression node.
*/
- private Node objectLiteral() {
+ private ObjectNode objectLiteral() {
// Capture LBRACE token.
final long objectToken = token;
// LBRACE tested in caller.
@@ -1972,11 +1985,11 @@
// ECMA section 11.1.5 Object Initialiser
// point # 4 on property assignment production
- final Node value = property.getValue();
+ final Expression value = property.getValue();
final FunctionNode getter = property.getGetter();
final FunctionNode setter = property.getSetter();
- final Node prevValue = existingProperty.getValue();
+ final Expression prevValue = existingProperty.getValue();
final FunctionNode prevGetter = existingProperty.getGetter();
final FunctionNode prevSetter = existingProperty.getSetter();
@@ -2052,7 +2065,7 @@
private PropertyKey propertyName() {
switch (type) {
case IDENT:
- return getIdent();
+ return getIdent().setIsPropertyName();
case OCTAL:
if (isStrictMode) {
throw error(AbstractParser.message("strict.no.octal"), token);
@@ -2129,7 +2142,7 @@
}
}
- propertyName = new IdentNode(propertyToken, finish, ident);
+ propertyName = new IdentNode(propertyToken, finish, ident).setIsPropertyName();
} else {
propertyName = propertyName();
}
@@ -2155,14 +2168,14 @@
* Parse left hand side expression.
* @return Expression node.
*/
- private Node leftHandSideExpression() {
+ private Expression leftHandSideExpression() {
int callLine = line;
long callToken = token;
- Node lhs = memberExpression();
+ Expression lhs = memberExpression();
if (type == LPAREN) {
- final List arguments = argumentList();
+ final List arguments = optimizeList(argumentList());
// Catch special functions.
if (lhs instanceof IdentNode) {
@@ -2181,7 +2194,7 @@
switch (type) {
case LPAREN:
// Get NEW or FUNCTION arguments.
- final List arguments = argumentList();
+ final List arguments = optimizeList(argumentList());
// Create call node.
lhs = new CallNode(callLine, callToken, finish, lhs, arguments);
@@ -2192,7 +2205,7 @@
next();
// Get array index.
- final Node rhs = expression();
+ final Expression rhs = expression();
expect(RBRACKET);
@@ -2229,19 +2242,19 @@
* Parse new expression.
* @return Expression node.
*/
- private Node newExpression() {
+ private Expression newExpression() {
final long newToken = token;
// NEW is tested in caller.
next();
// Get function base.
final int callLine = line;
- final Node constructor = memberExpression();
+ final Expression constructor = memberExpression();
if (constructor == null) {
return null;
}
// Get arguments.
- List arguments;
+ ArrayList arguments;
// Allow for missing arguments.
if (type == LPAREN) {
@@ -2259,12 +2272,11 @@
//
// The object literal following the "new Constructor()" expresssion
// is passed as an additional (last) argument to the constructor.
-
if (!env._no_syntax_extensions && type == LBRACE) {
arguments.add(objectLiteral());
}
- final CallNode callNode = new CallNode(callLine, constructor.getToken(), finish, constructor, arguments);
+ final CallNode callNode = new CallNode(callLine, constructor.getToken(), finish, constructor, optimizeList(arguments));
return new UnaryNode(newToken, callNode);
}
@@ -2282,9 +2294,9 @@
* Parse member expression.
* @return Expression node.
*/
- private Node memberExpression() {
+ private Expression memberExpression() {
// Prepare to build operation.
- Node lhs;
+ Expression lhs;
switch (type) {
case NEW:
@@ -2313,7 +2325,7 @@
next();
// Get array index.
- final Node index = expression();
+ final Expression index = expression();
expect(RBRACKET);
@@ -2358,9 +2370,9 @@
* Parse function call arguments.
* @return Argument list.
*/
- private List argumentList() {
+ private ArrayList argumentList() {
// Prepare to accumulate list of arguments.
- final List nodeList = new ArrayList<>();
+ final ArrayList nodeList = new ArrayList<>();
// LPAREN tested in caller.
next();
@@ -2380,9 +2392,23 @@
}
expect(RPAREN);
-
return nodeList;
- }
+ }
+
+ private static List optimizeList(ArrayList list) {
+ switch(list.size()) {
+ case 0: {
+ return Collections.emptyList();
+ }
+ case 1: {
+ return Collections.singletonList(list.get(0));
+ }
+ default: {
+ list.trimToSize();
+ return list;
+ }
+ }
+ }
/**
* FunctionDeclaration :
@@ -2398,7 +2424,7 @@
*
* @return Expression node.
*/
- private Node functionExpression(final boolean isStatement, final boolean topLevel) {
+ private Expression functionExpression(final boolean isStatement, final boolean topLevel) {
final long functionToken = token;
final int functionLine = line;
// FUNCTION is tested in caller.
@@ -2574,10 +2600,8 @@
*/
// just expression as function body
- final Node expr = assignmentExpression(true);
+ final Expression expr = assignmentExpression(true);
assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
- // create a return statement - this creates code in itself and does not need to be
- // wrapped into an ExecuteNode
final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), finish, expr);
appendStatement(returnNode);
lastToken = token;
@@ -2620,11 +2644,11 @@
}
}
- private RuntimeNode referenceError(final Node lhs, final Node rhs, final boolean earlyError) {
+ private RuntimeNode referenceError(final Expression lhs, final Expression rhs, final boolean earlyError) {
if (earlyError) {
throw error(JSErrorType.REFERENCE_ERROR, AbstractParser.message("invalid.lvalue"), lhs.getToken());
}
- final ArrayList args = new ArrayList<>();
+ final ArrayList args = new ArrayList<>();
args.add(lhs);
if (rhs == null) {
args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish()));
@@ -2669,18 +2693,18 @@
* Parse unary expression.
* @return Expression node.
*/
- private Node unaryExpression() {
+ private Expression unaryExpression() {
final int unaryLine = line;
final long unaryToken = token;
switch (type) {
case DELETE: {
next();
- final Node expr = unaryExpression();
+ final Expression expr = unaryExpression();
if (expr instanceof BaseNode || expr instanceof IdentNode) {
return new UnaryNode(unaryToken, expr);
}
- appendStatement(new ExecuteNode(unaryLine, unaryToken, finish, expr));
+ appendStatement(new ExpressionStatement(unaryLine, unaryToken, finish, expr));
return LiteralNode.newInstance(unaryToken, finish, true);
}
case VOID:
@@ -2690,7 +2714,7 @@
case BIT_NOT:
case NOT:
next();
- final Node expr = unaryExpression();
+ final Expression expr = unaryExpression();
return new UnaryNode(unaryToken, expr);
case INCPREFIX:
@@ -2698,7 +2722,7 @@
final TokenType opType = type;
next();
- final Node lhs = leftHandSideExpression();
+ final Expression lhs = leftHandSideExpression();
// ++, -- without operand..
if (lhs == null) {
throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
@@ -2723,14 +2747,14 @@
break;
}
- Node expression = leftHandSideExpression();
+ Expression expression = leftHandSideExpression();
if (last != EOL) {
switch (type) {
case INCPREFIX:
case DECPREFIX:
final TokenType opType = type;
- final Node lhs = expression;
+ final Expression lhs = expression;
// ++, -- without operand..
if (lhs == null) {
throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
@@ -2855,16 +2879,16 @@
* Parse expression.
* @return Expression node.
*/
- private Node expression() {
+ private Expression expression() {
// TODO - Destructuring array.
// Include commas in expression parsing.
return expression(unaryExpression(), COMMARIGHT.getPrecedence(), false);
}
- private Node expression(final Node exprLhs, final int minPrecedence, final boolean noIn) {
+ private Expression expression(final Expression exprLhs, final int minPrecedence, final boolean noIn) {
// Get the precedence of the next operator.
int precedence = type.getPrecedence();
- Node lhs = exprLhs;
+ Expression lhs = exprLhs;
// While greater precedence.
while (type.isOperator(noIn) && precedence >= minPrecedence) {
@@ -2877,12 +2901,12 @@
// Pass expression. Middle expression of a conditional expression can be a "in"
// expression - even in the contexts where "in" is not permitted.
- final Node rhs = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
+ final Expression rhs = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
expect(COLON);
// Fail expression.
- final Node third = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
+ final Expression third = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
// Build up node.
lhs = new TernaryNode(op, lhs, rhs, third);
@@ -2891,7 +2915,7 @@
next();
// Get the next primary expression.
- Node rhs = unaryExpression();
+ Expression rhs = unaryExpression();
// Get precedence of next operator.
int nextPrecedence = type.getPrecedence();
@@ -2913,7 +2937,7 @@
return lhs;
}
- private Node assignmentExpression(final boolean noIn) {
+ private Expression assignmentExpression(final boolean noIn) {
// TODO - Handle decompose.
// Exclude commas in expression parsing.
return expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Fri Jul 12 20:12:29 2013 +0530
@@ -147,9 +147,9 @@
* and are thus rebound with that as receiver
*
* @param property accessor property to rebind
- * @param delegate delegate script object to rebind receiver to
+ * @param delegate delegate object to rebind receiver to
*/
- public AccessorProperty(final AccessorProperty property, final ScriptObject delegate) {
+ public AccessorProperty(final AccessorProperty property, final Object delegate) {
super(property);
this.primitiveGetter = bindTo(property.primitiveGetter, delegate);
@@ -248,11 +248,10 @@
primitiveSetter = null;
if (isParameter() && hasArguments()) {
- final MethodHandle arguments = MH.getter(lookup, structure, "arguments", Object.class);
- final MethodHandle argumentsSO = MH.asType(arguments, arguments.type().changeReturnType(ScriptObject.class));
+ final MethodHandle arguments = MH.getter(lookup, structure, "arguments", ScriptObject.class);
- objectGetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.GET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot), Lookup.GET_OBJECT_TYPE);
- objectSetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.SET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot), Lookup.SET_OBJECT_TYPE);
+ objectGetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.GET_ARGUMENT.methodHandle(), 0, arguments), 1, slot), Lookup.GET_OBJECT_TYPE);
+ objectSetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.SET_ARGUMENT.methodHandle(), 0, arguments), 1, slot), Lookup.SET_OBJECT_TYPE);
} else {
final GettersSetters gs = GETTERS_SETTERS.get(structure);
objectGetter = gs.getters[slot];
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java Fri Jul 12 20:12:29 2013 +0530
@@ -62,4 +62,10 @@
* @param code bytecode to verify
*/
public void verify(final byte[] code);
+
+ /**
+ * Get next unique script id
+ * @return unique script id
+ */
+ public long getUniqueScriptId();
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/Context.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java Fri Jul 12 20:12:29 2013 +0530
@@ -36,15 +36,13 @@
import java.io.PrintWriter;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
+import java.util.concurrent.atomic.AtomicLong;
import java.net.MalformedURLException;
import java.net.URL;
-import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSigner;
import java.security.CodeSource;
-import java.security.Permissions;
import java.security.PrivilegedAction;
-import java.security.ProtectionDomain;
import java.util.Map;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
@@ -96,6 +94,11 @@
public void verify(final byte[] code) {
context.verify(code);
}
+
+ @Override
+ public long getUniqueScriptId() {
+ return context.getUniqueScriptId();
+ }
}
/** Is Context global debug mode enabled ? */
@@ -197,6 +200,9 @@
/** Current error manager. */
private final ErrorManager errors;
+ /** Unique id for script. Used only when --loader-per-compile=false */
+ private final AtomicLong uniqueScriptId;
+
private static final ClassLoader myLoader = Context.class.getClassLoader();
private static final StructureLoader sharedLoader;
@@ -253,7 +259,13 @@
this.env = new ScriptEnvironment(options, out, err);
this._strict = env._strict;
this.appLoader = appLoader;
- this.scriptLoader = env._loader_per_compile? null : createNewLoader();
+ if (env._loader_per_compile) {
+ this.scriptLoader = null;
+ this.uniqueScriptId = null;
+ } else {
+ this.scriptLoader = createNewLoader();
+ this.uniqueScriptId = new AtomicLong();
+ }
this.errors = errors;
// if user passed -classpath option, make a class loader with that and set it as
@@ -543,6 +555,21 @@
}
/**
+ * Checks that the given package can be accessed from current call stack.
+ *
+ * @param fullName fully qualified package name
+ */
+ public static void checkPackageAccess(final String fullName) {
+ final int index = fullName.lastIndexOf('.');
+ if (index != -1) {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPackageAccess(fullName.substring(0, index));
+ }
+ }
+ }
+
+ /**
* Lookup a Java class. This is used for JSR-223 stuff linking in from
* {@code jdk.nashorn.internal.objects.NativeJava} and {@code jdk.nashorn.internal.runtime.NativeJavaPackage}
*
@@ -554,19 +581,7 @@
*/
public Class> findClass(final String fullName) throws ClassNotFoundException {
// check package access as soon as possible!
- final int index = fullName.lastIndexOf('.');
- if (index != -1) {
- final SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- AccessController.doPrivileged(new PrivilegedAction() {
- @Override
- public Void run() {
- sm.checkPackageAccess(fullName.substring(0, index));
- return null;
- }
- }, createNoPermissionsContext());
- }
- }
+ checkPackageAccess(fullName);
// try the script -classpath loader, if that is set
if (classPathLoader != null) {
@@ -707,10 +722,6 @@
return (context != null) ? context : Context.getContextTrusted();
}
- private static AccessControlContext createNoPermissionsContext() {
- return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) });
- }
-
private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) {
ScriptFunction script = null;
@@ -818,4 +829,8 @@
private ScriptObject newGlobalTrusted() {
return new Global(this);
}
+
+ private long getUniqueScriptId() {
+ return uniqueScriptId.getAndIncrement();
+ }
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java Fri Jul 12 20:12:29 2013 +0530
@@ -41,7 +41,7 @@
public class FunctionScope extends ScriptObject implements Scope {
/** Area to store scope arguments. (public for access from scripts.) */
- public final Object arguments;
+ public final ScriptObject arguments;
/** Flag to indicate that a split method issued a return statement */
private int splitState = -1;
@@ -53,7 +53,7 @@
* @param callerScope caller scope
* @param arguments arguments
*/
- public FunctionScope(final PropertyMap map, final ScriptObject callerScope, final Object arguments) {
+ public FunctionScope(final PropertyMap map, final ScriptObject callerScope, final ScriptObject arguments) {
super(callerScope, map);
this.arguments = arguments;
setIsScope();
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java Fri Jul 12 20:12:29 2013 +0530
@@ -260,7 +260,7 @@
*
* @return New {@link PropertyMap} with {@link Property} added.
*/
- PropertyMap addPropertyBind(final AccessorProperty property, final ScriptObject bindTo) {
+ PropertyMap addPropertyBind(final AccessorProperty property, final Object bindTo) {
return addProperty(new AccessorProperty(property, bindTo));
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java Fri Jul 12 20:12:29 2013 +0530
@@ -71,6 +71,8 @@
private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH("isNonStrictFunction", boolean.class, Object.class, Object.class, ScriptFunctionData.class);
+ private static final MethodHandle ADD_ZEROTH_ELEMENT = findOwnMH("addZerothElement", Object[].class, Object[].class, Object.class);
+
/** The parent scope. */
private final ScriptObject scope;
@@ -546,7 +548,21 @@
}
private static MethodHandle bindToNameIfNeeded(final MethodHandle methodHandle, final String bindName) {
- return bindName == null ? methodHandle : MH.insertArguments(methodHandle, 1, bindName);
+ if (bindName == null) {
+ return methodHandle;
+ } else {
+ // if it is vararg method, we need to extend argument array with
+ // a new zeroth element that is set to bindName value.
+ final MethodType methodType = methodHandle.type();
+ final int parameterCount = methodType.parameterCount();
+ final boolean isVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
+
+ if (isVarArg) {
+ return MH.filterArguments(methodHandle, 1, MH.insertArguments(ADD_ZEROTH_ELEMENT, 1, bindName));
+ } else {
+ return MH.insertArguments(methodHandle, 1, bindName);
+ }
+ }
}
/**
@@ -586,6 +602,16 @@
return self instanceof ScriptFunction && ((ScriptFunction)self).data == data && arg instanceof ScriptObject;
}
+ @SuppressWarnings("unused")
+ private static Object[] addZerothElement(final Object[] args, final Object value) {
+ // extends input array with by adding new zeroth element
+ final Object[] src = (args == null)? ScriptRuntime.EMPTY_ARRAY : args;
+ final Object[] result = new Object[src.length + 1];
+ System.arraycopy(src, 0, result, 1, src.length);
+ result[0] = value;
+ return result;
+ }
+
private static MethodHandle findOwnMH(final String name, final Class> rtype, final Class>... types) {
final Class> own = ScriptFunction.class;
final MethodType mt = MH.type(rtype, types);
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Jul 12 20:12:29 2013 +0530
@@ -203,9 +203,19 @@
* @param source The source object to copy from.
*/
public void addBoundProperties(final ScriptObject source) {
+ addBoundProperties(source, source.getMap().getProperties());
+ }
+
+ /**
+ * Copy all properties from the array with their receiver bound to the source.
+ *
+ * @param source The source object to copy from.
+ * @param properties The array of properties to copy.
+ */
+ public void addBoundProperties(final ScriptObject source, final Property[] properties) {
PropertyMap newMap = this.getMap();
- for (final Property property : source.getMap().getProperties()) {
+ for (final Property property : properties) {
final String key = property.getKey();
if (newMap.findProperty(key) == null) {
@@ -222,6 +232,26 @@
}
/**
+ * Copy all properties from the array with their receiver bound to the source.
+ *
+ * @param source The source object to copy from.
+ * @param properties The collection of accessor properties to copy.
+ */
+ public void addBoundProperties(final Object source, final AccessorProperty[] properties) {
+ PropertyMap newMap = this.getMap();
+
+ for (final AccessorProperty property : properties) {
+ final String key = property.getKey();
+
+ if (newMap.findProperty(key) == null) {
+ newMap = newMap.addPropertyBind(property, source);
+ }
+ }
+
+ this.setMap(newMap);
+ }
+
+ /**
* Bind the method handle to the specified receiver, while preserving its original type (it will just ignore the
* first argument in lieu of the bound argument).
* @param methodHandle Method handle to bind to.
@@ -1948,7 +1978,12 @@
return noSuchProperty(desc, request);
}
- final ScriptFunction func = (ScriptFunction)getObjectValue(find);
+ final Object value = getObjectValue(find);
+ if (! (value instanceof ScriptFunction)) {
+ return createEmptyGetter(desc, name);
+ }
+
+ final ScriptFunction func = (ScriptFunction)value;
final Object thiz = scopeCall && func.isStrict() ? ScriptRuntime.UNDEFINED : this;
// TODO: It'd be awesome if we could bind "name" without binding "this".
return new GuardedInvocation(MH.dropArguments(MH.constant(ScriptFunction.class,
@@ -1968,8 +2003,13 @@
final boolean scopeAccess = isScope() && NashornCallSiteDescriptor.isScope(desc);
if (find != null) {
- final ScriptFunction func = (ScriptFunction)getObjectValue(find);
- MethodHandle methodHandle = getCallMethodHandle(func, desc.getMethodType(), name);
+ final Object value = getObjectValue(find);
+ ScriptFunction func = null;
+ MethodHandle methodHandle = null;
+ if (value instanceof ScriptFunction) {
+ func = (ScriptFunction)value;
+ methodHandle = getCallMethodHandle(func, desc.getMethodType(), name);
+ }
if (methodHandle != null) {
if (scopeAccess && func.isStrict()) {
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java Fri Jul 12 20:12:29 2013 +0530
@@ -83,7 +83,7 @@
*/
public InvokeByName(final String name, final Class> targetClass, final Class> rtype, final Class>... ptypes) {
this.name = name;
- getter = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getItem:" + name, Object.class, targetClass);
+ getter = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getElem:" + name, Object.class, targetClass);
final Class>[] finalPtypes;
final int plength = ptypes.length;
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Fri Jul 12 20:12:29 2013 +0530
@@ -43,6 +43,7 @@
import jdk.internal.dynalink.beans.StaticClass;
import jdk.internal.dynalink.support.LinkRequestImpl;
import jdk.nashorn.internal.objects.NativeJava;
+import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ECMAException;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
@@ -99,6 +100,13 @@
*/
public static StaticClass getAdapterClassFor(final Class>[] types, ScriptObject classOverrides) {
assert types != null && types.length > 0;
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ for (Class> type : types) {
+ // check for restricted package access
+ Context.checkPackageAccess(type.getName());
+ }
+ }
return getAdapterInfo(types).getAdapterClassFor(classOverrides);
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java Fri Jul 12 20:12:29 2013 +0530
@@ -28,7 +28,6 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
-import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import jdk.internal.dynalink.CallSiteDescriptor;
@@ -111,7 +110,7 @@
final NashornCallSiteDescriptor csd = new NashornCallSiteDescriptor(lookup, operator, operand, methodType, flags);
// Many of these call site descriptors are identical (e.g. every getter for a property color will be
// "dyn:getProp:color(Object)Object", so it makes sense canonicalizing them.
- final Map classCanonicals = canonicals.get(lookup.lookupClass());
+ final ConcurrentMap classCanonicals = canonicals.get(lookup.lookupClass());
final NashornCallSiteDescriptor canonical = classCanonicals.putIfAbsent(csd, csd);
return canonical != null ? canonical : csd;
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Fri Jul 12 20:12:29 2013 +0530
@@ -25,10 +25,14 @@
package jdk.nashorn.internal.runtime.linker;
+import java.lang.reflect.Modifier;
+import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.linker.LinkerServices;
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+import jdk.nashorn.internal.runtime.Context;
/**
* Check java reflection permission for java reflective and java.lang.invoke access from scripts
@@ -52,6 +56,25 @@
throws Exception {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
+ final LinkRequest requestWithoutContext = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
+ final Object self = requestWithoutContext.getReceiver();
+ // allow 'static' access on Class objects representing public classes of non-restricted packages
+ if ((self instanceof Class) && Modifier.isPublic(((Class>)self).getModifiers())) {
+ final CallSiteDescriptor desc = requestWithoutContext.getCallSiteDescriptor();
+ final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
+ // check for 'get' on 'static' property
+ switch (operator) {
+ case "getProp":
+ case "getMethod": {
+ if ("static".equals(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND))) {
+ Context.checkPackageAccess(((Class)self).getName());
+ // let bean linker do the actual linking part
+ return null;
+ }
+ }
+ break;
+ } // fall through for all other stuff
+ }
sm.checkPermission(new RuntimePermission("nashorn.JavaReflection"));
}
// let the next linker deal with actual linking
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java Fri Jul 12 20:12:29 2013 +0530
@@ -57,7 +57,10 @@
private final LinkedList forwardReferences = new LinkedList<>();
/** Current level of zero-width negative lookahead assertions. */
- private int negativeLookaheadLevel;
+ private int negLookaheadLevel;
+
+ /** Sequential id of current top-level zero-width negative lookahead assertion. */
+ private int negLookaheadGroup;
/** Are we currently inside a character class? */
private boolean inCharClass = false;
@@ -68,17 +71,18 @@
private static final String NON_IDENT_ESCAPES = "$^*+(){}[]|\\.?-";
private static class Capture {
- /**
- * Zero-width negative lookaheads enclosing the capture.
- */
- private final int negativeLookaheadLevel;
+ /** Zero-width negative lookaheads enclosing the capture. */
+ private final int negLookaheadLevel;
+ /** Sequential id of top-level negative lookaheads containing the capture. */
+ private final int negLookaheadGroup;
- Capture(final int negativeLookaheadLevel) {
- this.negativeLookaheadLevel = negativeLookaheadLevel;
+ Capture(final int negLookaheadGroup, final int negLookaheadLevel) {
+ this.negLookaheadGroup = negLookaheadGroup;
+ this.negLookaheadLevel = negLookaheadLevel;
}
- public int getNegativeLookaheadLevel() {
- return negativeLookaheadLevel;
+ boolean isContained(final int group, final int level) {
+ return group == this.negLookaheadGroup && level >= this.negLookaheadLevel;
}
}
@@ -152,7 +156,7 @@
BitVector vec = null;
for (int i = 0; i < caps.size(); i++) {
final Capture cap = caps.get(i);
- if (cap.getNegativeLookaheadLevel() > 0) {
+ if (cap.negLookaheadLevel > 0) {
if (vec == null) {
vec = new BitVector(caps.size() + 1);
}
@@ -311,11 +315,14 @@
commit(3);
if (isNegativeLookahead) {
- negativeLookaheadLevel++;
+ if (negLookaheadLevel == 0) {
+ negLookaheadGroup++;
+ }
+ negLookaheadLevel++;
}
disjunction();
if (isNegativeLookahead) {
- negativeLookaheadLevel--;
+ negLookaheadLevel--;
}
if (ch0 == ')') {
@@ -432,20 +439,17 @@
}
if (ch0 == '(') {
- boolean capturingParens = true;
commit(1);
if (ch0 == '?' && ch1 == ':') {
- capturingParens = false;
commit(2);
+ } else {
+ caps.add(new Capture(negLookaheadGroup, negLookaheadLevel));
}
disjunction();
if (ch0 == ')') {
commit(1);
- if (capturingParens) {
- caps.add(new Capture(negativeLookaheadLevel));
- }
return true;
}
}
@@ -675,24 +679,22 @@
sb.setLength(sb.length() - 1);
octalOrLiteral(Integer.toString(decimalValue), sb);
- } else if (decimalValue <= caps.size() && caps.get(decimalValue - 1).getNegativeLookaheadLevel() > 0) {
- // Captures that live inside a negative lookahead are dead after the
- // lookahead and will be undefined if referenced from outside.
- if (caps.get(decimalValue - 1).getNegativeLookaheadLevel() > negativeLookaheadLevel) {
+ } else if (decimalValue <= caps.size()) {
+ // Captures inside a negative lookahead are undefined when referenced from the outside.
+ if (!caps.get(decimalValue - 1).isContained(negLookaheadGroup, negLookaheadLevel)) {
+ // Reference to capture in negative lookahead, omit from output buffer.
sb.setLength(sb.length() - 1);
} else {
+ // Append backreference to output buffer.
sb.append(decimalValue);
}
- } else if (decimalValue > caps.size()) {
- // Forward reference to a capture group. Forward references are always undefined so we can omit
- // it from the output buffer. However, if the target capture does not exist, we need to rewrite
- // the reference as hex escape or literal string, so register the reference for later processing.
+ } else {
+ // Forward references to a capture group are always undefined so we can omit it from the output buffer.
+ // However, if the target capture does not exist, we need to rewrite the reference as hex escape
+ // or literal string, so register the reference for later processing.
sb.setLength(sb.length() - 1);
forwardReferences.add(decimalValue);
forwardReferences.add(sb.length());
- } else {
- // Append as backreference
- sb.append(decimalValue);
}
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java Fri Jul 12 20:12:29 2013 +0530
@@ -183,7 +183,7 @@
// add_code_range, be aware of it returning null!
public static CodeRangeBuffer addCodeRange(CodeRangeBuffer pbuf, ScanEnvironment env, int from, int to) {
- if (from >to) {
+ if (from > to) {
if (env.syntax.allowEmptyRangeInCC()) {
return pbuf;
} else {
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java Fri Jul 12 20:12:29 2013 +0530
@@ -125,32 +125,8 @@
break;
case RAW_BYTE:
- if (token.base != 0) { /* tok->base != 0 : octal or hexadec. */
- byte[] buf = new byte[4];
- int psave = p;
- int base = token.base;
- buf[0] = (byte)token.getC();
- int i;
- for (i=1; i<4; i++) {
- fetchTokenInCC();
- if (token.type != TokenType.RAW_BYTE || token.base != base) {
- fetched = true;
- break;
- }
- buf[i] = (byte)token.getC();
- }
-
- if (i == 1) {
- arg.v = buf[0] & 0xff;
- arg.inType = CCVALTYPE.SB; // goto raw_single
- } else {
- arg.v = EncodingHelper.mbcToCode(buf, 0, buf.length);
- arg.inType = CCVALTYPE.CODE_POINT;
- }
- } else {
- arg.v = token.getC();
- arg.inType = CCVALTYPE.SB; // raw_single:
- }
+ arg.v = token.getC();
+ arg.inType = CCVALTYPE.SB; // raw_single:
arg.vIsRaw = true;
parseCharClassValEntry2(cc, arg); // goto val_entry2
break;
@@ -615,31 +591,10 @@
StringNode node = new StringNode((char)token.getC());
node.setRaw();
- int len = 1;
- while (true) {
- if (len >= 1) {
- if (len == 1) {
- fetchToken();
- node.clearRaw();
- // !goto string_end;!
- return parseExpRepeat(node, group);
- }
- }
-
- fetchToken();
- if (token.type != TokenType.RAW_BYTE) {
- /* Don't use this, it is wrong for little endian encodings. */
- // USE_PAD_TO_SHORT_BYTE_CHAR ...
-
- newValueException(ERR_TOO_SHORT_MULTI_BYTE_STRING);
- }
-
- // important: we don't use 0xff mask here neither in the compiler
- // (in the template string) so we won't have to mask target
- // strings when comparing against them in the matcher
- node.cat((char)token.getC());
- len++;
- } // while
+ fetchToken();
+ node.clearRaw();
+ // !goto string_end;!
+ return parseExpRepeat(node, group);
}
private Node parseExpRepeat(Node target, boolean group) {
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Fri Jul 12 20:12:29 2013 +0530
@@ -48,7 +48,7 @@
var _packages = [];
var global = this;
var oldNoSuchProperty = global.__noSuchProperty__;
- global.__noSuchProperty__ = function(name) {
+ var __noSuchProperty__ = function(name) {
'use strict';
for (var i in _packages) {
try {
@@ -69,6 +69,11 @@
}
}
+ Object.defineProperty(global, "__noSuchProperty__", {
+ writable: true, configurable: true, enumerable: false,
+ value: __noSuchProperty__
+ });
+
var prefix = "[JavaPackage ";
return function() {
for (var i in arguments) {
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8012191.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8012191.js Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8012191: noSuchProperty can't cope with vararg functions
+ *
+ * @test
+ * @run
+ */
+
+// ClassCastException: Cannot cast java.lang.String to [Ljava.lang.Object;
+__noSuchProperty__ = function() {
+ print("obj.__noSuchProperty__ invoked for " + arguments[0]);
+}
+
+nonExistent;
+
+// related issue was seen in JSAdapter __get__, __set__ too
+var obj = new JSAdapter() {
+ __put__: function() {
+ print("JSAdapter.__put__");
+ print(arguments[0]);
+ print(arguments[1]);
+ },
+
+ __get__: function() {
+ print("JSAdapter.__get__");
+ print(arguments[0]);
+ }
+};
+
+obj.x = 343;
+obj.y
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8012191.js.EXPECTED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8012191.js.EXPECTED Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,6 @@
+obj.__noSuchProperty__ invoked for nonExistent
+JSAdapter.__put__
+x
+343
+JSAdapter.__get__
+y
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8014785.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8014785.js Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8014785: Ability to extend global instance by binding properties of another object
+ *
+ * @test
+ * @run
+ */
+
+var obj = { x: 34, y: 100 };
+var foo = {}
+
+// bind properties of "obj" to "foo" obj
+Object.bindProperties(foo, obj);
+
+// now we can access/write on foo properties
+print("foo.x = " + foo.x); // prints obj.x which is 34
+
+// update obj.x via foo.x
+foo.x = "hello";
+print("obj.x = " + obj.x); // prints "hello" now
+
+obj.x = 42; // foo.x also becomes 42
+print("obj.x = " + obj.x); // prints 42
+print("foo.x = " + foo.x); // prints 42
+
+// now bind a mirror object to an object
+var obj = loadWithNewGlobal({
+ name: "test",
+ script: "obj = { x: 33, y: 'hello' }"
+});
+
+Object.bindProperties(this, obj);
+print("x = " + x); // prints 33
+print("y = " + y); // prints "hello"
+
+x = Math.PI; // changes obj.x to Math.PI
+print("obj.x = " +obj.x); // prints Math.PI
+
+obj.y = 32;
+print("y = " + y); // should print 32
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8014785.js.EXPECTED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8014785.js.EXPECTED Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,8 @@
+foo.x = 34
+obj.x = hello
+obj.x = 42
+foo.x = 42
+x = 33
+y = hello
+obj.x = 3.141592653589793
+y = 32
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8016681.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8016681.js Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8016681: regex capture behaves differently than on V8
+ *
+ * @test
+ * @run
+ */
+
+// regexp similar to the one used in marked.js
+/^((?:[^\n]+\n?(?!( *[-*_]){3,} *(?:\n+|$)| *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)|([^\n]+)\n *(=|-){3,} *\n*))+)\n*/
+ .exec("a\n\nb")
+ .forEach(function(e) { print(e); });
+
+// simplified regexp
+/(x(?!(a))(?!(b))y)/
+ .exec("xy")
+ .forEach(function(e) { print(e); });
+
+// should not match as cross-negative-lookeahead backreference \2 should be undefined
+print(/(x(?!(a))(?!(b)\2))/.exec("xbc"));
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8016681.js.EXPECTED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8016681.js.EXPECTED Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,15 @@
+a
+
+
+a
+
+undefined
+undefined
+undefined
+undefined
+undefined
+xy
+xy
+undefined
+undefined
+null
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8019822.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8019822.js Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8019822: Duplicate name/signature for a function in finally block
+ *
+ * @test
+ */
+try { function (x) /x/ } finally { (function(id) { return id }); }
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8019963.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8019963.js Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8019963: empty char range in regex
+ *
+ * @test
+ * @run
+ */
+
+var re1 = /[\x00-\x08\x0B\x0C\x0E-\x9F\uD800-\uDFFF\uFFFE\uFFFF]/;
+
+print(re1.test("\x00"));
+print(re1.test("\x04"));
+print(re1.test("\x08"));
+print(re1.test("\x0a"));
+print(re1.test("\x0B"));
+print(re1.test("\x0C"));
+print(re1.test("\x0E"));
+print(re1.test("\x10"));
+print(re1.test("\x1A"));
+print(re1.test("\x2F"));
+print(re1.test("\x8E"));
+print(re1.test("\x8F"));
+print(re1.test("\x9F"));
+print(re1.test("\xA0"));
+print(re1.test("\xAF"));
+print(re1.test("\uD800"));
+print(re1.test("\xDA00"));
+print(re1.test("\xDCFF"));
+print(re1.test("\xDFFF"));
+print(re1.test("\xFFFE"));
+print(re1.test("\xFFFF"));
+
+var re2 = /[\x1F\x7F-\x84\x86]/;
+
+print(re2.test("\x1F"));
+print(re2.test("\x2F"));
+print(re2.test("\x3F"));
+print(re2.test("\x7F"));
+print(re2.test("\x80"));
+print(re2.test("\x84"));
+print(re2.test("\x85"));
+print(re2.test("\x86"));
+
+var re3 = /^([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})*$/;
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8019963.js.EXPECTED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8019963.js.EXPECTED Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,29 @@
+true
+true
+true
+false
+true
+true
+true
+true
+true
+true
+true
+true
+true
+false
+false
+true
+true
+true
+true
+true
+true
+true
+false
+false
+true
+true
+true
+false
+true
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8020124.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8020124.js Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020124: explicit conversion needed for switch tag
+ *
+ * @test
+ * @run
+ */
+
+x = {};
+Function("switch((a? x = 1 : 3)) { default: return; }")
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8020223.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8020223.js Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020223: ClassCastException: String can not be casted to ScriptFunction
+ *
+ * @test
+ * @run
+ */
+
+__noSuchMethod__ = "";
+
+try {
+ foo();
+ fail("Must have thrown exception");
+} catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("TypeError expected, got " + e);
+ }
+}
+
+__noSuchProperty__ = 23;
+
+try {
+ foo;
+ fail("Must have thrown exception");
+} catch (e) {
+ if (! (e instanceof ReferenceError)) {
+ fail("ReferenceError expected, got " + e);
+ }
+}
+
+var obj = new JSAdapter() {
+ __get__: 332,
+ __call__: "hello"
+}
+
+try {
+ obj.foo; // should just be undefined
+} catch (e) {
+ fail("unexpected error : " + e);
+}
+
+try {
+ obj.foo();
+ fail("Must have thrown exception");
+} catch(e) {
+ if (! (e instanceof TypeError)) {
+ fail("TypeError expected, got " + e);
+ }
+}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8020325.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8020325.js Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020325: static property does not work on accessible, public classes
+ *
+ * @test
+ * @run
+ */
+
+function printStatic(obj) {
+ print(obj.getClass().static);
+}
+
+printStatic(new java.util.ArrayList());
+printStatic(new java.util.HashMap());
+printStatic(new java.lang.Object());
+printStatic(new (Java.type("java.lang.Object[]"))(0));
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8020325.js.EXPECTED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8020325.js.EXPECTED Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,4 @@
+[JavaClass java.util.ArrayList]
+[JavaClass java.util.HashMap]
+[JavaClass java.lang.Object]
+[JavaClass [Ljava.lang.Object;]
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8020380.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8020380.js Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020380: __noSuchProperty__ defined in mozilla_compat.js script should be non-enumerable
+ *
+ * @test
+ * @run
+ */
+
+load("nashorn:mozilla_compat.js");
+
+var desc = Object.getOwnPropertyDescriptor(this, "__noSuchProperty__");
+if (typeof desc.enumerable != 'boolean' || desc.enumerable != false) {
+ fail("__noSuchProperty__ is enumerable");
+}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/basic/JDK-8020437.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8020437.js Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020437: Wrong handling of line numbers with multiline string literals
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+print({
+ text: < (test/script/basic/JDK-8020437.js:37)
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/currently-failing/JDK-8006529.js
--- a/nashorn/test/script/currently-failing/JDK-8006529.js Mon Jul 08 18:43:41 2013 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * 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-8006529 : Methods should not always get callee parameter, and they
- * should not be too eager in creation of scopes.
- *
- * @test
- * @run
- */
-
-/*
- * This test script depends on nashorn Compiler internals. It uses reflection
- * to get access to private field and many public methods of Compiler and
- * FunctionNode classes. Note that this is trusted code and access to such
- * internal package classes and methods is okay. But, if you modify any
- * Compiler or FunctionNode class, you may have to revisit this script.
- * We cannot use direct Java class (via dynalink bean linker) to Compiler
- * and FunctionNode because of package-access check and so reflective calls.
- */
-
-var Parser = Java.type("jdk.nashorn.internal.parser.Parser")
-var Compiler = Java.type("jdk.nashorn.internal.codegen.Compiler")
-var Context = Java.type("jdk.nashorn.internal.runtime.Context")
-var ScriptEnvironment = Java.type("jdk.nashorn.internal.runtime.ScriptEnvironment")
-var Source = Java.type("jdk.nashorn.internal.runtime.Source")
-var FunctionNode = Java.type("jdk.nashorn.internal.ir.FunctionNode")
-var ThrowErrorManager = Java.type("jdk.nashorn.internal.runtime.Context$ThrowErrorManager");
-
-// Compiler class methods and fields
-var parseMethod = Parser.class.getMethod("parse");
-var compileMethod = Compiler.class.getMethod("compile");
-
-// NOTE: private field. But this is a trusted test!
-// Compiler.functionNode
-var functionNodeField = Compiler.class.getDeclaredField("functionNode");
-functionNodeField.setAccessible(true);
-
-// FunctionNode methods
-
-// FunctionNode.getFunctions method
-var getFunctionsMethod = FunctionNode.class.getMethod("getFunctions");
-
-// These are method names of methods in FunctionNode class
-var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'needsScope', 'needsSelfSymbol', 'isSplit', 'hasEval', 'hasWith', 'hasDeepWithOrEval', 'allVarsInScope', 'isStrictMode']
-
-// corresponding Method objects of FunctionNode class
-var functionNodeMethods = {};
-// initialize FunctionNode methods
-(function() {
- for (var f in allAssertionList) {
- var method = allAssertionList[f];
- functionNodeMethods[method] = FunctionNode.class.getMethod(method);
- }
-})();
-
-// returns "script" functionNode from Compiler instance
-function getScriptNode(compiler) {
- // compiler.functionNode
- return functionNodeField.get(compiler);
-}
-
-// returns functionNode.getFunctions().get(0)
-function getFirstFunction(functionNode) {
- // functionNode.getFunctions().get(0)
- return getFunctionsMethod.invoke(functionNode).get(0);
-}
-
-// compile(script) -- compiles a script specified as a string with its
-// source code, returns a jdk.nashorn.internal.ir.FunctionNode object
-// representing it.
-function compile(source) {
- var source = new Source("", source);
- var parser = new Parser(Context.getContext().getEnv(), source, new ThrowErrorManager());
- var func = parseMethod.invoke(parser);
- var compiler = new Compiler(Context.getContext().getEnv(), func);
-
- compileMethod.invoke(compiler);
-
- return getScriptNode(compiler);
-};
-
-var allAssertions = (function() {
- var allAssertions = {}
- for(var assertion in allAssertionList) {
- allAssertions[allAssertionList[assertion]] = true
- }
- return allAssertions;
-})();
-
-
-// test(f[, assertions...]) tests whether all the specified assertions on the
-// passed function node are true.
-function test(f) {
- var assertions = {}
- for(var i = 1; i < arguments.length; ++i) {
- var assertion = arguments[i]
- if(!allAssertions[assertion]) {
- throw "Unknown assertion " + assertion + " for " + f;
- }
- assertions[assertion] = true
- }
- for(var assertion in allAssertions) {
- var expectedValue = !!assertions[assertion]
- if(functionNodeMethods[assertion].invoke(f) !== expectedValue) {
- throw "Expected " + assertion + " === " + expectedValue + " for " + f;
- }
- }
-}
-
-// testFirstFn(script[, assertions...] tests whether all the specified
-// assertions are true in the first function in the given script; "script"
-// is a string with the source text of the script.
-function testFirstFn(script) {
- arguments[0] = getFirstFunction(compile(script))
- test.apply(null, arguments)
-}
-
-// ---------------------------------- ACTUAL TESTS START HERE --------------
-
-// The simplest possible functions have no attributes set
-testFirstFn("function f() { }")
-testFirstFn("function f(x) { x }")
-
-// A function referencing a global needs parent scope, and it needs callee
-// (because parent scope is passed through callee)
-testFirstFn("function f() { x }", 'needsCallee', 'needsParentScope')
-
-// A function referencing "arguments" will have to be vararg. It also needs
-// the callee, as it needs to fill out "arguments.callee".
-testFirstFn("function f() { arguments }", 'needsCallee', 'isVarArg')
-
-// A function referencing "arguments" will have to be vararg. If it is
-// strict, it will not have to have a callee, though.
-testFirstFn("function f() {'use strict'; arguments }", 'isVarArg', 'isStrictMode')
-
-// A function defining "arguments" as a parameter will not be vararg.
-testFirstFn("function f(arguments) { arguments }")
-
-// A function defining "arguments" as a nested function will not be vararg.
-testFirstFn("function f() { function arguments() {}; arguments; }")
-
-// A function defining "arguments" as a local variable will be vararg.
-testFirstFn("function f() { var arguments; arguments; }", 'isVarArg', 'needsCallee')
-
-// A self-referencing function defined as a statement doesn't need a self
-// symbol, as it'll rather obtain itself from the parent scope.
-testFirstFn("function f() { f() }", 'needsCallee', 'needsParentScope')
-
-// A self-referencing function defined as an expression needs a self symbol,
-// as it can't obtain itself from the parent scope.
-testFirstFn("(function f() { f() })", 'needsCallee', 'needsSelfSymbol')
-
-// A child function accessing parent's variable triggers the need for scope
-// in parent
-testFirstFn("(function f() { var x; function g() { x } })", 'needsScope')
-
-// A child function accessing parent's parameter triggers the need for scope
-// in parent
-testFirstFn("(function f(x) { function g() { x } })", 'needsScope')
-
-// A child function accessing a global variable triggers the need for parent
-// scope in parent
-testFirstFn("(function f() { function g() { x } })", 'needsParentScope', 'needsCallee')
-
-// A child function redefining a local variable from its parent should not
-// affect the parent function in any way
-testFirstFn("(function f() { var x; function g() { var x; x } })")
-
-// Using "with" unleashes a lot of needs: parent scope, callee, own scope,
-// and all variables in scope. Actually, we could make "with" less wasteful,
-// and only put those variables in scope that it actually references, similar
-// to what nested functions do with variables in their parents.
-testFirstFn("(function f() { var o; with(o) {} })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasWith', 'hasDeepWithOrEval', 'allVarsInScope')
-
-// Using "eval" is as bad as using "with" with the added requirement of
-// being vararg, 'cause we don't know if eval will be using "arguments".
-testFirstFn("(function f() { eval() })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasEval', 'isVarArg', 'hasDeepWithOrEval', 'allVarsInScope')
-
-// Nested function using "with" is pretty much the same as the parent
-// function needing with.
-testFirstFn("(function f() { function g() { var o; with(o) {} } })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasDeepWithOrEval', 'allVarsInScope')
-// Nested function using "eval" is almost the same as parent function using
-// eval, but at least the parent doesn't have to be vararg.
-testFirstFn("(function f() { function g() { eval() } })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasDeepWithOrEval', 'allVarsInScope')
-
-// Function with 250 named parameters is ordinary
-testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250) { p250 = p249 }")
-
-// Function with 251 named parameters is variable arguments
-testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250, p251) { p250 = p251 }", 'isVarArg')
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/script/error/JDK-8020437-2.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/error/JDK-8020437-2.js Fri Jul 12 20:12:29 2013 +0530
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020437: Wrong handling of line numbers with multiline string literals
+ *
+ * @test/compile-error
+ * @option -scripting
+ */
+
+print({
+ text: <", source);
+
+ var env = getEnvMethod.invoke(getContextMethod.invoke(null))
+
+ var parser = new Parser(env, source, new ThrowErrorManager());
+ var func = parseMethod.invoke(parser);
+
+ var compiler = new Compiler(env);
+
+ return compileMethod.invoke(compiler, func);
+};
+
+var allAssertions = (function() {
+ var allAssertions = {}
+ for(var assertion in allAssertionList) {
+ allAssertions[allAssertionList[assertion]] = true
+ }
+ return allAssertions;
+})();
+
+
+// test(f[, assertions...]) tests whether all the specified assertions on the
+// passed function node are true.
+function test(f) {
+ var assertions = {}
+ for(var i = 1; i < arguments.length; ++i) {
+ var assertion = arguments[i]
+ if(!allAssertions[assertion]) {
+ throw "Unknown assertion " + assertion + " for " + f;
+ }
+ assertions[assertion] = true
+ }
+ for(var assertion in allAssertions) {
+ var expectedValue = !!assertions[assertion]
+ var actualValue = functionNodeMethods[assertion].invoke(f)
+ if(actualValue !== expectedValue) {
+ throw "Expected " + assertion + " === " + expectedValue + ", got " + actualValue + " for " + f + ":" + debugIdMethod.invoke(null, f);
+ }
+ }
+}
+
+// testFirstFn(script[, assertions...] tests whether all the specified
+// assertions are true in the first function in the given script; "script"
+// is a string with the source text of the script.
+function testFirstFn(script) {
+ arguments[0] = getFirstFunction(compile(script))
+ test.apply(null, arguments)
+}
+
+// ---------------------------------- ACTUAL TESTS START HERE --------------
+
+// The simplest possible functions have no attributes set
+testFirstFn("function f() { }")
+testFirstFn("function f(x) { x }")
+
+// A function referencing a global needs parent scope, and it needs callee
+// (because parent scope is passed through callee)
+testFirstFn("function f() { x }", 'needsCallee', 'needsParentScope')
+
+// A function referencing "arguments" will have to be vararg. It also needs
+// the callee, as it needs to fill out "arguments.callee".
+testFirstFn("function f() { arguments }", 'needsCallee', 'isVarArg')
+
+// A function referencing "arguments" will have to be vararg. If it is
+// strict, it will not have to have a callee, though.
+testFirstFn("function f() {'use strict'; arguments }", 'isVarArg', 'isStrict')
+
+// A function defining "arguments" as a parameter will not be vararg.
+testFirstFn("function f(arguments) { arguments }")
+
+// A function defining "arguments" as a nested function will not be vararg.
+testFirstFn("function f() { function arguments() {}; arguments; }")
+
+// A function defining "arguments" as a local variable will be vararg.
+testFirstFn("function f() { var arguments; arguments; }", 'isVarArg', 'needsCallee')
+
+// A self-referencing function defined as a statement doesn't need a self
+// symbol, as it'll rather obtain itself from the parent scope.
+testFirstFn("function f() { f() }", 'needsCallee', 'needsParentScope')
+
+// A self-referencing function defined as an expression needs a self symbol,
+// as it can't obtain itself from the parent scope.
+testFirstFn("(function f() { f() })", 'needsCallee', 'needsSelfSymbol')
+
+// A child function accessing parent's variable triggers the need for scope
+// in parent
+testFirstFn("(function f() { var x; function g() { x } })", 'hasScopeBlock')
+
+// A child function accessing parent's parameter triggers the need for scope
+// in parent
+testFirstFn("(function f(x) { function g() { x } })", 'hasScopeBlock')
+
+// A child function accessing a global variable triggers the need for parent
+// scope in parent
+testFirstFn("(function f() { function g() { x } })", 'needsParentScope', 'needsCallee')
+
+// A child function redefining a local variable from its parent should not
+// affect the parent function in any way
+testFirstFn("(function f() { var x; function g() { var x; x } })")
+
+// Using "with" on its own doesn't do much.
+testFirstFn("(function f() { var o; with(o) {} })")
+
+// "with" referencing a local variable triggers scoping.
+testFirstFn("(function f() { var x; var y; with(x) { y } })", 'hasScopeBlock')
+
+// "with" referencing a non-local variable triggers parent scope.
+testFirstFn("(function f() { var x; with(x) { y } })", 'needsCallee', 'needsParentScope')
+
+// Nested function using "with" is pretty much the same as the parent
+// function needing with.
+testFirstFn("(function f() { function g() { var o; with(o) {} } })")
+
+// Nested function using "with" referencing a local variable.
+testFirstFn("(function f() { var x; function g() { var o; with(o) { x } } })", 'hasScopeBlock')
+
+// Using "eval" triggers pretty much everything. The function even needs to be
+// vararg, 'cause we don't know if eval will be using "arguments".
+testFirstFn("(function f() { eval() })", 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'hasEval', 'isVarArg', 'allVarsInScope')
+
+// Nested function using "eval" is almost the same as parent function using
+// eval, but at least the parent doesn't have to be vararg.
+testFirstFn("(function f() { function g() { eval() } })", 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'allVarsInScope')
+
+// Function with 250 named parameters is ordinary
+testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250) { p250 = p249 }")
+
+// Function with 251 named parameters is variable arguments
+testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250, p251) { p250 = p251 }", 'isVarArg')
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Fri Jul 12 20:12:29 2013 +0530
@@ -36,6 +36,7 @@
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.Callable;
import javax.script.Bindings;
import javax.script.Compilable;
@@ -345,6 +346,23 @@
}
@Test
+ /**
+ * Try passing non-interface Class object for interface implementation.
+ */
+ public void getNonInterfaceGetInterfaceTest() {
+ final ScriptEngineManager manager = new ScriptEngineManager();
+ final ScriptEngine engine = manager.getEngineByName("nashorn");
+ try {
+ log(Objects.toString(((Invocable)engine).getInterface(Object.class)));
+ fail("Should have thrown IllegalArgumentException");
+ } catch (final Exception exp) {
+ if (! (exp instanceof IllegalArgumentException)) {
+ fail("IllegalArgumentException expected, got " + exp);
+ }
+ }
+ }
+
+ @Test
public void accessGlobalTest() {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine e = m.getEngineByName("nashorn");
@@ -927,4 +945,35 @@
Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]");
Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]");
}
+
+ @Test
+ /**
+ * Check that script can't implement sensitive package interfaces.
+ */
+ public void checkSensitiveInterfaceImplTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Object[] holder = new Object[1];
+ e.put("holder", holder);
+ // put an empty script object into array
+ e.eval("holder[0] = {}");
+ // holder[0] is an object of some subclass of ScriptObject
+ Class ScriptObjectClass = holder[0].getClass().getSuperclass();
+ Class PropertyAccessClass = ScriptObjectClass.getInterfaces()[0];
+ // implementation methods for PropertyAccess class
+ e.eval("function set() {}; function get() {}; function getInt(){} " +
+ "function getDouble(){}; function getLong() {}; " +
+ "this.delete = function () {}; function has() {}; " +
+ "function hasOwnProperty() {}");
+
+ // get implementation of a restricted package interface
+ try {
+ log(Objects.toString(((Invocable)e).getInterface((Class>)PropertyAccessClass)));
+ fail("should have thrown SecurityException");
+ } catch (final Exception exp) {
+ if (! (exp instanceof SecurityException)) {
+ fail("SecurityException expected, got " + exp);
+ }
+ }
+ }
}
diff -r 4abe332f1270 -r 7907640d3be5 nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java
--- a/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Mon Jul 08 18:43:41 2013 +0530
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Fri Jul 12 20:12:29 2013 +0530
@@ -145,4 +145,55 @@
fail("Cannot find nashorn factory!");
}
+
+ @Test
+ /**
+ * Test repeated evals with --loader-per-compile=false
+ * We used to get "class redefinition error".
+ */
+ public void noLoaderPerCompilerTest() {
+ final ScriptEngineManager sm = new ScriptEngineManager();
+ for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+ final String[] options = new String[] { "--loader-per-compile=false" };
+ final ScriptEngine e = nfac.getScriptEngine(options);
+ try {
+ e.eval("2 + 3");
+ e.eval("4 + 4");
+ } catch (final ScriptException se) {
+ se.printStackTrace();
+ fail(se.getMessage());
+ }
+ return;
+ }
+ }
+ fail("Cannot find nashorn factory!");
+ }
+
+ @Test
+ /**
+ * Test that we can use same script name in repeated evals with --loader-per-compile=false
+ * We used to get "class redefinition error" as name was derived from script name.
+ */
+ public void noLoaderPerCompilerWithSameNameTest() {
+ final ScriptEngineManager sm = new ScriptEngineManager();
+ for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+ final String[] options = new String[] { "--loader-per-compile=false" };
+ final ScriptEngine e = nfac.getScriptEngine(options);
+ e.put(ScriptEngine.FILENAME, "test.js");
+ try {
+ e.eval("2 + 3");
+ e.eval("4 + 4");
+ } catch (final ScriptException se) {
+ se.printStackTrace();
+ fail(se.getMessage());
+ }
+ return;
+ }
+ }
+ fail("Cannot find nashorn factory!");
+ }
}