Fri, 01 Feb 2013 02:24:15 +0100
8007060: Primitive wrap filter throws ClassCastException in test262parallel
Reviewed-by: sundar, jlaskey, lagergren
1.1 --- a/src/jdk/nashorn/internal/objects/Global.java Thu Jan 31 18:34:42 2013 +0100 1.2 +++ b/src/jdk/nashorn/internal/objects/Global.java Fri Feb 01 02:24:15 2013 +0100 1.3 @@ -419,18 +419,6 @@ 1.4 } 1.5 1.6 @Override 1.7 - public MethodHandle getWrapFilter(Object obj) { 1.8 - if (obj instanceof String || obj instanceof ConsString) { 1.9 - return NativeString.WRAPFILTER; 1.10 - } else if (obj instanceof Number) { 1.11 - return NativeNumber.WRAPFILTER; 1.12 - } else if (obj instanceof Boolean) { 1.13 - return NativeBoolean.WRAPFILTER; 1.14 - } 1.15 - throw new IllegalArgumentException("Unsupported primitive: " + obj); 1.16 - } 1.17 - 1.18 - @Override 1.19 public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) { 1.20 if (self instanceof String || self instanceof ConsString) { 1.21 return NativeString.lookupPrimitive(request, self);
2.1 --- a/src/jdk/nashorn/internal/objects/NativeFunction.java Thu Jan 31 18:34:42 2013 +0100 2.2 +++ b/src/jdk/nashorn/internal/objects/NativeFunction.java Fri Feb 01 02:24:15 2013 +0100 2.3 @@ -66,17 +66,6 @@ 2.4 return ((ScriptFunction)self).toSource(); 2.5 } 2.6 2.7 - private static Object convertThis(final ScriptFunction func, final Object thiz) { 2.8 - if (!(thiz instanceof ScriptObject) && func.isNonStrictFunction()) { 2.9 - if (thiz == UNDEFINED || thiz == null) { 2.10 - return Global.instance(); 2.11 - } 2.12 - return JSType.toScriptObject(thiz); 2.13 - } 2.14 - 2.15 - return thiz; 2.16 - } 2.17 - 2.18 /** 2.19 * ECMA 15.3.4.3 Function.prototype.apply (thisArg, argArray) 2.20 * 2.21 @@ -125,12 +114,7 @@ 2.22 typeError("function.apply.expects.array"); 2.23 } 2.24 2.25 - final ScriptFunction func = (ScriptFunction)self; 2.26 - // As per ECMA 5.1 spec, "this" is passed "as is". But the spec. 2.27 - // says 'this' is transformed when callee frame is created if callee 2.28 - // is a non-strict function. So, we convert 'this' here if callee is 2.29 - // not strict and not builtin function. 2.30 - return ScriptRuntime.apply(func, convertThis(func, thiz), args); 2.31 + return ScriptRuntime.apply((ScriptFunction)self, thiz, args); 2.32 } 2.33 2.34 /** 2.35 @@ -157,15 +141,7 @@ 2.36 arguments = ScriptRuntime.EMPTY_ARRAY; 2.37 } 2.38 2.39 - final ScriptFunction func = (ScriptFunction)self; 2.40 - 2.41 - // As per ECMA 5.1 spec, "this" is passed "as is". But the spec. 2.42 - // says 'this' is transformed when callee frame is created if callee 2.43 - // is a non-strict function. So, we convert 'this' here if callee is 2.44 - // not strict and not builtin function. 2.45 - thiz = convertThis(func, thiz); 2.46 - 2.47 - return ScriptRuntime.apply(func, thiz, arguments); 2.48 + return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments); 2.49 } 2.50 2.51 /** 2.52 @@ -182,12 +158,7 @@ 2.53 return UNDEFINED; 2.54 } 2.55 2.56 - // As per ECMA 5.1 spec, "this" is passed "as is". But the spec. 2.57 - // says 'this' is transformed when callee frame is created if callee 2.58 - // is a non-strict function. So, we convert 'this' here if callee is 2.59 - // not strict. Note that all builtin functions are marked as strict and 2.60 - // so 'this' transformation is not done for such functions. 2.61 - final Object thiz = convertThis((ScriptFunction)self, (args.length == 0) ? UNDEFINED : args[0]); 2.62 + final Object thiz = (args.length == 0) ? UNDEFINED : args[0]; 2.63 2.64 Object[] arguments; 2.65 if (args.length > 1) {
3.1 --- a/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Thu Jan 31 18:34:42 2013 +0100 3.2 +++ b/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Fri Feb 01 02:24:15 2013 +0100 3.3 @@ -293,7 +293,8 @@ 3.4 allArgs = ScriptRuntime.EMPTY_ARRAY; 3.5 } 3.6 3.7 - final MethodHandle boundMethod = MH.insertArguments(BOUND_FUNCTION, 0, this, thiz, allArgs); 3.8 + final Object boundThiz = convertThisObject(thiz); 3.9 + final MethodHandle boundMethod = MH.insertArguments(BOUND_FUNCTION, 0, this, boundThiz, allArgs); 3.10 final ScriptFunction boundFunc = makeFunction("", boundMethod, null, true); 3.11 3.12 MethodHandle consHandle = this.getConstructHandle();
4.1 --- a/src/jdk/nashorn/internal/runtime/GlobalObject.java Thu Jan 31 18:34:42 2013 +0100 4.2 +++ b/src/jdk/nashorn/internal/runtime/GlobalObject.java Fri Feb 01 02:24:15 2013 +0100 4.3 @@ -70,15 +70,6 @@ 4.4 4.5 4.6 /** 4.7 - * Get a MethodHandle that converts the argument to its JavaScript object representation 4.8 - * 4.9 - * @param obj a JavaScript primitive object (String, Number, or Boolean) 4.10 - * 4.11 - * @return wrap filter methodhandle 4.12 - */ 4.13 - public MethodHandle getWrapFilter(Object obj); 4.14 - 4.15 - /** 4.16 * Wrapper for {@link jdk.nashorn.internal.objects.Global#primitiveLookup(LinkRequest, Object)} 4.17 * 4.18 * @param request the link request for the dynamic call site.
5.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunction.java Thu Jan 31 18:34:42 2013 +0100 5.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunction.java Fri Feb 01 02:24:15 2013 +0100 5.3 @@ -40,7 +40,6 @@ 5.4 import jdk.nashorn.internal.parser.Token; 5.5 import jdk.nashorn.internal.runtime.linker.MethodHandleFactory; 5.6 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; 5.7 -import jdk.nashorn.internal.runtime.linker.NashornGuardedInvocation; 5.8 import jdk.nashorn.internal.runtime.linker.NashornGuards; 5.9 import jdk.nashorn.internal.runtime.options.Options; 5.10 import org.dynalang.dynalink.CallSiteDescriptor; 5.11 @@ -69,6 +68,8 @@ 5.12 5.13 private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class); 5.14 5.15 + private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", Object.class, Object.class); 5.16 + 5.17 /** method handle to arity setter for this ScriptFunction */ 5.18 public static final Call SET_ARITY = virtualCallNoLookup(ScriptFunction.class, "setArity", void.class, int.class); 5.19 /** method handle to scope getter for this ScriptFunction */ 5.20 @@ -352,7 +353,7 @@ 5.21 public abstract boolean isBuiltin(); 5.22 5.23 /** 5.24 - * Is this a non-strict (not built-in) script function? 5.25 + * Is this a non-strict and not-built-in script function? 5.26 * @return true if neither strict nor built-in 5.27 */ 5.28 public boolean isNonStrictFunction() { 5.29 @@ -371,42 +372,43 @@ 5.30 invokes++; 5.31 } 5.32 5.33 + final Object selfObj = convertThisObject(self); 5.34 final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments; 5.35 5.36 if (isVarArg(invokeHandle)) { 5.37 if (hasCalleeParameter()) { 5.38 - return invokeHandle.invokeExact(self, this, args); 5.39 + return invokeHandle.invokeExact(selfObj, this, args); 5.40 } 5.41 - return invokeHandle.invokeExact(self, args); 5.42 + return invokeHandle.invokeExact(selfObj, args); 5.43 } 5.44 5.45 final int paramCount = invokeHandle.type().parameterCount(); 5.46 if (hasCalleeParameter()) { 5.47 switch (paramCount) { 5.48 case 2: 5.49 - return invokeHandle.invokeExact(self, this); 5.50 + return invokeHandle.invokeExact(selfObj, this); 5.51 case 3: 5.52 - return invokeHandle.invokeExact(self, this, getArg(args, 0)); 5.53 + return invokeHandle.invokeExact(selfObj, this, getArg(args, 0)); 5.54 case 4: 5.55 - return invokeHandle.invokeExact(self, this, getArg(args, 0), getArg(args, 1)); 5.56 + return invokeHandle.invokeExact(selfObj, this, getArg(args, 0), getArg(args, 1)); 5.57 case 5: 5.58 - return invokeHandle.invokeExact(self, this, getArg(args, 0), getArg(args, 1), getArg(args, 2)); 5.59 + return invokeHandle.invokeExact(selfObj, this, getArg(args, 0), getArg(args, 1), getArg(args, 2)); 5.60 default: 5.61 - return invokeHandle.invokeWithArguments(withArguments(self, this, paramCount, args)); 5.62 + return invokeHandle.invokeWithArguments(withArguments(selfObj, this, paramCount, args)); 5.63 } 5.64 } 5.65 5.66 switch (paramCount) { 5.67 case 1: 5.68 - return invokeHandle.invokeExact(self); 5.69 + return invokeHandle.invokeExact(selfObj); 5.70 case 2: 5.71 - return invokeHandle.invokeExact(self, getArg(args, 0)); 5.72 + return invokeHandle.invokeExact(selfObj, getArg(args, 0)); 5.73 case 3: 5.74 - return invokeHandle.invokeExact(self, getArg(args, 0), getArg(args, 1)); 5.75 + return invokeHandle.invokeExact(selfObj, getArg(args, 0), getArg(args, 1)); 5.76 case 4: 5.77 - return invokeHandle.invokeExact(self, getArg(args, 0), getArg(args, 1), getArg(args, 2)); 5.78 + return invokeHandle.invokeExact(selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2)); 5.79 default: 5.80 - return invokeHandle.invokeWithArguments(withArguments(self, null, paramCount, args)); 5.81 + return invokeHandle.invokeWithArguments(withArguments(selfObj, null, paramCount, args)); 5.82 } 5.83 } 5.84 5.85 @@ -912,6 +914,14 @@ 5.86 return (result instanceof ScriptObject || !JSType.isPrimitive(result))? result : allocation; 5.87 } 5.88 5.89 + @SuppressWarnings("unused") 5.90 + private static Object wrapFilter(final Object obj) { 5.91 + if (obj instanceof ScriptObject || !isPrimitiveThis(obj)) { 5.92 + return obj; 5.93 + } 5.94 + return ((GlobalObject) Context.getGlobalTrusted()).wrapAsObject(obj); 5.95 + } 5.96 + 5.97 /** 5.98 * dyn:call call site signature: (callee, thiz, [args...]) 5.99 * generated method signature: (thiz, callee, [args...]) 5.100 @@ -933,11 +943,13 @@ 5.101 final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class, 5.102 type.parameterCount() - 2); 5.103 5.104 - return new GuardedInvocation(addPrimitiveWrap(collector, desc, request), 5.105 + return new GuardedInvocation(collector, 5.106 desc.getMethodType().parameterType(0) == ScriptFunction.class ? null : NashornGuards.getScriptFunctionGuard()); 5.107 } 5.108 5.109 MethodHandle boundHandle; 5.110 + MethodHandle guard = null; 5.111 + 5.112 if (hasCalleeParameter()) { 5.113 final MethodHandle callHandle = getBestSpecializedInvokeHandle(type); 5.114 5.115 @@ -956,14 +968,23 @@ 5.116 assert reorder[1] == 0; 5.117 final MethodType newType = oldType.changeParameterType(0, oldType.parameterType(1)).changeParameterType(1, oldType.parameterType(0)); 5.118 boundHandle = MethodHandles.permuteArguments(callHandle, newType, reorder); 5.119 - // thiz argument may be a JS primitive needing a wrapper 5.120 - boundHandle = addPrimitiveWrap(boundHandle, desc, request); 5.121 + 5.122 + // For non-strict functions, check whether this-object is primitive type. 5.123 + // If so add a to-object-wrapper argument filter. 5.124 + // Else install a guard that will trigger a relink when the argument becomes primitive. 5.125 + if (isNonStrictFunction()) { 5.126 + if (isPrimitiveThis(request.getArguments()[1])) { 5.127 + boundHandle = MH.filterArguments(boundHandle, 1, WRAPFILTER); 5.128 + } else { 5.129 + guard = NashornGuards.getNonStrictFunctionGuard(this); 5.130 + } 5.131 + } 5.132 } 5.133 } else { 5.134 final MethodHandle callHandle = getBestSpecializedInvokeHandle(type.dropParameterTypes(0, 1)); 5.135 5.136 if(NashornCallSiteDescriptor.isScope(desc)) { 5.137 - boundHandle = MH.bindTo(callHandle, isNonStrictFunction()? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED); 5.138 + boundHandle = MH.bindTo(callHandle, isNonStrictFunction() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED); 5.139 boundHandle = MH.dropArguments(boundHandle, 0, Object.class, Object.class); 5.140 } else { 5.141 boundHandle = MH.dropArguments(callHandle, 0, Object.class); 5.142 @@ -971,7 +992,7 @@ 5.143 } 5.144 5.145 boundHandle = pairArguments(boundHandle, type); 5.146 - return new NashornGuardedInvocation(boundHandle, null, NashornGuards.getFunctionGuard(this), isNonStrictFunction()); 5.147 + return new GuardedInvocation(boundHandle, guard == null ? NashornGuards.getFunctionGuard(this) : guard); 5.148 } 5.149 5.150 /** 5.151 @@ -997,16 +1018,25 @@ 5.152 return pairArguments(methodHandle, type); 5.153 } 5.154 5.155 - private MethodHandle addPrimitiveWrap(final MethodHandle mh, final CallSiteDescriptor desc, final LinkRequest request) { 5.156 - // Check whether thiz is a JS primitive type and needs an object wrapper for non-strict function 5.157 - if (!NashornCallSiteDescriptor.isScope(desc) && isNonStrictFunction()) { 5.158 - Object self = request.getArguments()[1]; 5.159 - if (isPrimitiveThis(self)) { 5.160 - MethodHandle wrapFilter = ((GlobalObject) Context.getGlobalTrusted()).getWrapFilter(self); 5.161 - return MH.filterArguments(mh, 1, MH.asType(wrapFilter, wrapFilter.type().changeReturnType(Object.class))); 5.162 + /** 5.163 + * Convert this argument for non-strict functions according to ES 10.4.3 5.164 + * 5.165 + * @param thiz the this argument 5.166 + * 5.167 + * @return the converted this object 5.168 + */ 5.169 + protected Object convertThisObject(final Object thiz) { 5.170 + if (!(thiz instanceof ScriptObject) && isNonStrictFunction()) { 5.171 + if (JSType.nullOrUndefined(thiz)) { 5.172 + return Context.getGlobalTrusted(); 5.173 + } 5.174 + 5.175 + if (isPrimitiveThis(thiz)) { 5.176 + return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(thiz); 5.177 } 5.178 } 5.179 - return mh; 5.180 + 5.181 + return thiz; 5.182 } 5.183 5.184 private static boolean isPrimitiveThis(Object obj) {
6.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Thu Jan 31 18:34:42 2013 +0100 6.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Feb 01 02:24:15 2013 +0100 6.3 @@ -64,7 +64,6 @@ 6.4 import jdk.nashorn.internal.runtime.linker.Lookup; 6.5 import jdk.nashorn.internal.runtime.linker.MethodHandleFactory; 6.6 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; 6.7 -import jdk.nashorn.internal.runtime.linker.NashornGuardedInvocation; 6.8 import jdk.nashorn.internal.runtime.linker.NashornGuards; 6.9 import org.dynalang.dynalink.CallSiteDescriptor; 6.10 import org.dynalang.dynalink.linker.GuardedInvocation; 6.11 @@ -1712,11 +1711,9 @@ 6.12 if (methodHandle != null) { 6.13 assert methodHandle.type().returnType().equals(returnType); 6.14 final ScriptFunction getter = find.getGetterFunction(); 6.15 - final boolean nonStrict = getter != null && getter.isNonStrictFunction(); 6.16 if (find.isSelf()) { 6.17 - return new NashornGuardedInvocation(methodHandle, null, ObjectClassGenerator.OBJECT_FIELDS_ONLY && 6.18 - NashornCallSiteDescriptor.isFastScope(desc) && !property.canChangeType() ? null : guard, 6.19 - nonStrict); 6.20 + return new GuardedInvocation(methodHandle, ObjectClassGenerator.OBJECT_FIELDS_ONLY && 6.21 + NashornCallSiteDescriptor.isFastScope(desc) && !property.canChangeType() ? null : guard); 6.22 } 6.23 6.24 final ScriptObject prototype = find.getOwner(); 6.25 @@ -1724,7 +1721,7 @@ 6.26 if (!property.hasGetterFunction()) { 6.27 methodHandle = bindTo(methodHandle, prototype); 6.28 } 6.29 - return new NashornGuardedInvocation(methodHandle, getMap().getProtoGetSwitchPoint(name), guard, nonStrict); 6.30 + return new GuardedInvocation(methodHandle, getMap().getProtoGetSwitchPoint(name), guard); 6.31 } 6.32 6.33 assert !NashornCallSiteDescriptor.isFastScope(desc);
7.1 --- a/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Thu Jan 31 18:34:42 2013 +0100 7.2 +++ b/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Fri Feb 01 02:24:15 2013 +0100 7.3 @@ -33,7 +33,6 @@ 7.4 import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator; 7.5 import jdk.nashorn.internal.runtime.linker.Lookup; 7.6 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; 7.7 -import jdk.nashorn.internal.runtime.linker.NashornGuardedInvocation; 7.8 import jdk.nashorn.internal.runtime.linker.NashornGuards; 7.9 7.10 import org.dynalang.dynalink.CallSiteDescriptor; 7.11 @@ -41,8 +40,8 @@ 7.12 7.13 /** 7.14 * Instances of this class are quite ephemeral; they only exist for the duration of an invocation of 7.15 - * {@link ScriptObject#findSetMethod(CallSiteDescriptor, boolean)} and serve as the actual encapsulation of the 7.16 - * algorithm for creating an appropriate property setter method. 7.17 + * {@link ScriptObject#findSetMethod(CallSiteDescriptor, org.dynalang.dynalink.linker.LinkRequest)} and 7.18 + * serve as the actual encapsulation of the algorithm for creating an appropriate property setter method. 7.19 */ 7.20 class SetMethodCreator { 7.21 // See constructor parameters for description of fields 7.22 @@ -89,19 +88,16 @@ 7.23 private class SetMethod { 7.24 private final MethodHandle methodHandle; 7.25 private final Property property; 7.26 - private final boolean nonStrict; 7.27 7.28 /** 7.29 * Creates a new lookup result. 7.30 * @param methodHandle the actual method handle 7.31 * @param property the property object. Can be null in case we're creating a new property in the global object. 7.32 - * @param nonStrict True if an existing property with a non-strict function as property setter is discovered. 7.33 */ 7.34 - SetMethod(final MethodHandle methodHandle, final Property property, final boolean nonStrict) { 7.35 + SetMethod(final MethodHandle methodHandle, final Property property) { 7.36 assert methodHandle != null; 7.37 this.methodHandle = methodHandle; 7.38 this.property = property; 7.39 - this.nonStrict = nonStrict; 7.40 } 7.41 7.42 /** 7.43 @@ -109,7 +105,7 @@ 7.44 * @return the composed guarded invocation that represents the dynamic setter method for the property. 7.45 */ 7.46 GuardedInvocation createGuardedInvocation() { 7.47 - return new NashornGuardedInvocation(methodHandle, null, getGuard(), nonStrict); 7.48 + return new GuardedInvocation(methodHandle, getGuard()); 7.49 } 7.50 7.51 private MethodHandle getGuard() { 7.52 @@ -162,17 +158,12 @@ 7.53 } else { 7.54 boundHandle = methodHandle; 7.55 } 7.56 - return new SetMethod(boundHandle, property, getExistingSetterNonStrictFlag()); 7.57 - } 7.58 - 7.59 - private boolean getExistingSetterNonStrictFlag() { 7.60 - final ScriptFunction setter = find.getSetterFunction(); 7.61 - return setter != null && setter.isNonStrictFunction(); 7.62 + return new SetMethod(boundHandle, property); 7.63 } 7.64 7.65 private SetMethod createGlobalPropertySetter() { 7.66 final ScriptObject global = Context.getGlobalTrusted(); 7.67 - return new SetMethod(ScriptObject.bindTo(global.addSpill(getName()), global), null, false); 7.68 + return new SetMethod(ScriptObject.bindTo(global.addSpill(getName()), global), null); 7.69 } 7.70 7.71 private SetMethod createNewPropertySetter() { 7.72 @@ -192,7 +183,7 @@ 7.73 final int nextSpill = getMap().getSpillLength(); 7.74 7.75 final Property property = createSpillProperty(nextSpill); 7.76 - return new SetMethod(createSpillMethodHandle(nextSpill, property), property, false); 7.77 + return new SetMethod(createSpillMethodHandle(nextSpill, property), property); 7.78 } 7.79 7.80 private Property createSpillProperty(final int nextSpill) { 7.81 @@ -222,7 +213,7 @@ 7.82 final Property property = new SpillProperty(getName(), 0, nextEmbed, ScriptObject.GET_EMBED[nextEmbed], ScriptObject.SET_EMBED[nextEmbed]); 7.83 //TODO specfields 7.84 final MethodHandle methodHandle = MH.insertArguments(ScriptObject.SETEMBED, 0, desc, getMap(), getNewMap(property), property.getSetter(Object.class, getMap()), nextEmbed); 7.85 - return new SetMethod(methodHandle, property, false); 7.86 + return new SetMethod(methodHandle, property); 7.87 } 7.88 7.89 private PropertyMap getNewMap(Property property) {
8.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornGuardedInvocation.java Thu Jan 31 18:34:42 2013 +0100 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,69 +0,0 @@ 8.4 -/* 8.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 8.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 - * 8.8 - * This code is free software; you can redistribute it and/or modify it 8.9 - * under the terms of the GNU General Public License version 2 only, as 8.10 - * published by the Free Software Foundation. Oracle designates this 8.11 - * particular file as subject to the "Classpath" exception as provided 8.12 - * by Oracle in the LICENSE file that accompanied this code. 8.13 - * 8.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 8.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.17 - * version 2 for more details (a copy is included in the LICENSE file that 8.18 - * accompanied this code). 8.19 - * 8.20 - * You should have received a copy of the GNU General Public License version 8.21 - * 2 along with this work; if not, write to the Free Software Foundation, 8.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.23 - * 8.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.25 - * or visit www.oracle.com if you need additional information or have any 8.26 - * questions. 8.27 - */ 8.28 - 8.29 -package jdk.nashorn.internal.runtime.linker; 8.30 - 8.31 -import java.lang.invoke.MethodHandle; 8.32 -import java.lang.invoke.SwitchPoint; 8.33 -import org.dynalang.dynalink.linker.GuardedInvocation; 8.34 - 8.35 -/** 8.36 - * Guarded invocation with Nashorn specific bits. 8.37 - */ 8.38 -public class NashornGuardedInvocation extends GuardedInvocation { 8.39 - 8.40 - private final boolean nonStrict; 8.41 - 8.42 - /** 8.43 - * Constructor 8.44 - * 8.45 - * @param invocation invocation target 8.46 - * @param switchPoint SwitchPoint that will, when invalidated, require relinking callsite, null if no SwitchPoint 8.47 - * @param guard guard that will, when failed, require relinking callsite, null if no guard 8.48 - * @param nonStrict non-strict invocation target flag 8.49 - */ 8.50 - public NashornGuardedInvocation(final MethodHandle invocation, final SwitchPoint switchPoint, final MethodHandle guard, final boolean nonStrict) { 8.51 - super(invocation, switchPoint, guard); 8.52 - this.nonStrict = nonStrict; 8.53 - 8.54 - } 8.55 - 8.56 - /** 8.57 - * Is the target of this invocation a non-strict function? 8.58 - * @return true if invocation target is non-strict 8.59 - */ 8.60 - public boolean isNonStrict() { 8.61 - return nonStrict; 8.62 - } 8.63 - 8.64 - /** 8.65 - * Check whether the target of this invocation is a non-strict script function. 8.66 - * @param inv guarded invocation 8.67 - * @return true if invocation target is non-strict 8.68 - */ 8.69 - public static boolean isNonStrict(final GuardedInvocation inv) { 8.70 - return inv instanceof NashornGuardedInvocation && ((NashornGuardedInvocation)inv).isNonStrict(); 8.71 - } 8.72 -}
9.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java Thu Jan 31 18:34:42 2013 +0100 9.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java Fri Feb 01 02:24:15 2013 +0100 9.3 @@ -41,6 +41,7 @@ 9.4 private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class); 9.5 private static final MethodHandle IS_MAP = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class); 9.6 private static final MethodHandle IS_FUNCTION_MH = findOwnMH("isFunctionMH", boolean.class, Object.class, MethodHandle.class); 9.7 + private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH("isNonStrictFunction", boolean.class, Object.class, Object.class, MethodHandle.class); 9.8 private static final MethodHandle IS_INSTANCEOF_2 = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class); 9.9 9.10 // don't create me! 9.11 @@ -99,6 +100,20 @@ 9.12 return MH.insertArguments(IS_FUNCTION_MH, 1, function.getInvokeHandle()); 9.13 } 9.14 9.15 + /** 9.16 + * Get a guard that checks if a {@link ScriptFunction} is equal to 9.17 + * a known ScriptFunction using reference comparison, and whether the type of 9.18 + * the second argument (this-object) is not a JavaScript primitive type. 9.19 + * 9.20 + * @param function The ScriptFunction to check against. This will be bound to the guard method handle 9.21 + * 9.22 + * @return method handle for guard 9.23 + */ 9.24 + public static MethodHandle getNonStrictFunctionGuard(final ScriptFunction function) { 9.25 + assert function.getInvokeHandle() != null; 9.26 + return MH.insertArguments(IS_NONSTRICT_FUNCTION, 2, function.getInvokeHandle()); 9.27 + } 9.28 + 9.29 @SuppressWarnings("unused") 9.30 private static boolean isScriptObject(final Object self) { 9.31 return self instanceof ScriptObject; 9.32 @@ -120,6 +135,11 @@ 9.33 } 9.34 9.35 @SuppressWarnings("unused") 9.36 + private static boolean isNonStrictFunction(final Object self, final Object arg, final MethodHandle mh) { 9.37 + return self instanceof ScriptFunction && ((ScriptFunction)self).getInvokeHandle() == mh && arg instanceof ScriptObject; 9.38 + } 9.39 + 9.40 + @SuppressWarnings("unused") 9.41 private static boolean isInstanceOf2(final Object self, final Class<?> class1, final Class<?> class2) { 9.42 return class1.isInstance(self) || class2.isInstance(self); 9.43 }
10.1 --- a/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java Thu Jan 31 18:34:42 2013 +0100 10.2 +++ b/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java Fri Feb 01 02:24:15 2013 +0100 10.3 @@ -101,7 +101,7 @@ 10.4 if (link != null) { 10.5 MethodHandle method = link.getInvocation(); 10.6 final Class<?> receiverType = method.type().parameterType(0); 10.7 - if (receiverType != Object.class || NashornGuardedInvocation.isNonStrict(link)) { 10.8 + if (receiverType != Object.class) { 10.9 final MethodType wrapType = wrapFilter.type(); 10.10 assert receiverType.isAssignableFrom(wrapType.returnType()); 10.11 method = MH.filterArguments(method, 0, MH.asType(wrapFilter, wrapType.changeReturnType(receiverType)));
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/test/script/basic/JDK-8007060.js Fri Feb 01 02:24:15 2013 +0100 11.3 @@ -0,0 +1,94 @@ 11.4 +/* 11.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 + * 11.8 + * This code is free software; you can redistribute it and/or modify it 11.9 + * under the terms of the GNU General Public License version 2 only, as 11.10 + * published by the Free Software Foundation. 11.11 + * 11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.15 + * version 2 for more details (a copy is included in the LICENSE file that 11.16 + * accompanied this code). 11.17 + * 11.18 + * You should have received a copy of the GNU General Public License version 11.19 + * 2 along with this work; if not, write to the Free Software Foundation, 11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.21 + * 11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 11.23 + * or visit www.oracle.com if you need additional information or have any 11.24 + * questions. 11.25 + */ 11.26 + 11.27 +/** 11.28 + * JDK-8007060 : Primitive wrap filter throws ClassCastException in test262parallel 11.29 + * 11.30 + * @test 11.31 + * @run 11.32 + */ 11.33 + 11.34 +Object.prototype.T = function() { 11.35 + print(this, typeof this); 11.36 +}; 11.37 + 11.38 +function F() { 11.39 + print(this, typeof this); 11.40 +} 11.41 + 11.42 + 11.43 +function test(obj) { 11.44 + obj.T(); 11.45 +} 11.46 + 11.47 +// Ordinary callsite - call often so we go to megamorphic 11.48 +test(1); 11.49 +test({}); 11.50 +test("hello"); 11.51 +test(1); 11.52 +test({}); 11.53 +test("hello"); 11.54 +test(1); 11.55 +test({}); 11.56 +test("hello"); 11.57 +test(1); 11.58 +test({}); 11.59 +test("hello"); 11.60 +test(1); 11.61 +test({}); 11.62 +test("hello"); 11.63 +test(1); 11.64 +test({}); 11.65 +test("hello"); 11.66 +test(1); 11.67 +test({}); 11.68 +test("hello"); 11.69 +test(1); 11.70 +test({}); 11.71 +test("hello"); 11.72 + 11.73 +// Dynamic invoker callsite used by NativeArray 11.74 +[1, 2, 3].filter(F, 1); 11.75 +[1, 2, 3].filter(F, {}); 11.76 +[1, 2, 3].filter(F, "hello"); 11.77 +[1, 2, 3].filter(F, 1); 11.78 +[1, 2, 3].filter(F, {}); 11.79 +[1, 2, 3].filter(F, "hello"); 11.80 +[1, 2, 3].filter(F, 1); 11.81 +[1, 2, 3].filter(F, {}); 11.82 +[1, 2, 3].filter(F, "hello"); 11.83 +[1, 2, 3].filter(F, 1); 11.84 +[1, 2, 3].filter(F, {}); 11.85 +[1, 2, 3].filter(F, "hello"); 11.86 +[1, 2, 3].filter(F, 1); 11.87 +[1, 2, 3].filter(F, {}); 11.88 +[1, 2, 3].filter(F, "hello"); 11.89 +[1, 2, 3].filter(F, 1); 11.90 +[1, 2, 3].filter(F, {}); 11.91 +[1, 2, 3].filter(F, "hello"); 11.92 +[1, 2, 3].filter(F, 1); 11.93 +[1, 2, 3].filter(F, {}); 11.94 +[1, 2, 3].filter(F, "hello"); 11.95 +[1, 2, 3].filter(F, 1); 11.96 +[1, 2, 3].filter(F, {}); 11.97 +[1, 2, 3].filter(F, "hello"); 11.98 \ No newline at end of file
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/test/script/basic/JDK-8007060.js.EXPECTED Fri Feb 01 02:24:15 2013 +0100 12.3 @@ -0,0 +1,96 @@ 12.4 +1 object 12.5 +[object Object] object 12.6 +hello object 12.7 +1 object 12.8 +[object Object] object 12.9 +hello object 12.10 +1 object 12.11 +[object Object] object 12.12 +hello object 12.13 +1 object 12.14 +[object Object] object 12.15 +hello object 12.16 +1 object 12.17 +[object Object] object 12.18 +hello object 12.19 +1 object 12.20 +[object Object] object 12.21 +hello object 12.22 +1 object 12.23 +[object Object] object 12.24 +hello object 12.25 +1 object 12.26 +[object Object] object 12.27 +hello object 12.28 +1 object 12.29 +1 object 12.30 +1 object 12.31 +[object Object] object 12.32 +[object Object] object 12.33 +[object Object] object 12.34 +hello object 12.35 +hello object 12.36 +hello object 12.37 +1 object 12.38 +1 object 12.39 +1 object 12.40 +[object Object] object 12.41 +[object Object] object 12.42 +[object Object] object 12.43 +hello object 12.44 +hello object 12.45 +hello object 12.46 +1 object 12.47 +1 object 12.48 +1 object 12.49 +[object Object] object 12.50 +[object Object] object 12.51 +[object Object] object 12.52 +hello object 12.53 +hello object 12.54 +hello object 12.55 +1 object 12.56 +1 object 12.57 +1 object 12.58 +[object Object] object 12.59 +[object Object] object 12.60 +[object Object] object 12.61 +hello object 12.62 +hello object 12.63 +hello object 12.64 +1 object 12.65 +1 object 12.66 +1 object 12.67 +[object Object] object 12.68 +[object Object] object 12.69 +[object Object] object 12.70 +hello object 12.71 +hello object 12.72 +hello object 12.73 +1 object 12.74 +1 object 12.75 +1 object 12.76 +[object Object] object 12.77 +[object Object] object 12.78 +[object Object] object 12.79 +hello object 12.80 +hello object 12.81 +hello object 12.82 +1 object 12.83 +1 object 12.84 +1 object 12.85 +[object Object] object 12.86 +[object Object] object 12.87 +[object Object] object 12.88 +hello object 12.89 +hello object 12.90 +hello object 12.91 +1 object 12.92 +1 object 12.93 +1 object 12.94 +[object Object] object 12.95 +[object Object] object 12.96 +[object Object] object 12.97 +hello object 12.98 +hello object 12.99 +hello object