--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Apr 19 16:11:16 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Sat Apr 20 08:54:13 2013 -0300
@@ -901,7 +901,7 @@
final MethodHandle getter = find.getGetter(int.class);
if (getter != null) {
try {
- return (int)getter.invokeExact((Object)find.getOwner());
+ return (int)getter.invokeExact((Object)find.getGetterReceiver());
} catch (final Error|RuntimeException e) {
throw e;
} catch (final Throwable e) {
@@ -916,7 +916,7 @@
final MethodHandle getter = find.getGetter(long.class);
if (getter != null) {
try {
- return (long)getter.invokeExact((Object)find.getOwner());
+ return (long)getter.invokeExact((Object)find.getGetterReceiver());
} catch (final Error|RuntimeException e) {
throw e;
} catch (final Throwable e) {
@@ -931,7 +931,7 @@
final MethodHandle getter = find.getGetter(double.class);
if (getter != null) {
try {
- return (double)getter.invokeExact((Object)find.getOwner());
+ return (double)getter.invokeExact((Object)find.getGetterReceiver());
} catch (final Error|RuntimeException e) {
throw e;
} catch (final Throwable e) {
@@ -953,7 +953,7 @@
final MethodHandle getter = find.getGetter(Object.class);
if (getter != null) {
try {
- return getter.invokeExact((Object)find.getOwner());
+ return getter.invokeExact((Object)find.getGetterReceiver());
} catch (final Error|RuntimeException e) {
throw e;
} catch (final Throwable e) {
@@ -1679,12 +1679,7 @@
* @return GuardedInvocation to be invoked at call site.
*/
protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
- final String name = desc.getNameToken(2);
-
- if (request.isCallSiteUnstable()) {
- return findMegaMorphicGetMethod(desc, name);
- }
-
+ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
final FindProperty find = findProperty(name, true);
MethodHandle methodHandle;
@@ -1700,6 +1695,10 @@
throw new AssertionError(); // never invoked with any other operation
}
+ if (request.isCallSiteUnstable()) {
+ return findMegaMorphicGetMethod(desc, name);
+ }
+
final Class<?> returnType = desc.getMethodType().returnType();
final Property property = find.getProperty();
methodHandle = find.getGetter(returnType);
@@ -1727,7 +1726,9 @@
}
private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name) {
- final GuardedInvocation inv = findGetIndexMethod(desc.getMethodType().insertParameterTypes(1, Object.class));
+ final MethodType mhType = desc.getMethodType().insertParameterTypes(1, Object.class);
+ final GuardedInvocation inv = findGetIndexMethod(mhType);
+
return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard());
}
@@ -1890,8 +1891,8 @@
}
private static GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) {
- final GuardedInvocation inv = findSetIndexMethod(desc.getMethodType().insertParameterTypes(1, Object.class),
- NashornCallSiteDescriptor.isStrict(desc));
+ final MethodType type = desc.getMethodType().insertParameterTypes(1, Object.class);
+ final GuardedInvocation inv = findSetIndexMethod(type, NashornCallSiteDescriptor.isStrict(desc)).asType(type);
return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard());
}
@@ -1949,7 +1950,7 @@
* @return GuardedInvocation to be invoked at call site.
*/
public GuardedInvocation noSuchProperty(final CallSiteDescriptor desc, final LinkRequest request) {
- final String name = desc.getNameToken(2);
+ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
final boolean scopeAccess = isScope() && NashornCallSiteDescriptor.isScope(desc);
@@ -1973,6 +1974,24 @@
return createEmptyGetter(desc, name);
}
+ /**
+ * Invoke fall back if a property is not found.
+ * @param name Name of property.
+ * @return Result from call.
+ */
+ private Object invokeNoSuchProperty(final String name) {
+ final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
+
+ if (find != null) {
+ final Object func = getObjectValue(find);
+
+ if (func instanceof ScriptFunction) {
+ return ScriptRuntime.apply((ScriptFunction)func, this, name);
+ }
+ }
+
+ return UNDEFINED;
+ }
private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final String name) {
return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()), getMap().getProtoGetSwitchPoint(name), NashornGuards.getMapGuard(getMap()));
@@ -2239,310 +2258,158 @@
setArray(getArray().shrink(newLength));
getArray().setLength(newLength);
}
- }
+ }
+
+ private int getInt(final int index, final String key) {
+ for (ScriptObject object = this; object != null; object = object.getProto()) {
+ final ArrayData array = object.getArray();
+
+ if (array.has(index)) {
+ return array.getInt(index);
+ }
+
+ final FindProperty find = object.findProperty(key, false);
+
+ if (find != null) {
+ return getIntValue(new FindProperty(this, find.getOwner(), find.getProperty()));
+ }
+ }
+
+ return JSType.toInt32(invokeNoSuchProperty(key));
+ }
@Override
public int getInt(final Object key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getInt(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getIntValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getInt(key) : 0;
+ return getInt(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public int getInt(final double key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getInt(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getIntValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getInt(key) : 0;
+ return getInt(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public int getInt(final long key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getInt(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getIntValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getInt(key) : 0;
+ return getInt(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public int getInt(final int key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getInt(index);
+ return getInt(getArrayIndexNoThrow(key), convertKey(key));
+ }
+
+ private long getLong(final int index, final String key) {
+ for (ScriptObject object = this; object != null; object = object.getProto()) {
+ final ArrayData array = object.getArray();
+
+ if (array.has(index)) {
+ return array.getLong(index);
+ }
+
+ final FindProperty find = object.findProperty(key, false);
+
+ if (find != null) {
+ return getLongValue(new FindProperty(this, find.getOwner(), find.getProperty()));
+ }
}
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getIntValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getInt(key) : 0;
+ return JSType.toLong(invokeNoSuchProperty(key));
}
@Override
public long getLong(final Object key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getLong(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getLongValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getLong(key) : 0L;
+ return getLong(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public long getLong(final double key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getLong(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getLongValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getLong(key) : 0L;
+ return getLong(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public long getLong(final long key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getLong(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getLongValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getLong(key) : 0L;
+ return getLong(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public long getLong(final int key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getLong(index);
+ return getLong(getArrayIndexNoThrow(key), convertKey(key));
+ }
+
+ private double getDouble(final int index, final String key) {
+ for (ScriptObject object = this; object != null; object = object.getProto()) {
+ final ArrayData array = object.getArray();
+
+ if (array.has(index)) {
+ return array.getDouble(index);
+ }
+
+ final FindProperty find = object.findProperty(key, false);
+
+ if (find != null) {
+ return getDoubleValue(new FindProperty(this, find.getOwner(), find.getProperty()));
+ }
}
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getLongValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getLong(key) : 0L;
+ return JSType.toNumber(invokeNoSuchProperty(key));
}
@Override
public double getDouble(final Object key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getDouble(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getDoubleValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getDouble(key) : Double.NaN;
+ return getDouble(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public double getDouble(final double key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getDouble(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getDoubleValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getDouble(key) : Double.NaN;
+ return getDouble(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public double getDouble(final long key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getDouble(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getDoubleValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getDouble(key) : Double.NaN;
+ return getDouble(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public double getDouble(final int key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getDouble(index);
+ return getDouble(getArrayIndexNoThrow(key), convertKey(key));
+ }
+
+ private Object get(final int index, final String key) {
+ for (ScriptObject object = this; object != null; object = object.getProto()) {
+ final ArrayData array = object.getArray();
+
+ if (array.has(index)) {
+ return array.getObject(index);
+ }
+
+ final FindProperty find = object.findProperty(key, false);
+
+ if (find != null) {
+ return getObjectValue(new FindProperty(this, find.getOwner(), find.getProperty()));
+ }
}
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getDoubleValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.getDouble(key) : Double.NaN;
+ return invokeNoSuchProperty(key);
}
@Override
public Object get(final Object key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getObject(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getObjectValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.get(key) : UNDEFINED;
+ return get(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public Object get(final double key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getObject(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getObjectValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.get(key) : UNDEFINED;
+ return get(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public Object get(final long key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getObject(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getObjectValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.get(key) : UNDEFINED;
+ return get(getArrayIndexNoThrow(key), convertKey(key));
}
@Override
public Object get(final int key) {
- final int index = getArrayIndexNoThrow(key);
-
- if (getArray().has(index)) {
- return getArray().getObject(index);
- }
-
- final FindProperty find = findProperty(convertKey(key), false);
-
- if (find != null) {
- return getObjectValue(find);
- }
-
- final ScriptObject proto = this.getProto();
-
- return proto != null ? proto.get(key) : UNDEFINED;
+ return get(getArrayIndexNoThrow(key), convertKey(key));
}
/**
@@ -2613,8 +2480,6 @@
f = null;
}
- MethodHandle setter;
-
if (f != null) {
if (!f.getProperty().isWritable()) {
if (strict) {
@@ -2624,9 +2489,9 @@
return;
}
- setter = f.getSetter(Object.class, strict); //TODO specfields
try {
- setter.invokeExact((Object)f.getOwner(), value);
+ final MethodHandle setter = f.getSetter(Object.class, strict); //TODO specfields
+ setter.invokeExact((Object)f.getSetterReceiver(), value);
} catch (final Error|RuntimeException e) {
throw e;
} catch (final Throwable e) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8011578.js Sat Apr 20 08:54:13 2013 -0300
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8011578 : -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
+ *
+ * @test
+ * @option -Dnashorn.unstable.relink.threshold=1
+ * @run
+ */
+
+load(__DIR__ + "NASHORN-296.js");
+load(__DIR__ + "NASHORN-691.js");
+load(__DIR__ + "calllink.js");
+load(__DIR__ + "nosuchproperty.js");
+
+__noSuchProperty__ = function(x) {
+ print(x);
+ return x;
+}
+
+print(this["find"]);