Merge
This commit is contained in:
commit
70cc4e755b
@ -193,7 +193,8 @@ test262-test-sys-prop.test.js.enable.strict.mode=true
|
||||
|
||||
# list of test262 test dirs to be excluded
|
||||
test262-test-sys-prop.test.js.exclude.dir=\
|
||||
${test262.suite.dir}/intl402/
|
||||
${test262.suite.dir}/intl402/ \
|
||||
${test262.suite.dir}/bestPractice/
|
||||
|
||||
test262-test-sys-prop.test.failed.list.file=${build.dir}/test/failedTests
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
@ -30,3 +30,4 @@
|
||||
*/
|
||||
|
||||
print("Hello World");
|
||||
|
||||
|
@ -72,7 +72,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
||||
private final ScriptObject global;
|
||||
|
||||
// default options passed to Nashorn Options object
|
||||
private static final String[] DEFAULT_OPTIONS = new String[] { "-scripting", "-af", "-doe" };
|
||||
private static final String[] DEFAULT_OPTIONS = new String[] { "-scripting", "-doe" };
|
||||
|
||||
NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) {
|
||||
this(factory, DEFAULT_OPTIONS, appLoader);
|
||||
|
@ -342,6 +342,184 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
|
||||
});
|
||||
}
|
||||
|
||||
// Support for ECMAScript Object API on mirrors
|
||||
|
||||
/**
|
||||
* Return the __proto__ of this object.
|
||||
* @return __proto__ object.
|
||||
*/
|
||||
public Object getProto() {
|
||||
return inGlobal(new Callable<Object>() {
|
||||
@Override public Object call() {
|
||||
return wrap(getScriptObject().getProto(), global);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 8.12.1 [[GetOwnProperty]] (P)
|
||||
*
|
||||
* @param key property key
|
||||
*
|
||||
* @return Returns the Property Descriptor of the named own property of this
|
||||
* object, or undefined if absent.
|
||||
*/
|
||||
public Object getOwnPropertyDescriptor(final String key) {
|
||||
return inGlobal(new Callable<Object>() {
|
||||
@Override public Object call() {
|
||||
return wrap(getScriptObject().getOwnPropertyDescriptor(key), global);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* return an array of own property keys associated with the object.
|
||||
*
|
||||
* @param all True if to include non-enumerable keys.
|
||||
* @return Array of keys.
|
||||
*/
|
||||
public String[] getOwnKeys(final boolean all) {
|
||||
return inGlobal(new Callable<String[]>() {
|
||||
@Override public String[] call() {
|
||||
return getScriptObject().getOwnKeys(all);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag this script object as non extensible
|
||||
*
|
||||
* @return the object after being made non extensible
|
||||
*/
|
||||
public ScriptObjectMirror preventExtensions() {
|
||||
return inGlobal(new Callable<ScriptObjectMirror>() {
|
||||
@Override public ScriptObjectMirror call() {
|
||||
getScriptObject().preventExtensions();
|
||||
return ScriptObjectMirror.this;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this script object is extensible
|
||||
* @return true if extensible
|
||||
*/
|
||||
public boolean isExtensible() {
|
||||
return inGlobal(new Callable<Boolean>() {
|
||||
@Override public Boolean call() {
|
||||
return getScriptObject().isExtensible();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMAScript 15.2.3.8 - seal implementation
|
||||
* @return the sealed script object
|
||||
*/
|
||||
public ScriptObjectMirror seal() {
|
||||
return inGlobal(new Callable<ScriptObjectMirror>() {
|
||||
@Override public ScriptObjectMirror call() {
|
||||
getScriptObject().seal();
|
||||
return ScriptObjectMirror.this;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this script object is sealed
|
||||
* @return true if sealed
|
||||
*/
|
||||
public boolean isSealed() {
|
||||
return inGlobal(new Callable<Boolean>() {
|
||||
@Override public Boolean call() {
|
||||
return getScriptObject().isSealed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.2.39 - freeze implementation. Freeze this script object
|
||||
* @return the frozen script object
|
||||
*/
|
||||
public ScriptObjectMirror freeze() {
|
||||
return inGlobal(new Callable<ScriptObjectMirror>() {
|
||||
@Override public ScriptObjectMirror call() {
|
||||
getScriptObject().freeze();
|
||||
return ScriptObjectMirror.this;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this script object is frozen
|
||||
* @return true if frozen
|
||||
*/
|
||||
public boolean isFrozen() {
|
||||
return inGlobal(new Callable<Boolean>() {
|
||||
@Override public Boolean call() {
|
||||
return getScriptObject().isFrozen();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ECMAScript instanceof check
|
||||
|
||||
/**
|
||||
* Checking whether a script object is an instance of another by
|
||||
* walking the proto chain
|
||||
*
|
||||
* @param instance instace to check
|
||||
* @return true if 'instance' is an instance of this object
|
||||
*/
|
||||
public boolean isInstance(final ScriptObjectMirror instance) {
|
||||
// if not belongs to my global scope, return false
|
||||
if (instance == null || global != instance.global) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return inGlobal(new Callable<Boolean>() {
|
||||
@Override public Boolean call() {
|
||||
return getScriptObject().isInstance(instance.getScriptObject());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to check if given object is ECMAScript undefined value
|
||||
*
|
||||
* @param obj object to check
|
||||
* @return true if 'obj' is ECMAScript undefined value
|
||||
*/
|
||||
public static boolean isUndefined(final Object obj) {
|
||||
return obj == ScriptRuntime.UNDEFINED;
|
||||
}
|
||||
|
||||
/**
|
||||
* is this a function object?
|
||||
*
|
||||
* @return if this mirror wraps a ECMAScript function instance
|
||||
*/
|
||||
public boolean isFunction() {
|
||||
return getScriptObject() instanceof ScriptFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* is this a 'use strict' function object?
|
||||
*
|
||||
* @return true if this mirror represents a ECMAScript 'use strict' function
|
||||
*/
|
||||
public boolean isStrictFunction() {
|
||||
return isFunction() && ((ScriptFunction)getScriptObject()).isStrict();
|
||||
}
|
||||
|
||||
/**
|
||||
* is this an array object?
|
||||
*
|
||||
* @return if this mirror wraps a ECMAScript array object
|
||||
*/
|
||||
public boolean isArray() {
|
||||
return getScriptObject().isArray();
|
||||
}
|
||||
|
||||
// These are public only so that Context can access these.
|
||||
|
||||
|
@ -35,6 +35,7 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.SWITCH_TAG_PREFIX;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
|
||||
import static jdk.nashorn.internal.ir.Symbol.IS_ALWAYS_DEFINED;
|
||||
import static jdk.nashorn.internal.ir.Symbol.IS_CONSTANT;
|
||||
import static jdk.nashorn.internal.ir.Symbol.IS_FUNCTION_SELF;
|
||||
import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL;
|
||||
@ -128,6 +129,8 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
|
||||
private final Deque<Type> returnTypes;
|
||||
|
||||
private int catchNestingLevel;
|
||||
|
||||
private static final DebugLogger LOG = new DebugLogger("attr");
|
||||
private static final boolean DEBUG = LOG.isEnabled();
|
||||
|
||||
@ -169,14 +172,14 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
if (functionNode.isVarArg()) {
|
||||
initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL, Type.OBJECT_ARRAY);
|
||||
if (functionNode.needsArguments()) {
|
||||
initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL, Type.typeFor(ScriptObject.class));
|
||||
initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED, Type.typeFor(ScriptObject.class));
|
||||
addLocalDef(ARGUMENTS.symbolName());
|
||||
}
|
||||
}
|
||||
|
||||
initParameters(functionNode, body);
|
||||
initCompileConstant(SCOPE, body, IS_VAR | IS_INTERNAL, Type.typeFor(ScriptObject.class));
|
||||
initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL, Type.OBJECT);
|
||||
initCompileConstant(SCOPE, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED, Type.typeFor(ScriptObject.class));
|
||||
initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED, Type.OBJECT);
|
||||
}
|
||||
|
||||
|
||||
@ -320,10 +323,12 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
final Block block = lc.getCurrentBlock();
|
||||
|
||||
start(catchNode);
|
||||
catchNestingLevel++;
|
||||
|
||||
// define block-local exception variable
|
||||
final Symbol def = defineSymbol(block, exception.getName(), IS_VAR | IS_LET);
|
||||
newType(def, Type.OBJECT);
|
||||
final Symbol def = defineSymbol(block, exception.getName(), IS_VAR | IS_LET | IS_ALWAYS_DEFINED);
|
||||
newType(def, Type.OBJECT); //we can catch anything, not just ecma exceptions
|
||||
|
||||
addLocalDef(exception.getName());
|
||||
|
||||
return true;
|
||||
@ -334,6 +339,9 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
final IdentNode exception = catchNode.getException();
|
||||
final Block block = lc.getCurrentBlock();
|
||||
final Symbol symbol = findSymbol(block, exception.getName());
|
||||
|
||||
catchNestingLevel--;
|
||||
|
||||
assert symbol != null;
|
||||
return end(catchNode.setException((IdentNode)exception.setSymbol(lc, symbol)));
|
||||
}
|
||||
@ -543,9 +551,19 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
assert lc.getFunctionBody(functionNode).getExistingSymbol(CALLEE.symbolName()) != null;
|
||||
lc.setFlag(functionNode.getBody(), Block.NEEDS_SELF_SYMBOL);
|
||||
newType(symbol, FunctionNode.FUNCTION_TYPE);
|
||||
} else if (!identNode.isInitializedHere()) { // NASHORN-448
|
||||
// here is a use outside the local def scope
|
||||
if (!isLocalDef(name)) {
|
||||
} else if (!identNode.isInitializedHere()) {
|
||||
/*
|
||||
* See NASHORN-448, JDK-8016235
|
||||
*
|
||||
* Here is a use outside the local def scope
|
||||
* the inCatch check is a conservative approach to handle things that might have only been
|
||||
* defined in the try block, but with variable declarations, which due to JavaScript rules
|
||||
* have to be lifted up into the function scope outside the try block anyway, but as the
|
||||
* flow can fault at almost any place in the try block and get us to the catch block, all we
|
||||
* know is that we have a declaration, not a definition. This can be made better and less
|
||||
* conservative once we superimpose a CFG onto the AST.
|
||||
*/
|
||||
if (!isLocalDef(name) || inCatch()) {
|
||||
newType(symbol, Type.OBJECT);
|
||||
symbol.setCanBeUndefined();
|
||||
}
|
||||
@ -572,6 +590,10 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
return end(identNode.setSymbol(lc, symbol));
|
||||
}
|
||||
|
||||
private boolean inCatch() {
|
||||
return catchNestingLevel > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the symbol isn't already a scope symbol, and it is either not local to the current function, or it is being
|
||||
* referenced from within a with block, we force it to be a scope symbol.
|
||||
@ -584,26 +606,26 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
}
|
||||
|
||||
private boolean symbolNeedsToBeScope(Symbol symbol) {
|
||||
if(symbol.isThis() || symbol.isInternal()) {
|
||||
if (symbol.isThis() || symbol.isInternal()) {
|
||||
return false;
|
||||
}
|
||||
boolean previousWasBlock = false;
|
||||
for(final Iterator<LexicalContextNode> it = lc.getAllNodes(); it.hasNext();) {
|
||||
for (final Iterator<LexicalContextNode> it = lc.getAllNodes(); it.hasNext();) {
|
||||
final LexicalContextNode node = it.next();
|
||||
if(node instanceof FunctionNode) {
|
||||
if (node instanceof FunctionNode) {
|
||||
// We reached the function boundary without seeing a definition for the symbol - it needs to be in
|
||||
// scope.
|
||||
return true;
|
||||
} else if(node instanceof WithNode) {
|
||||
if(previousWasBlock) {
|
||||
} else if (node instanceof WithNode) {
|
||||
if (previousWasBlock) {
|
||||
// We reached a WithNode; the symbol must be scoped. Note that if the WithNode was not immediately
|
||||
// preceded by a block, this means we're currently processing its expression, not its body,
|
||||
// therefore it doesn't count.
|
||||
return true;
|
||||
}
|
||||
previousWasBlock = false;
|
||||
} else if(node instanceof Block) {
|
||||
if(((Block)node).getExistingSymbol(symbol.getName()) == symbol) {
|
||||
} else if (node instanceof Block) {
|
||||
if (((Block)node).getExistingSymbol(symbol.getName()) == symbol) {
|
||||
// We reached the block that defines the symbol without reaching either the function boundary, or a
|
||||
// WithNode. The symbol need not be scoped.
|
||||
return false;
|
||||
@ -1700,8 +1722,8 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
}
|
||||
|
||||
private void pushLocalsBlock() {
|
||||
localDefs.push(localDefs.isEmpty() ? new HashSet<String>() : new HashSet<>(localDefs.peek()));
|
||||
localUses.push(localUses.isEmpty() ? new HashSet<String>() : new HashSet<>(localUses.peek()));
|
||||
localDefs.push(new HashSet<>(localDefs.peek()));
|
||||
localUses.push(new HashSet<>(localUses.peek()));
|
||||
}
|
||||
|
||||
private void popLocals() {
|
||||
|
@ -86,7 +86,7 @@ public abstract class BreakableNode extends LexicalContextNode {
|
||||
|
||||
/**
|
||||
* Return the labels associated with this node. Breakable nodes that
|
||||
* aren't LoopNodes only have a break label -> the location immediately
|
||||
* aren't LoopNodes only have a break label - the location immediately
|
||||
* afterwards the node in code
|
||||
* @return list of labels representing locations around this node
|
||||
*/
|
||||
|
@ -55,23 +55,25 @@ public final class Symbol implements Comparable<Symbol> {
|
||||
public static final int KINDMASK = (1 << 3) - 1; // Kinds are represented by lower three bits
|
||||
|
||||
/** Is this scope */
|
||||
public static final int IS_SCOPE = 1 << 4;
|
||||
public static final int IS_SCOPE = 1 << 4;
|
||||
/** Is this a this symbol */
|
||||
public static final int IS_THIS = 1 << 5;
|
||||
public static final int IS_THIS = 1 << 5;
|
||||
/** Can this symbol ever be undefined */
|
||||
public static final int CAN_BE_UNDEFINED = 1 << 6;
|
||||
public static final int CAN_BE_UNDEFINED = 1 << 6;
|
||||
/** Is this symbol always defined? */
|
||||
public static final int IS_ALWAYS_DEFINED = 1 << 8;
|
||||
/** Can this symbol ever have primitive types */
|
||||
public static final int CAN_BE_PRIMITIVE = 1 << 7;
|
||||
public static final int CAN_BE_PRIMITIVE = 1 << 9;
|
||||
/** Is this a let */
|
||||
public static final int IS_LET = 1 << 8;
|
||||
public static final int IS_LET = 1 << 10;
|
||||
/** Is this an internal symbol, never represented explicitly in source code */
|
||||
public static final int IS_INTERNAL = 1 << 9;
|
||||
public static final int IS_INTERNAL = 1 << 11;
|
||||
/** Is this a function self-reference symbol */
|
||||
public static final int IS_FUNCTION_SELF = 1 << 10;
|
||||
public static final int IS_FUNCTION_SELF = 1 << 12;
|
||||
/** Is this a specialized param? */
|
||||
public static final int IS_SPECIALIZED_PARAM = 1 << 11;
|
||||
public static final int IS_SPECIALIZED_PARAM = 1 << 13;
|
||||
/** Is this symbol a shared temporary? */
|
||||
public static final int IS_SHARED = 1 << 12;
|
||||
public static final int IS_SHARED = 1 << 14;
|
||||
|
||||
/** Null or name identifying symbol. */
|
||||
private final String name;
|
||||
@ -384,7 +386,7 @@ public final class Symbol implements Comparable<Symbol> {
|
||||
* Mark this symbol as one being shared by multiple expressions. The symbol must be a temporary.
|
||||
*/
|
||||
public void setIsShared() {
|
||||
if(!isShared()) {
|
||||
if (!isShared()) {
|
||||
assert isTemp();
|
||||
trace("SET IS SHARED");
|
||||
flags |= IS_SHARED;
|
||||
@ -416,6 +418,14 @@ public final class Symbol implements Comparable<Symbol> {
|
||||
return (flags & KINDMASK) == IS_PARAM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this symbol is always defined, which overrides all canBeUndefined tags
|
||||
* @return true if always defined
|
||||
*/
|
||||
public boolean isAlwaysDefined() {
|
||||
return isParam() || (flags & IS_ALWAYS_DEFINED) == IS_ALWAYS_DEFINED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the range for this symbol
|
||||
* @return range for symbol
|
||||
@ -462,7 +472,9 @@ public final class Symbol implements Comparable<Symbol> {
|
||||
*/
|
||||
public void setCanBeUndefined() {
|
||||
assert type.isObject() : type;
|
||||
if (!isParam() && !canBeUndefined()) {//parameters are never undefined
|
||||
if (isAlwaysDefined()) {
|
||||
return;
|
||||
} else if (!canBeUndefined()) {
|
||||
assert !isShared();
|
||||
flags |= CAN_BE_UNDEFINED;
|
||||
}
|
||||
|
@ -138,18 +138,16 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr
|
||||
|
||||
@Override
|
||||
public PropertyDescriptor fillFrom(final ScriptObject sobj) {
|
||||
final boolean strict = isStrictContext();
|
||||
|
||||
if (sobj.has(CONFIGURABLE)) {
|
||||
this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE));
|
||||
} else {
|
||||
delete(CONFIGURABLE, strict);
|
||||
delete(CONFIGURABLE, false);
|
||||
}
|
||||
|
||||
if (sobj.has(ENUMERABLE)) {
|
||||
this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE));
|
||||
} else {
|
||||
delete(ENUMERABLE, strict);
|
||||
delete(ENUMERABLE, false);
|
||||
}
|
||||
|
||||
if (sobj.has(GET)) {
|
||||
@ -160,7 +158,7 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr
|
||||
throw typeError("not.a.function", ScriptRuntime.safeToString(getter));
|
||||
}
|
||||
} else {
|
||||
delete(GET, strict);
|
||||
delete(GET, false);
|
||||
}
|
||||
|
||||
if (sobj.has(SET)) {
|
||||
@ -171,7 +169,7 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr
|
||||
throw typeError("not.a.function", ScriptRuntime.safeToString(setter));
|
||||
}
|
||||
} else {
|
||||
delete(SET, strict);
|
||||
delete(SET, false);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -136,29 +136,28 @@ public final class DataPropertyDescriptor extends ScriptObject implements Proper
|
||||
|
||||
@Override
|
||||
public PropertyDescriptor fillFrom(final ScriptObject sobj) {
|
||||
final boolean strict = isStrictContext();
|
||||
if (sobj.has(CONFIGURABLE)) {
|
||||
this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE));
|
||||
} else {
|
||||
delete(CONFIGURABLE, strict);
|
||||
delete(CONFIGURABLE, false);
|
||||
}
|
||||
|
||||
if (sobj.has(ENUMERABLE)) {
|
||||
this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE));
|
||||
} else {
|
||||
delete(ENUMERABLE, strict);
|
||||
delete(ENUMERABLE, false);
|
||||
}
|
||||
|
||||
if (sobj.has(WRITABLE)) {
|
||||
this.writable = JSType.toBoolean(sobj.get(WRITABLE));
|
||||
} else {
|
||||
delete(WRITABLE, strict);
|
||||
delete(WRITABLE, false);
|
||||
}
|
||||
|
||||
if (sobj.has(VALUE)) {
|
||||
this.value = sobj.get(VALUE);
|
||||
} else {
|
||||
delete(VALUE, strict);
|
||||
delete(VALUE, false);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -124,17 +124,16 @@ public final class GenericPropertyDescriptor extends ScriptObject implements Pro
|
||||
|
||||
@Override
|
||||
public PropertyDescriptor fillFrom(final ScriptObject sobj) {
|
||||
final boolean strict = isStrictContext();
|
||||
if (sobj.has(CONFIGURABLE)) {
|
||||
this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE));
|
||||
} else {
|
||||
delete(CONFIGURABLE, strict);
|
||||
delete(CONFIGURABLE, false);
|
||||
}
|
||||
|
||||
if (sobj.has(ENUMERABLE)) {
|
||||
this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE));
|
||||
} else {
|
||||
delete(ENUMERABLE, strict);
|
||||
delete(ENUMERABLE, false);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -37,6 +37,7 @@ import java.lang.ref.SoftReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -372,7 +373,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
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, 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;
|
||||
@ -429,15 +430,6 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
return instance().context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Script access check for strict mode
|
||||
*
|
||||
* @return true if strict mode enabled in {@link Global#getThisContext()}
|
||||
*/
|
||||
static boolean isStrict() {
|
||||
return getEnv()._strict;
|
||||
}
|
||||
|
||||
// GlobalObject interface implementation
|
||||
|
||||
@Override
|
||||
@ -615,14 +607,12 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
|
||||
final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set);
|
||||
|
||||
final boolean strict = context.getEnv()._strict;
|
||||
|
||||
if (get == null) {
|
||||
desc.delete(PropertyDescriptor.GET, strict);
|
||||
desc.delete(PropertyDescriptor.GET, false);
|
||||
}
|
||||
|
||||
if (set == null) {
|
||||
desc.delete(PropertyDescriptor.SET, strict);
|
||||
desc.delete(PropertyDescriptor.SET, false);
|
||||
}
|
||||
|
||||
return desc;
|
||||
@ -750,17 +740,21 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
/**
|
||||
* Global loadWithNewGlobal implementation - Nashorn extension
|
||||
*
|
||||
* @param self scope
|
||||
* @param source source to load
|
||||
* @param args (optional) arguments to be passed to the loaded script
|
||||
* @param self scope
|
||||
* @param args from plus (optional) arguments to be passed to the loaded script
|
||||
*
|
||||
* @return result of load (undefined)
|
||||
* @return result of load (may be undefined)
|
||||
*
|
||||
* @throws IOException if source could not be read
|
||||
*/
|
||||
public static Object loadWithNewGlobal(final Object self, final Object source, final Object...args) throws IOException {
|
||||
public static Object loadWithNewGlobal(final Object self, final Object...args) throws IOException {
|
||||
final Global global = Global.instance();
|
||||
return global.context.loadWithNewGlobal(source, args);
|
||||
final int length = args.length;
|
||||
final boolean hasArgs = 0 < length;
|
||||
final Object from = hasArgs ? args[0] : UNDEFINED;
|
||||
final Object[] arguments = hasArgs ? Arrays.copyOfRange(args, 1, length) : args;
|
||||
|
||||
return global.context.loadWithNewGlobal(from, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1480,7 +1474,6 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
// Error objects
|
||||
this.builtinError = (ScriptFunction)initConstructor("Error");
|
||||
final ScriptObject errorProto = getErrorPrototype();
|
||||
final boolean strict = Global.isStrict();
|
||||
|
||||
// Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
|
||||
final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", NativeError.GET_STACK);
|
||||
@ -1498,10 +1491,10 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
|
||||
// ECMA 15.11.4.2 Error.prototype.name
|
||||
// Error.prototype.name = "Error";
|
||||
errorProto.set(NativeError.NAME, "Error", strict);
|
||||
errorProto.set(NativeError.NAME, "Error", false);
|
||||
// ECMA 15.11.4.3 Error.prototype.message
|
||||
// Error.prototype.message = "";
|
||||
errorProto.set(NativeError.MESSAGE, "", strict);
|
||||
errorProto.set(NativeError.MESSAGE, "", false);
|
||||
|
||||
this.builtinEvalError = initErrorSubtype("EvalError", errorProto);
|
||||
this.builtinRangeError = initErrorSubtype("RangeError", errorProto);
|
||||
@ -1514,9 +1507,8 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) {
|
||||
final ScriptObject cons = initConstructor(name);
|
||||
final ScriptObject prototype = ScriptFunction.getPrototype(cons);
|
||||
final boolean strict = Global.isStrict();
|
||||
prototype.set(NativeError.NAME, name, strict);
|
||||
prototype.set(NativeError.MESSAGE, "", strict);
|
||||
prototype.set(NativeError.NAME, name, false);
|
||||
prototype.set(NativeError.MESSAGE, "", false);
|
||||
prototype.setProto(errorProto);
|
||||
return (ScriptFunction)cons;
|
||||
}
|
||||
@ -1725,7 +1717,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
// <anon-function>
|
||||
builtinFunction.setProto(anon);
|
||||
builtinFunction.setPrototype(anon);
|
||||
anon.set("constructor", builtinFunction, anon.isStrict());
|
||||
anon.set("constructor", builtinFunction, false);
|
||||
anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
|
||||
|
||||
// now initialize Object
|
||||
|
@ -39,6 +39,7 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import jdk.nashorn.internal.objects.annotations.Attribute;
|
||||
import jdk.nashorn.internal.objects.annotations.Constructor;
|
||||
import jdk.nashorn.internal.objects.annotations.Function;
|
||||
@ -118,7 +119,7 @@ public final class NativeArray extends ScriptObject {
|
||||
if (value == ScriptRuntime.EMPTY) {
|
||||
arrayData = arrayData.delete(index);
|
||||
} else {
|
||||
arrayData = arrayData.set(index, value, isStrictContext());
|
||||
arrayData = arrayData.set(index, value, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,6 +159,11 @@ public final class NativeArray extends ScriptObject {
|
||||
|
||||
// Step 3
|
||||
if ("length".equals(key)) {
|
||||
// check for length being made non-writable
|
||||
if (desc.has(WRITABLE) && !desc.isWritable()) {
|
||||
setIsLengthNotWritable();
|
||||
}
|
||||
|
||||
// Step 3a
|
||||
if (!desc.has(VALUE)) {
|
||||
return super.defineOwnProperty("length", desc, reject);
|
||||
@ -286,7 +292,8 @@ public final class NativeArray extends ScriptObject {
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object isArray(final Object self, final Object arg) {
|
||||
return isArray(arg) || (arg == Global.instance().getArrayPrototype())
|
||||
|| (arg instanceof NativeRegExpExecResult);
|
||||
|| (arg instanceof NativeRegExpExecResult)
|
||||
|| (arg instanceof ScriptObjectMirror && ((ScriptObjectMirror)arg).isArray());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -603,7 +610,6 @@ public final class NativeArray extends ScriptObject {
|
||||
public static Object pop(final Object self) {
|
||||
try {
|
||||
final ScriptObject sobj = (ScriptObject)self;
|
||||
final boolean strict = sobj.isStrictContext();
|
||||
|
||||
if (bulkable(sobj)) {
|
||||
return sobj.getArray().pop();
|
||||
@ -612,15 +618,15 @@ public final class NativeArray extends ScriptObject {
|
||||
final long len = JSType.toUint32(sobj.getLength());
|
||||
|
||||
if (len == 0) {
|
||||
sobj.set("length", 0, strict);
|
||||
sobj.set("length", 0, true);
|
||||
return ScriptRuntime.UNDEFINED;
|
||||
}
|
||||
|
||||
final long index = len - 1;
|
||||
final Object element = sobj.get(index);
|
||||
|
||||
sobj.delete(index, strict);
|
||||
sobj.set("length", index, strict);
|
||||
sobj.delete(index, true);
|
||||
sobj.set("length", index, true);
|
||||
|
||||
return element;
|
||||
} catch (final ClassCastException | NullPointerException e) {
|
||||
@ -639,11 +645,10 @@ public final class NativeArray extends ScriptObject {
|
||||
public static Object push(final Object self, final Object... args) {
|
||||
try {
|
||||
final ScriptObject sobj = (ScriptObject)self;
|
||||
final boolean strict = sobj.isStrictContext();
|
||||
|
||||
if (bulkable(sobj)) {
|
||||
if (sobj.getArray().length() + args.length <= JSType.MAX_UINT) {
|
||||
final ArrayData newData = sobj.getArray().push(sobj.isStrictContext(), args);
|
||||
final ArrayData newData = sobj.getArray().push(true, args);
|
||||
sobj.setArray(newData);
|
||||
return newData.length();
|
||||
}
|
||||
@ -652,9 +657,9 @@ public final class NativeArray extends ScriptObject {
|
||||
|
||||
long len = JSType.toUint32(sobj.getLength());
|
||||
for (final Object element : args) {
|
||||
sobj.set(len++, element, strict);
|
||||
sobj.set(len++, element, true);
|
||||
}
|
||||
sobj.set("length", len, strict);
|
||||
sobj.set("length", len, true);
|
||||
|
||||
return len;
|
||||
} catch (final ClassCastException | NullPointerException e) {
|
||||
@ -672,7 +677,6 @@ public final class NativeArray extends ScriptObject {
|
||||
public static Object reverse(final Object self) {
|
||||
try {
|
||||
final ScriptObject sobj = (ScriptObject)self;
|
||||
final boolean strict = sobj.isStrictContext();
|
||||
final long len = JSType.toUint32(sobj.getLength());
|
||||
final long middle = len / 2;
|
||||
|
||||
@ -684,14 +688,14 @@ public final class NativeArray extends ScriptObject {
|
||||
final boolean upperExists = sobj.has(upper);
|
||||
|
||||
if (lowerExists && upperExists) {
|
||||
sobj.set(lower, upperValue, strict);
|
||||
sobj.set(upper, lowerValue, strict);
|
||||
sobj.set(lower, upperValue, true);
|
||||
sobj.set(upper, lowerValue, true);
|
||||
} else if (!lowerExists && upperExists) {
|
||||
sobj.set(lower, upperValue, strict);
|
||||
sobj.delete(upper, strict);
|
||||
sobj.set(lower, upperValue, true);
|
||||
sobj.delete(upper, true);
|
||||
} else if (lowerExists && !upperExists) {
|
||||
sobj.delete(lower, strict);
|
||||
sobj.set(upper, lowerValue, strict);
|
||||
sobj.delete(lower, true);
|
||||
sobj.set(upper, lowerValue, true);
|
||||
}
|
||||
}
|
||||
return sobj;
|
||||
@ -717,7 +721,6 @@ public final class NativeArray extends ScriptObject {
|
||||
}
|
||||
|
||||
final ScriptObject sobj = (ScriptObject) obj;
|
||||
final boolean strict = Global.isStrict();
|
||||
|
||||
long len = JSType.toUint32(sobj.getLength());
|
||||
|
||||
@ -728,15 +731,15 @@ public final class NativeArray extends ScriptObject {
|
||||
sobj.getArray().shiftLeft(1);
|
||||
} else {
|
||||
for (long k = 1; k < len; k++) {
|
||||
sobj.set(k - 1, sobj.get(k), strict);
|
||||
sobj.set(k - 1, sobj.get(k), true);
|
||||
}
|
||||
}
|
||||
sobj.delete(--len, strict);
|
||||
sobj.delete(--len, true);
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
|
||||
sobj.set("length", len, strict);
|
||||
sobj.set("length", len, true);
|
||||
|
||||
return first;
|
||||
}
|
||||
@ -833,7 +836,6 @@ public final class NativeArray extends ScriptObject {
|
||||
public static Object sort(final Object self, final Object comparefn) {
|
||||
try {
|
||||
final ScriptObject sobj = (ScriptObject) self;
|
||||
final boolean strict = sobj.isStrictContext();
|
||||
final long len = JSType.toUint32(sobj.getLength());
|
||||
ArrayData array = sobj.getArray();
|
||||
|
||||
@ -850,7 +852,7 @@ public final class NativeArray extends ScriptObject {
|
||||
final Object[] sorted = sort(src.toArray(), comparefn);
|
||||
|
||||
for (int i = 0; i < sorted.length; i++) {
|
||||
array = array.set(i, sorted[i], strict);
|
||||
array = array.set(i, sorted[i], true);
|
||||
}
|
||||
|
||||
// delete missing elements - which are at the end of sorted array
|
||||
@ -891,7 +893,6 @@ public final class NativeArray extends ScriptObject {
|
||||
}
|
||||
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
final boolean strict = Global.isStrict();
|
||||
final long len = JSType.toUint32(sobj.getLength());
|
||||
final long relativeStart = JSType.toLong(start);
|
||||
|
||||
@ -914,14 +915,14 @@ public final class NativeArray extends ScriptObject {
|
||||
final long to = k + items.length;
|
||||
|
||||
if (sobj.has(from)) {
|
||||
sobj.set(to, sobj.get(from), strict);
|
||||
sobj.set(to, sobj.get(from), true);
|
||||
} else {
|
||||
sobj.delete(to, strict);
|
||||
sobj.delete(to, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (long k = len; k > (len - actualDeleteCount + items.length); k--) {
|
||||
sobj.delete(k - 1, strict);
|
||||
sobj.delete(k - 1, true);
|
||||
}
|
||||
} else if (items.length > actualDeleteCount) {
|
||||
for (long k = len - actualDeleteCount; k > actualStart; k--) {
|
||||
@ -930,20 +931,20 @@ public final class NativeArray extends ScriptObject {
|
||||
|
||||
if (sobj.has(from)) {
|
||||
final Object fromValue = sobj.get(from);
|
||||
sobj.set(to, fromValue, strict);
|
||||
sobj.set(to, fromValue, true);
|
||||
} else {
|
||||
sobj.delete(to, strict);
|
||||
sobj.delete(to, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long k = actualStart;
|
||||
for (int i = 0; i < items.length; i++, k++) {
|
||||
sobj.set(k, items[i], strict);
|
||||
sobj.set(k, items[i], true);
|
||||
}
|
||||
|
||||
final long newLength = len - actualDeleteCount + items.length;
|
||||
sobj.set("length", newLength, strict);
|
||||
sobj.set("length", newLength, true);
|
||||
|
||||
return array;
|
||||
}
|
||||
@ -964,7 +965,6 @@ public final class NativeArray extends ScriptObject {
|
||||
}
|
||||
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
final boolean strict = Global.isStrict();
|
||||
final long len = JSType.toUint32(sobj.getLength());
|
||||
|
||||
if (items == null) {
|
||||
@ -975,7 +975,7 @@ public final class NativeArray extends ScriptObject {
|
||||
sobj.getArray().shiftRight(items.length);
|
||||
|
||||
for (int j = 0; j < items.length; j++) {
|
||||
sobj.setArray(sobj.getArray().set(j, items[j], sobj.isStrictContext()));
|
||||
sobj.setArray(sobj.getArray().set(j, items[j], true));
|
||||
}
|
||||
} else {
|
||||
for (long k = len; k > 0; k--) {
|
||||
@ -984,19 +984,19 @@ public final class NativeArray extends ScriptObject {
|
||||
|
||||
if (sobj.has(from)) {
|
||||
final Object fromValue = sobj.get(from);
|
||||
sobj.set(to, fromValue, strict);
|
||||
sobj.set(to, fromValue, true);
|
||||
} else {
|
||||
sobj.delete(to, strict);
|
||||
sobj.delete(to, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < items.length; j++) {
|
||||
sobj.set(j, items[j], strict);
|
||||
sobj.set(j, items[j], true);
|
||||
}
|
||||
}
|
||||
|
||||
final long newLength = len + items.length;
|
||||
sobj.set("length", newLength, strict);
|
||||
sobj.set("length", newLength, true);
|
||||
|
||||
return newLength;
|
||||
}
|
||||
@ -1239,7 +1239,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return true if optimizable
|
||||
*/
|
||||
private static boolean bulkable(final ScriptObject self) {
|
||||
return self.isArray() && !hasInheritedArrayEntries(self);
|
||||
return self.isArray() && !hasInheritedArrayEntries(self) && !self.isLengthNotWritable();
|
||||
}
|
||||
|
||||
private static boolean hasInheritedArrayEntries(final ScriptObject self) {
|
||||
|
@ -90,7 +90,7 @@ public final class NativeError extends ScriptObject {
|
||||
if (msg != UNDEFINED) {
|
||||
this.instMessage = JSType.toString(msg);
|
||||
} else {
|
||||
this.delete(NativeError.MESSAGE, Global.isStrict());
|
||||
this.delete(NativeError.MESSAGE, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ public final class NativeError extends ScriptObject {
|
||||
public static Object setLineNumber(final Object self, final Object value) {
|
||||
Global.checkObject(self);
|
||||
final ScriptObject sobj = (ScriptObject)self;
|
||||
sobj.set(LINENUMBER, value, Global.isStrict());
|
||||
sobj.set(LINENUMBER, value, false);
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ public final class NativeError extends ScriptObject {
|
||||
public static Object setColumnNumber(final Object self, final Object value) {
|
||||
Global.checkObject(self);
|
||||
final ScriptObject sobj = (ScriptObject)self;
|
||||
sobj.set(COLUMNNUMBER, value, Global.isStrict());
|
||||
sobj.set(COLUMNNUMBER, value, false);
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -222,7 +222,7 @@ public final class NativeError extends ScriptObject {
|
||||
public static Object setFileName(final Object self, final Object value) {
|
||||
Global.checkObject(self);
|
||||
final ScriptObject sobj = (ScriptObject)self;
|
||||
sobj.set(FILENAME, value, Global.isStrict());
|
||||
sobj.set(FILENAME, value, false);
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -278,7 +278,7 @@ public final class NativeError extends ScriptObject {
|
||||
public static Object setStack(final Object self, final Object value) {
|
||||
Global.checkObject(self);
|
||||
final ScriptObject sobj = (ScriptObject)self;
|
||||
sobj.set(STACK, value, Global.isStrict());
|
||||
sobj.set(STACK, value, false);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ public final class NativeEvalError extends ScriptObject {
|
||||
if (msg != UNDEFINED) {
|
||||
this.instMessage = JSType.toString(msg);
|
||||
} else {
|
||||
this.delete(NativeError.MESSAGE, Global.isStrict());
|
||||
this.delete(NativeError.MESSAGE, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||
|
||||
import java.util.List;
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import jdk.nashorn.internal.objects.annotations.Attribute;
|
||||
import jdk.nashorn.internal.objects.annotations.Constructor;
|
||||
import jdk.nashorn.internal.objects.annotations.Function;
|
||||
@ -102,6 +103,16 @@ public final class NativeFunction {
|
||||
list.toArray(args = new Object[list.size()]);
|
||||
} else if (array == null || array == UNDEFINED) {
|
||||
args = ScriptRuntime.EMPTY_ARRAY;
|
||||
} else if (array instanceof ScriptObjectMirror) {
|
||||
// look for array-like ScriptObjectMirror object
|
||||
final ScriptObjectMirror mirror = (ScriptObjectMirror)array;
|
||||
final Object len = mirror.containsKey("length")? mirror.getMember("length") : Integer.valueOf(0);
|
||||
final int n = (int)JSType.toUint32(len);
|
||||
|
||||
args = new Object[n];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
args[i] = mirror.containsKey(i)? mirror.getSlot(i) : UNDEFINED;
|
||||
}
|
||||
} else {
|
||||
throw typeError("function.apply.expects.array");
|
||||
}
|
||||
@ -216,7 +227,7 @@ public final class NativeFunction {
|
||||
|
||||
final Global global = Global.instance();
|
||||
|
||||
return Global.directEval(global, sb.toString(), global, "<function>", Global.isStrict());
|
||||
return Global.directEval(global, sb.toString(), global, "<function>", global.isStrictContext());
|
||||
}
|
||||
|
||||
private static void checkFunctionParameters(final String params) {
|
||||
|
@ -158,7 +158,7 @@ public final class NativeJSON extends ScriptObject {
|
||||
state.gap = gap;
|
||||
|
||||
final ScriptObject wrapper = Global.newEmptyInstance();
|
||||
wrapper.set("", value, Global.isStrict());
|
||||
wrapper.set("", value, false);
|
||||
|
||||
return str("", wrapper, state);
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ public final class NativeJavaImporter extends ScriptObject {
|
||||
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
|
||||
final Object value = createProperty(name);
|
||||
if(value != null) {
|
||||
set(name, value, isStrictContext());
|
||||
set(name, value, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -28,11 +28,13 @@ package jdk.nashorn.internal.objects;
|
||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import jdk.nashorn.internal.objects.annotations.Attribute;
|
||||
import jdk.nashorn.internal.objects.annotations.Constructor;
|
||||
import jdk.nashorn.internal.objects.annotations.Function;
|
||||
import jdk.nashorn.internal.objects.annotations.ScriptClass;
|
||||
import jdk.nashorn.internal.objects.annotations.Where;
|
||||
import jdk.nashorn.internal.runtime.ECMAException;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
@ -54,6 +56,10 @@ public final class NativeObject {
|
||||
private NativeObject() {
|
||||
}
|
||||
|
||||
private static ECMAException notAnObject(final Object obj) {
|
||||
return typeError("not.an.object", ScriptRuntime.safeToString(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMA 15.2.3.2 Object.getPrototypeOf ( O )
|
||||
*
|
||||
@ -63,9 +69,13 @@ public final class NativeObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object getPrototypeOf(final Object self, final Object obj) {
|
||||
Global.checkObject(obj);
|
||||
|
||||
return ((ScriptObject)obj).getProto();
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).getProto();
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
return ((ScriptObjectMirror)obj).getProto();
|
||||
} else {
|
||||
throw notAnObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,12 +88,19 @@ public final class NativeObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object getOwnPropertyDescriptor(final Object self, final Object obj, final Object prop) {
|
||||
Global.checkObject(obj);
|
||||
if (obj instanceof ScriptObject) {
|
||||
final String key = JSType.toString(prop);
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
|
||||
final String key = JSType.toString(prop);
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
return sobj.getOwnPropertyDescriptor(key);
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
final String key = JSType.toString(prop);
|
||||
final ScriptObjectMirror sobjMirror = (ScriptObjectMirror)obj;
|
||||
|
||||
return sobj.getOwnPropertyDescriptor(key);
|
||||
return sobjMirror.getOwnPropertyDescriptor(key);
|
||||
} else {
|
||||
throw notAnObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,9 +112,13 @@ public final class NativeObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object getOwnPropertyNames(final Object self, final Object obj) {
|
||||
Global.checkObject(obj);
|
||||
|
||||
return new NativeArray(((ScriptObject)obj).getOwnKeys(true));
|
||||
if (obj instanceof ScriptObject) {
|
||||
return new NativeArray(((ScriptObject)obj).getOwnKeys(true));
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
return new NativeArray(((ScriptObjectMirror)obj).getOwnKeys(true));
|
||||
} else {
|
||||
throw notAnObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,8 +196,13 @@ public final class NativeObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object seal(final Object self, final Object obj) {
|
||||
Global.checkObject(obj);
|
||||
return ((ScriptObject)obj).seal();
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).seal();
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
return ((ScriptObjectMirror)obj).seal();
|
||||
} else {
|
||||
throw notAnObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -189,8 +215,13 @@ public final class NativeObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object freeze(final Object self, final Object obj) {
|
||||
Global.checkObject(obj);
|
||||
return ((ScriptObject)obj).freeze();
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).freeze();
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
return ((ScriptObjectMirror)obj).freeze();
|
||||
} else {
|
||||
throw notAnObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -202,8 +233,13 @@ public final class NativeObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object preventExtensions(final Object self, final Object obj) {
|
||||
Global.checkObject(obj);
|
||||
return ((ScriptObject)obj).preventExtensions();
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).preventExtensions();
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
return ((ScriptObjectMirror)obj).preventExtensions();
|
||||
} else {
|
||||
throw notAnObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -215,8 +251,13 @@ public final class NativeObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object isSealed(final Object self, final Object obj) {
|
||||
Global.checkObject(obj);
|
||||
return ((ScriptObject)obj).isSealed();
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).isSealed();
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
return ((ScriptObjectMirror)obj).isSealed();
|
||||
} else {
|
||||
throw notAnObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -228,8 +269,13 @@ public final class NativeObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object isFrozen(final Object self, final Object obj) {
|
||||
Global.checkObject(obj);
|
||||
return ((ScriptObject)obj).isFrozen();
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).isFrozen();
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
return ((ScriptObjectMirror)obj).isFrozen();
|
||||
} else {
|
||||
throw notAnObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,8 +287,13 @@ public final class NativeObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object isExtensible(final Object self, final Object obj) {
|
||||
Global.checkObject(obj);
|
||||
return ((ScriptObject)obj).isExtensible();
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).isExtensible();
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
return ((ScriptObjectMirror)obj).isExtensible();
|
||||
} else {
|
||||
throw notAnObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -254,9 +305,15 @@ public final class NativeObject {
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object keys(final Object self, final Object obj) {
|
||||
Global.checkObject(obj);
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
return new NativeArray(sobj.getOwnKeys(false));
|
||||
if (obj instanceof ScriptObject) {
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
return new NativeArray(sobj.getOwnKeys(false));
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
final ScriptObjectMirror sobjMirror = (ScriptObjectMirror)obj;
|
||||
return new NativeArray(sobjMirror.getOwnKeys(false));
|
||||
} else {
|
||||
throw notAnObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,7 +59,7 @@ public final class NativeRangeError extends ScriptObject {
|
||||
if (msg != UNDEFINED) {
|
||||
this.instMessage = JSType.toString(msg);
|
||||
} else {
|
||||
this.delete(NativeError.MESSAGE, Global.isStrict());
|
||||
this.delete(NativeError.MESSAGE, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ public final class NativeReferenceError extends ScriptObject {
|
||||
if (msg != UNDEFINED) {
|
||||
this.instMessage = JSType.toString(msg);
|
||||
} else {
|
||||
this.delete(NativeError.MESSAGE, Global.isStrict());
|
||||
this.delete(NativeError.MESSAGE, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -641,26 +641,19 @@ public final class NativeRegExp extends ScriptObject {
|
||||
return string;
|
||||
}
|
||||
|
||||
/*
|
||||
* $$ -> $
|
||||
* $& -> the matched substring
|
||||
* $` -> the portion of string that preceeds matched substring
|
||||
* $' -> the portion of string that follows the matched substring
|
||||
* $n -> the nth capture, where n is [1-9] and $n is NOT followed by a decimal digit
|
||||
* $nn -> the nnth capture, where nn is a two digit decimal number [01-99].
|
||||
*/
|
||||
String replace = replacement;
|
||||
|
||||
if (!regexp.isGlobal()) {
|
||||
if (!matcher.search(0)) {
|
||||
return string;
|
||||
}
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(string, 0, matcher.start());
|
||||
|
||||
if (function != null) {
|
||||
replace = callReplaceValue(function, matcher, string);
|
||||
sb.append(callReplaceValue(function, matcher, string));
|
||||
} else {
|
||||
appendReplacement(matcher, string, replacement, sb);
|
||||
}
|
||||
appendReplacement(matcher, string, replace, sb, 0);
|
||||
sb.append(string, matcher.end(), string.length());
|
||||
return sb.toString();
|
||||
}
|
||||
@ -676,12 +669,13 @@ public final class NativeRegExp extends ScriptObject {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
do {
|
||||
sb.append(string, thisIndex, matcher.start());
|
||||
if (function != null) {
|
||||
replace = callReplaceValue(function, matcher, string);
|
||||
sb.append(callReplaceValue(function, matcher, string));
|
||||
} else {
|
||||
appendReplacement(matcher, string, replacement, sb);
|
||||
}
|
||||
|
||||
appendReplacement(matcher, string, replace, sb, thisIndex);
|
||||
|
||||
// ECMA 15.5.4.10 String.prototype.match(regexp)
|
||||
thisIndex = matcher.end();
|
||||
if (thisIndex == previousLastIndex) {
|
||||
@ -697,10 +691,19 @@ public final class NativeRegExp extends ScriptObject {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void appendReplacement(final RegExpMatcher matcher, final String text, final String replacement, final StringBuilder sb, final int lastAppendPosition) {
|
||||
// Process substitution string to replace group references with groups
|
||||
private void appendReplacement(final RegExpMatcher matcher, final String text, final String replacement, final StringBuilder sb) {
|
||||
/*
|
||||
* Process substitution patterns:
|
||||
*
|
||||
* $$ -> $
|
||||
* $& -> the matched substring
|
||||
* $` -> the portion of string that preceeds matched substring
|
||||
* $' -> the portion of string that follows the matched substring
|
||||
* $n -> the nth capture, where n is [1-9] and $n is NOT followed by a decimal digit
|
||||
* $nn -> the nnth capture, where nn is a two digit decimal number [01-99].
|
||||
*/
|
||||
|
||||
int cursor = 0;
|
||||
final StringBuilder result = new StringBuilder();
|
||||
Object[] groups = null;
|
||||
|
||||
while (cursor < replacement.length()) {
|
||||
@ -732,37 +735,33 @@ public final class NativeRegExp extends ScriptObject {
|
||||
}
|
||||
// Append group if matched.
|
||||
if (groups[refNum] != UNDEFINED) {
|
||||
result.append((String) groups[refNum]);
|
||||
sb.append((String) groups[refNum]);
|
||||
}
|
||||
} else { // $0. ignore.
|
||||
assert refNum == 0;
|
||||
result.append("$0");
|
||||
sb.append("$0");
|
||||
}
|
||||
} else if (nextChar == '$') {
|
||||
result.append('$');
|
||||
sb.append('$');
|
||||
cursor++;
|
||||
} else if (nextChar == '&') {
|
||||
result.append(matcher.group());
|
||||
sb.append(matcher.group());
|
||||
cursor++;
|
||||
} else if (nextChar == '`') {
|
||||
result.append(text.substring(0, matcher.start()));
|
||||
sb.append(text, 0, matcher.start());
|
||||
cursor++;
|
||||
} else if (nextChar == '\'') {
|
||||
result.append(text.substring(matcher.end()));
|
||||
sb.append(text, matcher.end(), text.length());
|
||||
cursor++;
|
||||
} else {
|
||||
// unknown substitution or $n with n>m. skip.
|
||||
result.append('$');
|
||||
sb.append('$');
|
||||
}
|
||||
} else {
|
||||
result.append(nextChar);
|
||||
sb.append(nextChar);
|
||||
cursor++;
|
||||
}
|
||||
}
|
||||
// Append the intervening text
|
||||
sb.append(text, lastAppendPosition, matcher.start());
|
||||
// Append the match substitution
|
||||
sb.append(result);
|
||||
}
|
||||
|
||||
private String callReplaceValue(final ScriptFunction function, final RegExpMatcher matcher, final String string) {
|
||||
|
@ -59,7 +59,7 @@ public final class NativeSyntaxError extends ScriptObject {
|
||||
if (msg != UNDEFINED) {
|
||||
this.instMessage = JSType.toString(msg);
|
||||
} else {
|
||||
this.delete(NativeError.MESSAGE, Global.isStrict());
|
||||
this.delete(NativeError.MESSAGE, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ public final class NativeTypeError extends ScriptObject {
|
||||
if (msg != UNDEFINED) {
|
||||
this.instMessage = JSType.toString(msg);
|
||||
} else {
|
||||
delete(NativeError.MESSAGE, Global.isStrict());
|
||||
delete(NativeError.MESSAGE, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ public final class NativeURIError extends ScriptObject {
|
||||
if (msg != UNDEFINED) {
|
||||
this.instMessage = JSType.toString(msg);
|
||||
} else {
|
||||
this.delete(NativeError.MESSAGE, Global.isStrict());
|
||||
this.delete(NativeError.MESSAGE, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,9 +149,9 @@ public class JSONParser extends AbstractParser {
|
||||
@Override
|
||||
protected void scanNumber() {
|
||||
// Record beginning of number.
|
||||
final int start = position;
|
||||
final int startPosition = position;
|
||||
// Assume value is a decimal.
|
||||
TokenType type = TokenType.DECIMAL;
|
||||
TokenType valueType = TokenType.DECIMAL;
|
||||
|
||||
// floating point can't start with a "." with no leading digit before
|
||||
if (ch0 == '.') {
|
||||
@ -211,11 +211,11 @@ public class JSONParser extends AbstractParser {
|
||||
}
|
||||
}
|
||||
|
||||
type = TokenType.FLOATING;
|
||||
valueType = TokenType.FLOATING;
|
||||
}
|
||||
|
||||
// Add number token.
|
||||
add(type, start);
|
||||
add(valueType, startPosition);
|
||||
}
|
||||
|
||||
// ECMA 15.12.1.1 The JSON Lexical Grammar - JSONEscapeCharacter
|
||||
|
@ -666,43 +666,54 @@ public class Lexer extends Scanner {
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of a numeric sequence.
|
||||
*
|
||||
* @param base Numeric base.
|
||||
* @param max Maximum number of digits.
|
||||
* @param skip Skip over escape first.
|
||||
* @param check Tells whether to throw error if a digit is invalid for the given base.
|
||||
* @param type Type of token to report against.
|
||||
* Get the value of a hexadecimal numeric sequence.
|
||||
*
|
||||
* @param length Number of digits.
|
||||
* @param type Type of token to report against.
|
||||
* @return Value of sequence or < 0 if no digits.
|
||||
*/
|
||||
private int valueOfSequence(final int base, final int max, final boolean skip, final boolean check, final TokenType type) {
|
||||
assert base == 16 || base == 8 : "base other than 16 or 8";
|
||||
final boolean isHex = base == 16;
|
||||
final int shift = isHex ? 4 : 3;
|
||||
private int hexSequence(final int length, final TokenType type) {
|
||||
int value = 0;
|
||||
|
||||
if (skip) {
|
||||
skip(2);
|
||||
}
|
||||
|
||||
for (int i = 0; i < max; i++) {
|
||||
final int digit = convertDigit(ch0, base);
|
||||
for (int i = 0; i < length; i++) {
|
||||
final int digit = convertDigit(ch0, 16);
|
||||
|
||||
if (digit == -1) {
|
||||
if (check) {
|
||||
error(Lexer.message("invalid." + (isHex ? "hex" : "octal")), type, position, limit);
|
||||
}
|
||||
error(Lexer.message("invalid.hex"), type, position, limit);
|
||||
return i == 0 ? -1 : value;
|
||||
}
|
||||
|
||||
value = value << shift | digit;
|
||||
value = digit | value << 4;
|
||||
skip(1);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of an octal numeric sequence. This parses up to 3 digits with a maximum value of 255.
|
||||
*
|
||||
* @return Value of sequence.
|
||||
*/
|
||||
private int octalSequence() {
|
||||
int value = 0;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
final int digit = convertDigit(ch0, 8);
|
||||
|
||||
if (digit == -1) {
|
||||
break;
|
||||
}
|
||||
value = digit | value << 3;
|
||||
skip(1);
|
||||
|
||||
if (i == 1 && value >= 32) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to a JavaScript identifier.
|
||||
*
|
||||
@ -724,7 +735,8 @@ public class Lexer extends Scanner {
|
||||
while (!atEOF() && position < end && !isEOL(ch0)) {
|
||||
// If escape character.
|
||||
if (ch0 == '\\' && ch1 == 'u') {
|
||||
final int ch = valueOfSequence(16, 4, true, true, TokenType.IDENT);
|
||||
skip(2);
|
||||
final int ch = hexSequence(4, TokenType.IDENT);
|
||||
if (isWhitespace((char)ch)) {
|
||||
return null;
|
||||
}
|
||||
@ -815,7 +827,7 @@ public class Lexer extends Scanner {
|
||||
}
|
||||
reset(afterSlash);
|
||||
// Octal sequence.
|
||||
final int ch = valueOfSequence(8, 3, false, false, STRING);
|
||||
final int ch = octalSequence();
|
||||
|
||||
if (ch < 0) {
|
||||
sb.append('\\');
|
||||
@ -862,7 +874,7 @@ public class Lexer extends Scanner {
|
||||
break;
|
||||
case 'x': {
|
||||
// Hex sequence.
|
||||
final int ch = valueOfSequence(16, 2, false, true, STRING);
|
||||
final int ch = hexSequence(2, STRING);
|
||||
|
||||
if (ch < 0) {
|
||||
sb.append('\\');
|
||||
@ -874,7 +886,7 @@ public class Lexer extends Scanner {
|
||||
break;
|
||||
case 'u': {
|
||||
// Unicode sequence.
|
||||
final int ch = valueOfSequence(16, 4, false, true, STRING);
|
||||
final int ch = hexSequence(4, STRING);
|
||||
|
||||
if (ch < 0) {
|
||||
sb.append('\\');
|
||||
@ -907,6 +919,7 @@ public class Lexer extends Scanner {
|
||||
|
||||
/**
|
||||
* Scan over a string literal.
|
||||
* @param add true if we nare not just scanning but should actually modify the token stream
|
||||
*/
|
||||
protected void scanString(final boolean add) {
|
||||
// Type of string.
|
||||
@ -1103,6 +1116,10 @@ public class Lexer extends Scanner {
|
||||
}
|
||||
}
|
||||
|
||||
if (Character.isJavaIdentifierStart(ch0)) {
|
||||
error(Lexer.message("missing.space.after.number"), type, position, 1);
|
||||
}
|
||||
|
||||
// Add number token.
|
||||
add(type, start);
|
||||
}
|
||||
@ -1191,7 +1208,8 @@ public class Lexer extends Scanner {
|
||||
|
||||
// Make sure first character is valid start character.
|
||||
if (ch0 == '\\' && ch1 == 'u') {
|
||||
final int ch = valueOfSequence(16, 4, true, true, TokenType.IDENT);
|
||||
skip(2);
|
||||
final int ch = hexSequence(4, TokenType.IDENT);
|
||||
|
||||
if (!Character.isJavaIdentifierStart(ch)) {
|
||||
error(Lexer.message("illegal.identifier.character"), TokenType.IDENT, start, position);
|
||||
@ -1204,7 +1222,8 @@ public class Lexer extends Scanner {
|
||||
// Make sure remaining characters are valid part characters.
|
||||
while (!atEOF()) {
|
||||
if (ch0 == '\\' && ch1 == 'u') {
|
||||
final int ch = valueOfSequence(16, 4, true, true, TokenType.IDENT);
|
||||
skip(2);
|
||||
final int ch = hexSequence(4, TokenType.IDENT);
|
||||
|
||||
if (!Character.isJavaIdentifierPart(ch)) {
|
||||
error(Lexer.message("illegal.identifier.character"), TokenType.IDENT, start, position);
|
||||
@ -1596,6 +1615,12 @@ public class Lexer extends Scanner {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correctly localized error message for a given message id format arguments
|
||||
* @param msgId message id
|
||||
* @param args format arguments
|
||||
* @return message
|
||||
*/
|
||||
protected static String message(final String msgId, final String... args) {
|
||||
return ECMAErrors.getMessage("lexer.error." + msgId, args);
|
||||
}
|
||||
|
@ -2403,7 +2403,7 @@ loop:
|
||||
verifyStrictIdent(name, "function name");
|
||||
} else if (isStatement) {
|
||||
// Nashorn extension: anonymous function statements
|
||||
if (env._no_syntax_extensions || !env._anon_functions) {
|
||||
if (env._no_syntax_extensions) {
|
||||
expect(IDENT);
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ import java.security.CodeSource;
|
||||
import java.security.Permissions;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Map;
|
||||
import jdk.internal.org.objectweb.asm.ClassReader;
|
||||
import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
@ -188,7 +189,7 @@ public final class Context {
|
||||
private final ScriptEnvironment env;
|
||||
|
||||
/** is this context in strict mode? Cached from env. as this is used heavily. */
|
||||
public final boolean _strict;
|
||||
final boolean _strict;
|
||||
|
||||
/** class loader to resolve classes from script. */
|
||||
private final ClassLoader appLoader;
|
||||
@ -482,6 +483,13 @@ public final class Context {
|
||||
final String name = JSType.toString(sobj.get("name"));
|
||||
source = new Source(name, script);
|
||||
}
|
||||
} else if (src instanceof Map) {
|
||||
final Map map = (Map)src;
|
||||
if (map.containsKey("script") && map.containsKey("name")) {
|
||||
final String script = JSType.toString(map.get("script"));
|
||||
final String name = JSType.toString(map.get("name"));
|
||||
source = new Source(name, script);
|
||||
}
|
||||
}
|
||||
|
||||
if (source != null) {
|
||||
|
@ -373,11 +373,16 @@ loop:
|
||||
sb.append(ch);
|
||||
} else if (ch < 256) {
|
||||
sb.append('%');
|
||||
final byte b = (byte)ch;
|
||||
sb.append(Integer.toHexString(b & 0xFF).toUpperCase(Locale.ENGLISH));
|
||||
if (ch < 16) {
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append(Integer.toHexString(ch).toUpperCase(Locale.ENGLISH));
|
||||
} else {
|
||||
sb.append("%u");
|
||||
sb.append(Integer.toHexString(ch & 0xFFFF).toUpperCase(Locale.ENGLISH));
|
||||
if (ch < 4096) {
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append(Integer.toHexString(ch).toUpperCase(Locale.ENGLISH));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,6 @@ public final class JSONFunctions {
|
||||
final Object val = holder.get(name);
|
||||
if (val instanceof ScriptObject) {
|
||||
final ScriptObject valueObj = (ScriptObject)val;
|
||||
final boolean strict = valueObj.isStrictContext();
|
||||
final Iterator<String> iter = valueObj.propertyIterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
@ -109,9 +108,9 @@ public final class JSONFunctions {
|
||||
final Object newElement = walk(valueObj, key, reviver);
|
||||
|
||||
if (newElement == ScriptRuntime.UNDEFINED) {
|
||||
valueObj.delete(key, strict);
|
||||
valueObj.delete(key, false);
|
||||
} else {
|
||||
setPropertyValue(valueObj, key, newElement, strict);
|
||||
setPropertyValue(valueObj, key, newElement, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -164,14 +163,13 @@ public final class JSONFunctions {
|
||||
} else if (node instanceof ObjectNode) {
|
||||
final ObjectNode objNode = (ObjectNode) node;
|
||||
final ScriptObject object = ((GlobalObject)global).newObject();
|
||||
final boolean strict = global.isStrictContext();
|
||||
|
||||
for (final PropertyNode pNode: objNode.getElements()) {
|
||||
final Node valueNode = pNode.getValue();
|
||||
|
||||
final String name = pNode.getKeyName();
|
||||
final Object value = convertNode(global, valueNode);
|
||||
setPropertyValue(object, name, value, strict);
|
||||
setPropertyValue(object, name, value, false);
|
||||
}
|
||||
|
||||
return object;
|
||||
|
@ -199,7 +199,6 @@ public final class NativeJavaPackage extends ScriptObject {
|
||||
final String fullName = name.isEmpty() ? propertyName : name + "." + propertyName;
|
||||
|
||||
final Context context = getContext();
|
||||
final boolean strict = context._strict;
|
||||
|
||||
Class<?> javaClass = null;
|
||||
try {
|
||||
@ -209,9 +208,9 @@ public final class NativeJavaPackage extends ScriptObject {
|
||||
}
|
||||
|
||||
if (javaClass == null) {
|
||||
set(propertyName, new NativeJavaPackage(fullName, getProto()), strict);
|
||||
set(propertyName, new NativeJavaPackage(fullName, getProto()), false);
|
||||
} else {
|
||||
set(propertyName, StaticClass.forClass(javaClass), strict);
|
||||
set(propertyName, StaticClass.forClass(javaClass), false);
|
||||
}
|
||||
|
||||
return super.lookup(desc, request);
|
||||
|
@ -61,7 +61,7 @@ public class PropertyListenerManager implements PropertyListener {
|
||||
*
|
||||
* @param listener The property listener that is added.
|
||||
*/
|
||||
public final void addPropertyListener(final PropertyListener listener) {
|
||||
public synchronized final void addPropertyListener(final PropertyListener listener) {
|
||||
if (listeners == null) {
|
||||
listeners = new WeakHashMap<>();
|
||||
}
|
||||
@ -77,7 +77,7 @@ public class PropertyListenerManager implements PropertyListener {
|
||||
*
|
||||
* @param listener The property listener that is removed.
|
||||
*/
|
||||
public final void removePropertyListener(final PropertyListener listener) {
|
||||
public synchronized final void removePropertyListener(final PropertyListener listener) {
|
||||
if (listeners != null) {
|
||||
if (Context.DEBUG) {
|
||||
listenersRemoved++;
|
||||
@ -92,7 +92,7 @@ public class PropertyListenerManager implements PropertyListener {
|
||||
* @param object The ScriptObject to which property was added.
|
||||
* @param prop The property being added.
|
||||
*/
|
||||
protected final void notifyPropertyAdded(final ScriptObject object, final Property prop) {
|
||||
protected synchronized final void notifyPropertyAdded(final ScriptObject object, final Property prop) {
|
||||
if (listeners != null) {
|
||||
for (PropertyListener listener : listeners.keySet()) {
|
||||
listener.propertyAdded(object, prop);
|
||||
@ -106,7 +106,7 @@ public class PropertyListenerManager implements PropertyListener {
|
||||
* @param object The ScriptObject from which property was deleted.
|
||||
* @param prop The property being deleted.
|
||||
*/
|
||||
protected final void notifyPropertyDeleted(final ScriptObject object, final Property prop) {
|
||||
protected synchronized final void notifyPropertyDeleted(final ScriptObject object, final Property prop) {
|
||||
if (listeners != null) {
|
||||
for (PropertyListener listener : listeners.keySet()) {
|
||||
listener.propertyDeleted(object, prop);
|
||||
@ -121,7 +121,7 @@ public class PropertyListenerManager implements PropertyListener {
|
||||
* @param oldProp The old property being replaced.
|
||||
* @param newProp The new property that replaces the old property.
|
||||
*/
|
||||
protected final void notifyPropertyModified(final ScriptObject object, final Property oldProp, final Property newProp) {
|
||||
protected synchronized final void notifyPropertyModified(final ScriptObject object, final Property oldProp, final Property newProp) {
|
||||
if (listeners != null) {
|
||||
for (PropertyListener listener : listeners.keySet()) {
|
||||
listener.propertyModified(object, oldProp, newProp);
|
||||
|
@ -95,7 +95,6 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
|
||||
*/
|
||||
private PropertyMap(final PropertyHashMap properties, final int fieldCount, final int fieldMaximum) {
|
||||
this.properties = properties;
|
||||
this.hashCode = computeHashCode();
|
||||
this.fieldCount = fieldCount;
|
||||
this.fieldMaximum = fieldMaximum;
|
||||
|
||||
@ -125,7 +124,6 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
|
||||
this.spillLength = propertyMap.spillLength;
|
||||
this.fieldCount = propertyMap.fieldCount;
|
||||
this.fieldMaximum = propertyMap.fieldMaximum;
|
||||
this.hashCode = computeHashCode();
|
||||
|
||||
if (Context.DEBUG) {
|
||||
count++;
|
||||
@ -610,6 +608,9 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (hashCode == 0 && !properties.isEmpty()) {
|
||||
hashCode = computeHashCode();
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
|
@ -56,9 +56,6 @@ public final class ScriptEnvironment {
|
||||
/** Current Options object. */
|
||||
private final Options options;
|
||||
|
||||
/** Always allow functions as statements */
|
||||
public final boolean _anon_functions;
|
||||
|
||||
/** Size of the per-global Class cache size */
|
||||
public final int _class_cache_size;
|
||||
|
||||
@ -192,7 +189,6 @@ public final class ScriptEnvironment {
|
||||
this.namespace = new Namespace();
|
||||
this.options = options;
|
||||
|
||||
_anon_functions = options.getBoolean("anon.functions");
|
||||
_class_cache_size = options.getInteger("class.cache.size");
|
||||
_compile_only = options.getBoolean("compile.only");
|
||||
_debug_lines = options.getBoolean("debug.lines");
|
||||
|
@ -105,6 +105,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
/** Is this a prototype PropertyMap? */
|
||||
public static final int IS_PROTOTYPE = 0b0000_1000;
|
||||
|
||||
/** Is length property not-writable? */
|
||||
public static final int IS_LENGTH_NOT_WRITABLE = 0b0001_0000;
|
||||
|
||||
/** Spill growth rate - by how many elements does {@link ScriptObject#spill} when full */
|
||||
public static final int SPILL_RATE = 8;
|
||||
|
||||
@ -443,7 +446,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
if (newValue && property != null) {
|
||||
// Temporarily clear flags.
|
||||
property = modifyOwnProperty(property, 0);
|
||||
set(key, value, getContext()._strict);
|
||||
set(key, value, false);
|
||||
}
|
||||
|
||||
if (property == null) {
|
||||
@ -998,7 +1001,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
* @param value the value to write at the given index
|
||||
*/
|
||||
public void setArgument(final int key, final Object value) {
|
||||
set(key, value, getContext()._strict);
|
||||
set(key, value, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1105,7 +1108,8 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
}
|
||||
|
||||
/**
|
||||
* return a List of own keys associated with the object.
|
||||
* return an array of own property keys associated with the object.
|
||||
*
|
||||
* @param all True if to include non-enumerable keys.
|
||||
* @return Array of keys.
|
||||
*/
|
||||
@ -1206,7 +1210,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
* the proto chain
|
||||
*
|
||||
* @param instance instace to check
|
||||
* @return true if instance of instance
|
||||
* @return true if 'instance' is an instance of this object
|
||||
*/
|
||||
public boolean isInstance(final ScriptObject instance) {
|
||||
return false;
|
||||
@ -1277,20 +1281,36 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
*
|
||||
* @return {@code true} if is prototype
|
||||
*/
|
||||
public boolean isPrototype() {
|
||||
public final boolean isPrototype() {
|
||||
return (flags & IS_PROTOTYPE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag this object as having a prototype.
|
||||
*/
|
||||
public void setIsPrototype() {
|
||||
public final void setIsPrototype() {
|
||||
if (proto != null && !isPrototype()) {
|
||||
proto.addPropertyListener(this);
|
||||
}
|
||||
flags |= IS_PROTOTYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this object has non-writable length property
|
||||
*
|
||||
* @return {@code true} if 'length' property is non-writable
|
||||
*/
|
||||
public final boolean isLengthNotWritable() {
|
||||
return (flags & IS_LENGTH_NOT_WRITABLE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag this object as having non-writable length property
|
||||
*/
|
||||
public void setIsLengthNotWritable() {
|
||||
flags |= IS_LENGTH_NOT_WRITABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link ArrayData} for this ScriptObject if it is an array
|
||||
* @return array data
|
||||
@ -1363,7 +1383,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
|
||||
/**
|
||||
* Check whether this ScriptObject is frozen
|
||||
* @return true if frozed
|
||||
* @return true if frozen
|
||||
*/
|
||||
public boolean isFrozen() {
|
||||
return getMap().isFrozen();
|
||||
@ -1393,7 +1413,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
* (java.util.Map-like method to help ScriptObjectMirror implementation)
|
||||
*/
|
||||
public void clear() {
|
||||
final boolean strict = getContext()._strict;
|
||||
final boolean strict = isStrictContext();
|
||||
final Iterator<String> iter = propertyIterator();
|
||||
while (iter.hasNext()) {
|
||||
delete(iter.next(), strict);
|
||||
@ -1481,7 +1501,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
*/
|
||||
public Object put(final Object key, final Object value) {
|
||||
final Object oldValue = get(key);
|
||||
set(key, value, getContext()._strict);
|
||||
set(key, value, isStrictContext());
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@ -1493,7 +1513,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
* @param otherMap a {@literal <key,value>} map of properties to add
|
||||
*/
|
||||
public void putAll(final Map<?, ?> otherMap) {
|
||||
final boolean strict = getContext()._strict;
|
||||
final boolean strict = isStrictContext();
|
||||
for (final Map.Entry<?, ?> entry : otherMap.entrySet()) {
|
||||
set(entry.getKey(), entry.getValue(), strict);
|
||||
}
|
||||
@ -1508,7 +1528,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
*/
|
||||
public Object remove(final Object key) {
|
||||
final Object oldValue = get(key);
|
||||
delete(key, getContext()._strict);
|
||||
delete(key, isStrictContext());
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@ -1520,7 +1540,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
* @return if the delete was successful or not
|
||||
*/
|
||||
public boolean delete(final Object key) {
|
||||
return delete(key, getContext()._strict);
|
||||
return delete(key, isStrictContext());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2222,7 +2242,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean isStrict = getContext()._strict;
|
||||
final boolean isStrict = isStrictContext();
|
||||
|
||||
if (newLength > arrayLength) {
|
||||
setArray(getArray().ensure(newLength - 1));
|
||||
|
@ -825,6 +825,13 @@ public final class ScriptRuntime {
|
||||
return ((StaticClass)clazz).getRepresentedClass().isInstance(obj);
|
||||
}
|
||||
|
||||
if (clazz instanceof ScriptObjectMirror) {
|
||||
if (obj instanceof ScriptObjectMirror) {
|
||||
return ((ScriptObjectMirror)clazz).isInstance((ScriptObjectMirror)obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
throw typeError("instanceof.on.non.object");
|
||||
}
|
||||
|
||||
|
@ -221,10 +221,9 @@ public final class ScriptingFunctions {
|
||||
final String err = errBuffer.toString();
|
||||
|
||||
// Set globals for secondary results.
|
||||
final boolean isStrict = global.isStrictContext();
|
||||
global.set(OUT_NAME, out, isStrict);
|
||||
global.set(ERR_NAME, err, isStrict);
|
||||
global.set(EXIT_NAME, exit, isStrict);
|
||||
global.set(OUT_NAME, out, false);
|
||||
global.set(ERR_NAME, err, false);
|
||||
global.set(EXIT_NAME, exit, false);
|
||||
|
||||
// Propagate exception if present.
|
||||
for (int i = 0; i < exception.length; i++) {
|
||||
|
@ -83,6 +83,6 @@ public class ArrayIterator extends ArrayLikeIterator<Object> {
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
array.delete(index, array.isStrictContext());
|
||||
array.delete(index, false);
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
package jdk.nashorn.internal.runtime.arrays;
|
||||
|
||||
import java.util.Iterator;
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
|
||||
@ -125,6 +126,10 @@ abstract public class ArrayLikeIterator<T> implements Iterator<T> {
|
||||
return new MapIterator((ScriptObject)obj, includeUndefined);
|
||||
}
|
||||
|
||||
if (obj instanceof ScriptObjectMirror) {
|
||||
return new ScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined);
|
||||
}
|
||||
|
||||
return new EmptyArrayLikeIterator();
|
||||
}
|
||||
|
||||
@ -146,6 +151,10 @@ abstract public class ArrayLikeIterator<T> implements Iterator<T> {
|
||||
return new ReverseMapIterator((ScriptObject)obj, includeUndefined);
|
||||
}
|
||||
|
||||
if (obj instanceof ScriptObjectMirror) {
|
||||
return new ReverseScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined);
|
||||
}
|
||||
|
||||
assert !obj.getClass().isArray();
|
||||
|
||||
return new EmptyArrayLikeIterator();
|
||||
|
@ -27,6 +27,7 @@ package jdk.nashorn.internal.runtime.arrays;
|
||||
|
||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
@ -96,12 +97,18 @@ public abstract class IteratorAction<T> {
|
||||
* @return result of apply
|
||||
*/
|
||||
public final T apply() {
|
||||
if (!(callbackfn instanceof ScriptFunction)) {
|
||||
final boolean strict;
|
||||
if (callbackfn instanceof ScriptFunction) {
|
||||
strict = ((ScriptFunction)callbackfn).isStrict();
|
||||
} else if (callbackfn instanceof ScriptObjectMirror &&
|
||||
((ScriptObjectMirror)callbackfn).isFunction()) {
|
||||
strict = ((ScriptObjectMirror)callbackfn).isStrictFunction();
|
||||
} else {
|
||||
throw typeError("not.a.function", ScriptRuntime.safeToString(callbackfn));
|
||||
}
|
||||
final ScriptFunction func = ((ScriptFunction)callbackfn);
|
||||
|
||||
// for non-strict callback, need to translate undefined thisArg to be global object
|
||||
thisArg = (thisArg == ScriptRuntime.UNDEFINED && !func.isStrict()) ? Context.getGlobal() : thisArg;
|
||||
thisArg = (thisArg == ScriptRuntime.UNDEFINED && !strict)? Context.getGlobal() : thisArg;
|
||||
|
||||
applyLoopBegin(iter);
|
||||
final boolean reverse = iter.isReverse();
|
||||
|
@ -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. 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.runtime.arrays;
|
||||
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
|
||||
/**
|
||||
* Reverse iterator over a ScriptObjectMirror
|
||||
*/
|
||||
final class ReverseScriptObjectMirrorIterator extends ScriptObjectMirrorIterator {
|
||||
|
||||
ReverseScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) {
|
||||
super(obj, includeUndefined);
|
||||
this.index = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0) - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReverse() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean indexInArray() {
|
||||
return index >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long bumpIndex() {
|
||||
return index--;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.runtime.arrays;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
|
||||
/**
|
||||
* Iterator over a ScriptObjectMirror
|
||||
*/
|
||||
class ScriptObjectMirrorIterator extends ArrayLikeIterator<Object> {
|
||||
|
||||
protected final ScriptObjectMirror obj;
|
||||
private final long length;
|
||||
|
||||
ScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) {
|
||||
super(includeUndefined);
|
||||
this.obj = obj;
|
||||
this.length = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0);
|
||||
this.index = 0;
|
||||
}
|
||||
|
||||
protected boolean indexInArray() {
|
||||
return index < length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (length == 0L) {
|
||||
return false; //return empty string if toUint32(length) == 0
|
||||
}
|
||||
|
||||
while (indexInArray()) {
|
||||
if (obj.containsKey(index) || includeUndefined) {
|
||||
break;
|
||||
}
|
||||
bumpIndex();
|
||||
}
|
||||
|
||||
return indexInArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object next() {
|
||||
if (indexInArray()) {
|
||||
return obj.get(bumpIndex());
|
||||
}
|
||||
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,8 @@
|
||||
lexer.error.edit.string.missing.brace=Edit string expression missing closing brace
|
||||
lexer.error.here.missing.end.marker=Here string missing end marker "{0}"
|
||||
lexer.error.missing.close.quote=Missing close quote
|
||||
lexer.error.missing.space.after.number=Missing space after numeric literal
|
||||
lexer.error.invalid.hex=Invalid hex digit
|
||||
lexer.error.invalid.octal=Invalid octal digit
|
||||
lexer.error.strict.no.octal=cannot use octal escapes in strict mode
|
||||
lexer.error.json.invalid.number=Invalid JSON number format
|
||||
lexer.error.invalid.escape.char=Invalid escape character
|
||||
|
@ -59,7 +59,7 @@ nashorn.options.D.key = nashorn.option.D
|
||||
## is_undocumented - should this option never appear in the online help. defaults to no.
|
||||
## desc - description of what the option does
|
||||
## default - default value of the option. e.g. debug.lines is true by default. Not set means option not available by default
|
||||
## dependency - does this arg imply another arg, e.g. scripting -> anon-functions
|
||||
## dependency - does this arg imply another arg.
|
||||
## confict - does this arg conflict with another arg e.g trace && instrument
|
||||
## value_next_arg - is the opton's value passed as next argument in command line?
|
||||
##
|
||||
@ -77,16 +77,9 @@ nashorn.option.xhelp = { \
|
||||
desc="Print extended help for command line flags." \
|
||||
}
|
||||
|
||||
nashorn.option.anon.functions = { \
|
||||
name="--anon-functions", \
|
||||
short_name="-af", \
|
||||
is_undocumented=true, \
|
||||
desc="Always allow functions as statements." \
|
||||
}
|
||||
|
||||
nashorn.option.class.cache.size ={ \
|
||||
name="--class-cache-size", \
|
||||
short_name="--ccs", \
|
||||
short_name="-ccs", \
|
||||
desc="Size of the Class cache size per global scope.", \
|
||||
is_undocumented=true, \
|
||||
type=Integer, \
|
||||
@ -201,10 +194,10 @@ nashorn.option.loader.per.compile = { \
|
||||
|
||||
nashorn.option.no.syntax.extensions = { \
|
||||
name="--no-syntax-extensions", \
|
||||
short_name="--nse", \
|
||||
short_name="-nse", \
|
||||
is_undocumented=true, \
|
||||
desc="No non-standard syntax extensions", \
|
||||
default=-anon-functions=false \
|
||||
default=false \
|
||||
}
|
||||
|
||||
nashorn.option.package = { \
|
||||
@ -296,8 +289,7 @@ nashorn.option.strict = { \
|
||||
|
||||
nashorn.option.scripting = { \
|
||||
name="-scripting", \
|
||||
desc="Enable scripting features.", \
|
||||
dependency="--anon-functions=true" \
|
||||
desc="Enable scripting features." \
|
||||
}
|
||||
|
||||
nashorn.option.specialize.calls = { \
|
||||
|
51
nashorn/test/script/basic/JDK-8011893.js
Normal file
51
nashorn/test/script/basic/JDK-8011893.js
Normal file
@ -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-8011893: JS Object builtin prototype is not thread safe
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
var a = {};
|
||||
var thread = new java.lang.Thread(new java.lang.Runnable() {
|
||||
run: function() {
|
||||
print("Thread starts");
|
||||
for (var i = 0; i < 1000000; i++) {
|
||||
// Unsubscribe to builtin, subscribe to new proto
|
||||
var b = Object.create(a);
|
||||
}
|
||||
print("Thread done");
|
||||
}
|
||||
});
|
||||
|
||||
print("Main starts");
|
||||
thread.start();
|
||||
for (var j = 0; j < 1000000; j++) {
|
||||
// Subscribe to builtin prototype.
|
||||
a = {};
|
||||
}
|
||||
|
||||
thread.join();
|
||||
print("Main done");
|
4
nashorn/test/script/basic/JDK-8011893.js.EXPECTED
Normal file
4
nashorn/test/script/basic/JDK-8011893.js.EXPECTED
Normal file
@ -0,0 +1,4 @@
|
||||
Main starts
|
||||
Thread starts
|
||||
Thread done
|
||||
Main done
|
122
nashorn/test/script/basic/JDK-8015355.js
Normal file
122
nashorn/test/script/basic/JDK-8015355.js
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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-8015355: Array.prototype functions don't honour non-writable length and / or index properties
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
function fail(msg) {
|
||||
print(msg);
|
||||
}
|
||||
|
||||
function check(callback) {
|
||||
try {
|
||||
callback();
|
||||
fail("TypeError expected for " + callback);
|
||||
} catch (e) {
|
||||
if (! (e instanceof TypeError)) {
|
||||
fail("TypeError expected, got " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var array = Object.defineProperty([],"length", { writable: false });
|
||||
|
||||
check(function() {
|
||||
array.push(0)
|
||||
});
|
||||
|
||||
check(function() {
|
||||
array.pop()
|
||||
});
|
||||
|
||||
check(function() {
|
||||
Object.defineProperty([,,],"0",{ writable: false }).reverse();
|
||||
});
|
||||
|
||||
check(function() {
|
||||
array.shift()
|
||||
});
|
||||
|
||||
check(function() {
|
||||
array.splice(0)
|
||||
});
|
||||
|
||||
check(function() {
|
||||
array.unshift()
|
||||
});
|
||||
|
||||
// try the above via call
|
||||
|
||||
check(function() {
|
||||
Array.prototype.push.call(array, 0);
|
||||
});
|
||||
|
||||
check(function() {
|
||||
Array.prototype.pop.call(array);
|
||||
});
|
||||
|
||||
check(function() {
|
||||
Array.prototype.shift.call(array);
|
||||
});
|
||||
|
||||
check(function() {
|
||||
Array.prototype.unshift.call(array);
|
||||
});
|
||||
|
||||
check(function() {
|
||||
Array.prototype.splice.call(array, 0);
|
||||
});
|
||||
|
||||
check(function() {
|
||||
Array.prototype.reverse.call(Object.defineProperty([,,],"0",{ writable: false }));
|
||||
});
|
||||
|
||||
// try the above via apply
|
||||
|
||||
check(function() {
|
||||
Array.prototype.push.apply(array, [ 0 ]);
|
||||
});
|
||||
|
||||
check(function() {
|
||||
Array.prototype.pop.apply(array);
|
||||
});
|
||||
|
||||
check(function() {
|
||||
Array.prototype.shift.apply(array);
|
||||
});
|
||||
|
||||
check(function() {
|
||||
Array.prototype.unshift.apply(array);
|
||||
});
|
||||
|
||||
check(function() {
|
||||
Array.prototype.splice.apply(array, [ 0 ]);
|
||||
});
|
||||
|
||||
check(function() {
|
||||
Array.prototype.reverse.apply(Object.defineProperty([,,],"0",{ writable: false }));
|
||||
});
|
51
nashorn/test/script/basic/JDK-8016235.js
Normal file
51
nashorn/test/script/basic/JDK-8016235.js
Normal file
@ -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-8016235 : use before definition in catch block generated erroneous bytecode
|
||||
* as there is no guarantee anything in the try block has executed.
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
function f() {
|
||||
try {
|
||||
var parser = {};
|
||||
} catch (e) {
|
||||
parser = parser.context();
|
||||
}
|
||||
}
|
||||
|
||||
function g() {
|
||||
try {
|
||||
return "apa";
|
||||
} catch (tmp) {
|
||||
//for now, too conservative as var ex declaration exists on the function
|
||||
//level, but at least the code does not break, and the analysis is driven
|
||||
//from the catch block (the rare case), not the try block (the common case)
|
||||
var ex = new Error("DOM Exception 5");
|
||||
ex.code = ex.number = 5;
|
||||
return ex;
|
||||
}
|
||||
}
|
38
nashorn/test/script/basic/JDK-8016518.js
Normal file
38
nashorn/test/script/basic/JDK-8016518.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-8016518: Parsing of octal string escapes is broken
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
print("\471".charCodeAt(0));
|
||||
print("\471".charCodeAt(1));
|
||||
|
||||
print("\377".length);
|
||||
print("\377".charCodeAt(0));
|
||||
print("\400".length);
|
||||
print("\400".charCodeAt(0));
|
||||
print("\400".charCodeAt(1));
|
7
nashorn/test/script/basic/JDK-8016518.js.EXPECTED
Normal file
7
nashorn/test/script/basic/JDK-8016518.js.EXPECTED
Normal file
@ -0,0 +1,7 @@
|
||||
39
|
||||
49
|
||||
1
|
||||
255
|
||||
2
|
||||
32
|
||||
48
|
33
nashorn/test/script/basic/JDK-8016528.js
Normal file
33
nashorn/test/script/basic/JDK-8016528.js
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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-8016528: Hex code from escape() should be padded
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
for (var i = 0; i < 8192; i++) {
|
||||
print(escape(String.fromCharCode(i)));
|
||||
}
|
8192
nashorn/test/script/basic/JDK-8016528.js.EXPECTED
Normal file
8192
nashorn/test/script/basic/JDK-8016528.js.EXPECTED
Normal file
File diff suppressed because it is too large
Load Diff
37
nashorn/test/script/basic/JDK-8016542.js
Normal file
37
nashorn/test/script/basic/JDK-8016542.js
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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-8016542: String.prototype.replace called with function argument should not replace $ patterns
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
print("abc".replace("a", "$&"));
|
||||
print("abc".replace("b", "$&"));
|
||||
print("abc".replace("c", "$&"));
|
||||
|
||||
print("abc".replace("a", function(){return "$&"}));
|
||||
print("abc".replace("b", function(){return "$&"}));
|
||||
print("abc".replace("c", function(){return "$&"}));
|
6
nashorn/test/script/basic/JDK-8016542.js.EXPECTED
Normal file
6
nashorn/test/script/basic/JDK-8016542.js.EXPECTED
Normal file
@ -0,0 +1,6 @@
|
||||
abc
|
||||
abc
|
||||
abc
|
||||
$&bc
|
||||
a$&c
|
||||
ab$&
|
132
nashorn/test/script/basic/JDK-8016618.js
Normal file
132
nashorn/test/script/basic/JDK-8016618.js
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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-8016618: script mirror object access should be improved
|
||||
*
|
||||
* @test
|
||||
* @option -scripting
|
||||
* @option -strict
|
||||
* @run
|
||||
*/
|
||||
|
||||
var global = loadWithNewGlobal({
|
||||
name: "code",
|
||||
script: <<EOF
|
||||
var x = 33;
|
||||
|
||||
function func(x, y) {
|
||||
print('func.x = ' + x);
|
||||
print('func.x = ' + y)
|
||||
};
|
||||
|
||||
var obj = {
|
||||
foo: 'hello',
|
||||
bar: 42
|
||||
};
|
||||
|
||||
Object.defineProperty(obj, "bar",
|
||||
{ enumerable: false, writable: false });
|
||||
|
||||
// return global
|
||||
this;
|
||||
EOF
|
||||
});
|
||||
|
||||
// load on mirror with local object as argument
|
||||
global.load({
|
||||
name: "code",
|
||||
script: "print('x = ' + x)"
|
||||
});
|
||||
|
||||
function f() {
|
||||
// mirror function called with local arguments
|
||||
global.func.apply(obj, arguments);
|
||||
}
|
||||
|
||||
f(23, "hello");
|
||||
|
||||
var fObject = global.eval("Object");
|
||||
|
||||
// instanceof on mirrors
|
||||
print("global instanceof fObject? " + (global instanceof fObject));
|
||||
|
||||
// Object API on mirrors
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor(global, "x");
|
||||
print("x is wriable ? " + desc.writable);
|
||||
print("x value = " + desc.value);
|
||||
|
||||
var proto = Object.getPrototypeOf(global);
|
||||
print("global's __proto__ " + proto);
|
||||
|
||||
var obj = global.obj;
|
||||
var keys = Object.keys(obj);
|
||||
print("Object.keys on obj");
|
||||
for (var i in keys) {
|
||||
print(keys[i]);
|
||||
}
|
||||
|
||||
print("Object.getOwnProperties on obj");
|
||||
var keys = Object.getOwnPropertyNames(obj);
|
||||
for (var i in keys) {
|
||||
print(keys[i]);
|
||||
}
|
||||
|
||||
// mirror array access
|
||||
var array = global.eval("[334, 55, 65]");
|
||||
Array.prototype.forEach.call(array, function(elem) {
|
||||
print("forEach " + elem)
|
||||
});
|
||||
|
||||
print("reduceRight " + Array.prototype.reduceRight.call(array,
|
||||
function(previousValue, currentValue, index, array) {
|
||||
print("reduceRight cur value " + currentValue);
|
||||
return previousValue + currentValue;
|
||||
}, 0));
|
||||
|
||||
print("reduce " + Array.prototype.reduce.call(array,
|
||||
function(previousValue, currentValue, index, array) {
|
||||
print("reduce cur value " + currentValue);
|
||||
return previousValue + currentValue;
|
||||
}, 0));
|
||||
|
||||
print("forEach");
|
||||
Array.prototype.forEach.call(array, function(o) {
|
||||
print(o);
|
||||
});
|
||||
|
||||
print("Array.isArray(array)? " + Array.isArray(array));
|
||||
|
||||
// try to write to a non-writable property of mirror
|
||||
try {
|
||||
obj.bar = 33;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
// mirror function called with local callback
|
||||
print("forEach on mirror");
|
||||
array.forEach(function(toto) {
|
||||
print(toto);
|
||||
});
|
33
nashorn/test/script/basic/JDK-8016618.js.EXPECTED
Normal file
33
nashorn/test/script/basic/JDK-8016618.js.EXPECTED
Normal file
@ -0,0 +1,33 @@
|
||||
x = 33
|
||||
func.x = 23
|
||||
func.x = hello
|
||||
global instanceof fObject? true
|
||||
x is wriable ? true
|
||||
x value = 33
|
||||
global's __proto__ [object Object]
|
||||
Object.keys on obj
|
||||
foo
|
||||
Object.getOwnProperties on obj
|
||||
foo
|
||||
bar
|
||||
forEach 334
|
||||
forEach 55
|
||||
forEach 65
|
||||
reduceRight cur value 65
|
||||
reduceRight cur value 55
|
||||
reduceRight cur value 334
|
||||
reduceRight 454
|
||||
reduce cur value 334
|
||||
reduce cur value 55
|
||||
reduce cur value 65
|
||||
reduce 454
|
||||
forEach
|
||||
334
|
||||
55
|
||||
65
|
||||
Array.isArray(array)? true
|
||||
TypeError: "bar" is not a writable property of [object Object]
|
||||
forEach on mirror
|
||||
334
|
||||
55
|
||||
65
|
@ -25,7 +25,6 @@
|
||||
* This loads "module.js" and calls the anonymous top-level function from it.
|
||||
*
|
||||
* @test
|
||||
* @option --anon-functions
|
||||
* @run
|
||||
*/
|
||||
|
||||
|
30
nashorn/test/script/error/JDK-8016522.js
Normal file
30
nashorn/test/script/error/JDK-8016522.js
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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-8016522: Numeric literal must not be followed by IdentifierStart
|
||||
*
|
||||
* @test/compile-error
|
||||
*/
|
||||
|
||||
3in {};
|
3
nashorn/test/script/error/JDK-8016522.js.EXPECTED
Normal file
3
nashorn/test/script/error/JDK-8016522.js.EXPECTED
Normal file
@ -0,0 +1,3 @@
|
||||
test/script/error/JDK-8016522.js:30:1 Missing space after numeric literal
|
||||
3in {};
|
||||
^
|
Loading…
x
Reference in New Issue
Block a user