Mercurial > hg > icedtea8-forest > nashorn
changeset 329:d92b756bc739 jdk8-b94
Merge
author | lana |
---|---|
date | Mon, 10 Jun 2013 17:04:30 -0700 |
parents | e857ab684db0 (current diff) e3bd0ed64da8 (diff) |
children | cbc9926f5b40 |
files | src/jdk/nashorn/internal/objects/DateParser.java |
diffstat | 58 files changed, 1750 insertions(+), 1020 deletions(-) [+] |
line wrap: on
line diff
--- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Mon Jun 10 17:04:30 2013 -0700 @@ -31,7 +31,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -48,7 +48,7 @@ * access ScriptObject via the javax.script.Bindings interface or * netscape.javascript.JSObject interface. */ -final class ScriptObjectMirror extends JSObject implements Bindings { +public final class ScriptObjectMirror extends JSObject implements Bindings { private final ScriptObject sobj; private final ScriptObject global; @@ -217,7 +217,7 @@ return inGlobal(new Callable<Set<Map.Entry<String, Object>>>() { @Override public Set<Map.Entry<String, Object>> call() { final Iterator<String> iter = sobj.propertyIterator(); - final Set<Map.Entry<String, Object>> entries = new HashSet<>(); + final Set<Map.Entry<String, Object>> entries = new LinkedHashSet<>(); while (iter.hasNext()) { final String key = iter.next(); @@ -253,7 +253,7 @@ return inGlobal(new Callable<Set<String>>() { @Override public Set<String> call() { final Iterator<String> iter = sobj.propertyIterator(); - final Set<String> keySet = new HashSet<>(); + final Set<String> keySet = new LinkedHashSet<>(); while (iter.hasNext()) { keySet.add(iter.next()); @@ -302,6 +302,21 @@ }); } + /** + * Delete a property from this object. + * + * @param key the property to be deleted + * + * @return if the delete was successful or not + */ + public boolean delete(final Object key) { + return inGlobal(new Callable<Boolean>() { + @Override public Boolean call() { + return sobj.delete(unwrap(key, global)); + } + }); + } + @Override public int size() { return inGlobal(new Callable<Integer>() { @@ -327,20 +342,28 @@ }); } - // package-privates below this. - ScriptObject getScriptObject() { - return sobj; - } + + // These are public only so that Context can access these. - static Object translateUndefined(Object obj) { - return (obj == ScriptRuntime.UNDEFINED)? null : obj; - } - - static Object wrap(final Object obj, final ScriptObject homeGlobal) { + /** + * Make a script object mirror on given object if needed. + * + * @param obj object to be wrapped + * @param homeGlobal global to which this object belongs + * @return wrapped object + */ + public static Object wrap(final Object obj, final ScriptObject homeGlobal) { return (obj instanceof ScriptObject) ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj; } - static Object unwrap(final Object obj, final ScriptObject homeGlobal) { + /** + * Unwrap a script object mirror if needed. + * + * @param obj object to be unwrapped + * @param homeGlobal global to which this object belongs + * @return unwrapped object + */ + public static Object unwrap(final Object obj, final ScriptObject homeGlobal) { if (obj instanceof ScriptObjectMirror) { final ScriptObjectMirror mirror = (ScriptObjectMirror)obj; return (mirror.global == homeGlobal)? mirror.sobj : obj; @@ -349,7 +372,14 @@ return obj; } - static Object[] wrapArray(final Object[] args, final ScriptObject homeGlobal) { + /** + * Wrap an array of object to script object mirrors if needed. + * + * @param args array to be unwrapped + * @param homeGlobal global to which this object belongs + * @return wrapped array + */ + public static Object[] wrapArray(final Object[] args, final ScriptObject homeGlobal) { if (args == null || args.length == 0) { return args; } @@ -363,7 +393,14 @@ return newArgs; } - static Object[] unwrapArray(final Object[] args, final ScriptObject homeGlobal) { + /** + * Unwrap an array of script object mirrors if needed. + * + * @param args array to be unwrapped + * @param homeGlobal global to which this object belongs + * @return unwrapped array + */ + public static Object[] unwrapArray(final Object[] args, final ScriptObject homeGlobal) { if (args == null || args.length == 0) { return args; } @@ -376,4 +413,13 @@ } return newArgs; } + + // package-privates below this. + ScriptObject getScriptObject() { + return sobj; + } + + static Object translateUndefined(Object obj) { + return (obj == ScriptRuntime.UNDEFINED)? null : obj; + } }
--- a/src/jdk/nashorn/internal/codegen/Attr.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/codegen/Attr.java Mon Jun 10 17:04:30 2013 -0700 @@ -84,13 +84,12 @@ import jdk.nashorn.internal.ir.UnaryNode; import jdk.nashorn.internal.ir.VarNode; import jdk.nashorn.internal.ir.WithNode; +import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor; -import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Debug; import jdk.nashorn.internal.runtime.DebugLogger; -import jdk.nashorn.internal.runtime.ECMAException; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; @@ -1323,7 +1322,7 @@ @Override public Node leaveForNode(final ForNode forNode) { if (forNode.isForIn()) { - forNode.setIterator(newInternal(lc.getCurrentFunction().uniqueName(ITERATOR_PREFIX.symbolName()), Type.OBJECT)); //NASHORN-73 + forNode.setIterator(newInternal(lc.getCurrentFunction().uniqueName(ITERATOR_PREFIX.symbolName()), Type.typeFor(ITERATOR_PREFIX.type()))); //NASHORN-73 /* * Iterators return objects, so we need to widen the scope of the * init variable if it, for example, has been assigned double type @@ -1500,7 +1499,7 @@ } private Symbol exceptionSymbol() { - return newInternal(lc.getCurrentFunction().uniqueName(EXCEPTION_PREFIX.symbolName()), Type.typeFor(ECMAException.class)); + return newInternal(lc.getCurrentFunction().uniqueName(EXCEPTION_PREFIX.symbolName()), Type.typeFor(EXCEPTION_PREFIX.type())); } /**
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Mon Jun 10 17:04:30 2013 -0700 @@ -60,7 +60,6 @@ import java.util.List; import java.util.Locale; import java.util.TreeMap; - import jdk.nashorn.internal.codegen.ClassEmitter.Flag; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.codegen.RuntimeCallSite.SpecializedRuntimeNode; @@ -80,11 +79,11 @@ import jdk.nashorn.internal.ir.ExecuteNode; import jdk.nashorn.internal.ir.ForNode; import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.IdentNode; import jdk.nashorn.internal.ir.IfNode; import jdk.nashorn.internal.ir.IndexNode; +import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.LexicalContextNode; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; @@ -457,17 +456,18 @@ } private void initSymbols(final LinkedList<Symbol> symbols, final Type type) { - if (symbols.isEmpty()) { - return; - } - - method.loadUndefined(type); - while (!symbols.isEmpty()) { - final Symbol symbol = symbols.removeFirst(); - if (!symbols.isEmpty()) { - method.dup(); - } - method.store(symbol); + final Iterator<Symbol> it = symbols.iterator(); + if(it.hasNext()) { + method.loadUndefined(type); + boolean hasNext; + do { + final Symbol symbol = it.next(); + hasNext = it.hasNext(); + if(hasNext) { + method.dup(); + } + method.store(symbol); + } while(hasNext); } } @@ -942,11 +942,6 @@ */ final FieldObjectCreator<Symbol> foc = new FieldObjectCreator<Symbol>(this, nameList, newSymbols, values, true, hasArguments) { @Override - protected Type getValueType(final Symbol value) { - return value.getSymbolType(); - } - - @Override protected void loadValue(final Symbol value) { method.load(value); } @@ -1331,8 +1326,7 @@ @Override public boolean enterObjectNode(final ObjectNode objectNode) { - final List<Node> elements = objectNode.getElements(); - final int size = elements.size(); + final List<PropertyNode> elements = objectNode.getElements(); final List<String> keys = new ArrayList<>(); final List<Symbol> symbols = new ArrayList<>(); @@ -1340,8 +1334,7 @@ boolean hasGettersSetters = false; - for (int i = 0; i < size; i++) { - final PropertyNode propertyNode = (PropertyNode)elements.get(i); + for (PropertyNode propertyNode: elements) { final Node value = propertyNode.getValue(); final String key = propertyNode.getKeyName(); final Symbol symbol = value == null ? null : propertyNode.getSymbol(); @@ -1357,11 +1350,6 @@ new FieldObjectCreator<Node>(this, keys, symbols, values) { @Override - protected Type getValueType(final Node node) { - return node.getType(); - } - - @Override protected void loadValue(final Node node) { load(node); }
--- a/src/jdk/nashorn/internal/codegen/CompilerConstants.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/codegen/CompilerConstants.java Mon Jun 10 17:04:30 2013 -0700 @@ -29,6 +29,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.util.Iterator; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; @@ -105,13 +106,13 @@ ARGUMENTS("arguments", Object.class, 2), /** prefix for iterators for for (x in ...) */ - ITERATOR_PREFIX(":i"), + ITERATOR_PREFIX(":i", Iterator.class), /** prefix for tag variable used for switch evaluation */ SWITCH_TAG_PREFIX(":s"), /** prefix for all exceptions */ - EXCEPTION_PREFIX(":e"), + EXCEPTION_PREFIX(":e", Throwable.class), /** prefix for quick slots generated in Store */ QUICK_PREFIX(":q"),
--- a/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java Mon Jun 10 17:04:30 2013 -0700 @@ -145,15 +145,6 @@ protected abstract void loadValue(T value); /** - * Determine the type of a value. Defined by anonymous subclasses in code gen. - * - * @param value Value to inspect. - * - * @return Value type. - */ - protected abstract Type getValueType(T value); - - /** * Store a value in a field of the generated class object. * * @param method Script method. @@ -165,13 +156,6 @@ method.dup(); loadValue(value); - - final Type valueType = getValueType(value); - // for example when we have a with scope - if (valueType.isObject() || valueType.isBoolean()) { - method.convert(OBJECT); - } - method.convert(OBJECT); method.putField(getClassName(), ObjectClassGenerator.getFieldName(fieldIndex, Type.OBJECT), typeDescriptor(Object.class)); }
--- a/src/jdk/nashorn/internal/codegen/Lower.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/codegen/Lower.java Mon Jun 10 17:04:30 2013 -0700 @@ -32,7 +32,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; - import jdk.nashorn.internal.ir.BaseNode; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; @@ -258,7 +257,7 @@ return throwNode; } - private static Node ensureUniqueNamesIn(final LexicalContext lc, final Node node) { + private static Node ensureUniqueNamesIn(final Node node) { return node.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { @Override public Node leaveFunctionNode(final FunctionNode functionNode) { @@ -273,10 +272,10 @@ }); } - private static List<Statement> copyFinally(final LexicalContext lc, final Block finallyBody) { + private static List<Statement> copyFinally(final Block finallyBody) { final List<Statement> newStatements = new ArrayList<>(); for (final Statement statement : finallyBody.getStatements()) { - newStatements.add((Statement)ensureUniqueNamesIn(lc, statement)); + newStatements.add((Statement)ensureUniqueNamesIn(statement)); if (statement.hasTerminalFlags()) { return newStatements; } @@ -340,7 +339,7 @@ @Override public Node leaveThrowNode(final ThrowNode throwNode) { if (rethrows.contains(throwNode)) { - final List<Statement> newStatements = copyFinally(lc, finallyBody); + final List<Statement> newStatements = copyFinally(finallyBody); if (!isTerminal(newStatements)) { newStatements.add(throwNode); } @@ -374,7 +373,7 @@ resultNode = null; } - newStatements.addAll(copyFinally(lc, finallyBody)); + newStatements.addAll(copyFinally(finallyBody)); if (!isTerminal(newStatements)) { newStatements.add(expr == null ? returnNode : returnNode.setExpression(resultNode)); } @@ -384,7 +383,7 @@ private Node copy(final Statement endpoint, final Node targetNode) { if (!insideTry.contains(targetNode)) { - final List<Statement> newStatements = copyFinally(lc, finallyBody); + final List<Statement> newStatements = copyFinally(finallyBody); if (!isTerminal(newStatements)) { newStatements.add(endpoint); } @@ -550,7 +549,7 @@ final FunctionNode currentFunction = lc.getCurrentFunction(); return callNode.setEvalArgs( new CallNode.EvalArgs( - ensureUniqueNamesIn(lc, args.get(0)).accept(this), + ensureUniqueNamesIn(args.get(0)).accept(this), compilerConstant(THIS), evalLocation(callee), currentFunction.isStrict()));
--- a/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java Mon Jun 10 17:04:30 2013 -0700 @@ -41,10 +41,10 @@ import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.RuntimeNode; import jdk.nashorn.internal.ir.RuntimeNode.Request; +import jdk.nashorn.internal.lookup.Lookup; +import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.linker.Bootstrap; -import jdk.nashorn.internal.lookup.Lookup; -import jdk.nashorn.internal.lookup.MethodHandleFactory; /** * Optimistic call site that assumes its Object arguments to be of a boxed type. @@ -59,12 +59,10 @@ public final class RuntimeCallSite extends MutableCallSite { static final Call BOOTSTRAP = staticCallNoLookup(Bootstrap.class, "runtimeBootstrap", CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); - private static final MethodHandle NEXT = findOwnMH("next", MethodHandle.class); + private static final MethodHandle NEXT = findOwnMH("next", MethodHandle.class, String.class); private final RuntimeNode.Request request; - private String name; - /** * A specialized runtime node, i.e. on where we know at least one more specific type than object */ @@ -203,7 +201,6 @@ */ public RuntimeCallSite(final MethodType type, final String name) { super(type); - this.name = name; this.request = Request.valueOf(name.substring(0, name.indexOf(SpecializedRuntimeNode.REQUEST_SEPARATOR))); setTarget(makeMethod(name)); } @@ -292,7 +289,7 @@ mh = MH.explicitCastArguments(mh, type()); } - final MethodHandle fallback = MH.foldArguments(MethodHandles.exactInvoker(type()), MH.bindTo(NEXT, this)); + final MethodHandle fallback = MH.foldArguments(MethodHandles.exactInvoker(type()), MH.insertArguments(NEXT, 0, this, requestName)); MethodHandle guard; if (type().parameterType(0).isPrimitive()) { @@ -336,20 +333,15 @@ * * Do not call directly * + * @param name current name (with type) of runtime call at the call site * @return next wider specialization method for this RuntimeCallSite */ - public MethodHandle next() { - this.name = nextName(name); - final MethodHandle next = makeMethod(name); + public MethodHandle next(final String name) { + final MethodHandle next = makeMethod(nextName(name)); setTarget(next); return next; } - @Override - public String toString() { - return super.toString() + " " + name; - } - /** Method cache */ private static final Map<String, MethodHandle> METHODS;
--- a/src/jdk/nashorn/internal/ir/BlockLexicalContext.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/ir/BlockLexicalContext.java Mon Jun 10 17:04:30 2013 -0700 @@ -63,7 +63,6 @@ return sstack.pop(); } - @SuppressWarnings("unchecked") @Override public <T extends LexicalContextNode> T pop(final T node) { T expected = node;
--- a/src/jdk/nashorn/internal/ir/FunctionNode.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java Mon Jun 10 17:04:30 2013 -0700 @@ -30,7 +30,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; - import jdk.nashorn.internal.codegen.CompileUnit; import jdk.nashorn.internal.codegen.Compiler; import jdk.nashorn.internal.codegen.CompilerConstants; @@ -385,7 +384,7 @@ * @return function node or a new one if state was changed */ public FunctionNode setState(final LexicalContext lc, final CompilationState state) { - if (this.compilationState.equals(state)) { + if (this.compilationState.contains(state)) { return this; } final EnumSet<CompilationState> newState = EnumSet.copyOf(this.compilationState);
--- a/src/jdk/nashorn/internal/ir/LiteralNode.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/ir/LiteralNode.java Mon Jun 10 17:04:30 2013 -0700 @@ -28,7 +28,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; - import jdk.nashorn.internal.codegen.CompileUnit; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; @@ -242,8 +241,8 @@ * * @return the new literal node */ - public static LiteralNode<Node> newInstance(final long token, final int finish) { - return new NodeLiteralNode(token, finish); + public static LiteralNode<Object> newInstance(final long token, final int finish) { + return new NullLiteralNode(token, finish); } /** @@ -253,8 +252,8 @@ * * @return the new literal node */ - public static LiteralNode<?> newInstance(final Node parent) { - return new NodeLiteralNode(parent.getToken(), parent.getFinish()); + public static LiteralNode<Object> newInstance(final Node parent) { + return new NullLiteralNode(parent.getToken(), parent.getFinish()); } @Immutable @@ -496,33 +495,15 @@ return new LexerTokenLiteralNode(parent.getToken(), parent.getFinish(), value); } - private static final class NodeLiteralNode extends LiteralNode<Node> { - - private NodeLiteralNode(final long token, final int finish) { - this(token, finish, null); - } + private static final class NullLiteralNode extends LiteralNode<Object> { - private NodeLiteralNode(final long token, final int finish, final Node value) { - super(Token.recast(token, TokenType.OBJECT), finish, value); - } - - private NodeLiteralNode(final LiteralNode<Node> literalNode) { - super(literalNode); - } - - private NodeLiteralNode(final LiteralNode<Node> literalNode, final Node value) { - super(literalNode, value); + private NullLiteralNode(final long token, final int finish) { + super(Token.recast(token, TokenType.OBJECT), finish, null); } @Override public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { if (visitor.enterLiteralNode(this)) { - if (value != null) { - final Node newValue = value.accept(visitor); - if(value != newValue) { - return visitor.leaveLiteralNode(new NodeLiteralNode(this, newValue)); - } - } return visitor.leaveLiteralNode(this); } @@ -531,38 +512,13 @@ @Override public Type getType() { - return value == null ? Type.OBJECT : super.getType(); + return Type.OBJECT; } @Override public Type getWidestOperationType() { - return value == null ? Type.OBJECT : value.getWidestOperationType(); + return Type.OBJECT; } - - } - /** - * Create a new node literal for an arbitrary node - * - * @param token token - * @param finish finish - * @param value the literal value node - * - * @return the new literal node - */ - public static LiteralNode<Node> newInstance(final long token, final int finish, final Node value) { - return new NodeLiteralNode(token, finish, value); - } - - /** - * Create a new node literal based on a parent node (source, token, finish) - * - * @param parent parent node - * @param value node value - * - * @return the new literal node - */ - public static LiteralNode<?> newInstance(final Node parent, final Node value) { - return new NodeLiteralNode(parent.getToken(), parent.getFinish(), value); } /**
--- a/src/jdk/nashorn/internal/ir/ObjectNode.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/ir/ObjectNode.java Mon Jun 10 17:04:30 2013 -0700 @@ -27,7 +27,6 @@ import java.util.Collections; import java.util.List; - import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; @@ -38,7 +37,7 @@ public final class ObjectNode extends Node { /** Literal elements. */ - private final List<Node> elements; + private final List<PropertyNode> elements; /** * Constructor @@ -47,12 +46,12 @@ * @param finish finish * @param elements the elements used to initialize this ObjectNode */ - public ObjectNode(final long token, final int finish, final List<Node> elements) { + public ObjectNode(final long token, final int finish, final List<PropertyNode> elements) { super(token, finish); this.elements = elements; } - private ObjectNode(final ObjectNode objectNode, final List<Node> elements) { + private ObjectNode(final ObjectNode objectNode, final List<PropertyNode> elements) { super(objectNode); this.elements = elements; } @@ -60,7 +59,7 @@ @Override public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { if (visitor.enterObjectNode(this)) { - return visitor.leaveObjectNode(setElements(Node.accept(visitor, Node.class, elements))); + return visitor.leaveObjectNode(setElements(Node.accept(visitor, PropertyNode.class, elements))); } return this; @@ -92,11 +91,11 @@ * Get the elements of this literal node * @return a list of elements */ - public List<Node> getElements() { + public List<PropertyNode> getElements() { return Collections.unmodifiableList(elements); } - private ObjectNode setElements(final List<Node> elements) { + private ObjectNode setElements(final List<PropertyNode> elements) { if (this.elements == elements) { return this; }
--- a/src/jdk/nashorn/internal/objects/DateParser.java Thu Jun 06 20:48:44 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,706 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.objects; - -import static java.lang.Character.DECIMAL_DIGIT_NUMBER; -import static java.lang.Character.LOWERCASE_LETTER; -import static java.lang.Character.OTHER_PUNCTUATION; -import static java.lang.Character.SPACE_SEPARATOR; -import static java.lang.Character.UPPERCASE_LETTER; - -import java.util.HashMap; -import java.util.Locale; - -/** - * JavaScript date parser. This class first tries to parse a date string - * according to the extended ISO 8601 format specified in ES5 15.9.1.15. - * If that fails, it falls back to legacy mode in which it accepts a range - * of different formats. - * - * <p>This class is neither thread-safe nor reusable. Calling the - * <tt>parse()</tt> method more than once will yield undefined results.</p> - */ -public class DateParser { - - /** Constant for index position of parsed year value. */ - public final static int YEAR = 0; - /** Constant for index position of parsed month value. */ - public final static int MONTH = 1; - /** Constant for index position of parsed day value. */ - public final static int DAY = 2; - /** Constant for index position of parsed hour value. */ - public final static int HOUR = 3; - /** Constant for index position of parsed minute value. */ - public final static int MINUTE = 4; - /** Constant for index position of parsed second value. */ - public final static int SECOND = 5; - /** Constant for index position of parsed millisecond value. */ - public final static int MILLISECOND = 6; - /** Constant for index position of parsed time zone offset value. */ - public final static int TIMEZONE = 7; - - private enum Token { - UNKNOWN, NUMBER, SEPARATOR, PARENTHESIS, NAME, SIGN, END - } - - private final String string; - private final int length; - private final Integer[] fields; - private int pos = 0; - private Token token; - private int tokenLength; - private Name nameValue; - private int numValue; - private int currentField = YEAR; - private int yearSign = 0; - private boolean namedMonth = false; - - private final static HashMap<String,Name> names = new HashMap<>(); - - static { - addName("monday", Name.DAY_OF_WEEK, 0); - addName("tuesday", Name.DAY_OF_WEEK, 0); - addName("wednesday", Name.DAY_OF_WEEK, 0); - addName("thursday", Name.DAY_OF_WEEK, 0); - addName("friday", Name.DAY_OF_WEEK, 0); - addName("saturday", Name.DAY_OF_WEEK, 0); - addName("sunday", Name.DAY_OF_WEEK, 0); - addName("january", Name.MONTH_NAME, 1); - addName("february", Name.MONTH_NAME, 2); - addName("march", Name.MONTH_NAME, 3); - addName("april", Name.MONTH_NAME, 4); - addName("may", Name.MONTH_NAME, 5); - addName("june", Name.MONTH_NAME, 6); - addName("july", Name.MONTH_NAME, 7); - addName("august", Name.MONTH_NAME, 8); - addName("september", Name.MONTH_NAME, 9); - addName("october", Name.MONTH_NAME, 10); - addName("november", Name.MONTH_NAME, 11); - addName("december", Name.MONTH_NAME, 12); - addName("am", Name.AM_PM, 0); - addName("pm", Name.AM_PM, 12); - addName("z", Name.TIMEZONE_ID, 0); - addName("gmt", Name.TIMEZONE_ID, 0); - addName("ut", Name.TIMEZONE_ID, 0); - addName("utc", Name.TIMEZONE_ID, 0); - addName("est", Name.TIMEZONE_ID, -5 * 60); - addName("edt", Name.TIMEZONE_ID, -4 * 60); - addName("cst", Name.TIMEZONE_ID, -6 * 60); - addName("cdt", Name.TIMEZONE_ID, -5 * 60); - addName("mst", Name.TIMEZONE_ID, -7 * 60); - addName("mdt", Name.TIMEZONE_ID, -6 * 60); - addName("pst", Name.TIMEZONE_ID, -8 * 60); - addName("pdt", Name.TIMEZONE_ID, -7 * 60); - addName("t", Name.TIME_SEPARATOR, 0); - } - - /** - * Construct a new <tt>DateParser</tt> instance for parsing the given string. - * @param string the string to be parsed - */ - public DateParser(final String string) { - this.string = string; - this.length = string.length(); - this.fields = new Integer[TIMEZONE + 1]; - } - - /** - * Try parsing the given string as date according to the extended ISO 8601 format - * specified in ES5 15.9.1.15. Fall back to legacy mode if that fails. - * This method returns <tt>true</tt> if the string could be parsed. - * @return true if the string could be parsed as date - */ - public boolean parse() { - return parseEcmaDate() || parseLegacyDate(); - } - - /** - * Try parsing the date string according to the rules laid out in ES5 15.9.1.15. - * The date string must conform to the following format: - * - * <pre> [('-'|'+')yy]yyyy[-MM[-dd]][hh:mm[:ss[.sss]][Z|(+|-)hh:mm]] </pre> - * - * <p>If the string does not contain a time zone offset, the <tt>TIMEZONE</tt> field - * is set to <tt>0</tt> (GMT).</p> - * @return true if string represents a valid ES5 date string. - */ - public boolean parseEcmaDate() { - - if (token == null) { - token = next(); - } - - while (token != Token.END) { - - switch (token) { - case NUMBER: - if (currentField == YEAR && yearSign != 0) { - // 15.9.1.15.1 Extended year must have six digits - if (tokenLength != 6) { - return false; - } - numValue *= yearSign; - } else if (!checkEcmaField(currentField, numValue)) { - return false; - } - if (!skipEcmaDelimiter()) { - return false; - } - if (currentField < TIMEZONE) { - set(currentField++, numValue); - } - break; - - case NAME: - if (nameValue == null) { - return false; - } - switch (nameValue.type) { - case Name.TIME_SEPARATOR: - if (currentField == YEAR || currentField > HOUR) { - return false; - } - currentField = HOUR; - break; - case Name.TIMEZONE_ID: - if (!nameValue.key.equals("z") || !setTimezone(nameValue.value, false)) { - return false; - } - break; - default: - return false; - } - break; - - case SIGN: - if (currentField == YEAR) { - yearSign = numValue; - } else if (currentField < SECOND || !setTimezone(readTimeZoneOffset(), true)) { - // Note: Spidermonkey won't parse timezone unless time includes seconds and milliseconds - return false; - } - break; - - default: - return false; - } - token = next(); - } - - return patchResult(true); - } - - /** - * Try parsing the date using a fuzzy algorithm that can handle a variety of formats. - * - * <p>Numbers separated by <tt>':'</tt> are treated as time values, optionally followed by a - * millisecond value separated by <tt>'.'</tt>. Other number values are treated as date values. - * The exact sequence of day, month, and year values to apply is determined heuristically.</p> - * - * <p>English month names and selected time zone names as well as AM/PM markers are recognized - * and handled properly. Additionally, numeric time zone offsets such as <tt>(+|-)hh:mm</tt> or - * <tt>(+|-)hhmm</tt> are recognized. If the string does not contain a time zone offset - * the <tt>TIMEZONE</tt>field is left undefined, meaning the local time zone should be applied.</p> - * - * <p>English weekday names are recognized but ignored. All text in parentheses is ignored as well. - * All other text causes parsing to fail.</p> - * - * @return true if the string could be parsed - */ - public boolean parseLegacyDate() { - - if (yearSign != 0 || currentField > DAY) { - // we don't support signed years in legacy mode - return false; - } - if (token == null) { - token = next(); - } - - while (token != Token.END) { - - switch (token) { - case NUMBER: - if (skip(':')) { - // A number followed by ':' is parsed as time - if (!setTimeField(numValue)) { - return false; - } - // consume remaining time tokens - do { - token = next(); - if (token != Token.NUMBER || !setTimeField(numValue)) { - return false; - } - } while (skip(isSet(SECOND) ? '.' : ':')); - - } else { - // Parse as date token - if (!setDateField(numValue)) { - return false; - } - skip('-'); - } - break; - - case NAME: - if (nameValue == null) { - return false; - } - switch (nameValue.type) { - case Name.AM_PM: - if (!setAmPm(nameValue.value)) { - return false; - } - break; - case Name.MONTH_NAME: - if (!setMonth(nameValue.value)) { - return false; - } - break; - case Name.TIMEZONE_ID: - if (!setTimezone(nameValue.value, false)) { - return false; - } - break; - case Name.TIME_SEPARATOR: - return false; - default: - break; - } - if (nameValue.type != Name.TIMEZONE_ID) { - skip('-'); - } - break; - - case SIGN: - if (!setTimezone(readTimeZoneOffset(), true)) { - return false; - } - break; - - case PARENTHESIS: - if (!skipParentheses()) { - return false; - } - break; - - case SEPARATOR: - break; - - default: - return false; - } - token = next(); - } - - return patchResult(false); - } - - /** - * Get the parsed date and time fields as an array of <tt>Integers</tt>. - * - * <p>If parsing was successful, all fields are guaranteed to be set except for the - * <tt>TIMEZONE</tt> field which may be <tt>null</tt>, meaning that local time zone - * offset should be applied.</p> - * - * @return the parsed date fields - */ - public Integer[] getDateFields() { - return fields; - } - - private boolean isSet(final int field) { - return fields[field] != null; - } - - private Integer get(final int field) { - return fields[field]; - } - - private void set(final int field, final int value) { - fields[field] = value; - } - - private int peek() { - return pos < length ? string.charAt(pos) : -1; - } - - private boolean skip(final char c) { - if (pos < length && string.charAt(pos) == c) { - token = null; - pos++; - return true; - } - return false; - } - - private Token next() { - if (pos >= length) { - tokenLength = 0; - return Token.END; - } - - final char c = string.charAt(pos); - - if (c > 0x80) { - tokenLength = 1; - pos++; - return Token.UNKNOWN; // We only deal with ASCII here - } - - final int type = Character.getType(c); - switch (type) { - case DECIMAL_DIGIT_NUMBER: - numValue = readNumber(6); - return Token.NUMBER; - case SPACE_SEPARATOR : - case OTHER_PUNCTUATION: - tokenLength = 1; - pos++; - return Token.SEPARATOR; - case UPPERCASE_LETTER: - case LOWERCASE_LETTER: - nameValue = readName(); - return Token.NAME; - default: - tokenLength = 1; - pos++; - switch (c) { - case '(': - return Token.PARENTHESIS; - case '-': - case '+': - numValue = c == '-' ? -1 : 1; - return Token.SIGN; - default: - return Token.UNKNOWN; - } - } - } - - private static boolean checkLegacyField(final int field, final int value) { - switch (field) { - case HOUR: - return isHour(value); - case MINUTE: - case SECOND: - return isMinuteOrSecond(value); - case MILLISECOND: - return isMillisecond(value); - default: - // skip validation on other legacy fields as we don't know what's what - return true; - } - } - - private boolean checkEcmaField(final int field, final int value) { - switch (field) { - case YEAR: - return tokenLength == 4; - case MONTH: - return tokenLength == 2 && isMonth(value); - case DAY: - return tokenLength == 2 && isDay(value); - case HOUR: - return tokenLength == 2 && isHour(value); - case MINUTE: - case SECOND: - return tokenLength == 2 && isMinuteOrSecond(value); - case MILLISECOND: - // we allow millisecond to be less than 3 digits - return tokenLength < 4 && isMillisecond(value); - default: - return true; - } - } - - private boolean skipEcmaDelimiter() { - switch (currentField) { - case YEAR: - case MONTH: - return skip('-') || peek() == 'T' || peek() == -1; - case DAY: - return peek() == 'T' || peek() == -1; - case HOUR: - case MINUTE: - return skip(':') || endOfTime(); - case SECOND: - return skip('.') || endOfTime(); - default: - return true; - } - } - - private boolean endOfTime() { - final int c = peek(); - return c == -1 || c == 'Z' || c == '-' || c == '+' || c == ' '; - } - - private static boolean isAsciiLetter(final char ch) { - return ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z'); - } - - private static boolean isAsciiDigit(final char ch) { - return '0' <= ch && ch <= '9'; - } - - private int readNumber(final int maxDigits) { - final int start = pos; - int n = 0; - final int max = Math.min(length, pos + maxDigits); - while (pos < max && isAsciiDigit(string.charAt(pos))) { - n = n * 10 + string.charAt(pos++) - '0'; - } - tokenLength = pos - start; - return n; - } - - private Name readName() { - final int start = pos; - final int limit = Math.min(pos + 3, length); - - // first read up to the key length - while (pos < limit && isAsciiLetter(string.charAt(pos))) { - pos++; - } - final String key = string.substring(start, pos).toLowerCase(Locale.ENGLISH); - final Name name = names.get(key); - // then advance to end of name - while (pos < length && isAsciiLetter(string.charAt(pos))) { - pos++; - } - - tokenLength = pos - start; - // make sure we have the full name or a prefix - if (name != null && name.matches(string, start, tokenLength)) { - return name; - } - return null; - } - - private int readTimeZoneOffset() { - final int sign = string.charAt(pos - 1) == '+' ? 1 : -1; - int offset = readNumber(2); - skip(':'); - offset = offset * 60 + readNumber(2); - return sign * offset; - } - - private boolean skipParentheses() { - int parenCount = 1; - while (pos < length && parenCount != 0) { - final char c = string.charAt(pos++); - if (c == '(') { - parenCount++; - } else if (c == ')') { - parenCount--; - } - } - return true; - } - - private static int getDefaultValue(final int field) { - switch (field) { - case MONTH: - case DAY: - return 1; - default: - return 0; - } - } - - private static boolean isDay(final int n) { - return 1 <= n && n <= 31; - } - - private static boolean isMonth(final int n) { - return 1 <= n && n <= 12; - } - - private static boolean isHour(final int n) { - return 0 <= n && n <= 24; - } - - private static boolean isMinuteOrSecond(final int n) { - return 0 <= n && n < 60; - } - - private static boolean isMillisecond(final int n) { - return 0<= n && n < 1000; - } - - private boolean setMonth(final int m) { - if (!isSet(MONTH)) { - namedMonth = true; - set(MONTH, m); - return true; - } - return false; - } - - private boolean setDateField(final int n) { - for (int field = YEAR; field != HOUR; field++) { - if (!isSet(field)) { - // no validation on legacy date fields - set(field, n); - return true; - } - } - return false; - } - - private boolean setTimeField(final int n) { - for (int field = HOUR; field != TIMEZONE; field++) { - if (!isSet(field)) { - if (checkLegacyField(field, n)) { - set(field, n); - return true; - } - return false; - } - } - return false; - } - - private boolean setTimezone(final int offset, final boolean asNumericOffset) { - if (!isSet(TIMEZONE) || (asNumericOffset && get(TIMEZONE) == 0)) { - set(TIMEZONE, offset); - return true; - } - return false; - } - - private boolean setAmPm(final int offset) { - if (!isSet(HOUR)) { - return false; - } - final int hour = get(HOUR); - if (hour >= 0 && hour <= 12) { - set(HOUR, hour + offset); - } - return true; - } - - private boolean patchResult(final boolean strict) { - // sanity checks - make sure we have something - if (!isSet(YEAR) && !isSet(HOUR)) { - return false; - } - if (isSet(HOUR) && !isSet(MINUTE)) { - return false; - } - // fill in default values for unset fields except timezone - for (int field = YEAR; field <= TIMEZONE; field++) { - if (get(field) == null) { - if (field == TIMEZONE && !strict) { - // We only use UTC as default timezone for dates parsed complying with - // the format specified in ES5 15.9.1.15. Otherwise the slot is left empty - // and local timezone is used. - continue; - } - final int value = getDefaultValue(field); - set(field, value); - } - } - - if (!strict) { - // swap year, month, and day if it looks like the right thing to do - if (isDay(get(YEAR))) { - final int d = get(YEAR); - set(YEAR, get(DAY)); - if (namedMonth) { - // d-m-y - set(DAY, d); - } else { - // m-d-y - final int d2 = get(MONTH); - set(MONTH, d); - set(DAY, d2); - } - } - // sanity checks now that we know what's what - if (!isMonth(get(MONTH)) || !isDay(get(DAY))) { - return false; - } - - // add 1900 or 2000 to year if it's between 0 and 100 - final int year = get(YEAR); - if (year >= 0 && year < 100) { - set(YEAR, year >= 50 ? 1900 + year : 2000 + year); - } - } else { - // 24 hour value is only allowed if all other time values are zero - if (get(HOUR) == 24 && - (get(MINUTE) != 0 || get(SECOND) != 0 || get(MILLISECOND) != 0)) { - return false; - } - } - - // set month to 0-based - set(MONTH, get(MONTH) - 1); - return true; - } - - private static void addName(final String str, final int type, final int value) { - final Name name = new Name(str, type, value); - names.put(name.key, name); - } - - private static class Name { - final String name; - final String key; - final int value; - final int type; - - final static int DAY_OF_WEEK = -1; - final static int MONTH_NAME = 0; - final static int AM_PM = 1; - final static int TIMEZONE_ID = 2; - final static int TIME_SEPARATOR = 3; - - Name(final String name, final int type, final int value) { - assert name != null; - assert name.equals(name.toLowerCase(Locale.ENGLISH)); - - this.name = name; - // use first three characters as lookup key - this.key = name.substring(0, Math.min(3, name.length())); - this.type = type; - this.value = value; - } - - public boolean matches(final String str, final int offset, final int len) { - return name.regionMatches(true, 0, str, offset, len); - } - - @Override - public String toString() { - return name; - } - } - -}
--- a/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java Mon Jun 10 17:04:30 2013 -0700 @@ -150,11 +150,11 @@ if (this == obj) { return true; } - if (!(obj instanceof AccessorPropertyDescriptor)) { + if (!(obj instanceof GenericPropertyDescriptor)) { return false; } - final AccessorPropertyDescriptor other = (AccessorPropertyDescriptor)obj; + final GenericPropertyDescriptor other = (GenericPropertyDescriptor)obj; return ScriptRuntime.sameValue(configurable, other.configurable) && ScriptRuntime.sameValue(enumerable, other.enumerable); }
--- a/src/jdk/nashorn/internal/objects/Global.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/objects/Global.java Mon Jun 10 17:04:30 2013 -0700 @@ -119,6 +119,10 @@ @Property(attributes = Attribute.NOT_ENUMERABLE) public Object load; + /** Nashorn extension: global.loadWithNewGlobal */ + @Property(attributes = Attribute.NOT_ENUMERABLE) + public Object loadWithNewGlobal; + /** Nashorn extension: global.exit */ @Property(attributes = Attribute.NOT_ENUMERABLE) public Object exit; @@ -364,11 +368,12 @@ // Used to store the last RegExp result to support deprecated RegExp constructor properties private RegExpResult lastRegExpResult; - private static final MethodHandle EVAL = findOwnMH("eval", Object.class, Object.class, Object.class); - private static final MethodHandle PRINT = findOwnMH("print", Object.class, Object.class, Object[].class); - private static final MethodHandle PRINTLN = findOwnMH("println", Object.class, Object.class, Object[].class); - private static final MethodHandle LOAD = findOwnMH("load", Object.class, Object.class, Object.class); - private static final MethodHandle EXIT = findOwnMH("exit", Object.class, Object.class, Object.class); + private static final MethodHandle EVAL = findOwnMH("eval", Object.class, Object.class, Object.class); + private static final MethodHandle PRINT = findOwnMH("print", Object.class, Object.class, Object[].class); + private static final MethodHandle PRINTLN = findOwnMH("println", Object.class, Object.class, Object[].class); + private static final MethodHandle LOAD = findOwnMH("load", Object.class, Object.class, Object.class); + private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH("loadWithNewGlobal", Object.class, Object.class, Object.class); + private static final MethodHandle EXIT = findOwnMH("exit", Object.class, Object.class, Object.class); private final Context context; @@ -743,6 +748,21 @@ } /** + * Global loadWithNewGlobal implementation - Nashorn extension + * + * @param self scope + * @param source source to load + * + * @return result of load (undefined) + * + * @throws IOException if source could not be read + */ + public static Object loadWithNewGlobal(final Object self, final Object source) throws IOException { + final Global global = Global.instance(); + return global.context.loadWithNewGlobal(source); + } + + /** * Global exit and quit implementation - Nashorn extension: perform a {@code System.exit} call from the script * * @param self self reference @@ -1387,6 +1407,7 @@ this.unescape = ScriptFunctionImpl.makeFunction("unescape", GlobalFunctions.UNESCAPE); this.print = ScriptFunctionImpl.makeFunction("print", env._print_no_newline ? PRINT : PRINTLN); this.load = ScriptFunctionImpl.makeFunction("load", LOAD); + this.loadWithNewGlobal = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOADWITHNEWGLOBAL); this.exit = ScriptFunctionImpl.makeFunction("exit", EXIT); this.quit = ScriptFunctionImpl.makeFunction("quit", EXIT); @@ -1628,20 +1649,21 @@ @SuppressWarnings("resource") private static Object printImpl(final boolean newLine, final Object... objects) { final PrintWriter out = Global.getEnv().getOut(); + final StringBuilder sb = new StringBuilder(); - boolean first = true; for (final Object object : objects) { - if (first) { - first = false; - } else { - out.print(' '); + if (sb.length() != 0) { + sb.append(' '); } - out.print(JSType.toString(object)); + sb.append(JSType.toString(object)); } + // Print all at once to ensure thread friendly result. if (newLine) { - out.println(); + out.println(sb.toString()); + } else { + out.print(sb.toString()); } out.flush();
--- a/src/jdk/nashorn/internal/objects/NativeArray.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeArray.java Mon Jun 10 17:04:30 2013 -0700 @@ -75,7 +75,7 @@ private static final MethodHandle FILTER_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class); private static final MethodHandle REDUCE_CALLBACK_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class, - Object.class, Undefined.class, Object.class, Object.class, int.class, Object.class); + Object.class, Undefined.class, Object.class, Object.class, long.class, Object.class); private static final MethodHandle CALL_CMP = Bootstrap.createDynamicInvoker("dyn:call", double.class, ScriptFunction.class, Object.class, Object.class, Object.class); @@ -1086,7 +1086,7 @@ private static boolean applyEvery(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, true) { @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { return (result = (boolean)EVERY_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self)); } }.apply(); @@ -1104,7 +1104,7 @@ public static Object some(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, false) { @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { return !(result = (boolean)SOME_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self)); } }.apply(); @@ -1122,7 +1122,7 @@ public static Object forEach(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<Object>(Global.toObject(self), callbackfn, thisArg, ScriptRuntime.UNDEFINED) { @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { FOREACH_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self); return true; } @@ -1141,9 +1141,9 @@ public static Object map(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, null) { @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { final Object r = MAP_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self); - result.defineOwnProperty(index, r); + result.defineOwnProperty((int)index, r); return true; } @@ -1167,12 +1167,12 @@ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static Object filter(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, new NativeArray()) { - private int to = 0; + private long to = 0; @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { if ((boolean)FILTER_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self)) { - result.defineOwnProperty(to++, val); + result.defineOwnProperty((int)(to++), val); } return true; } @@ -1200,7 +1200,7 @@ //if initial value is ScriptRuntime.UNDEFINED - step forward once. return new IteratorAction<Object>(Global.toObject(self), callbackfn, ScriptRuntime.UNDEFINED, initialValue, iter) { @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { // TODO: why can't I declare the second arg as Undefined.class? result = REDUCE_CALLBACK_INVOKER.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self); return true; @@ -1258,7 +1258,7 @@ private static MethodHandle createIteratorCallbackInvoker(final Class<?> rtype) { return Bootstrap.createDynamicInvoker("dyn:call", rtype, Object.class, Object.class, Object.class, - int.class, Object.class); + long.class, Object.class); } }
--- a/src/jdk/nashorn/internal/objects/NativeDate.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeDate.java Mon Jun 10 17:04:30 2013 -0700 @@ -39,6 +39,7 @@ import jdk.nashorn.internal.objects.annotations.ScriptClass; import jdk.nashorn.internal.objects.annotations.SpecializedConstructor; import jdk.nashorn.internal.objects.annotations.Where; +import jdk.nashorn.internal.parser.DateParser; import jdk.nashorn.internal.runtime.ConsString; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptEnvironment;
--- a/src/jdk/nashorn/internal/objects/NativeError.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeError.java Mon Jun 10 17:04:30 2013 -0700 @@ -32,6 +32,7 @@ import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.List; +import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; @@ -248,7 +249,13 @@ final List<StackTraceElement> filtered = new ArrayList<>(); for (final StackTraceElement st : frames) { if (ECMAErrors.isScriptFrame(st)) { - filtered.add(st); + final String className = "<" + st.getFileName() + ">"; + String methodName = st.getMethodName(); + if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) { + methodName = "<program>"; + } + filtered.add(new StackTraceElement(className, methodName, + st.getFileName(), st.getLineNumber())); } } res = filtered.toArray();
--- a/src/jdk/nashorn/internal/objects/NativeFunction.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeFunction.java Mon Jun 10 17:04:30 2013 -0700 @@ -33,10 +33,14 @@ 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.parser.Parser; +import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.JSType; +import jdk.nashorn.internal.runtime.ParserException; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.internal.runtime.Source; /** * ECMA 15.3 Function Objects @@ -187,16 +191,25 @@ sb.append("(function ("); if (args.length > 0) { + final StringBuilder paramListBuf = new StringBuilder(); for (int i = 0; i < args.length - 1; i++) { - sb.append(JSType.toString(args[i])); + paramListBuf.append(JSType.toString(args[i])); if (i < args.length - 2) { - sb.append(","); + paramListBuf.append(","); } } + + final String paramList = paramListBuf.toString(); + if (! paramList.isEmpty()) { + checkFunctionParameters(paramList); + sb.append(paramList); + } } sb.append(") {\n"); if (args.length > 0) { - sb.append(JSType.toString(args[args.length - 1])); + final String funcBody = JSType.toString(args[args.length - 1]); + checkFunctionBody(funcBody); + sb.append(funcBody); sb.append('\n'); } sb.append("})"); @@ -205,4 +218,24 @@ return Global.directEval(global, sb.toString(), global, "<function>", Global.isStrict()); } + + private static void checkFunctionParameters(final String params) { + final Source src = new Source("<function>", params); + final Parser parser = new Parser(Global.getEnv(), src, new Context.ThrowErrorManager()); + try { + parser.parseFormalParameterList(); + } catch (final ParserException pe) { + pe.throwAsEcmaException(); + } + } + + private static void checkFunctionBody(final String funcBody) { + final Source src = new Source("<function>", funcBody); + final Parser parser = new Parser(Global.getEnv(), src, new Context.ThrowErrorManager()); + try { + parser.parseFunctionBody(); + } catch (final ParserException pe) { + pe.throwAsEcmaException(); + } + } }
--- a/src/jdk/nashorn/internal/objects/NativeMath.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeMath.java Mon Jun 10 17:04:30 2013 -0700 @@ -31,7 +31,6 @@ import jdk.nashorn.internal.objects.annotations.ScriptClass; import jdk.nashorn.internal.objects.annotations.SpecializedFunction; import jdk.nashorn.internal.objects.annotations.Where; -import jdk.nashorn.internal.runtime.GlobalFunctions; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptObject;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk/nashorn/internal/parser/DateParser.java Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,716 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.parser; + +import static java.lang.Character.DECIMAL_DIGIT_NUMBER; +import static java.lang.Character.LOWERCASE_LETTER; +import static java.lang.Character.OTHER_PUNCTUATION; +import static java.lang.Character.SPACE_SEPARATOR; +import static java.lang.Character.UPPERCASE_LETTER; + +import java.util.HashMap; +import java.util.Locale; + +/** + * JavaScript date parser. This class first tries to parse a date string + * according to the extended ISO 8601 format specified in ES5 15.9.1.15. + * If that fails, it falls back to legacy mode in which it accepts a range + * of different formats. + * + * <p>This class is neither thread-safe nor reusable. Calling the + * <tt>parse()</tt> method more than once will yield undefined results.</p> + */ +public class DateParser { + + /** Constant for index position of parsed year value. */ + public final static int YEAR = 0; + /** Constant for index position of parsed month value. */ + public final static int MONTH = 1; + /** Constant for index position of parsed day value. */ + public final static int DAY = 2; + /** Constant for index position of parsed hour value. */ + public final static int HOUR = 3; + /** Constant for index position of parsed minute value. */ + public final static int MINUTE = 4; + /** Constant for index position of parsed second value. */ + public final static int SECOND = 5; + /** Constant for index position of parsed millisecond value. */ + public final static int MILLISECOND = 6; + /** Constant for index position of parsed time zone offset value. */ + public final static int TIMEZONE = 7; + + private enum Token { + UNKNOWN, NUMBER, SEPARATOR, PARENTHESIS, NAME, SIGN, END + } + + private final String string; + private final int length; + private final Integer[] fields; + private int pos = 0; + private Token token; + private int tokenLength; + private Name nameValue; + private int numValue; + private int currentField = YEAR; + private int yearSign = 0; + private boolean namedMonth = false; + + private final static HashMap<String,Name> names = new HashMap<>(); + + static { + addName("monday", Name.DAY_OF_WEEK, 0); + addName("tuesday", Name.DAY_OF_WEEK, 0); + addName("wednesday", Name.DAY_OF_WEEK, 0); + addName("thursday", Name.DAY_OF_WEEK, 0); + addName("friday", Name.DAY_OF_WEEK, 0); + addName("saturday", Name.DAY_OF_WEEK, 0); + addName("sunday", Name.DAY_OF_WEEK, 0); + addName("january", Name.MONTH_NAME, 1); + addName("february", Name.MONTH_NAME, 2); + addName("march", Name.MONTH_NAME, 3); + addName("april", Name.MONTH_NAME, 4); + addName("may", Name.MONTH_NAME, 5); + addName("june", Name.MONTH_NAME, 6); + addName("july", Name.MONTH_NAME, 7); + addName("august", Name.MONTH_NAME, 8); + addName("september", Name.MONTH_NAME, 9); + addName("october", Name.MONTH_NAME, 10); + addName("november", Name.MONTH_NAME, 11); + addName("december", Name.MONTH_NAME, 12); + addName("am", Name.AM_PM, 0); + addName("pm", Name.AM_PM, 12); + addName("z", Name.TIMEZONE_ID, 0); + addName("gmt", Name.TIMEZONE_ID, 0); + addName("ut", Name.TIMEZONE_ID, 0); + addName("utc", Name.TIMEZONE_ID, 0); + addName("est", Name.TIMEZONE_ID, -5 * 60); + addName("edt", Name.TIMEZONE_ID, -4 * 60); + addName("cst", Name.TIMEZONE_ID, -6 * 60); + addName("cdt", Name.TIMEZONE_ID, -5 * 60); + addName("mst", Name.TIMEZONE_ID, -7 * 60); + addName("mdt", Name.TIMEZONE_ID, -6 * 60); + addName("pst", Name.TIMEZONE_ID, -8 * 60); + addName("pdt", Name.TIMEZONE_ID, -7 * 60); + addName("t", Name.TIME_SEPARATOR, 0); + } + + /** + * Construct a new <tt>DateParser</tt> instance for parsing the given string. + * @param string the string to be parsed + */ + public DateParser(final String string) { + this.string = string; + this.length = string.length(); + this.fields = new Integer[TIMEZONE + 1]; + } + + /** + * Try parsing the given string as date according to the extended ISO 8601 format + * specified in ES5 15.9.1.15. Fall back to legacy mode if that fails. + * This method returns <tt>true</tt> if the string could be parsed. + * @return true if the string could be parsed as date + */ + public boolean parse() { + return parseEcmaDate() || parseLegacyDate(); + } + + /** + * Try parsing the date string according to the rules laid out in ES5 15.9.1.15. + * The date string must conform to the following format: + * + * <pre> [('-'|'+')yy]yyyy[-MM[-dd]][hh:mm[:ss[.sss]][Z|(+|-)hh:mm]] </pre> + * + * <p>If the string does not contain a time zone offset, the <tt>TIMEZONE</tt> field + * is set to <tt>0</tt> (GMT).</p> + * @return true if string represents a valid ES5 date string. + */ + public boolean parseEcmaDate() { + + if (token == null) { + token = next(); + } + + while (token != Token.END) { + + switch (token) { + case NUMBER: + if (currentField == YEAR && yearSign != 0) { + // 15.9.1.15.1 Extended year must have six digits + if (tokenLength != 6) { + return false; + } + numValue *= yearSign; + } else if (!checkEcmaField(currentField, numValue)) { + return false; + } + if (!skipEcmaDelimiter()) { + return false; + } + if (currentField < TIMEZONE) { + set(currentField++, numValue); + } + break; + + case NAME: + if (nameValue == null) { + return false; + } + switch (nameValue.type) { + case Name.TIME_SEPARATOR: + if (currentField == YEAR || currentField > HOUR) { + return false; + } + currentField = HOUR; + break; + case Name.TIMEZONE_ID: + if (!nameValue.key.equals("z") || !setTimezone(nameValue.value, false)) { + return false; + } + break; + default: + return false; + } + break; + + case SIGN: + if (peek() == -1) { + // END after sign - wrong! + return false; + } + + if (currentField == YEAR) { + yearSign = numValue; + } else if (currentField < SECOND || !setTimezone(readTimeZoneOffset(), true)) { + // Note: Spidermonkey won't parse timezone unless time includes seconds and milliseconds + return false; + } + break; + + default: + return false; + } + token = next(); + } + + return patchResult(true); + } + + /** + * Try parsing the date using a fuzzy algorithm that can handle a variety of formats. + * + * <p>Numbers separated by <tt>':'</tt> are treated as time values, optionally followed by a + * millisecond value separated by <tt>'.'</tt>. Other number values are treated as date values. + * The exact sequence of day, month, and year values to apply is determined heuristically.</p> + * + * <p>English month names and selected time zone names as well as AM/PM markers are recognized + * and handled properly. Additionally, numeric time zone offsets such as <tt>(+|-)hh:mm</tt> or + * <tt>(+|-)hhmm</tt> are recognized. If the string does not contain a time zone offset + * the <tt>TIMEZONE</tt>field is left undefined, meaning the local time zone should be applied.</p> + * + * <p>English weekday names are recognized but ignored. All text in parentheses is ignored as well. + * All other text causes parsing to fail.</p> + * + * @return true if the string could be parsed + */ + public boolean parseLegacyDate() { + + if (yearSign != 0 || currentField > DAY) { + // we don't support signed years in legacy mode + return false; + } + if (token == null) { + token = next(); + } + + while (token != Token.END) { + + switch (token) { + case NUMBER: + if (skip(':')) { + // A number followed by ':' is parsed as time + if (!setTimeField(numValue)) { + return false; + } + // consume remaining time tokens + do { + token = next(); + if (token != Token.NUMBER || !setTimeField(numValue)) { + return false; + } + } while (skip(isSet(SECOND) ? '.' : ':')); + + } else { + // Parse as date token + if (!setDateField(numValue)) { + return false; + } + skip('-'); + } + break; + + case NAME: + if (nameValue == null) { + return false; + } + switch (nameValue.type) { + case Name.AM_PM: + if (!setAmPm(nameValue.value)) { + return false; + } + break; + case Name.MONTH_NAME: + if (!setMonth(nameValue.value)) { + return false; + } + break; + case Name.TIMEZONE_ID: + if (!setTimezone(nameValue.value, false)) { + return false; + } + break; + case Name.TIME_SEPARATOR: + return false; + default: + break; + } + if (nameValue.type != Name.TIMEZONE_ID) { + skip('-'); + } + break; + + case SIGN: + if (peek() == -1) { + // END after sign - wrong! + return false; + } + + if (!setTimezone(readTimeZoneOffset(), true)) { + return false; + } + break; + + case PARENTHESIS: + if (!skipParentheses()) { + return false; + } + break; + + case SEPARATOR: + break; + + default: + return false; + } + token = next(); + } + + return patchResult(false); + } + + /** + * Get the parsed date and time fields as an array of <tt>Integers</tt>. + * + * <p>If parsing was successful, all fields are guaranteed to be set except for the + * <tt>TIMEZONE</tt> field which may be <tt>null</tt>, meaning that local time zone + * offset should be applied.</p> + * + * @return the parsed date fields + */ + public Integer[] getDateFields() { + return fields; + } + + private boolean isSet(final int field) { + return fields[field] != null; + } + + private Integer get(final int field) { + return fields[field]; + } + + private void set(final int field, final int value) { + fields[field] = value; + } + + private int peek() { + return pos < length ? string.charAt(pos) : -1; + } + + private boolean skip(final char c) { + if (pos < length && string.charAt(pos) == c) { + token = null; + pos++; + return true; + } + return false; + } + + private Token next() { + if (pos >= length) { + tokenLength = 0; + return Token.END; + } + + final char c = string.charAt(pos); + + if (c > 0x80) { + tokenLength = 1; + pos++; + return Token.UNKNOWN; // We only deal with ASCII here + } + + final int type = Character.getType(c); + switch (type) { + case DECIMAL_DIGIT_NUMBER: + numValue = readNumber(6); + return Token.NUMBER; + case SPACE_SEPARATOR : + case OTHER_PUNCTUATION: + tokenLength = 1; + pos++; + return Token.SEPARATOR; + case UPPERCASE_LETTER: + case LOWERCASE_LETTER: + nameValue = readName(); + return Token.NAME; + default: + tokenLength = 1; + pos++; + switch (c) { + case '(': + return Token.PARENTHESIS; + case '-': + case '+': + numValue = c == '-' ? -1 : 1; + return Token.SIGN; + default: + return Token.UNKNOWN; + } + } + } + + private static boolean checkLegacyField(final int field, final int value) { + switch (field) { + case HOUR: + return isHour(value); + case MINUTE: + case SECOND: + return isMinuteOrSecond(value); + case MILLISECOND: + return isMillisecond(value); + default: + // skip validation on other legacy fields as we don't know what's what + return true; + } + } + + private boolean checkEcmaField(final int field, final int value) { + switch (field) { + case YEAR: + return tokenLength == 4; + case MONTH: + return tokenLength == 2 && isMonth(value); + case DAY: + return tokenLength == 2 && isDay(value); + case HOUR: + return tokenLength == 2 && isHour(value); + case MINUTE: + case SECOND: + return tokenLength == 2 && isMinuteOrSecond(value); + case MILLISECOND: + // we allow millisecond to be less than 3 digits + return tokenLength < 4 && isMillisecond(value); + default: + return true; + } + } + + private boolean skipEcmaDelimiter() { + switch (currentField) { + case YEAR: + case MONTH: + return skip('-') || peek() == 'T' || peek() == -1; + case DAY: + return peek() == 'T' || peek() == -1; + case HOUR: + case MINUTE: + return skip(':') || endOfTime(); + case SECOND: + return skip('.') || endOfTime(); + default: + return true; + } + } + + private boolean endOfTime() { + final int c = peek(); + return c == -1 || c == 'Z' || c == '-' || c == '+' || c == ' '; + } + + private static boolean isAsciiLetter(final char ch) { + return ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z'); + } + + private static boolean isAsciiDigit(final char ch) { + return '0' <= ch && ch <= '9'; + } + + private int readNumber(final int maxDigits) { + final int start = pos; + int n = 0; + final int max = Math.min(length, pos + maxDigits); + while (pos < max && isAsciiDigit(string.charAt(pos))) { + n = n * 10 + string.charAt(pos++) - '0'; + } + tokenLength = pos - start; + return n; + } + + private Name readName() { + final int start = pos; + final int limit = Math.min(pos + 3, length); + + // first read up to the key length + while (pos < limit && isAsciiLetter(string.charAt(pos))) { + pos++; + } + final String key = string.substring(start, pos).toLowerCase(Locale.ENGLISH); + final Name name = names.get(key); + // then advance to end of name + while (pos < length && isAsciiLetter(string.charAt(pos))) { + pos++; + } + + tokenLength = pos - start; + // make sure we have the full name or a prefix + if (name != null && name.matches(string, start, tokenLength)) { + return name; + } + return null; + } + + private int readTimeZoneOffset() { + final int sign = string.charAt(pos - 1) == '+' ? 1 : -1; + int offset = readNumber(2); + skip(':'); + offset = offset * 60 + readNumber(2); + return sign * offset; + } + + private boolean skipParentheses() { + int parenCount = 1; + while (pos < length && parenCount != 0) { + final char c = string.charAt(pos++); + if (c == '(') { + parenCount++; + } else if (c == ')') { + parenCount--; + } + } + return true; + } + + private static int getDefaultValue(final int field) { + switch (field) { + case MONTH: + case DAY: + return 1; + default: + return 0; + } + } + + private static boolean isDay(final int n) { + return 1 <= n && n <= 31; + } + + private static boolean isMonth(final int n) { + return 1 <= n && n <= 12; + } + + private static boolean isHour(final int n) { + return 0 <= n && n <= 24; + } + + private static boolean isMinuteOrSecond(final int n) { + return 0 <= n && n < 60; + } + + private static boolean isMillisecond(final int n) { + return 0<= n && n < 1000; + } + + private boolean setMonth(final int m) { + if (!isSet(MONTH)) { + namedMonth = true; + set(MONTH, m); + return true; + } + return false; + } + + private boolean setDateField(final int n) { + for (int field = YEAR; field != HOUR; field++) { + if (!isSet(field)) { + // no validation on legacy date fields + set(field, n); + return true; + } + } + return false; + } + + private boolean setTimeField(final int n) { + for (int field = HOUR; field != TIMEZONE; field++) { + if (!isSet(field)) { + if (checkLegacyField(field, n)) { + set(field, n); + return true; + } + return false; + } + } + return false; + } + + private boolean setTimezone(final int offset, final boolean asNumericOffset) { + if (!isSet(TIMEZONE) || (asNumericOffset && get(TIMEZONE) == 0)) { + set(TIMEZONE, offset); + return true; + } + return false; + } + + private boolean setAmPm(final int offset) { + if (!isSet(HOUR)) { + return false; + } + final int hour = get(HOUR); + if (hour >= 0 && hour <= 12) { + set(HOUR, hour + offset); + } + return true; + } + + private boolean patchResult(final boolean strict) { + // sanity checks - make sure we have something + if (!isSet(YEAR) && !isSet(HOUR)) { + return false; + } + if (isSet(HOUR) && !isSet(MINUTE)) { + return false; + } + // fill in default values for unset fields except timezone + for (int field = YEAR; field <= TIMEZONE; field++) { + if (get(field) == null) { + if (field == TIMEZONE && !strict) { + // We only use UTC as default timezone for dates parsed complying with + // the format specified in ES5 15.9.1.15. Otherwise the slot is left empty + // and local timezone is used. + continue; + } + final int value = getDefaultValue(field); + set(field, value); + } + } + + if (!strict) { + // swap year, month, and day if it looks like the right thing to do + if (isDay(get(YEAR))) { + final int d = get(YEAR); + set(YEAR, get(DAY)); + if (namedMonth) { + // d-m-y + set(DAY, d); + } else { + // m-d-y + final int d2 = get(MONTH); + set(MONTH, d); + set(DAY, d2); + } + } + // sanity checks now that we know what's what + if (!isMonth(get(MONTH)) || !isDay(get(DAY))) { + return false; + } + + // add 1900 or 2000 to year if it's between 0 and 100 + final int year = get(YEAR); + if (year >= 0 && year < 100) { + set(YEAR, year >= 50 ? 1900 + year : 2000 + year); + } + } else { + // 24 hour value is only allowed if all other time values are zero + if (get(HOUR) == 24 && + (get(MINUTE) != 0 || get(SECOND) != 0 || get(MILLISECOND) != 0)) { + return false; + } + } + + // set month to 0-based + set(MONTH, get(MONTH) - 1); + return true; + } + + private static void addName(final String str, final int type, final int value) { + final Name name = new Name(str, type, value); + names.put(name.key, name); + } + + private static class Name { + final String name; + final String key; + final int value; + final int type; + + final static int DAY_OF_WEEK = -1; + final static int MONTH_NAME = 0; + final static int AM_PM = 1; + final static int TIMEZONE_ID = 2; + final static int TIME_SEPARATOR = 3; + + Name(final String name, final int type, final int value) { + assert name != null; + assert name.equals(name.toLowerCase(Locale.ENGLISH)); + + this.name = name; + // use first three characters as lookup key + this.key = name.substring(0, Math.min(3, name.length())); + this.type = type; + this.value = value; + } + + public boolean matches(final String str, final int offset, final int len) { + return name.regionMatches(true, 0, str, offset, len); + } + + @Override + public String toString() { + return name; + } + } + +}
--- a/src/jdk/nashorn/internal/parser/JSONParser.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/parser/JSONParser.java Mon Jun 10 17:04:30 2013 -0700 @@ -282,7 +282,7 @@ next(); // Prepare to accumulate elements. - final List<Node> elements = new ArrayList<>(); + final List<PropertyNode> elements = new ArrayList<>(); // Create a block for the object literal. loop: @@ -298,7 +298,7 @@ default: // Get and add the next property. - final Node property = propertyAssignment(); + final PropertyNode property = propertyAssignment(); elements.add(property); // Comma between property assigments is mandatory in JSON. @@ -317,7 +317,7 @@ * Parse a property assignment from the token stream * @return the property assignment as a Node */ - private Node propertyAssignment() { + private PropertyNode propertyAssignment() { // Capture firstToken. final long propertyToken = token; LiteralNode<?> name = null;
--- a/src/jdk/nashorn/internal/parser/Parser.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/parser/Parser.java Mon Jun 10 17:04:30 2013 -0700 @@ -59,7 +59,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; - import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.codegen.Namespace; import jdk.nashorn.internal.ir.AccessNode; @@ -192,36 +191,110 @@ // Begin parse. return program(scriptName); } catch (final Exception e) { - // Extract message from exception. The message will be in error - // message format. - String message = e.getMessage(); - - // If empty message. - if (message == null) { - message = e.toString(); - } - - // Issue message. - if (e instanceof ParserException) { - errors.error((ParserException)e); - } else { - errors.error(message); - } - - if (env._dump_on_error) { - e.printStackTrace(env.getErr()); - } + handleParseException(e); return null; - } finally { - final String end = this + " end '" + scriptName + "'"; - if (Timing.isEnabled()) { - Timing.accumulateTime(toString(), System.currentTimeMillis() - t0); - LOG.info(end, "' in ", (System.currentTimeMillis() - t0), " ms"); - } else { - LOG.info(end); - } - } + } finally { + final String end = this + " end '" + scriptName + "'"; + if (Timing.isEnabled()) { + Timing.accumulateTime(toString(), System.currentTimeMillis() - t0); + LOG.info(end, "' in ", (System.currentTimeMillis() - t0), " ms"); + } else { + LOG.info(end); + } + } + } + + /** + * Parse and return the list of function parameter list. A comma + * separated list of function parameter identifiers is expected to be parsed. + * Errors will be thrown and the error manager will contain information + * if parsing should fail. This method is used to check if parameter Strings + * passed to "Function" constructor is a valid or not. + * + * @return the list of IdentNodes representing the formal parameter list + */ + public List<IdentNode> parseFormalParameterList() { + try { + stream = new TokenStream(); + lexer = new Lexer(source, stream, scripting && !env._no_syntax_extensions); + + // Set up first token (skips opening EOL.) + k = -1; + next(); + + return formalParameterList(TokenType.EOF); + } catch (final Exception e) { + handleParseException(e); + return null; + } + } + + /** + * Execute parse and return the resulting function node. + * Errors will be thrown and the error manager will contain information + * if parsing should fail. This method is used to check if code String + * passed to "Function" constructor is a valid function body or not. + * + * @return function node resulting from successful parse + */ + public FunctionNode parseFunctionBody() { + try { + stream = new TokenStream(); + lexer = new Lexer(source, stream, scripting && !env._no_syntax_extensions); + + // Set up first token (skips opening EOL.) + k = -1; + next(); + + // Make a fake token for the function. + final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength()); + // Set up the function to append elements. + + FunctionNode function = newFunctionNode( + functionToken, + new IdentNode(functionToken, Token.descPosition(functionToken), RUN_SCRIPT.symbolName()), + new ArrayList<IdentNode>(), + FunctionNode.Kind.NORMAL); + + functionDeclarations = new ArrayList<>(); + sourceElements(); + addFunctionDeclarations(function); + functionDeclarations = null; + + expect(EOF); + + function.setFinish(source.getLength() - 1); + + function = restoreFunctionNode(function, token); //commit code + function = function.setBody(lc, function.getBody().setNeedsScope(lc)); + return function; + } catch (final Exception e) { + handleParseException(e); + return null; + } + } + + private void handleParseException(final Exception e) { + // Extract message from exception. The message will be in error + // message format. + String message = e.getMessage(); + + // If empty message. + if (message == null) { + message = e.toString(); + } + + // Issue message. + if (e instanceof ParserException) { + errors.error((ParserException)e); + } else { + errors.error(message); + } + + if (env._dump_on_error) { + e.printStackTrace(env.getErr()); + } } /** @@ -1954,7 +2027,7 @@ } } - return new ObjectNode(objectToken, finish, new ArrayList<Node>(map.values())); + return new ObjectNode(objectToken, finish, new ArrayList<>(map.values())); } /** @@ -2424,12 +2497,29 @@ * @return List of parameter nodes. */ private List<IdentNode> formalParameterList() { + return formalParameterList(RPAREN); + } + + /** + * Same as the other method of the same name - except that the end + * token type expected is passed as argument to this method. + * + * FormalParameterList : + * Identifier + * FormalParameterList , Identifier + * + * See 13 + * + * Parse function parameter list. + * @return List of parameter nodes. + */ + private List<IdentNode> formalParameterList(final TokenType endType) { // Prepare to gather parameters. final List<IdentNode> parameters = new ArrayList<>(); // Track commas. boolean first = true; - while (type != RPAREN) { + while (type != endType) { // Comma prior to every argument except the first. if (!first) { expect(COMMARIGHT);
--- a/src/jdk/nashorn/internal/runtime/Context.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/Context.java Mon Jun 10 17:04:30 2013 -0700 @@ -48,6 +48,7 @@ import java.security.ProtectionDomain; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; +import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.codegen.Compiler; import jdk.nashorn.internal.codegen.ObjectClassGenerator; import jdk.nashorn.internal.ir.FunctionNode; @@ -491,6 +492,40 @@ } /** + * Implementation of {@code loadWithNewGlobal} Nashorn extension. Load a script file from a source + * expression, after creating a new global scope. + * + * @param from source expression for script + * + * @return return value for load call (undefined) + * + * @throws IOException if source cannot be found or loaded + */ + public Object loadWithNewGlobal(final Object from) throws IOException { + final ScriptObject oldGlobal = getGlobalTrusted(); + final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() { + @Override + public ScriptObject run() { + try { + return createGlobal(); + } catch (final RuntimeException e) { + if (Context.DEBUG) { + e.printStackTrace(); + } + throw e; + } + } + }); + setGlobalTrusted(newGlobal); + + try { + return ScriptObjectMirror.wrap(load(newGlobal, from), newGlobal); + } finally { + setGlobalTrusted(oldGlobal); + } + } + + /** * Load or get a structure class. Structure class names are based on the number of parameter fields * and {@link AccessorProperty} fields in them. Structure classes are used to represent ScriptObjects *
--- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java Mon Jun 10 17:04:30 2013 -0700 @@ -25,9 +25,11 @@ package jdk.nashorn.internal.runtime; +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow; +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex; + import java.lang.invoke.MethodHandle; import java.util.Iterator; -import java.util.List; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.ObjectNode; @@ -36,8 +38,6 @@ import jdk.nashorn.internal.parser.JSONParser; import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.runtime.linker.Bootstrap; -import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow; -import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex; /** * Utilities used by "JSON" object implementation. @@ -171,10 +171,8 @@ final ObjectNode objNode = (ObjectNode) node; final ScriptObject object = ((GlobalObject)global).newObject(); final boolean strict = global.isStrictContext(); - final List<Node> elements = objNode.getElements(); - for (final Node elem : elements) { - final PropertyNode pNode = (PropertyNode) elem; + for (final PropertyNode pNode: objNode.getElements()) { final Node valueNode = pNode.getValue(); final String name = pNode.getKeyName();
--- a/src/jdk/nashorn/internal/runtime/ListAdapter.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/ListAdapter.java Mon Jun 10 17:04:30 2013 -0700 @@ -15,10 +15,11 @@ * as dequeues, it's still slightly more efficient to be able to translate dequeue operations into pushes, pops, shifts, * and unshifts, than to blindly translate all list's add/remove operations into splices. Also, it is conceivable that a * custom script object that implements an Array-like API can have a background data representation that is optimized - * for dequeue-like access. Note that with ECMAScript arrays, {@code push} and {@pop} operate at the end of the array, - * while in Java {@code Deque} they operate on the front of the queue and as such the Java dequeue {@link #push(Object)} - * and {@link #pop()} operations will translate to {@code unshift} and {@code shift} script operations respectively, - * while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and {@code pop}. + * for dequeue-like access. Note that with ECMAScript arrays, {@code push} and {@code pop} operate at the end of the + * array, while in Java {@code Deque} they operate on the front of the queue and as such the Java dequeue + * {@link #push(Object)} and {@link #pop()} operations will translate to {@code unshift} and {@code shift} script + * operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and + * {@code pop}. */ public class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> { // These add to the back and front of the list
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Jun 10 17:04:30 2013 -0700 @@ -1512,6 +1512,17 @@ } /** + * Delete a property from the ScriptObject. + * (to help ScriptObjectMirror implementation) + * + * @param key the key of the property + * @return if the delete was successful or not + */ + public boolean delete(final Object key) { + return delete(key, getContext()._strict); + } + + /** * Return the size of the ScriptObject - i.e. the number of properties * it contains * (java.util.Map-like method to help ScriptObjectMirror implementation)
--- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Mon Jun 10 17:04:30 2013 -0700 @@ -40,6 +40,7 @@ import java.util.NoSuchElementException; import java.util.Objects; import jdk.internal.dynalink.beans.StaticClass; +import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.ir.debug.JSONWriter; import jdk.nashorn.internal.parser.Lexer; @@ -240,6 +241,10 @@ }; } + if (obj instanceof ScriptObjectMirror) { + return ((ScriptObjectMirror)obj).keySet().iterator(); + } + return Collections.emptyIterator(); } @@ -280,6 +285,10 @@ }; } + if (obj instanceof ScriptObjectMirror) { + return ((ScriptObjectMirror)obj).values().iterator(); + } + if (obj instanceof Iterable) { return ((Iterable<?>)obj).iterator(); } @@ -591,6 +600,10 @@ throw typeError("cant.delete.property", safeToString(property), "null"); } + if (obj instanceof ScriptObjectMirror) { + return ((ScriptObjectMirror)obj).delete(property); + } + if (JSType.isPrimitive(obj)) { return ((ScriptObject) JSType.toScriptObject(obj)).delete(property, Boolean.TRUE.equals(strict)); }
--- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Mon Jun 10 17:04:30 2013 -0700 @@ -32,9 +32,8 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; -import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.util.Map; @@ -165,36 +164,61 @@ // Start the process. final Process process = processBuilder.start(); + final IOException exception[] = new IOException[2]; + + // Collect output. + final StringBuilder outBuffer = new StringBuilder(); + Thread outThread = new Thread(new Runnable() { + @Override + public void run() { + char buffer[] = new char[1024]; + try (final InputStreamReader inputStream = new InputStreamReader(process.getInputStream())) { + for (int length; (length = inputStream.read(buffer, 0, buffer.length)) != -1; ) { + outBuffer.append(buffer, 0, length); + } + } catch (IOException ex) { + exception[0] = ex; + } + } + }, "$EXEC output"); + + // Collect errors. + final StringBuilder errBuffer = new StringBuilder(); + Thread errThread = new Thread(new Runnable() { + @Override + public void run() { + char buffer[] = new char[1024]; + try (final InputStreamReader inputStream = new InputStreamReader(process.getErrorStream())) { + for (int length; (length = inputStream.read(buffer, 0, buffer.length)) != -1; ) { + outBuffer.append(buffer, 0, length); + } + } catch (IOException ex) { + exception[1] = ex; + } + } + }, "$EXEC error"); + + // Start gathering output. + outThread.start(); + errThread.start(); // If input is present, pass on to process. - try (OutputStream outputStream = process.getOutputStream()) { + try (OutputStreamWriter outputStream = new OutputStreamWriter(process.getOutputStream())) { if (input != UNDEFINED) { - outputStream.write(JSType.toString(input).getBytes()); + String in = JSType.toString(input); + outputStream.write(in, 0, in.length()); } + } catch (IOException ex) { + // Process was not expecting input. May be normal state of affairs. } // Wait for the process to complete. final int exit = process.waitFor(); + outThread.join(); + errThread.join(); - // Collect output. - String out; - try (InputStream inputStream = process.getInputStream()) { - final StringBuilder outBuffer = new StringBuilder(); - for (int ch; (ch = inputStream.read()) != -1; ) { - outBuffer.append((char)ch); - } - out = outBuffer.toString(); - } - - // Collect errors. - String err; - try (InputStream errorStream = process.getErrorStream()) { - final StringBuilder errBuffer = new StringBuilder(); - for (int ch; (ch = errorStream.read()) != -1; ) { - errBuffer.append((char)ch); - } - err = errBuffer.toString(); - } + final String out = outBuffer.toString(); + final String err = errBuffer.toString(); // Set globals for secondary results. final boolean isStrict = global.isStrictContext(); @@ -202,6 +226,13 @@ global.set(ERR_NAME, err, isStrict); global.set(EXIT_NAME, exit, isStrict); + // Propagate exception if present. + for (int i = 0; i < exception.length; i++) { + if (exception[i] != null) { + throw exception[i]; + } + } + // Return the result from stdout. return out; }
--- a/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java Mon Jun 10 17:04:30 2013 -0700 @@ -36,7 +36,7 @@ protected final ScriptObject array; /** length of array */ - protected final int length; + protected final long length; /** * Constructor @@ -46,7 +46,7 @@ protected ArrayIterator(final ScriptObject array, final boolean includeUndefined) { super(includeUndefined); this.array = array; - this.length = (int) array.getArray().length(); + this.length = array.getArray().length(); } /** @@ -63,7 +63,7 @@ } @Override - public int getLength() { + public long getLength() { return length; }
--- a/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java Mon Jun 10 17:04:30 2013 -0700 @@ -38,7 +38,7 @@ abstract public class ArrayLikeIterator<T> implements Iterator<T> { /** current element index in iteration */ - protected int index; + protected long index; /** should undefined elements be included in the iteration? */ protected final boolean includeUndefined; @@ -65,7 +65,7 @@ * Go the the next valid element index of the iterator * @return next index */ - protected int bumpIndex() { + protected long bumpIndex() { return index++; } @@ -73,7 +73,7 @@ * Return the next valid element index of the iterator * @return next index */ - public int nextIndex() { + public long nextIndex() { return index; } @@ -86,7 +86,7 @@ * Get the length of the iteration * @return length */ - public abstract int getLength(); + public abstract long getLength(); /** * ArrayLikeIterator factory
--- a/src/jdk/nashorn/internal/runtime/arrays/EmptyArrayLikeIterator.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/EmptyArrayLikeIterator.java Mon Jun 10 17:04:30 2013 -0700 @@ -47,7 +47,7 @@ } @Override - public int getLength() { + public long getLength() { return 0; } }
--- a/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java Mon Jun 10 17:04:30 2013 -0700 @@ -49,7 +49,7 @@ protected T result; /** Current array index of iterator */ - protected int index; + protected long index; /** Iterator object */ private final ArrayLikeIterator<Object> iter; @@ -134,6 +134,6 @@ * * @throws Throwable if invocation throws an exception/error */ - protected abstract boolean forEach(final Object val, final int i) throws Throwable; + protected abstract boolean forEach(final Object val, final long i) throws Throwable; }
--- a/src/jdk/nashorn/internal/runtime/arrays/MapIterator.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/MapIterator.java Mon Jun 10 17:04:30 2013 -0700 @@ -49,8 +49,8 @@ } @Override - public int getLength() { - return (int) length; + public long getLength() { + return length; } @Override
--- a/src/jdk/nashorn/internal/runtime/arrays/ReverseArrayIterator.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/ReverseArrayIterator.java Mon Jun 10 17:04:30 2013 -0700 @@ -39,7 +39,7 @@ */ public ReverseArrayIterator(final ScriptObject array, final boolean includeUndefined) { super(array, includeUndefined); - this.index = (int) (array.getArray().length() - 1); + this.index = array.getArray().length() - 1; } @Override @@ -53,7 +53,7 @@ } @Override - protected int bumpIndex() { + protected long bumpIndex() { return index--; } }
--- a/src/jdk/nashorn/internal/runtime/arrays/ReverseMapIterator.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/ReverseMapIterator.java Mon Jun 10 17:04:30 2013 -0700 @@ -35,7 +35,7 @@ ReverseMapIterator(final ScriptObject obj, final boolean includeUndefined) { super(obj, includeUndefined); - this.index = JSType.toInt32(obj.getLength()) - 1; + this.index = JSType.toUint32(obj.getLength()) - 1; } @Override @@ -49,7 +49,7 @@ } @Override - protected int bumpIndex() { + protected long bumpIndex() { return index--; } }
--- a/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java Mon Jun 10 17:04:30 2013 -0700 @@ -23,23 +23,23 @@ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup; import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase; -import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType; import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.AnyCharNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode; +import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode.CCStateArg; import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.Node; import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode; -import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode.CCStateArg; import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType; import jdk.nashorn.internal.runtime.regexp.joni.constants.CCSTATE; import jdk.nashorn.internal.runtime.regexp.joni.constants.CCVALTYPE; import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType; import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType; import jdk.nashorn.internal.runtime.regexp.joni.constants.TokenType; +import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType; class Parser extends Lexer {
--- a/src/jdk/nashorn/internal/runtime/resources/fx/controls.js Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/resources/fx/controls.js Mon Jun 10 17:04:30 2013 -0700 @@ -70,7 +70,7 @@ CheckBoxTreeCell = Java.type("javafx.scene.control.cell.CheckBoxTreeCell"); CheckBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeCellBuilder"); CheckBoxTreeTableCell = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCell"); -CheckBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCellBuilder"); +//CheckBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCellBuilder"); ChoiceBoxListCell = Java.type("javafx.scene.control.cell.ChoiceBoxListCell"); ChoiceBoxListCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxListCellBuilder"); ChoiceBoxTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTableCell"); @@ -78,7 +78,7 @@ ChoiceBoxTreeCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCell"); ChoiceBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCellBuilder"); ChoiceBoxTreeTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCell"); -ChoiceBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCellBuilder"); +//ChoiceBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCellBuilder"); ComboBoxListCell = Java.type("javafx.scene.control.cell.ComboBoxListCell"); ComboBoxListCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxListCellBuilder"); ComboBoxTableCell = Java.type("javafx.scene.control.cell.ComboBoxTableCell"); @@ -86,7 +86,7 @@ ComboBoxTreeCell = Java.type("javafx.scene.control.cell.ComboBoxTreeCell"); ComboBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeCellBuilder"); ComboBoxTreeTableCell = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCell"); -ComboBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCellBuilder"); +//ComboBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCellBuilder"); MapValueFactory = Java.type("javafx.scene.control.cell.MapValueFactory"); ProgressBarTableCell = Java.type("javafx.scene.control.cell.ProgressBarTableCell"); ProgressBarTreeTableCell = Java.type("javafx.scene.control.cell.ProgressBarTreeTableCell"); @@ -99,9 +99,9 @@ TextFieldTreeCell = Java.type("javafx.scene.control.cell.TextFieldTreeCell"); TextFieldTreeCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeCellBuilder"); TextFieldTreeTableCell = Java.type("javafx.scene.control.cell.TextFieldTreeTableCell"); -TextFieldTreeTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeTableCellBuilder"); +//TextFieldTreeTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeTableCellBuilder"); TreeItemPropertyValueFactory = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactory"); -TreeItemPropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactoryBuilder"); +//TreeItemPropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactoryBuilder"); CellBuilder = Java.type("javafx.scene.control.CellBuilder"); CheckBox = Java.type("javafx.scene.control.CheckBox"); CheckBoxBuilder = Java.type("javafx.scene.control.CheckBoxBuilder"); @@ -167,7 +167,7 @@ RadioMenuItem = Java.type("javafx.scene.control.RadioMenuItem"); RadioMenuItemBuilder = Java.type("javafx.scene.control.RadioMenuItemBuilder"); ResizeFeaturesBase = Java.type("javafx.scene.control.ResizeFeaturesBase"); -ResizeFeaturesBaseBuilder = Java.type("javafx.scene.control.ResizeFeaturesBaseBuilder"); +//ResizeFeaturesBaseBuilder = Java.type("javafx.scene.control.ResizeFeaturesBaseBuilder"); ScrollBar = Java.type("javafx.scene.control.ScrollBar"); ScrollBarBuilder = Java.type("javafx.scene.control.ScrollBarBuilder"); ScrollPane = Java.type("javafx.scene.control.ScrollPane"); @@ -183,7 +183,7 @@ SingleSelectionModel = Java.type("javafx.scene.control.SingleSelectionModel"); Skin = Java.type("javafx.scene.control.Skin"); SkinBase = Java.type("javafx.scene.control.SkinBase"); -SkinBaseBuilder = Java.type("javafx.scene.control.SkinBaseBuilder"); +//SkinBaseBuilder = Java.type("javafx.scene.control.SkinBaseBuilder"); Skinnable = Java.type("javafx.scene.control.Skinnable"); Slider = Java.type("javafx.scene.control.Slider"); SliderBuilder = Java.type("javafx.scene.control.SliderBuilder"); @@ -202,7 +202,7 @@ TableColumn$CellEditEvent = Java.type("javafx.scene.control.TableColumn$CellEditEvent"); TableColumn$SortType = Java.type("javafx.scene.control.TableColumn$SortType"); TableColumnBase = Java.type("javafx.scene.control.TableColumnBase"); -TableColumnBaseBuilder = Java.type("javafx.scene.control.TableColumnBaseBuilder"); +//TableColumnBaseBuilder = Java.type("javafx.scene.control.TableColumnBaseBuilder"); TableColumnBuilder = Java.type("javafx.scene.control.TableColumnBuilder"); TableFocusModel = Java.type("javafx.scene.control.TableFocusModel"); TablePosition = Java.type("javafx.scene.control.TablePosition"); @@ -210,7 +210,7 @@ TableRow = Java.type("javafx.scene.control.TableRow"); TableRowBuilder = Java.type("javafx.scene.control.TableRowBuilder"); TableSelectionModel = Java.type("javafx.scene.control.TableSelectionModel"); -TableSelectionModelBuilder = Java.type("javafx.scene.control.TableSelectionModelBuilder"); +//TableSelectionModelBuilder = Java.type("javafx.scene.control.TableSelectionModelBuilder"); TableView = Java.type("javafx.scene.control.TableView"); TableView$ResizeFeatures = Java.type("javafx.scene.control.TableView$ResizeFeatures"); TableView$TableViewFocusModel = Java.type("javafx.scene.control.TableView$TableViewFocusModel"); @@ -244,21 +244,21 @@ TreeItemBuilder = Java.type("javafx.scene.control.TreeItemBuilder"); TreeSortMode = Java.type("javafx.scene.control.TreeSortMode"); TreeTableCell = Java.type("javafx.scene.control.TreeTableCell"); -TreeTableCellBuilder = Java.type("javafx.scene.control.TreeTableCellBuilder"); +//TreeTableCellBuilder = Java.type("javafx.scene.control.TreeTableCellBuilder"); TreeTableColumn = Java.type("javafx.scene.control.TreeTableColumn"); TreeTableColumn$CellDataFeatures = Java.type("javafx.scene.control.TreeTableColumn$CellDataFeatures"); TreeTableColumn$CellEditEvent = Java.type("javafx.scene.control.TreeTableColumn$CellEditEvent"); TreeTableColumn$SortType = Java.type("javafx.scene.control.TreeTableColumn$SortType"); -TreeTableColumnBuilder = Java.type("javafx.scene.control.TreeTableColumnBuilder"); +//TreeTableColumnBuilder = Java.type("javafx.scene.control.TreeTableColumnBuilder"); TreeTablePosition = Java.type("javafx.scene.control.TreeTablePosition"); TreeTableRow = Java.type("javafx.scene.control.TreeTableRow"); -TreeTableRowBuilder = Java.type("javafx.scene.control.TreeTableRowBuilder"); +//TreeTableRowBuilder = Java.type("javafx.scene.control.TreeTableRowBuilder"); TreeTableView = Java.type("javafx.scene.control.TreeTableView"); TreeTableView$EditEvent = Java.type("javafx.scene.control.TreeTableView$EditEvent"); TreeTableView$ResizeFeatures = Java.type("javafx.scene.control.TreeTableView$ResizeFeatures"); TreeTableView$TreeTableViewFocusModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewFocusModel"); TreeTableView$TreeTableViewSelectionModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewSelectionModel"); -TreeTableViewBuilder = Java.type("javafx.scene.control.TreeTableViewBuilder"); +//TreeTableViewBuilder = Java.type("javafx.scene.control.TreeTableViewBuilder"); TreeView = Java.type("javafx.scene.control.TreeView"); TreeView$EditEvent = Java.type("javafx.scene.control.TreeView$EditEvent"); TreeViewBuilder = Java.type("javafx.scene.control.TreeViewBuilder");
--- a/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js Mon Jun 10 17:04:30 2013 -0700 @@ -134,10 +134,10 @@ PrintResolution = Java.type("javafx.print.PrintResolution"); PrintSides = Java.type("javafx.print.PrintSides"); AmbientLight = Java.type("javafx.scene.AmbientLight"); -AmbientLightBuilder = Java.type("javafx.scene.AmbientLightBuilder"); +//AmbientLightBuilder = Java.type("javafx.scene.AmbientLightBuilder"); CacheHint = Java.type("javafx.scene.CacheHint"); Camera = Java.type("javafx.scene.Camera"); -CameraBuilder = Java.type("javafx.scene.CameraBuilder"); +//CameraBuilder = Java.type("javafx.scene.CameraBuilder"); Canvas = Java.type("javafx.scene.canvas.Canvas"); CanvasBuilder = Java.type("javafx.scene.canvas.CanvasBuilder"); GraphicsContext = Java.type("javafx.scene.canvas.GraphicsContext"); @@ -209,12 +209,12 @@ DragEvent = Java.type("javafx.scene.input.DragEvent"); GestureEvent = Java.type("javafx.scene.input.GestureEvent"); InputEvent = Java.type("javafx.scene.input.InputEvent"); -InputEventBuilder = Java.type("javafx.scene.input.InputEventBuilder"); +//InputEventBuilder = Java.type("javafx.scene.input.InputEventBuilder"); InputMethodEvent = Java.type("javafx.scene.input.InputMethodEvent"); InputMethodHighlight = Java.type("javafx.scene.input.InputMethodHighlight"); InputMethodRequests = Java.type("javafx.scene.input.InputMethodRequests"); InputMethodTextRun = Java.type("javafx.scene.input.InputMethodTextRun"); -InputMethodTextRunBuilder = Java.type("javafx.scene.input.InputMethodTextRunBuilder"); +//InputMethodTextRunBuilder = Java.type("javafx.scene.input.InputMethodTextRunBuilder"); KeyCharacterCombination = Java.type("javafx.scene.input.KeyCharacterCombination"); KeyCharacterCombinationBuilder = Java.type("javafx.scene.input.KeyCharacterCombinationBuilder"); KeyCode = Java.type("javafx.scene.input.KeyCode"); @@ -238,35 +238,35 @@ TouchEvent = Java.type("javafx.scene.input.TouchEvent"); TouchPoint = Java.type("javafx.scene.input.TouchPoint"); TouchPoint$State = Java.type("javafx.scene.input.TouchPoint$State"); -TouchPointBuilder = Java.type("javafx.scene.input.TouchPointBuilder"); +//TouchPointBuilder = Java.type("javafx.scene.input.TouchPointBuilder"); TransferMode = Java.type("javafx.scene.input.TransferMode"); ZoomEvent = Java.type("javafx.scene.input.ZoomEvent"); AnchorPane = Java.type("javafx.scene.layout.AnchorPane"); AnchorPaneBuilder = Java.type("javafx.scene.layout.AnchorPaneBuilder"); Background = Java.type("javafx.scene.layout.Background"); -BackgroundBuilder = Java.type("javafx.scene.layout.BackgroundBuilder"); +//BackgroundBuilder = Java.type("javafx.scene.layout.BackgroundBuilder"); BackgroundFill = Java.type("javafx.scene.layout.BackgroundFill"); -BackgroundFillBuilder = Java.type("javafx.scene.layout.BackgroundFillBuilder"); +//BackgroundFillBuilder = Java.type("javafx.scene.layout.BackgroundFillBuilder"); BackgroundImage = Java.type("javafx.scene.layout.BackgroundImage"); -BackgroundImageBuilder = Java.type("javafx.scene.layout.BackgroundImageBuilder"); +//BackgroundImageBuilder = Java.type("javafx.scene.layout.BackgroundImageBuilder"); BackgroundPosition = Java.type("javafx.scene.layout.BackgroundPosition"); -BackgroundPositionBuilder = Java.type("javafx.scene.layout.BackgroundPositionBuilder"); +//BackgroundPositionBuilder = Java.type("javafx.scene.layout.BackgroundPositionBuilder"); BackgroundRepeat = Java.type("javafx.scene.layout.BackgroundRepeat"); BackgroundSize = Java.type("javafx.scene.layout.BackgroundSize"); -BackgroundSizeBuilder = Java.type("javafx.scene.layout.BackgroundSizeBuilder"); +//BackgroundSizeBuilder = Java.type("javafx.scene.layout.BackgroundSizeBuilder"); Border = Java.type("javafx.scene.layout.Border"); -BorderBuilder = Java.type("javafx.scene.layout.BorderBuilder"); +//BorderBuilder = Java.type("javafx.scene.layout.BorderBuilder"); BorderImage = Java.type("javafx.scene.layout.BorderImage"); -BorderImageBuilder = Java.type("javafx.scene.layout.BorderImageBuilder"); +//BorderImageBuilder = Java.type("javafx.scene.layout.BorderImageBuilder"); BorderPane = Java.type("javafx.scene.layout.BorderPane"); BorderPaneBuilder = Java.type("javafx.scene.layout.BorderPaneBuilder"); BorderRepeat = Java.type("javafx.scene.layout.BorderRepeat"); BorderStroke = Java.type("javafx.scene.layout.BorderStroke"); -BorderStrokeBuilder = Java.type("javafx.scene.layout.BorderStrokeBuilder"); +//BorderStrokeBuilder = Java.type("javafx.scene.layout.BorderStrokeBuilder"); BorderStrokeStyle = Java.type("javafx.scene.layout.BorderStrokeStyle"); -BorderStrokeStyleBuilder = Java.type("javafx.scene.layout.BorderStrokeStyleBuilder"); +//BorderStrokeStyleBuilder = Java.type("javafx.scene.layout.BorderStrokeStyleBuilder"); BorderWidths = Java.type("javafx.scene.layout.BorderWidths"); -BorderWidthsBuilder = Java.type("javafx.scene.layout.BorderWidthsBuilder"); +//BorderWidthsBuilder = Java.type("javafx.scene.layout.BorderWidthsBuilder"); ColumnConstraints = Java.type("javafx.scene.layout.ColumnConstraints"); ColumnConstraintsBuilder = Java.type("javafx.scene.layout.ColumnConstraintsBuilder"); ConstraintsBase = Java.type("javafx.scene.layout.ConstraintsBase"); @@ -291,7 +291,7 @@ VBox = Java.type("javafx.scene.layout.VBox"); VBoxBuilder = Java.type("javafx.scene.layout.VBoxBuilder"); LightBase = Java.type("javafx.scene.LightBase"); -LightBaseBuilder = Java.type("javafx.scene.LightBaseBuilder"); +//LightBaseBuilder = Java.type("javafx.scene.LightBaseBuilder"); Node = Java.type("javafx.scene.Node"); NodeBuilder = Java.type("javafx.scene.NodeBuilder"); Color = Java.type("javafx.scene.paint.Color"); @@ -304,19 +304,19 @@ Material = Java.type("javafx.scene.paint.Material"); Paint = Java.type("javafx.scene.paint.Paint"); PhongMaterial = Java.type("javafx.scene.paint.PhongMaterial"); -PhongMaterialBuilder = Java.type("javafx.scene.paint.PhongMaterialBuilder"); +//PhongMaterialBuilder = Java.type("javafx.scene.paint.PhongMaterialBuilder"); RadialGradient = Java.type("javafx.scene.paint.RadialGradient"); RadialGradientBuilder = Java.type("javafx.scene.paint.RadialGradientBuilder"); Stop = Java.type("javafx.scene.paint.Stop"); StopBuilder = Java.type("javafx.scene.paint.StopBuilder"); ParallelCamera = Java.type("javafx.scene.ParallelCamera"); -ParallelCameraBuilder = Java.type("javafx.scene.ParallelCameraBuilder"); +//ParallelCameraBuilder = Java.type("javafx.scene.ParallelCameraBuilder"); Parent = Java.type("javafx.scene.Parent"); ParentBuilder = Java.type("javafx.scene.ParentBuilder"); PerspectiveCamera = Java.type("javafx.scene.PerspectiveCamera"); PerspectiveCameraBuilder = Java.type("javafx.scene.PerspectiveCameraBuilder"); PointLight = Java.type("javafx.scene.PointLight"); -PointLightBuilder = Java.type("javafx.scene.PointLightBuilder"); +//PointLightBuilder = Java.type("javafx.scene.PointLightBuilder"); //Scene = Java.type("javafx.scene.Scene"); SceneBuilder = Java.type("javafx.scene.SceneBuilder"); Arc = Java.type("javafx.scene.shape.Arc"); @@ -325,7 +325,7 @@ ArcToBuilder = Java.type("javafx.scene.shape.ArcToBuilder"); ArcType = Java.type("javafx.scene.shape.ArcType"); Box = Java.type("javafx.scene.shape.Box"); -BoxBuilder = Java.type("javafx.scene.shape.BoxBuilder"); +//BoxBuilder = Java.type("javafx.scene.shape.BoxBuilder"); Circle = Java.type("javafx.scene.shape.Circle"); CircleBuilder = Java.type("javafx.scene.shape.CircleBuilder"); ClosePath = Java.type("javafx.scene.shape.ClosePath"); @@ -336,7 +336,7 @@ CubicCurveToBuilder = Java.type("javafx.scene.shape.CubicCurveToBuilder"); CullFace = Java.type("javafx.scene.shape.CullFace"); Cylinder = Java.type("javafx.scene.shape.Cylinder"); -CylinderBuilder = Java.type("javafx.scene.shape.CylinderBuilder"); +//CylinderBuilder = Java.type("javafx.scene.shape.CylinderBuilder"); DrawMode = Java.type("javafx.scene.shape.DrawMode"); Ellipse = Java.type("javafx.scene.shape.Ellipse"); EllipseBuilder = Java.type("javafx.scene.shape.EllipseBuilder"); @@ -349,7 +349,7 @@ LineToBuilder = Java.type("javafx.scene.shape.LineToBuilder"); Mesh = Java.type("javafx.scene.shape.Mesh"); MeshView = Java.type("javafx.scene.shape.MeshView"); -MeshViewBuilder = Java.type("javafx.scene.shape.MeshViewBuilder"); +//MeshViewBuilder = Java.type("javafx.scene.shape.MeshViewBuilder"); MoveTo = Java.type("javafx.scene.shape.MoveTo"); MoveToBuilder = Java.type("javafx.scene.shape.MoveToBuilder"); Path = Java.type("javafx.scene.shape.Path"); @@ -368,10 +368,10 @@ RectangleBuilder = Java.type("javafx.scene.shape.RectangleBuilder"); Shape = Java.type("javafx.scene.shape.Shape"); Shape3D = Java.type("javafx.scene.shape.Shape3D"); -Shape3DBuilder = Java.type("javafx.scene.shape.Shape3DBuilder"); +//Shape3DBuilder = Java.type("javafx.scene.shape.Shape3DBuilder"); ShapeBuilder = Java.type("javafx.scene.shape.ShapeBuilder"); Sphere = Java.type("javafx.scene.shape.Sphere"); -SphereBuilder = Java.type("javafx.scene.shape.SphereBuilder"); +//SphereBuilder = Java.type("javafx.scene.shape.SphereBuilder"); StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap"); StrokeLineJoin = Java.type("javafx.scene.shape.StrokeLineJoin"); StrokeType = Java.type("javafx.scene.shape.StrokeType"); @@ -384,7 +384,7 @@ SnapshotParametersBuilder = Java.type("javafx.scene.SnapshotParametersBuilder"); SnapshotResult = Java.type("javafx.scene.SnapshotResult"); SubScene = Java.type("javafx.scene.SubScene"); -SubSceneBuilder = Java.type("javafx.scene.SubSceneBuilder"); +//SubSceneBuilder = Java.type("javafx.scene.SubSceneBuilder"); Font = Java.type("javafx.scene.text.Font"); FontBuilder = Java.type("javafx.scene.text.FontBuilder"); FontPosture = Java.type("javafx.scene.text.FontPosture"); @@ -395,7 +395,7 @@ TextBoundsType = Java.type("javafx.scene.text.TextBoundsType"); TextBuilder = Java.type("javafx.scene.text.TextBuilder"); TextFlow = Java.type("javafx.scene.text.TextFlow"); -TextFlowBuilder = Java.type("javafx.scene.text.TextFlowBuilder"); +//TextFlowBuilder = Java.type("javafx.scene.text.TextFlowBuilder"); Affine = Java.type("javafx.scene.transform.Affine"); AffineBuilder = Java.type("javafx.scene.transform.AffineBuilder"); MatrixType = Java.type("javafx.scene.transform.MatrixType"); @@ -407,7 +407,7 @@ Shear = Java.type("javafx.scene.transform.Shear"); ShearBuilder = Java.type("javafx.scene.transform.ShearBuilder"); Transform = Java.type("javafx.scene.transform.Transform"); -TransformBuilder = Java.type("javafx.scene.transform.TransformBuilder"); +//TransformBuilder = Java.type("javafx.scene.transform.TransformBuilder"); TransformChangedEvent = Java.type("javafx.scene.transform.TransformChangedEvent"); Translate = Java.type("javafx.scene.transform.Translate"); TranslateBuilder = Java.type("javafx.scene.transform.TranslateBuilder");
--- a/src/jdk/nashorn/internal/runtime/resources/fx/swt.js Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/resources/fx/swt.js Mon Jun 10 17:04:30 2013 -0700 @@ -24,6 +24,6 @@ */ CustomTransfer = Java.type("javafx.embed.swt.CustomTransfer"); -CustomTransferBuilder = Java.type("javafx.embed.swt.CustomTransferBuilder"); +//CustomTransferBuilder = Java.type("javafx.embed.swt.CustomTransferBuilder"); FXCanvas = Java.type("javafx.embed.swt.FXCanvas"); SWTFXUtils = Java.type("javafx.embed.swt.SWTFXUtils");
--- a/src/jdk/nashorn/internal/runtime/resources/fx/web.js Thu Jun 06 20:48:44 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/resources/fx/web.js Mon Jun 10 17:04:30 2013 -0700 @@ -24,10 +24,10 @@ */ HTMLEditor = Java.type("javafx.scene.web.HTMLEditor"); -HTMLEditorBuilder = Java.type("javafx.scene.web.HTMLEditorBuilder"); +//HTMLEditorBuilder = Java.type("javafx.scene.web.HTMLEditorBuilder"); PopupFeatures = Java.type("javafx.scene.web.PopupFeatures"); PromptData = Java.type("javafx.scene.web.PromptData"); -PromptDataBuilder = Java.type("javafx.scene.web.PromptDataBuilder"); +//PromptDataBuilder = Java.type("javafx.scene.web.PromptDataBuilder"); WebEngine = Java.type("javafx.scene.web.WebEngine"); WebEngineBuilder = Java.type("javafx.scene.web.WebEngineBuilder"); WebEvent = Java.type("javafx.scene.web.WebEvent");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8012164.js Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,55 @@ +/* + * 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-8012164: Error.stack needs trimming + * + * @test + * @run + */ + +function func() { + error(); +} + +function error() { + try { + throw new Error('foo'); + } catch (e) { + for (i in e.stack) { + printFrame(e.stack[i]); + } + } +} + +func(); + +// See JDK-8015855: test/script/basic/JDK-8012164.js fails on Windows +// Replace '\' to '/' in class and file names of StackFrameElement objects +function printFrame(stack) { + var fileName = stack.fileName.replace(/\\/g, '/'); + var className = stack.className.replace(/\\/g, '/'); + print(className + '.' + stack.methodName + '(' + + fileName + ':' + stack.lineNumber + ')'); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8012164.js.EXPECTED Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,3 @@ +<test/script/basic/JDK-8012164.js>.error(test/script/basic/JDK-8012164.js:38) +<test/script/basic/JDK-8012164.js>.func(test/script/basic/JDK-8012164.js:33) +<test/script/basic/JDK-8012164.js>.<program>(test/script/basic/JDK-8012164.js:46)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015345.js Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,64 @@ +/* + * 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-8015345: Function("}),print('test'),({") should throw SyntaxError + * + * @test + * @run + */ + +function checkFunction(code) { + try { + Function(code); + fail("should have thrown SyntaxError for :" + code); + } catch (e) { + if (! (e instanceof SyntaxError)) { + fail("SyntaxError expected, but got " + e); + } + print(e); + } +} + +// invalid body +checkFunction("}),print('test'),({"); + +// invalid param list +checkFunction("x**y", "print('x')"); + +// invalid param identifier +checkFunction("in", "print('hello')"); +//checkFunction("<>", "print('hello')") + +// invalid param list and body +checkFunction("x--y", ")"); + +// check few valid cases as well +var f = Function("x", "return x*x"); +print(f(10)) + +f = Function("x", "y", "return x+y"); +print(f(33, 22)); + +f = Function("x,y", "return x/y"); +print(f(24, 2));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015345.js.EXPECTED Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,15 @@ +SyntaxError: <function>:1:0 Expected eof but found } +}),print('test'),({ +^ +SyntaxError: <function>:1:2 Expected an operand but found * +x**y + ^ +SyntaxError: <function>:1:0 Expected an operand but found in +in +^ +SyntaxError: <function>:1:3 Expected ; but found y +x--y + ^ +100 +55 +12
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015350.js Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8015350: Array.prototype.reduceRight issue with large length and index + * + * @test + * @run + */ + +function reduce(obj) { + try { + Array.prototype.reduceRight.call(obj, function(acc, v, i, o){ + print(v + i); + throw "stop"; + }, 0); + } catch (error) { + print(error); + } +} + +// array-like object +reduce({ + length:0xffffffff, + 0xfffffffe: "index: " +}); + +// actual sparse array +var array = []; +array[0xfffffffe] = "index: "; +reduce(array);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015350.js.EXPECTED Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,4 @@ +index: 4294967294 +stop +index: 4294967294 +stop
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015353.js Mon Jun 10 17:04:30 2013 -0700 @@ -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-8015353: Date.parse illegal string parsing issues + * + * @test + * @run + */ + +function checkDate(str) { + if (! isNaN(Date.parse(str))) { + fail(str + " is parsed as legal Date"); + } +} + +checkDate("2012-01-10T00:00:00.000-"); +checkDate("2012-01-01T00:00+");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015741.js Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,57 @@ +/* + * 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-8015741 : Need a global.load function that starts with a new global scope. + * + * @test + * @run + */ + +var Thread = java.lang.Thread; + +myGlobal = "#0"; +var script1 = {name: "script 1", script: 'myGlobal = "#1"; print(myGlobal);'}; +var script2 = {name: "script 2", script: 'myGlobal = "#2"; print(myGlobal);'}; +var script3 = {name: "script 3", script: 'myGlobal = "#3"; print(myGlobal);'}; +var script4 = {name: "script 4", script: 'myGlobal = "#4"; print(myGlobal);'}; + +print(myGlobal); +load(script1); +print(myGlobal); + +print(myGlobal); +var thread1 = new Thread(function() { load(script2); }); +thread1.start(); +thread1.join(); +print(myGlobal); + +print(myGlobal); +loadWithNewGlobal(script3); +print(myGlobal); + +print(myGlobal); +var thread2 = new Thread(function() { loadWithNewGlobal(script4); }); +thread2.start(); +thread2.join(); +print(myGlobal);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015741.js.EXPECTED Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,12 @@ +#0 +#1 +#1 +#1 +#2 +#2 +#2 +#3 +#2 +#2 +#4 +#2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015830.js Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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-8015830: Javascript mapping of ScriptEngine bindings does not expose keys + * + * @test + * @run + */ + +var m = new javax.script.ScriptEngineManager(); +var engine = m.getEngineByName("nashorn"); + +engine.eval("x = 100; doit = function () { }"); + +var global = engine.getBindings(javax.script.ScriptContext.ENGINE_SCOPE); + +for(k in global){ + print(k + " = " + global[k]); +} + +for each (k in global) { + print(k); +} + +for(k in global) { + delete global[k]; +} + +for(k in global){ + print(k + " = " + global[k]); +} + +for each(k in global) { + print(k); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015830.js.EXPECTED Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,4 @@ +x = 100 +doit = function () { } +100 +function () { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015945.js Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,55 @@ +/* + * 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-8015945: loadWithNewGlobal return value has to be properly wrapped + * + * @test + * @option -scripting + * @run + */ + +var global = loadWithNewGlobal({ name: "<code>", + script: <<EOF + +function squares() { + var res = new Array(arguments.length); + for (var i in arguments) { + res[i] = arguments[i]*arguments[i] + } + return res; +} + +this; + +EOF +}) + +print("global an Object? " + (global instanceof Object)); +var res = global.squares(2, 3, 4, 5); +print("global.squares returns Array? " + (res instanceof Array)); +// still can access array index properties and length +print("result length " + res.length); +for (var i in res) { + print(i + " = " + res[i]); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015945.js.EXPECTED Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,7 @@ +global an Object? false +global.squares returns Array? false +result length 4 +0 = 4 +1 = 9 +2 = 16 +3 = 25
--- a/test/script/basic/NASHORN-108.js.EXPECTED Thu Jun 06 20:48:44 2013 -0700 +++ b/test/script/basic/NASHORN-108.js.EXPECTED Mon Jun 10 17:04:30 2013 -0700 @@ -1,3 +1,3 @@ -runScript 33 -runScript 32 +<program> 33 +<program> 32 done
--- a/test/script/basic/NASHORN-109.js.EXPECTED Thu Jun 06 20:48:44 2013 -0700 +++ b/test/script/basic/NASHORN-109.js.EXPECTED Mon Jun 10 17:04:30 2013 -0700 @@ -1,2 +1,2 @@ -runScript 33 +<program> 33 done
--- a/test/script/basic/errorstack.js.EXPECTED Thu Jun 06 20:48:44 2013 -0700 +++ b/test/script/basic/errorstack.js.EXPECTED Mon Jun 10 17:04:30 2013 -0700 @@ -1,4 +1,4 @@ func3 : 40 func2 : 36 func1 : 32 -runScript : 44 +<program> : 44
--- a/test/script/basic/funcconstructor.js.EXPECTED Thu Jun 06 20:48:44 2013 -0700 +++ b/test/script/basic/funcconstructor.js.EXPECTED Mon Jun 10 17:04:30 2013 -0700 @@ -4,7 +4,7 @@ print('anon func'); return x*x; } syntax error? true -SyntaxError: <function>:2:13 Missing close quote +SyntaxError: <function>:1:13 Missing close quote print('hello) ^ done
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/typedarrays.js Mon Jun 10 17:04:30 2013 -0700 @@ -0,0 +1,96 @@ +/* + * 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. + */ + +/** + * typedarray test. + * + * @test + * @run + */ + + +var typeDefinitions = [ +Int8Array, +Uint8Array, +Uint8ClampedArray, +Int16Array, +Uint16Array, +Int32Array, +Uint32Array, +Float32Array, +Float64Array, +]; + +var mem1 = new ArrayBuffer(1024); +mem1.byteLength; +mem1.slice(512); +mem1.slice(512, 748); + +var size = 128; +var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; +var arr2 = [99, 89]; +var partial = []; +var all = []; + +typeDefinitions.forEach(function(arrayDef) { + var p = arrayDef.prototype; + var sub = []; + sub.push(new arrayDef(mem1, arrayDef.BYTES_PER_ELEMENT, 3)); + sub.push(new arrayDef(size)); + sub.push(new arrayDef(arr)); + //push the instances, they will be reused to do instance based construction + partial.push({ + instances:sub, + type:arrayDef + }); + + all.concat(all, sub); + +}); + +partial.forEach(function(inst) { + // build new instances with TypeArray instance as parameter. + partial.forEach(function(other) { + other.instances.forEach(function(otherInstance) { + var ii = new inst.type(otherInstance); + all.push(ii); + }); + }) +}); + +all.forEach(function(instance) { + // cover instance props and functions + var arr = Object.getOwnPropertyNames(instance); + arr.forEach(function(p) { + var val = instance[p]; + if(!isNaN(p)){ + val[p] = 99; + } + }); + + instance.set(instance, 0); + instance.set(instance); + instance.set(arr2); + instance.subarray(5, 9); + instance.subarray(5); +});