mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-14 00:49:42 +00:00
Merge
This commit is contained in:
commit
424252851f
@ -31,7 +31,7 @@ import java.util.AbstractMap;
|
||||
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 @@ import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
* 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 @@ final class ScriptObjectMirror extends JSObject implements Bindings {
|
||||
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 @@ final class ScriptObjectMirror extends JSObject implements Bindings {
|
||||
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 @@ final class ScriptObjectMirror extends JSObject implements Bindings {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ final class ScriptObjectMirror extends JSObject implements Bindings {
|
||||
});
|
||||
}
|
||||
|
||||
// package-privates below this.
|
||||
ScriptObject getScriptObject() {
|
||||
return sobj;
|
||||
}
|
||||
|
||||
static Object translateUndefined(Object obj) {
|
||||
return (obj == ScriptRuntime.UNDEFINED)? null : obj;
|
||||
}
|
||||
// These are public only so that Context can access these.
|
||||
|
||||
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 @@ final class ScriptObjectMirror extends JSObject implements Bindings {
|
||||
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 @@ final class ScriptObjectMirror extends JSObject implements Bindings {
|
||||
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 @@ final class ScriptObjectMirror extends JSObject implements Bindings {
|
||||
}
|
||||
return newArgs;
|
||||
}
|
||||
|
||||
// package-privates below this.
|
||||
ScriptObject getScriptObject() {
|
||||
return sobj;
|
||||
}
|
||||
|
||||
static Object translateUndefined(Object obj) {
|
||||
return (obj == ScriptRuntime.UNDEFINED)? null : obj;
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,13 +84,12 @@ import jdk.nashorn.internal.ir.TryNode;
|
||||
import jdk.nashorn.internal.ir.UnaryNode;
|
||||
import jdk.nashorn.internal.ir.VarNode;
|
||||
import jdk.nashorn.internal.ir.WithNode;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||
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 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
@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 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
}
|
||||
|
||||
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()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -60,7 +60,6 @@ import java.util.LinkedList;
|
||||
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.EmptyNode;
|
||||
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 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -941,11 +941,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
* bootstrap code for object
|
||||
*/
|
||||
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);
|
||||
@ -1356,11 +1351,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -29,6 +29,7 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||
|
||||
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 @@ public enum CompilerConstants {
|
||||
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"),
|
||||
|
||||
@ -144,15 +144,6 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator {
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -165,13 +156,6 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator {
|
||||
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));
|
||||
}
|
||||
|
||||
@ -59,12 +59,10 @@ import jdk.nashorn.internal.lookup.MethodHandleFactory;
|
||||
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 final class RuntimeCallSite extends MutableCallSite {
|
||||
*/
|
||||
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 @@ public final class RuntimeCallSite extends MutableCallSite {
|
||||
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()) {
|
||||
@ -338,18 +335,12 @@ public final class RuntimeCallSite extends MutableCallSite {
|
||||
*
|
||||
* @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;
|
||||
|
||||
|
||||
@ -28,7 +28,6 @@ package jdk.nashorn.internal.ir;
|
||||
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 @@ public abstract class LiteralNode<T> extends Node implements PropertyKey {
|
||||
*
|
||||
* @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 @@ public abstract class LiteralNode<T> extends Node implements PropertyKey {
|
||||
*
|
||||
* @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 @@ public abstract class LiteralNode<T> extends Node implements PropertyKey {
|
||||
return new LexerTokenLiteralNode(parent.getToken(), parent.getFinish(), value);
|
||||
}
|
||||
|
||||
private static final class NodeLiteralNode extends LiteralNode<Node> {
|
||||
private static final class NullLiteralNode extends LiteralNode<Object> {
|
||||
|
||||
private NodeLiteralNode(final long token, final int finish) {
|
||||
this(token, finish, null);
|
||||
}
|
||||
|
||||
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 @@ public abstract class LiteralNode<T> extends Node implements PropertyKey {
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -119,6 +119,10 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
@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 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
// 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;
|
||||
|
||||
@ -742,6 +747,21 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
return global.context.load(scope, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
@ -1387,6 +1407,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
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 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
@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();
|
||||
|
||||
@ -39,6 +39,7 @@ import jdk.nashorn.internal.objects.annotations.Function;
|
||||
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;
|
||||
|
||||
@ -32,6 +32,7 @@ import java.lang.invoke.MethodHandle;
|
||||
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 @@ public final class NativeError extends ScriptObject {
|
||||
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();
|
||||
|
||||
@ -33,10 +33,14 @@ import jdk.nashorn.internal.objects.annotations.Attribute;
|
||||
import jdk.nashorn.internal.objects.annotations.Constructor;
|
||||
import jdk.nashorn.internal.objects.annotations.Function;
|
||||
import jdk.nashorn.internal.objects.annotations.ScriptClass;
|
||||
import jdk.nashorn.internal.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 @@ public final class NativeFunction {
|
||||
|
||||
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 @@ public final class NativeFunction {
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.nashorn.internal.objects;
|
||||
package jdk.nashorn.internal.parser;
|
||||
|
||||
import static java.lang.Character.DECIMAL_DIGIT_NUMBER;
|
||||
import static java.lang.Character.LOWERCASE_LETTER;
|
||||
@ -196,6 +196,11 @@ public class DateParser {
|
||||
break;
|
||||
|
||||
case SIGN:
|
||||
if (peek() == -1) {
|
||||
// END after sign - wrong!
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentField == YEAR) {
|
||||
yearSign = numValue;
|
||||
} else if (currentField < SECOND || !setTimezone(readTimeZoneOffset(), true)) {
|
||||
@ -297,6 +302,11 @@ public class DateParser {
|
||||
break;
|
||||
|
||||
case SIGN:
|
||||
if (peek() == -1) {
|
||||
// END after sign - wrong!
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!setTimezone(readTimeZoneOffset(), true)) {
|
||||
return false;
|
||||
}
|
||||
@ -192,36 +192,110 @@ public class Parser extends AbstractParser {
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2424,12 +2498,29 @@ loop:
|
||||
* @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);
|
||||
|
||||
@ -48,6 +48,7 @@ import java.security.PrivilegedAction;
|
||||
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;
|
||||
@ -490,6 +491,40 @@ public final class Context {
|
||||
throw typeError("cant.load.script", ScriptRuntime.safeToString(from));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, RuntimeException {
|
||||
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
|
||||
|
||||
@ -1511,6 +1511,17 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a property from the ScriptObject.
|
||||
* (to help ScriptObjectMirror implementation)
|
||||
*
|
||||
* @param key the key of the property
|
||||
* @return if the delete was successful or not
|
||||
*/
|
||||
public boolean delete(final Object key) {
|
||||
return delete(key, getContext()._strict);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the ScriptObject - i.e. the number of properties
|
||||
* it contains
|
||||
|
||||
@ -40,6 +40,7 @@ import java.util.Locale;
|
||||
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 @@ public final class ScriptRuntime {
|
||||
};
|
||||
}
|
||||
|
||||
if (obj instanceof ScriptObjectMirror) {
|
||||
return ((ScriptObjectMirror)obj).keySet().iterator();
|
||||
}
|
||||
|
||||
return Collections.emptyIterator();
|
||||
}
|
||||
|
||||
@ -280,6 +285,10 @@ public final class ScriptRuntime {
|
||||
};
|
||||
}
|
||||
|
||||
if (obj instanceof ScriptObjectMirror) {
|
||||
return ((ScriptObjectMirror)obj).values().iterator();
|
||||
}
|
||||
|
||||
if (obj instanceof Iterable) {
|
||||
return ((Iterable<?>)obj).iterator();
|
||||
}
|
||||
@ -591,6 +600,10 @@ public final class ScriptRuntime {
|
||||
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));
|
||||
}
|
||||
|
||||
55
nashorn/test/script/basic/JDK-8012164.js
Normal file
55
nashorn/test/script/basic/JDK-8012164.js
Normal file
@ -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 + ')');
|
||||
}
|
||||
3
nashorn/test/script/basic/JDK-8012164.js.EXPECTED
Normal file
3
nashorn/test/script/basic/JDK-8012164.js.EXPECTED
Normal file
@ -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)
|
||||
64
nashorn/test/script/basic/JDK-8015345.js
Normal file
64
nashorn/test/script/basic/JDK-8015345.js
Normal file
@ -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));
|
||||
15
nashorn/test/script/basic/JDK-8015345.js.EXPECTED
Normal file
15
nashorn/test/script/basic/JDK-8015345.js.EXPECTED
Normal file
@ -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
|
||||
38
nashorn/test/script/basic/JDK-8015353.js
Normal file
38
nashorn/test/script/basic/JDK-8015353.js
Normal file
@ -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+");
|
||||
57
nashorn/test/script/basic/JDK-8015741.js
Normal file
57
nashorn/test/script/basic/JDK-8015741.js
Normal file
@ -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);
|
||||
12
nashorn/test/script/basic/JDK-8015741.js.EXPECTED
Normal file
12
nashorn/test/script/basic/JDK-8015741.js.EXPECTED
Normal file
@ -0,0 +1,12 @@
|
||||
#0
|
||||
#1
|
||||
#1
|
||||
#1
|
||||
#2
|
||||
#2
|
||||
#2
|
||||
#3
|
||||
#2
|
||||
#2
|
||||
#4
|
||||
#2
|
||||
56
nashorn/test/script/basic/JDK-8015830.js
Normal file
56
nashorn/test/script/basic/JDK-8015830.js
Normal file
@ -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);
|
||||
}
|
||||
4
nashorn/test/script/basic/JDK-8015830.js.EXPECTED
Normal file
4
nashorn/test/script/basic/JDK-8015830.js.EXPECTED
Normal file
@ -0,0 +1,4 @@
|
||||
x = 100
|
||||
doit = function () { }
|
||||
100
|
||||
function () { }
|
||||
55
nashorn/test/script/basic/JDK-8015945.js
Normal file
55
nashorn/test/script/basic/JDK-8015945.js
Normal file
@ -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]);
|
||||
}
|
||||
7
nashorn/test/script/basic/JDK-8015945.js.EXPECTED
Normal file
7
nashorn/test/script/basic/JDK-8015945.js.EXPECTED
Normal file
@ -0,0 +1,7 @@
|
||||
global an Object? false
|
||||
global.squares returns Array? false
|
||||
result length 4
|
||||
0 = 4
|
||||
1 = 9
|
||||
2 = 16
|
||||
3 = 25
|
||||
@ -1,3 +1,3 @@
|
||||
runScript 33
|
||||
runScript 32
|
||||
<program> 33
|
||||
<program> 32
|
||||
done
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
runScript 33
|
||||
<program> 33
|
||||
done
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
func3 : 40
|
||||
func2 : 36
|
||||
func1 : 32
|
||||
runScript : 44
|
||||
<program> : 44
|
||||
|
||||
@ -4,7 +4,7 @@ function (x) {
|
||||
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
|
||||
|
||||
96
nashorn/test/script/basic/typedarrays.js
Normal file
96
nashorn/test/script/basic/typedarrays.js
Normal file
@ -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);
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user