# HG changeset patch # User hannesw # Date 1359681855 -3600 # Node ID ed4aec2d599c0145bb75b1dba09e061a512dab9c # Parent 83069fa0935b03f77a0ba8fc9376c20f1b6e2f45 8007060: Primitive wrap filter throws ClassCastException in test262parallel Reviewed-by: sundar, jlaskey, lagergren diff -r 83069fa0935b -r ed4aec2d599c nashorn/src/jdk/nashorn/internal/objects/Global.java --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java Thu Jan 31 18:34:42 2013 +0100 +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java Fri Feb 01 02:24:15 2013 +0100 @@ -419,18 +419,6 @@ } @Override - public MethodHandle getWrapFilter(Object obj) { - if (obj instanceof String || obj instanceof ConsString) { - return NativeString.WRAPFILTER; - } else if (obj instanceof Number) { - return NativeNumber.WRAPFILTER; - } else if (obj instanceof Boolean) { - return NativeBoolean.WRAPFILTER; - } - throw new IllegalArgumentException("Unsupported primitive: " + obj); - } - - @Override public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) { if (self instanceof String || self instanceof ConsString) { return NativeString.lookupPrimitive(request, self); diff -r 83069fa0935b -r ed4aec2d599c nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java Thu Jan 31 18:34:42 2013 +0100 +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java Fri Feb 01 02:24:15 2013 +0100 @@ -66,17 +66,6 @@ return ((ScriptFunction)self).toSource(); } - private static Object convertThis(final ScriptFunction func, final Object thiz) { - if (!(thiz instanceof ScriptObject) && func.isNonStrictFunction()) { - if (thiz == UNDEFINED || thiz == null) { - return Global.instance(); - } - return JSType.toScriptObject(thiz); - } - - return thiz; - } - /** * ECMA 15.3.4.3 Function.prototype.apply (thisArg, argArray) * @@ -125,12 +114,7 @@ typeError("function.apply.expects.array"); } - final ScriptFunction func = (ScriptFunction)self; - // As per ECMA 5.1 spec, "this" is passed "as is". But the spec. - // says 'this' is transformed when callee frame is created if callee - // is a non-strict function. So, we convert 'this' here if callee is - // not strict and not builtin function. - return ScriptRuntime.apply(func, convertThis(func, thiz), args); + return ScriptRuntime.apply((ScriptFunction)self, thiz, args); } /** @@ -157,15 +141,7 @@ arguments = ScriptRuntime.EMPTY_ARRAY; } - final ScriptFunction func = (ScriptFunction)self; - - // As per ECMA 5.1 spec, "this" is passed "as is". But the spec. - // says 'this' is transformed when callee frame is created if callee - // is a non-strict function. So, we convert 'this' here if callee is - // not strict and not builtin function. - thiz = convertThis(func, thiz); - - return ScriptRuntime.apply(func, thiz, arguments); + return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments); } /** @@ -182,12 +158,7 @@ return UNDEFINED; } - // As per ECMA 5.1 spec, "this" is passed "as is". But the spec. - // says 'this' is transformed when callee frame is created if callee - // is a non-strict function. So, we convert 'this' here if callee is - // not strict. Note that all builtin functions are marked as strict and - // so 'this' transformation is not done for such functions. - final Object thiz = convertThis((ScriptFunction)self, (args.length == 0) ? UNDEFINED : args[0]); + final Object thiz = (args.length == 0) ? UNDEFINED : args[0]; Object[] arguments; if (args.length > 1) { diff -r 83069fa0935b -r ed4aec2d599c nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java --- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Thu Jan 31 18:34:42 2013 +0100 +++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Fri Feb 01 02:24:15 2013 +0100 @@ -293,7 +293,8 @@ allArgs = ScriptRuntime.EMPTY_ARRAY; } - final MethodHandle boundMethod = MH.insertArguments(BOUND_FUNCTION, 0, this, thiz, allArgs); + final Object boundThiz = convertThisObject(thiz); + final MethodHandle boundMethod = MH.insertArguments(BOUND_FUNCTION, 0, this, boundThiz, allArgs); final ScriptFunction boundFunc = makeFunction("", boundMethod, null, true); MethodHandle consHandle = this.getConstructHandle(); diff -r 83069fa0935b -r ed4aec2d599c nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java --- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java Thu Jan 31 18:34:42 2013 +0100 +++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java Fri Feb 01 02:24:15 2013 +0100 @@ -70,15 +70,6 @@ /** - * Get a MethodHandle that converts the argument to its JavaScript object representation - * - * @param obj a JavaScript primitive object (String, Number, or Boolean) - * - * @return wrap filter methodhandle - */ - public MethodHandle getWrapFilter(Object obj); - - /** * Wrapper for {@link jdk.nashorn.internal.objects.Global#primitiveLookup(LinkRequest, Object)} * * @param request the link request for the dynamic call site. diff -r 83069fa0935b -r ed4aec2d599c nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java Thu Jan 31 18:34:42 2013 +0100 +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java Fri Feb 01 02:24:15 2013 +0100 @@ -40,7 +40,6 @@ import jdk.nashorn.internal.parser.Token; import jdk.nashorn.internal.runtime.linker.MethodHandleFactory; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; -import jdk.nashorn.internal.runtime.linker.NashornGuardedInvocation; import jdk.nashorn.internal.runtime.linker.NashornGuards; import jdk.nashorn.internal.runtime.options.Options; import org.dynalang.dynalink.CallSiteDescriptor; @@ -69,6 +68,8 @@ private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class); + private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", Object.class, Object.class); + /** method handle to arity setter for this ScriptFunction */ public static final Call SET_ARITY = virtualCallNoLookup(ScriptFunction.class, "setArity", void.class, int.class); /** method handle to scope getter for this ScriptFunction */ @@ -352,7 +353,7 @@ public abstract boolean isBuiltin(); /** - * Is this a non-strict (not built-in) script function? + * Is this a non-strict and not-built-in script function? * @return true if neither strict nor built-in */ public boolean isNonStrictFunction() { @@ -371,42 +372,43 @@ invokes++; } + final Object selfObj = convertThisObject(self); final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments; if (isVarArg(invokeHandle)) { if (hasCalleeParameter()) { - return invokeHandle.invokeExact(self, this, args); + return invokeHandle.invokeExact(selfObj, this, args); } - return invokeHandle.invokeExact(self, args); + return invokeHandle.invokeExact(selfObj, args); } final int paramCount = invokeHandle.type().parameterCount(); if (hasCalleeParameter()) { switch (paramCount) { case 2: - return invokeHandle.invokeExact(self, this); + return invokeHandle.invokeExact(selfObj, this); case 3: - return invokeHandle.invokeExact(self, this, getArg(args, 0)); + return invokeHandle.invokeExact(selfObj, this, getArg(args, 0)); case 4: - return invokeHandle.invokeExact(self, this, getArg(args, 0), getArg(args, 1)); + return invokeHandle.invokeExact(selfObj, this, getArg(args, 0), getArg(args, 1)); case 5: - return invokeHandle.invokeExact(self, this, getArg(args, 0), getArg(args, 1), getArg(args, 2)); + return invokeHandle.invokeExact(selfObj, this, getArg(args, 0), getArg(args, 1), getArg(args, 2)); default: - return invokeHandle.invokeWithArguments(withArguments(self, this, paramCount, args)); + return invokeHandle.invokeWithArguments(withArguments(selfObj, this, paramCount, args)); } } switch (paramCount) { case 1: - return invokeHandle.invokeExact(self); + return invokeHandle.invokeExact(selfObj); case 2: - return invokeHandle.invokeExact(self, getArg(args, 0)); + return invokeHandle.invokeExact(selfObj, getArg(args, 0)); case 3: - return invokeHandle.invokeExact(self, getArg(args, 0), getArg(args, 1)); + return invokeHandle.invokeExact(selfObj, getArg(args, 0), getArg(args, 1)); case 4: - return invokeHandle.invokeExact(self, getArg(args, 0), getArg(args, 1), getArg(args, 2)); + return invokeHandle.invokeExact(selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2)); default: - return invokeHandle.invokeWithArguments(withArguments(self, null, paramCount, args)); + return invokeHandle.invokeWithArguments(withArguments(selfObj, null, paramCount, args)); } } @@ -912,6 +914,14 @@ return (result instanceof ScriptObject || !JSType.isPrimitive(result))? result : allocation; } + @SuppressWarnings("unused") + private static Object wrapFilter(final Object obj) { + if (obj instanceof ScriptObject || !isPrimitiveThis(obj)) { + return obj; + } + return ((GlobalObject) Context.getGlobalTrusted()).wrapAsObject(obj); + } + /** * dyn:call call site signature: (callee, thiz, [args...]) * generated method signature: (thiz, callee, [args...]) @@ -933,11 +943,13 @@ final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class, type.parameterCount() - 2); - return new GuardedInvocation(addPrimitiveWrap(collector, desc, request), + return new GuardedInvocation(collector, desc.getMethodType().parameterType(0) == ScriptFunction.class ? null : NashornGuards.getScriptFunctionGuard()); } MethodHandle boundHandle; + MethodHandle guard = null; + if (hasCalleeParameter()) { final MethodHandle callHandle = getBestSpecializedInvokeHandle(type); @@ -956,14 +968,23 @@ assert reorder[1] == 0; final MethodType newType = oldType.changeParameterType(0, oldType.parameterType(1)).changeParameterType(1, oldType.parameterType(0)); boundHandle = MethodHandles.permuteArguments(callHandle, newType, reorder); - // thiz argument may be a JS primitive needing a wrapper - boundHandle = addPrimitiveWrap(boundHandle, desc, request); + + // For non-strict functions, check whether this-object is primitive type. + // If so add a to-object-wrapper argument filter. + // Else install a guard that will trigger a relink when the argument becomes primitive. + if (isNonStrictFunction()) { + if (isPrimitiveThis(request.getArguments()[1])) { + boundHandle = MH.filterArguments(boundHandle, 1, WRAPFILTER); + } else { + guard = NashornGuards.getNonStrictFunctionGuard(this); + } + } } } else { final MethodHandle callHandle = getBestSpecializedInvokeHandle(type.dropParameterTypes(0, 1)); if(NashornCallSiteDescriptor.isScope(desc)) { - boundHandle = MH.bindTo(callHandle, isNonStrictFunction()? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED); + boundHandle = MH.bindTo(callHandle, isNonStrictFunction() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED); boundHandle = MH.dropArguments(boundHandle, 0, Object.class, Object.class); } else { boundHandle = MH.dropArguments(callHandle, 0, Object.class); @@ -971,7 +992,7 @@ } boundHandle = pairArguments(boundHandle, type); - return new NashornGuardedInvocation(boundHandle, null, NashornGuards.getFunctionGuard(this), isNonStrictFunction()); + return new GuardedInvocation(boundHandle, guard == null ? NashornGuards.getFunctionGuard(this) : guard); } /** @@ -997,16 +1018,25 @@ return pairArguments(methodHandle, type); } - private MethodHandle addPrimitiveWrap(final MethodHandle mh, final CallSiteDescriptor desc, final LinkRequest request) { - // Check whether thiz is a JS primitive type and needs an object wrapper for non-strict function - if (!NashornCallSiteDescriptor.isScope(desc) && isNonStrictFunction()) { - Object self = request.getArguments()[1]; - if (isPrimitiveThis(self)) { - MethodHandle wrapFilter = ((GlobalObject) Context.getGlobalTrusted()).getWrapFilter(self); - return MH.filterArguments(mh, 1, MH.asType(wrapFilter, wrapFilter.type().changeReturnType(Object.class))); + /** + * Convert this argument for non-strict functions according to ES 10.4.3 + * + * @param thiz the this argument + * + * @return the converted this object + */ + protected Object convertThisObject(final Object thiz) { + if (!(thiz instanceof ScriptObject) && isNonStrictFunction()) { + if (JSType.nullOrUndefined(thiz)) { + return Context.getGlobalTrusted(); + } + + if (isPrimitiveThis(thiz)) { + return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(thiz); } } - return mh; + + return thiz; } private static boolean isPrimitiveThis(Object obj) { diff -r 83069fa0935b -r ed4aec2d599c nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Thu Jan 31 18:34:42 2013 +0100 +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Feb 01 02:24:15 2013 +0100 @@ -64,7 +64,6 @@ import jdk.nashorn.internal.runtime.linker.Lookup; import jdk.nashorn.internal.runtime.linker.MethodHandleFactory; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; -import jdk.nashorn.internal.runtime.linker.NashornGuardedInvocation; import jdk.nashorn.internal.runtime.linker.NashornGuards; import org.dynalang.dynalink.CallSiteDescriptor; import org.dynalang.dynalink.linker.GuardedInvocation; @@ -1712,11 +1711,9 @@ if (methodHandle != null) { assert methodHandle.type().returnType().equals(returnType); final ScriptFunction getter = find.getGetterFunction(); - final boolean nonStrict = getter != null && getter.isNonStrictFunction(); if (find.isSelf()) { - return new NashornGuardedInvocation(methodHandle, null, ObjectClassGenerator.OBJECT_FIELDS_ONLY && - NashornCallSiteDescriptor.isFastScope(desc) && !property.canChangeType() ? null : guard, - nonStrict); + return new GuardedInvocation(methodHandle, ObjectClassGenerator.OBJECT_FIELDS_ONLY && + NashornCallSiteDescriptor.isFastScope(desc) && !property.canChangeType() ? null : guard); } final ScriptObject prototype = find.getOwner(); @@ -1724,7 +1721,7 @@ if (!property.hasGetterFunction()) { methodHandle = bindTo(methodHandle, prototype); } - return new NashornGuardedInvocation(methodHandle, getMap().getProtoGetSwitchPoint(name), guard, nonStrict); + return new GuardedInvocation(methodHandle, getMap().getProtoGetSwitchPoint(name), guard); } assert !NashornCallSiteDescriptor.isFastScope(desc); diff -r 83069fa0935b -r ed4aec2d599c nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java --- a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Thu Jan 31 18:34:42 2013 +0100 +++ b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Fri Feb 01 02:24:15 2013 +0100 @@ -33,7 +33,6 @@ import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator; import jdk.nashorn.internal.runtime.linker.Lookup; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; -import jdk.nashorn.internal.runtime.linker.NashornGuardedInvocation; import jdk.nashorn.internal.runtime.linker.NashornGuards; import org.dynalang.dynalink.CallSiteDescriptor; @@ -41,8 +40,8 @@ /** * Instances of this class are quite ephemeral; they only exist for the duration of an invocation of - * {@link ScriptObject#findSetMethod(CallSiteDescriptor, boolean)} and serve as the actual encapsulation of the - * algorithm for creating an appropriate property setter method. + * {@link ScriptObject#findSetMethod(CallSiteDescriptor, org.dynalang.dynalink.linker.LinkRequest)} and + * serve as the actual encapsulation of the algorithm for creating an appropriate property setter method. */ class SetMethodCreator { // See constructor parameters for description of fields @@ -89,19 +88,16 @@ private class SetMethod { private final MethodHandle methodHandle; private final Property property; - private final boolean nonStrict; /** * Creates a new lookup result. * @param methodHandle the actual method handle * @param property the property object. Can be null in case we're creating a new property in the global object. - * @param nonStrict True if an existing property with a non-strict function as property setter is discovered. */ - SetMethod(final MethodHandle methodHandle, final Property property, final boolean nonStrict) { + SetMethod(final MethodHandle methodHandle, final Property property) { assert methodHandle != null; this.methodHandle = methodHandle; this.property = property; - this.nonStrict = nonStrict; } /** @@ -109,7 +105,7 @@ * @return the composed guarded invocation that represents the dynamic setter method for the property. */ GuardedInvocation createGuardedInvocation() { - return new NashornGuardedInvocation(methodHandle, null, getGuard(), nonStrict); + return new GuardedInvocation(methodHandle, getGuard()); } private MethodHandle getGuard() { @@ -162,17 +158,12 @@ } else { boundHandle = methodHandle; } - return new SetMethod(boundHandle, property, getExistingSetterNonStrictFlag()); - } - - private boolean getExistingSetterNonStrictFlag() { - final ScriptFunction setter = find.getSetterFunction(); - return setter != null && setter.isNonStrictFunction(); + return new SetMethod(boundHandle, property); } private SetMethod createGlobalPropertySetter() { final ScriptObject global = Context.getGlobalTrusted(); - return new SetMethod(ScriptObject.bindTo(global.addSpill(getName()), global), null, false); + return new SetMethod(ScriptObject.bindTo(global.addSpill(getName()), global), null); } private SetMethod createNewPropertySetter() { @@ -192,7 +183,7 @@ final int nextSpill = getMap().getSpillLength(); final Property property = createSpillProperty(nextSpill); - return new SetMethod(createSpillMethodHandle(nextSpill, property), property, false); + return new SetMethod(createSpillMethodHandle(nextSpill, property), property); } private Property createSpillProperty(final int nextSpill) { @@ -222,7 +213,7 @@ final Property property = new SpillProperty(getName(), 0, nextEmbed, ScriptObject.GET_EMBED[nextEmbed], ScriptObject.SET_EMBED[nextEmbed]); //TODO specfields final MethodHandle methodHandle = MH.insertArguments(ScriptObject.SETEMBED, 0, desc, getMap(), getNewMap(property), property.getSetter(Object.class, getMap()), nextEmbed); - return new SetMethod(methodHandle, property, false); + return new SetMethod(methodHandle, property); } private PropertyMap getNewMap(Property property) { diff -r 83069fa0935b -r ed4aec2d599c nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuardedInvocation.java --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuardedInvocation.java Thu Jan 31 18:34:42 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.runtime.linker; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.SwitchPoint; -import org.dynalang.dynalink.linker.GuardedInvocation; - -/** - * Guarded invocation with Nashorn specific bits. - */ -public class NashornGuardedInvocation extends GuardedInvocation { - - private final boolean nonStrict; - - /** - * Constructor - * - * @param invocation invocation target - * @param switchPoint SwitchPoint that will, when invalidated, require relinking callsite, null if no SwitchPoint - * @param guard guard that will, when failed, require relinking callsite, null if no guard - * @param nonStrict non-strict invocation target flag - */ - public NashornGuardedInvocation(final MethodHandle invocation, final SwitchPoint switchPoint, final MethodHandle guard, final boolean nonStrict) { - super(invocation, switchPoint, guard); - this.nonStrict = nonStrict; - - } - - /** - * Is the target of this invocation a non-strict function? - * @return true if invocation target is non-strict - */ - public boolean isNonStrict() { - return nonStrict; - } - - /** - * Check whether the target of this invocation is a non-strict script function. - * @param inv guarded invocation - * @return true if invocation target is non-strict - */ - public static boolean isNonStrict(final GuardedInvocation inv) { - return inv instanceof NashornGuardedInvocation && ((NashornGuardedInvocation)inv).isNonStrict(); - } -} diff -r 83069fa0935b -r ed4aec2d599c nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java Thu Jan 31 18:34:42 2013 +0100 +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java Fri Feb 01 02:24:15 2013 +0100 @@ -41,6 +41,7 @@ private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class); private static final MethodHandle IS_MAP = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class); private static final MethodHandle IS_FUNCTION_MH = findOwnMH("isFunctionMH", boolean.class, Object.class, MethodHandle.class); + private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH("isNonStrictFunction", boolean.class, Object.class, Object.class, MethodHandle.class); private static final MethodHandle IS_INSTANCEOF_2 = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class); // don't create me! @@ -99,6 +100,20 @@ return MH.insertArguments(IS_FUNCTION_MH, 1, function.getInvokeHandle()); } + /** + * Get a guard that checks if a {@link ScriptFunction} is equal to + * a known ScriptFunction using reference comparison, and whether the type of + * the second argument (this-object) is not a JavaScript primitive type. + * + * @param function The ScriptFunction to check against. This will be bound to the guard method handle + * + * @return method handle for guard + */ + public static MethodHandle getNonStrictFunctionGuard(final ScriptFunction function) { + assert function.getInvokeHandle() != null; + return MH.insertArguments(IS_NONSTRICT_FUNCTION, 2, function.getInvokeHandle()); + } + @SuppressWarnings("unused") private static boolean isScriptObject(final Object self) { return self instanceof ScriptObject; @@ -120,6 +135,11 @@ } @SuppressWarnings("unused") + private static boolean isNonStrictFunction(final Object self, final Object arg, final MethodHandle mh) { + return self instanceof ScriptFunction && ((ScriptFunction)self).getInvokeHandle() == mh && arg instanceof ScriptObject; + } + + @SuppressWarnings("unused") private static boolean isInstanceOf2(final Object self, final Class class1, final Class class2) { return class1.isInstance(self) || class2.isInstance(self); } diff -r 83069fa0935b -r ed4aec2d599c nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java Thu Jan 31 18:34:42 2013 +0100 +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java Fri Feb 01 02:24:15 2013 +0100 @@ -101,7 +101,7 @@ if (link != null) { MethodHandle method = link.getInvocation(); final Class receiverType = method.type().parameterType(0); - if (receiverType != Object.class || NashornGuardedInvocation.isNonStrict(link)) { + if (receiverType != Object.class) { final MethodType wrapType = wrapFilter.type(); assert receiverType.isAssignableFrom(wrapType.returnType()); method = MH.filterArguments(method, 0, MH.asType(wrapFilter, wrapType.changeReturnType(receiverType))); diff -r 83069fa0935b -r ed4aec2d599c nashorn/test/script/basic/JDK-8007060.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8007060.js Fri Feb 01 02:24:15 2013 +0100 @@ -0,0 +1,94 @@ +/* + * 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-8007060 : Primitive wrap filter throws ClassCastException in test262parallel + * + * @test + * @run + */ + +Object.prototype.T = function() { + print(this, typeof this); +}; + +function F() { + print(this, typeof this); +} + + +function test(obj) { + obj.T(); +} + +// Ordinary callsite - call often so we go to megamorphic +test(1); +test({}); +test("hello"); +test(1); +test({}); +test("hello"); +test(1); +test({}); +test("hello"); +test(1); +test({}); +test("hello"); +test(1); +test({}); +test("hello"); +test(1); +test({}); +test("hello"); +test(1); +test({}); +test("hello"); +test(1); +test({}); +test("hello"); + +// Dynamic invoker callsite used by NativeArray +[1, 2, 3].filter(F, 1); +[1, 2, 3].filter(F, {}); +[1, 2, 3].filter(F, "hello"); +[1, 2, 3].filter(F, 1); +[1, 2, 3].filter(F, {}); +[1, 2, 3].filter(F, "hello"); +[1, 2, 3].filter(F, 1); +[1, 2, 3].filter(F, {}); +[1, 2, 3].filter(F, "hello"); +[1, 2, 3].filter(F, 1); +[1, 2, 3].filter(F, {}); +[1, 2, 3].filter(F, "hello"); +[1, 2, 3].filter(F, 1); +[1, 2, 3].filter(F, {}); +[1, 2, 3].filter(F, "hello"); +[1, 2, 3].filter(F, 1); +[1, 2, 3].filter(F, {}); +[1, 2, 3].filter(F, "hello"); +[1, 2, 3].filter(F, 1); +[1, 2, 3].filter(F, {}); +[1, 2, 3].filter(F, "hello"); +[1, 2, 3].filter(F, 1); +[1, 2, 3].filter(F, {}); +[1, 2, 3].filter(F, "hello"); \ No newline at end of file diff -r 83069fa0935b -r ed4aec2d599c nashorn/test/script/basic/JDK-8007060.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8007060.js.EXPECTED Fri Feb 01 02:24:15 2013 +0100 @@ -0,0 +1,96 @@ +1 object +[object Object] object +hello object +1 object +[object Object] object +hello object +1 object +[object Object] object +hello object +1 object +[object Object] object +hello object +1 object +[object Object] object +hello object +1 object +[object Object] object +hello object +1 object +[object Object] object +hello object +1 object +[object Object] object +hello object +1 object +1 object +1 object +[object Object] object +[object Object] object +[object Object] object +hello object +hello object +hello object +1 object +1 object +1 object +[object Object] object +[object Object] object +[object Object] object +hello object +hello object +hello object +1 object +1 object +1 object +[object Object] object +[object Object] object +[object Object] object +hello object +hello object +hello object +1 object +1 object +1 object +[object Object] object +[object Object] object +[object Object] object +hello object +hello object +hello object +1 object +1 object +1 object +[object Object] object +[object Object] object +[object Object] object +hello object +hello object +hello object +1 object +1 object +1 object +[object Object] object +[object Object] object +[object Object] object +hello object +hello object +hello object +1 object +1 object +1 object +[object Object] object +[object Object] object +[object Object] object +hello object +hello object +hello object +1 object +1 object +1 object +[object Object] object +[object Object] object +[object Object] object +hello object +hello object +hello object