8007060: Primitive wrap filter throws ClassCastException in test262parallel

Reviewed-by: sundar, jlaskey, lagergren
This commit is contained in:
Hannes Wallnöfer 2013-02-01 02:24:15 +01:00
parent fe52eb5992
commit 4f2891ca8d
12 changed files with 284 additions and 174 deletions

View File

@ -418,18 +418,6 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
}
}
@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) {

View File

@ -66,17 +66,6 @@ public final class NativeFunction {
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 @@ public final class NativeFunction {
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 @@ public final class NativeFunction {
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 @@ public final class NativeFunction {
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) {

View File

@ -293,7 +293,8 @@ public class ScriptFunctionImpl extends ScriptFunction {
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();

View File

@ -69,15 +69,6 @@ public interface GlobalObject {
public Object wrapAsObject(Object obj);
/**
* 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)}
*

View File

@ -40,7 +40,6 @@ import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
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 @@ public abstract class ScriptFunction extends ScriptObject {
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 class ScriptFunction extends ScriptObject {
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 @@ public abstract class ScriptFunction extends ScriptObject {
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 @@ public abstract class ScriptFunction extends ScriptObject {
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 @@ public abstract class ScriptFunction extends ScriptObject {
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 @@ public abstract class ScriptFunction extends ScriptObject {
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 @@ public abstract class ScriptFunction extends ScriptObject {
}
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 @@ public abstract class ScriptFunction extends ScriptObject {
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) {

View File

@ -64,7 +64,6 @@ import jdk.nashorn.internal.runtime.linker.Bootstrap;
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);

View File

@ -33,7 +33,6 @@ import java.lang.invoke.MethodHandle;
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 @@ import org.dynalang.dynalink.linker.GuardedInvocation;
/**
* 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 @@ class SetMethodCreator {
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 @@ class SetMethodCreator {
* @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 @@ class SetMethodCreator {
} 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 @@ class SetMethodCreator {
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 @@ class SetMethodCreator {
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) {

View File

@ -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();
}
}

View File

@ -41,6 +41,7 @@ public final class NashornGuards {
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 @@ public final class NashornGuards {
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;
@ -119,6 +134,11 @@ public final class NashornGuards {
return self instanceof ScriptFunction && ((ScriptFunction)self).getInvokeHandle() == mh;
}
@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);

View File

@ -101,7 +101,7 @@ public class PrimitiveLookup {
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)));

View File

@ -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");

View File

@ -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