Merge
This commit is contained in:
commit
600a087671
@ -23,6 +23,7 @@ report.xml
|
||||
CC/*
|
||||
jcov2/*
|
||||
.idea/*
|
||||
test/lib/testng*.zip
|
||||
test/lib/testng.jar
|
||||
test/script/external/*
|
||||
.project
|
||||
|
@ -55,7 +55,7 @@ import java.util.List;
|
||||
import jdk.internal.org.objectweb.asm.Handle;
|
||||
|
||||
/**
|
||||
* This class generates constructor class for a @ClassInfo annotated class.
|
||||
* This class generates constructor class for a @ScriptClass annotated class.
|
||||
*
|
||||
*/
|
||||
public class ConstructorGenerator extends ClassGenerator {
|
||||
@ -75,7 +75,7 @@ public class ConstructorGenerator extends ClassGenerator {
|
||||
}
|
||||
|
||||
byte[] getClassBytes() {
|
||||
// new class extensing from ScriptObject
|
||||
// new class extending from ScriptObject
|
||||
final String superClass = (constructor != null)? SCRIPTFUNCTIONIMPL_TYPE : SCRIPTOBJECT_TYPE;
|
||||
cw.visit(V1_7, ACC_FINAL, className, null, superClass, null);
|
||||
if (memberCount > 0) {
|
||||
|
@ -161,7 +161,7 @@ public final class MemberInfo implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag something as optimitic builtin or not
|
||||
* Tag something as optimistic builtin or not
|
||||
* @param isOptimistic boolean, true if builtin constructor
|
||||
*/
|
||||
public void setIsOptimistic(final boolean isOptimistic) {
|
||||
@ -178,7 +178,7 @@ public final class MemberInfo implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set thre SpecializedFunction link logic class for specializations, i.e. optimistic
|
||||
* Set the SpecializedFunction link logic class for specializations, i.e. optimistic
|
||||
* builtins
|
||||
* @param linkLogicClass link logic class
|
||||
*/
|
||||
|
@ -42,7 +42,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class generates prototype class for a @ClassInfo annotated class.
|
||||
* This class generates prototype class for a @ScriptClass annotated class.
|
||||
*
|
||||
*/
|
||||
public class PrototypeGenerator extends ClassGenerator {
|
||||
@ -57,7 +57,7 @@ public class PrototypeGenerator extends ClassGenerator {
|
||||
}
|
||||
|
||||
byte[] getClassBytes() {
|
||||
// new class extensing from ScriptObject
|
||||
// new class extending from ScriptObject
|
||||
cw.visit(V1_7, ACC_FINAL | ACC_SUPER, className, null, PROTOTYPEOBJECT_TYPE, null);
|
||||
if (memberCount > 0) {
|
||||
// add fields
|
||||
@ -155,7 +155,7 @@ public class PrototypeGenerator extends ClassGenerator {
|
||||
*/
|
||||
public static void main(final String[] args) throws IOException {
|
||||
if (args.length != 1) {
|
||||
System.err.println("Usage: " + ConstructorGenerator.class.getName() + " <class>");
|
||||
System.err.println("Usage: " + PrototypeGenerator.class.getName() + " <class>");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind;
|
||||
*
|
||||
*/
|
||||
public final class ScriptClassInfo {
|
||||
// descriptots for various annotations
|
||||
// descriptors for various annotations
|
||||
static final String SCRIPT_CLASS_ANNO_DESC = Type.getDescriptor(ScriptClass.class);
|
||||
static final String CONSTRUCTOR_ANNO_DESC = Type.getDescriptor(Constructor.class);
|
||||
static final String FUNCTION_ANNO_DESC = Type.getDescriptor(Function.class);
|
||||
@ -140,7 +140,7 @@ public final class ScriptClassInfo {
|
||||
}
|
||||
|
||||
boolean isPrototypeNeeded() {
|
||||
// Prototype class generation is needed if we have atleast one
|
||||
// Prototype class generation is needed if we have at least one
|
||||
// prototype property or @Constructor defined in the class.
|
||||
for (final MemberInfo memInfo : members) {
|
||||
if (memInfo.getWhere() == Where.PROTOTYPE || memInfo.isConstructor()) {
|
||||
|
@ -118,7 +118,7 @@ public class ScriptClassInfoCollector extends ClassVisitor {
|
||||
addScriptMember(memInfo);
|
||||
|
||||
return new AnnotationVisitor(Main.ASM_VERSION, delegateAV) {
|
||||
// These could be "null" if values are not suppiled,
|
||||
// These could be "null" if values are not supplied,
|
||||
// in which case we have to use the default values.
|
||||
private String name;
|
||||
private Integer attributes;
|
||||
@ -194,7 +194,7 @@ public class ScriptClassInfoCollector extends ClassVisitor {
|
||||
|
||||
final MemberInfo memInfo = new MemberInfo();
|
||||
|
||||
//annokind == e.g. GETTER or SPECIALIZED_FUNCTION
|
||||
// annoKind == GETTER or SPECIALIZED_FUNCTION
|
||||
memInfo.setKind(annoKind);
|
||||
memInfo.setJavaName(methodName);
|
||||
memInfo.setJavaDesc(methodDesc);
|
||||
@ -203,7 +203,7 @@ public class ScriptClassInfoCollector extends ClassVisitor {
|
||||
addScriptMember(memInfo);
|
||||
|
||||
return new AnnotationVisitor(Main.ASM_VERSION, delegateAV) {
|
||||
// These could be "null" if values are not suppiled,
|
||||
// These could be "null" if values are not supplied,
|
||||
// in which case we have to use the default values.
|
||||
private String name;
|
||||
private Integer attributes;
|
||||
|
@ -64,7 +64,6 @@ import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind;
|
||||
* 2) add "Map" type static field named "$map".
|
||||
* 3) add static initializer block to initialize map.
|
||||
*/
|
||||
|
||||
public class ScriptClassInstrumentor extends ClassVisitor {
|
||||
private final ScriptClassInfo scriptClassInfo;
|
||||
private final int memberCount;
|
||||
@ -266,7 +265,7 @@ public class ScriptClassInstrumentor extends ClassVisitor {
|
||||
*/
|
||||
public static void main(final String[] args) throws IOException {
|
||||
if (args.length != 1) {
|
||||
System.err.println("Usage: " + ScriptClassInfoCollector.class.getName() + " <class>");
|
||||
System.err.println("Usage: " + ScriptClassInstrumentor.class.getName() + " <class>");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ public abstract class AbstractJSObject implements JSObject {
|
||||
/**
|
||||
* Checking whether the given object is an instance of 'this' object.
|
||||
*
|
||||
* @param instance instace to check
|
||||
* @param instance instance to check
|
||||
* @return true if the given 'instance' is an instance of this 'function' object
|
||||
*/
|
||||
@Override
|
||||
|
@ -142,7 +142,7 @@ public interface JSObject {
|
||||
/**
|
||||
* Checking whether the given object is an instance of 'this' object.
|
||||
*
|
||||
* @param instance instace to check
|
||||
* @param instance instance to check
|
||||
* @return true if the given 'instance' is an instance of this 'function' object
|
||||
*/
|
||||
public boolean isInstance(final Object instance);
|
||||
|
@ -2118,17 +2118,18 @@ public final class Global extends Scope {
|
||||
}
|
||||
}
|
||||
|
||||
final boolean extensible = isExtensible();
|
||||
for (final jdk.nashorn.internal.runtime.Property property : properties) {
|
||||
if (property.isLexicalBinding()) {
|
||||
assert lexScope != null;
|
||||
lexicalMap = lexScope.addBoundProperty(lexicalMap, source, property);
|
||||
lexicalMap = lexScope.addBoundProperty(lexicalMap, source, property, true);
|
||||
|
||||
if (ownMap.findProperty(property.getKey()) != null) {
|
||||
// If property exists in the global object invalidate any global constant call sites.
|
||||
invalidateGlobalConstant(property.getKey());
|
||||
}
|
||||
} else {
|
||||
ownMap = addBoundProperty(ownMap, source, property);
|
||||
ownMap = addBoundProperty(ownMap, source, property, extensible);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2730,9 +2731,9 @@ public final class Global extends Scope {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final jdk.nashorn.internal.runtime.Property property) {
|
||||
protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final jdk.nashorn.internal.runtime.Property property, final boolean extensible) {
|
||||
// We override this method just to make it callable by Global
|
||||
return super.addBoundProperty(propMap, source, property);
|
||||
return super.addBoundProperty(propMap, source, property, extensible);
|
||||
}
|
||||
|
||||
private static GuardedInvocation filterInvocation(final GuardedInvocation invocation) {
|
||||
|
@ -22,6 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.nashorn.internal.objects;
|
||||
|
||||
import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
|
||||
|
@ -108,7 +108,7 @@ public final class NativeFunction {
|
||||
throw new AssertionError("Should not reach here");
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Given an array-like object, converts it into a Java object array suitable for invocation of ScriptRuntime.apply
|
||||
* or for direct invocation of the applied function.
|
||||
* @param array the array-like object. Can be null in which case a zero-length array is created.
|
||||
|
@ -187,14 +187,14 @@ public final class GlobalFunctions {
|
||||
|
||||
double result = 0.0;
|
||||
int digit;
|
||||
// we should see atleast one valid digit
|
||||
// we should see at least one valid digit
|
||||
boolean entered = false;
|
||||
while (idx < length) {
|
||||
digit = fastDigit(str.charAt(idx++), radix);
|
||||
if (digit < 0) {
|
||||
break;
|
||||
}
|
||||
// we have seen atleast one valid digit in the specified radix
|
||||
// we have seen at least one valid digit in the specified radix
|
||||
entered = true;
|
||||
result *= radix;
|
||||
result += digit;
|
||||
|
@ -104,16 +104,28 @@ public final class JSONFunctions {
|
||||
final Object val = holder.get(name);
|
||||
if (val instanceof ScriptObject) {
|
||||
final ScriptObject valueObj = (ScriptObject)val;
|
||||
final Iterator<String> iter = valueObj.propertyIterator();
|
||||
if (valueObj.isArray()) {
|
||||
final int length = JSType.toInteger(valueObj.getLength());
|
||||
for (int i = 0; i < length; i++) {
|
||||
final String key = Integer.toString(i);
|
||||
final Object newElement = walk(valueObj, key, reviver);
|
||||
|
||||
while (iter.hasNext()) {
|
||||
final String key = iter.next();
|
||||
final Object newElement = walk(valueObj, key, reviver);
|
||||
if (newElement == ScriptRuntime.UNDEFINED) {
|
||||
valueObj.delete(i, false);
|
||||
} else {
|
||||
setPropertyValue(valueObj, key, newElement);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final String[] keys = valueObj.getOwnKeys(false);
|
||||
for (final String key : keys) {
|
||||
final Object newElement = walk(valueObj, key, reviver);
|
||||
|
||||
if (newElement == ScriptRuntime.UNDEFINED) {
|
||||
valueObj.delete(key, false);
|
||||
} else {
|
||||
setPropertyValue(valueObj, key, newElement);
|
||||
if (newElement == ScriptRuntime.UNDEFINED) {
|
||||
valueObj.delete(key, false);
|
||||
} else {
|
||||
setPropertyValue(valueObj, key, newElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
* same combination of prototype and property map.
|
||||
*
|
||||
* @param proto the prototype object
|
||||
* @param map intial {@link PropertyMap}
|
||||
* @param map initial {@link PropertyMap}
|
||||
*/
|
||||
protected ScriptObject(final ScriptObject proto, final PropertyMap map) {
|
||||
this(map);
|
||||
@ -287,9 +287,10 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
*/
|
||||
public void addBoundProperties(final ScriptObject source, final Property[] properties) {
|
||||
PropertyMap newMap = this.getMap();
|
||||
final boolean extensible = newMap.isExtensible();
|
||||
|
||||
for (final Property property : properties) {
|
||||
newMap = addBoundProperty(newMap, source, property);
|
||||
newMap = addBoundProperty(newMap, source, property, extensible);
|
||||
}
|
||||
|
||||
this.setMap(newMap);
|
||||
@ -302,13 +303,18 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
* @param propMap the property map
|
||||
* @param source the source object
|
||||
* @param property the property to be added
|
||||
* @param extensible whether the current object is extensible or not
|
||||
* @return the new property map
|
||||
*/
|
||||
protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final Property property) {
|
||||
protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final Property property, final boolean extensible) {
|
||||
PropertyMap newMap = propMap;
|
||||
final String key = property.getKey();
|
||||
final Property oldProp = newMap.findProperty(key);
|
||||
if (oldProp == null) {
|
||||
if (! extensible) {
|
||||
throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
|
||||
}
|
||||
|
||||
if (property instanceof UserAccessorProperty) {
|
||||
// Note: we copy accessor functions to this object which is semantically different from binding.
|
||||
final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
|
||||
@ -337,11 +343,15 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
*/
|
||||
public void addBoundProperties(final Object source, final AccessorProperty[] properties) {
|
||||
PropertyMap newMap = this.getMap();
|
||||
final boolean extensible = newMap.isExtensible();
|
||||
|
||||
for (final AccessorProperty property : properties) {
|
||||
final String key = property.getKey();
|
||||
|
||||
if (newMap.findProperty(key) == null) {
|
||||
if (! extensible) {
|
||||
throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
|
||||
}
|
||||
newMap = newMap.addPropertyBind(property, source);
|
||||
}
|
||||
}
|
||||
@ -1247,7 +1257,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
if (oldProto != newProto) {
|
||||
proto = newProto;
|
||||
|
||||
// Let current listeners know that the protototype has changed and set our map
|
||||
// Let current listeners know that the prototype has changed and set our map
|
||||
final PropertyListeners listeners = getMap().getListeners();
|
||||
if (listeners != null) {
|
||||
listeners.protoChanged();
|
||||
@ -1442,7 +1452,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
* in {@link ScriptFunction} for hasInstance implementation, walks
|
||||
* the proto chain
|
||||
*
|
||||
* @param instance instace to check
|
||||
* @param instance instance to check
|
||||
* @return true if 'instance' is an instance of this object
|
||||
*/
|
||||
public boolean isInstance(final ScriptObject instance) {
|
||||
@ -1859,7 +1869,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
* @param desc the call site descriptor.
|
||||
* @param request the link request
|
||||
*
|
||||
* @return GuardedInvocation to be invoed at call site.
|
||||
* @return GuardedInvocation to be invoked at call site.
|
||||
*/
|
||||
protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
|
||||
return notAFunction();
|
||||
|
@ -69,7 +69,7 @@ public final class Bootstrap {
|
||||
private static final MethodHandle VOID_TO_OBJECT = MH.constant(Object.class, ScriptRuntime.UNDEFINED);
|
||||
|
||||
/**
|
||||
* The default dynalink relink threshold for megamorphisism is 8. In the case
|
||||
* The default dynalink relink threshold for megamorphism is 8. In the case
|
||||
* of object fields only, it is fine. However, with dual fields, in order to get
|
||||
* performance on benchmarks with a lot of object instantiation and then field
|
||||
* reassignment, it can take slightly more relinks to become stable with type
|
||||
@ -213,7 +213,7 @@ public final class Bootstrap {
|
||||
* @param type method type
|
||||
* @param programPoint program point to bind to callsite
|
||||
*
|
||||
* @return callsite for a math instrinic node
|
||||
* @return callsite for a math intrinsic node
|
||||
*/
|
||||
public static CallSite mathBootstrap(final MethodHandles.Lookup lookup, final String name, final MethodType type, final int programPoint) {
|
||||
final MethodHandle mh;
|
||||
|
@ -571,7 +571,7 @@ final class JavaAdapterBytecodeGenerator {
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
if (fromFunction && !mi.getName().equals(samName)) {
|
||||
// Constructors initializing from a ScriptFunction only initialize methods with the SAM name.
|
||||
// NOTE: if there's a concrete overloaded method sharing the SAM name, it'll be overriden too. This
|
||||
// NOTE: if there's a concrete overloaded method sharing the SAM name, it'll be overridden too. This
|
||||
// is a deliberate design choice. All other method handles are initialized to null.
|
||||
mv.visitInsn(ACONST_NULL);
|
||||
} else {
|
||||
|
@ -500,7 +500,7 @@ public class LinkerCallSite extends ChainedCallSite {
|
||||
* @param desc callsite descriptor string
|
||||
* @param args arguments to function
|
||||
*
|
||||
* @throws Throwable if invocation failes or throws exception/error
|
||||
* @throws Throwable if invocation fails or throws exception/error
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public void traceMiss(final String desc, final Object... args) throws Throwable {
|
||||
|
@ -169,7 +169,7 @@ public class NashornBeansLinker implements GuardingDynamicLinker {
|
||||
}
|
||||
|
||||
for (final Class<?> iface : clazz.getInterfaces()) {
|
||||
// check accessiblity up-front
|
||||
// check accessibility up-front
|
||||
if (! Context.isAccessibleClass(iface)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor
|
||||
* {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
|
||||
* generated outside of Nashorn.
|
||||
* @param flag the tested flag
|
||||
* @return true if the flag is set, false otherwise (it will be false if the decriptor is not a Nashorn call site
|
||||
* @return true if the flag is set, false otherwise (it will be false if the descriptor is not a Nashorn call site
|
||||
* descriptor).
|
||||
*/
|
||||
private static boolean isFlag(final CallSiteDescriptor desc, final int flag) {
|
||||
|
@ -163,7 +163,7 @@ public final class OptionTemplate implements Comparable<OptionTemplate> {
|
||||
|
||||
/**
|
||||
* Does this option automatically enable another option, i.e. a dependency.
|
||||
* @return the dependecy or null if non exists
|
||||
* @return the dependency or null if none exists
|
||||
*/
|
||||
public String getDependency() {
|
||||
return this.dependency;
|
||||
|
89
nashorn/test/script/basic/JDK-8130853.js
Normal file
89
nashorn/test/script/basic/JDK-8130853.js
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* JDK-8130853: Non-extensible global is not handled property
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
// don't allow extensions to global
|
||||
Object.preventExtensions(this);
|
||||
try {
|
||||
eval("var x = 34;");
|
||||
throw new Error("should have thrown TypeError");
|
||||
} catch (e) {
|
||||
if (! (e instanceof TypeError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
eval("function func() {}");
|
||||
throw new Error("should have thrown TypeError");
|
||||
} catch (e) {
|
||||
if (! (e instanceof TypeError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
function checkLoad(code) {
|
||||
try {
|
||||
load({ name: "test", script: code });
|
||||
throw new Error("should have thrown TypeError for load: " + code);
|
||||
} catch (e) {
|
||||
if (! (e instanceof TypeError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkLoad("var y = 55");
|
||||
checkLoad("function f() {}");
|
||||
|
||||
// check script engine eval
|
||||
var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
|
||||
var e = new ScriptEngineManager().getEngineByName("nashorn");
|
||||
var global = e.eval("this");
|
||||
e.eval("Object.preventExtensions(this);");
|
||||
try {
|
||||
e.eval("var myVar = 33;");
|
||||
throw new Error("should have thrown TypeError");
|
||||
} catch (e) {
|
||||
if (! (e.cause.ecmaError instanceof global.TypeError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// Object.bindProperties on arbitrary non-extensible object
|
||||
var obj = {};
|
||||
Object.preventExtensions(obj);
|
||||
try {
|
||||
Object.bindProperties(obj, { foo: 434 });
|
||||
throw new Error("should have thrown TypeError");
|
||||
} catch (e) {
|
||||
if (! (e instanceof TypeError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
35
nashorn/test/script/basic/JDK-8131039.js
Normal file
35
nashorn/test/script/basic/JDK-8131039.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* JDK-8131039: after adding a function property to Object.prototype, JSON.parse with reviver function goes into infinite loop
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
Object.prototype.func = function() {}
|
||||
|
||||
function identity(k, v) { return v };
|
||||
var obj = JSON.parse('{\"name\" : \"nashorn\"}', identity);
|
||||
Assert.assertTrue(obj.name, "nashorn");
|
Loading…
Reference in New Issue
Block a user