提交 8c50098c 编写于 作者: M mullan

Merge

......@@ -117,3 +117,4 @@ d80954a89b49fda47c0c5cace65a17f5a758b8bd jdk7-b139
9315c733fb17ddfb9fb44be7e0ffea37bf3c727d jdk7-b140
63eeefe118da18c75ba3d36266768cd1ccaaca6b jdk7-b141
312612e89ece62633f4809706dec00bcd5fe7c2d jdk7-b142
efbf75c24b0f31847c9c403f6dc07dc80551908d jdk7-b143
......@@ -85,16 +85,21 @@ REMOTE_impls = \
sun.rmi.registry.RegistryImpl \
sun.rmi.transport.DGCImpl
ifeq ($(PLATFORM), windows)
build: stubs
else # PLATFORM
ifneq ($(ARCH_DATA_MODEL), 32)
build: stubs
else # ARCH_DATA_MODEL
build: stubs bin
#
# The java-rmi.cgi script in bin/ only gets delivered in certain situations
#
BUILD_TARGETS = stubs
ifeq ($(PLATFORM), linux)
BUILD_TARGETS += bin
endif
ifeq ($(PLATFORM), solaris)
ifeq ($(ARCH_DATA_MODEL), 32)
BUILD_TARGETS += bin
endif
endif
build: $(BUILD_TARGETS)
clean clobber:: bin.clean
......
......@@ -158,7 +158,6 @@ SUNWprivate_1.1 {
Java_sun_awt_X11_XRobotPeer_mouseReleaseImpl;
Java_sun_awt_X11_XRobotPeer_mouseWheelImpl;
Java_sun_awt_X11_XRobotPeer_setup;
Java_sun_awt_X11_XRobotPeer__1dispose;
Java_sun_awt_X11_XToolkit_getNumberOfButtonsImpl;
Java_java_awt_Component_initIDs;
Java_java_awt_Container_initIDs;
......
......@@ -2887,11 +2887,12 @@ public abstract class Component implements ImageObserver, MenuContainer,
/**
* Invalidates this component and its ancestors.
* <p>
* All the ancestors of this component up to the nearest validate root are
* marked invalid also. If there is no a validate root container for this
* component, all of its ancestors up to the root of the hierarchy are
* marked invalid as well. Marking a container <i>invalid</i> indicates
* that the container needs to be laid out.
* By default, all the ancestors of the component up to the top-most
* container of the hierarchy are marked invalid. If the {@code
* java.awt.smartInvalidate} system property is set to {@code true},
* invalidation stops on the nearest validate root of this component.
* Marking a container <i>invalid</i> indicates that the container needs to
* be laid out.
* <p>
* This method is called automatically when any layout-related information
* changes (e.g. setting the bounds of the component, or adding the
......
......@@ -41,6 +41,8 @@ import java.io.ObjectStreamField;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.security.AccessController;
import java.util.Arrays;
import java.util.EventListener;
import java.util.HashSet;
......@@ -60,6 +62,8 @@ import sun.awt.dnd.SunDropTargetEvent;
import sun.java2d.pipe.Region;
import sun.security.action.GetBooleanAction;
/**
* A generic Abstract Window Toolkit(AWT) container object is a component
* that can contain other AWT components.
......@@ -1506,12 +1510,18 @@ public class Container extends Component {
* Layout-related changes, such as bounds of the validate root descendants,
* do not affect the layout of the validate root parent. This peculiarity
* enables the {@code invalidate()} method to stop invalidating the
* component hierarchy when the method encounters a validate root.
* component hierarchy when the method encounters a validate root. However,
* to preserve backward compatibility this new optimized behavior is
* enabled only when the {@code java.awt.smartInvalidate} system property
* value is set to {@code true}.
* <p>
* If a component hierarchy contains validate roots, the {@code validate()}
* method must be invoked on the validate root of a previously invalidated
* component, rather than on the top-level container (such as a {@code
* Frame} object) to restore the validity of the hierarchy later.
* If a component hierarchy contains validate roots and the new optimized
* {@code invalidate()} behavior is enabled, the {@code validate()} method
* must be invoked on the validate root of a previously invalidated
* component to restore the validity of the hierarchy later. Otherwise,
* calling the {@code validate()} method on the top-level container (such
* as a {@code Frame} object) should be used to restore the validity of the
* component hierarchy.
* <p>
* The {@code Window} class and the {@code Applet} class are the validate
* roots in AWT. Swing introduces more validate roots.
......@@ -1527,13 +1537,20 @@ public class Container extends Component {
return false;
}
private static final boolean isJavaAwtSmartInvalidate;
static {
// Don't lazy-read because every app uses invalidate()
isJavaAwtSmartInvalidate = AccessController.doPrivileged(
new GetBooleanAction("java.awt.smartInvalidate"));
}
/**
* Invalidates the parent of the container unless the container
* is a validate root.
*/
@Override
void invalidateParent() {
if (!isValidateRoot()) {
if (!isJavaAwtSmartInvalidate || !isValidateRoot()) {
super.invalidateParent();
}
}
......@@ -1572,9 +1589,8 @@ public class Container extends Component {
* automatically. Note that the ancestors of the container may be
* invalidated also (see {@link Component#invalidate} for details.)
* Therefore, to restore the validity of the hierarchy, the {@code
* validate()} method should be invoked on a validate root of an
* invalidated component, or on the top-most container if the hierarchy
* does not contain validate roots.
* validate()} method should be invoked on the top-most invalid
* container of the hierarchy.
* <p>
* Validating the container may be a quite time-consuming operation. For
* performance reasons a developer may postpone the validation of the
......
......@@ -466,10 +466,7 @@ public abstract class Toolkit {
*/
protected void loadSystemColors(int[] systemColors)
throws HeadlessException {
if (GraphicsEnvironment.isHeadless()){
throw new HeadlessException();
}
GraphicsEnvironment.checkHeadless();
}
/**
......@@ -504,10 +501,7 @@ public abstract class Toolkit {
*/
public void setDynamicLayout(boolean dynamic)
throws HeadlessException {
if (GraphicsEnvironment.isHeadless()){
throw new HeadlessException();
}
GraphicsEnvironment.checkHeadless();
}
/**
......@@ -531,9 +525,8 @@ public abstract class Toolkit {
*/
protected boolean isDynamicLayoutSet()
throws HeadlessException {
if (GraphicsEnvironment.isHeadless()){
throw new HeadlessException();
}
GraphicsEnvironment.checkHeadless();
if (this != Toolkit.getDefaultToolkit()) {
return Toolkit.getDefaultToolkit().isDynamicLayoutSet();
} else {
......@@ -569,9 +562,8 @@ public abstract class Toolkit {
*/
public boolean isDynamicLayoutActive()
throws HeadlessException {
if (GraphicsEnvironment.isHeadless()){
throw new HeadlessException();
}
GraphicsEnvironment.checkHeadless();
if (this != Toolkit.getDefaultToolkit()) {
return Toolkit.getDefaultToolkit().isDynamicLayoutActive();
} else {
......@@ -615,9 +607,7 @@ public abstract class Toolkit {
*/
public Insets getScreenInsets(GraphicsConfiguration gc)
throws HeadlessException {
if (GraphicsEnvironment.isHeadless()){
throw new HeadlessException();
}
GraphicsEnvironment.checkHeadless();
if (this != Toolkit.getDefaultToolkit()) {
return Toolkit.getDefaultToolkit().getScreenInsets(gc);
} else {
......@@ -1200,10 +1190,7 @@ public abstract class Toolkit {
* security manager's <code>checkPermission</code> method with a <code>
* RuntimePermission("queuePrintJob")</code> permission.
*
* @param frame the parent of the print dialog. May be null if and only
* if jobAttributes is not null and jobAttributes.getDialog()
* returns JobAttributes.DialogType.NONE or
* JobAttributes.DialogType.COMMON.
* @param frame the parent of the print dialog. May not be null.
* @param jobtitle the title of the PrintJob. A null title is equivalent
* to "".
* @param jobAttributes a set of job attributes which will control the
......@@ -1359,9 +1346,8 @@ public abstract class Toolkit {
* @since 1.4
*/
public Clipboard getSystemSelection() throws HeadlessException {
if (GraphicsEnvironment.isHeadless()){
throw new HeadlessException();
}
GraphicsEnvironment.checkHeadless();
if (this != Toolkit.getDefaultToolkit()) {
return Toolkit.getDefaultToolkit().getSystemSelection();
} else {
......@@ -1391,9 +1377,7 @@ public abstract class Toolkit {
* @since JDK1.1
*/
public int getMenuShortcutKeyMask() throws HeadlessException {
if (GraphicsEnvironment.isHeadless()){
throw new HeadlessException();
}
GraphicsEnvironment.checkHeadless();
return Event.CTRL_MASK;
}
......@@ -1418,7 +1402,10 @@ public abstract class Toolkit {
* @since 1.3
*/
public boolean getLockingKeyState(int keyCode)
throws UnsupportedOperationException {
throws UnsupportedOperationException
{
GraphicsEnvironment.checkHeadless();
if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK ||
keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) {
throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
......@@ -1449,7 +1436,10 @@ public abstract class Toolkit {
* @since 1.3
*/
public void setLockingKeyState(int keyCode, boolean on)
throws UnsupportedOperationException {
throws UnsupportedOperationException
{
GraphicsEnvironment.checkHeadless();
if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK ||
keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) {
throw new IllegalArgumentException("invalid key for Toolkit.setLockingKeyState");
......@@ -1523,9 +1513,8 @@ public abstract class Toolkit {
*/
public Dimension getBestCursorSize(int preferredWidth,
int preferredHeight) throws HeadlessException {
if (GraphicsEnvironment.isHeadless()){
throw new HeadlessException();
}
GraphicsEnvironment.checkHeadless();
// Override to implement custom cursor support.
if (this != Toolkit.getDefaultToolkit()) {
return Toolkit.getDefaultToolkit().
......@@ -1553,9 +1542,8 @@ public abstract class Toolkit {
* @since 1.2
*/
public int getMaximumCursorColors() throws HeadlessException {
if (GraphicsEnvironment.isHeadless()){
throw new HeadlessException();
}
GraphicsEnvironment.checkHeadless();
// Override to implement custom cursor support.
if (this != Toolkit.getDefaultToolkit()) {
return Toolkit.getDefaultToolkit().getMaximumCursorColors();
......@@ -1605,9 +1593,8 @@ public abstract class Toolkit {
public boolean isFrameStateSupported(int state)
throws HeadlessException
{
if (GraphicsEnvironment.isHeadless()){
throw new HeadlessException();
}
GraphicsEnvironment.checkHeadless();
if (this != Toolkit.getDefaultToolkit()) {
return Toolkit.getDefaultToolkit().
isFrameStateSupported(state);
......@@ -2614,9 +2601,8 @@ public abstract class Toolkit {
* @since 1.7
*/
public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
if (GraphicsEnvironment.isHeadless()){
throw new HeadlessException();
}
GraphicsEnvironment.checkHeadless();
return Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled();
}
}
......@@ -777,7 +777,8 @@ public class Throwable implements Serializable {
* @see java.lang.Throwable#printStackTrace()
*/
public synchronized Throwable fillInStackTrace() {
if (stackTrace != null) {
if (stackTrace != null ||
backtrace != null /* Out of protocol state */ ) {
fillInStackTrace(0);
stackTrace = UNASSIGNED_STACK;
}
......@@ -817,7 +818,8 @@ public class Throwable implements Serializable {
private synchronized StackTraceElement[] getOurStackTrace() {
// Initialize stack trace field with information from
// backtrace if this is the first call to this method
if (stackTrace == UNASSIGNED_STACK) {
if (stackTrace == UNASSIGNED_STACK ||
(stackTrace == null && backtrace != null) /* Out of protocol state */) {
int depth = getStackTraceDepth();
stackTrace = new StackTraceElement[depth];
for (int i=0; i < depth; i++)
......@@ -865,7 +867,8 @@ public class Throwable implements Serializable {
}
synchronized (this) {
if (this.stackTrace == null) // Immutable stack
if (this.stackTrace == null && // Immutable stack
backtrace == null) // Test for out of protocol state
return;
this.stackTrace = defensiveCopy;
}
......
......@@ -273,9 +273,9 @@ public class CallSite {
Object binding;
info = maybeReBox(info);
if (info == null) {
binding = bootstrapMethod.invokeGeneric(caller, name, type);
binding = bootstrapMethod.invoke(caller, name, type);
} else if (!info.getClass().isArray()) {
binding = bootstrapMethod.invokeGeneric(caller, name, type, info);
binding = bootstrapMethod.invoke(caller, name, type, info);
} else {
Object[] argv = (Object[]) info;
maybeReBoxElements(argv);
......@@ -283,10 +283,10 @@ public class CallSite {
throw new BootstrapMethodError("too many bootstrap method arguments");
MethodType bsmType = bootstrapMethod.type();
if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class)
binding = bootstrapMethod.invokeGeneric(caller, name, type, argv);
binding = bootstrapMethod.invoke(caller, name, type, argv);
else
binding = MethodHandles.spreadInvoker(bsmType, 3)
.invokeGeneric(bootstrapMethod, caller, name, type, argv);
.invoke(bootstrapMethod, caller, name, type, argv);
}
//System.out.println("BSM for "+name+type+" => "+binding);
if (binding instanceof CallSite) {
......
......@@ -61,6 +61,10 @@ class FilterGeneric {
return ad;
}
static {
assert(MethodHandleNatives.workaroundWithoutRicochetFrames()); // this class is deprecated
}
Adapter makeInstance(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
Adapter ad = getAdapter(kind, pos);
return ad.makeInstance(ad.prototypeEntryPoint(), filter, target);
......
......@@ -67,6 +67,10 @@ class FilterOneArgument extends BoundMethodHandle {
this.target = target;
}
static {
assert(MethodHandleNatives.workaroundWithoutRicochetFrames()); // this class is deprecated
}
public static MethodHandle make(MethodHandle filter, MethodHandle target) {
if (filter == null) return target;
if (target == null) return filter;
......
......@@ -98,6 +98,10 @@ class FromGeneric {
this.unboxingInvoker = computeUnboxingInvoker(targetType, internalType0);
}
static {
assert(MethodHandleNatives.workaroundWithoutRicochetFrames()); // this class is deprecated
}
/**
* The typed target will be called according to targetType.
* The adapter code will in fact see the raw result from internalType,
......@@ -112,10 +116,10 @@ class FromGeneric {
assert(iret == Object.class);
return ValueConversions.identity();
} else if (wrap.primitiveType() == iret) {
return ValueConversions.box(wrap, false);
return ValueConversions.box(wrap);
} else {
assert(tret == double.class ? iret == long.class : iret == int.class);
return ValueConversions.boxRaw(wrap, false);
return ValueConversions.boxRaw(wrap);
}
}
......@@ -135,7 +139,7 @@ class FromGeneric {
MethodType fixArgsType = internalType.changeReturnType(targetType.returnType());
MethodHandle fixArgs = MethodHandleImpl.convertArguments(
invoker, Invokers.invokerType(fixArgsType),
invoker.type(), null);
invoker.type(), 0);
if (fixArgs == null)
throw new InternalError("bad fixArgs");
// reinterpret the calling sequence as raw:
......@@ -160,7 +164,6 @@ class FromGeneric {
/** Build an adapter of the given generic type, which invokes typedTarget
* on the incoming arguments, after unboxing as necessary.
* The return value is boxed if necessary.
* @param genericType the required type of the result
* @param typedTarget the target
* @return an adapter method handle
*/
......@@ -231,7 +234,7 @@ class FromGeneric {
}
static Adapter buildAdapterFromBytecodes(MethodType internalType) {
throw new UnsupportedOperationException("NYI");
throw new UnsupportedOperationException("NYI "+internalType);
}
/**
......
......@@ -29,12 +29,12 @@ import sun.invoke.util.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
/**
* Adapters which manage MethodHandle.invokeGeneric calls.
* Adapters which manage inexact MethodHandle.invoke calls.
* The JVM calls one of these when the exact type match fails.
* @author jrose
*/
class InvokeGeneric {
// erased type for the call, which originates from an invokeGeneric site
// erased type for the call, which originates from an inexact invoke site
private final MethodType erasedCallerType;
// an invoker of type (MT, MH; A...) -> R
private final MethodHandle initialInvoker;
......@@ -56,7 +56,7 @@ class InvokeGeneric {
}
/** Return the adapter information for this type's erasure. */
/*non-public*/ static MethodHandle genericInvokerOf(MethodType erasedCallerType) throws ReflectiveOperationException {
/*non-public*/ static MethodHandle generalInvokerOf(MethodType erasedCallerType) throws ReflectiveOperationException {
InvokeGeneric gen = new InvokeGeneric(erasedCallerType);
return gen.initialInvoker;
}
......
......@@ -43,10 +43,10 @@ class Invokers {
private /*lazy*/ MethodHandle erasedInvoker;
/*lazy*/ MethodHandle erasedInvokerWithDrops; // for InvokeGeneric
// generic (untyped) invoker for the outgoing call
private /*lazy*/ MethodHandle genericInvoker;
// general invoker for the outgoing call
private /*lazy*/ MethodHandle generalInvoker;
// generic (untyped) invoker for the outgoing call; accepts a single Object[]
// general invoker for the outgoing call; accepts a single Object[]
private final /*lazy*/ MethodHandle[] spreadInvokers;
// invoker for an unbound callsite
......@@ -77,13 +77,13 @@ class Invokers {
return invoker;
}
/*non-public*/ MethodHandle genericInvoker() {
/*non-public*/ MethodHandle generalInvoker() {
MethodHandle invoker1 = exactInvoker();
MethodHandle invoker = genericInvoker;
MethodHandle invoker = generalInvoker;
if (invoker != null) return invoker;
MethodType genericType = targetType.generic();
invoker = MethodHandles.convertArguments(invoker1, invokerType(genericType));
genericInvoker = invoker;
MethodType generalType = targetType.generic();
invoker = invoker1.asType(invokerType(generalType));
generalInvoker = invoker;
return invoker;
}
......@@ -93,9 +93,9 @@ class Invokers {
if (invoker != null) return invoker;
MethodType erasedType = targetType.erase();
if (erasedType == targetType.generic())
invoker = genericInvoker();
invoker = generalInvoker();
else
invoker = MethodHandles.convertArguments(invoker1, invokerType(erasedType));
invoker = invoker1.asType(invokerType(erasedType));
erasedInvoker = invoker;
return invoker;
}
......@@ -103,7 +103,7 @@ class Invokers {
/*non-public*/ MethodHandle spreadInvoker(int objectArgCount) {
MethodHandle vaInvoker = spreadInvokers[objectArgCount];
if (vaInvoker != null) return vaInvoker;
MethodHandle gInvoker = genericInvoker();
MethodHandle gInvoker = generalInvoker();
vaInvoker = gInvoker.asSpreader(Object[].class, targetType.parameterCount() - objectArgCount);
spreadInvokers[objectArgCount] = vaInvoker;
return vaInvoker;
......
......@@ -525,7 +525,7 @@ import static java.lang.invoke.MethodHandleStatics.*;
/** A factory type for resolving member names with the help of the VM.
* TBD: Define access-safe public constructors for this factory.
*/
public static class Factory {
/*non-public*/ static class Factory {
private Factory() { } // singleton pattern
static Factory INSTANCE = new Factory();
......
......@@ -115,6 +115,8 @@ class MethodHandleNatives {
/** Which conv-ops are implemented by the JVM? */
static final int CONV_OP_IMPLEMENTED_MASK;
/** Derived mode flag. Only false on some old JVM implementations. */
static final boolean HAVE_RICOCHET_FRAMES;
private static native void registerNatives();
static {
......@@ -141,6 +143,7 @@ class MethodHandleNatives {
if (CONV_OP_IMPLEMENTED_MASK_ == 0)
CONV_OP_IMPLEMENTED_MASK_ = DEFAULT_CONV_OP_IMPLEMENTED_MASK;
CONV_OP_IMPLEMENTED_MASK = CONV_OP_IMPLEMENTED_MASK_;
HAVE_RICOCHET_FRAMES = (CONV_OP_IMPLEMENTED_MASK & (1<<OP_COLLECT_ARGS)) != 0;
}
// All compile-time constants go here.
......@@ -186,25 +189,26 @@ class MethodHandleNatives {
*/
static final int
OP_RETYPE_ONLY = 0x0, // no argument changes; straight retype
OP_RETYPE_RAW = 0x1, // no argument changes; straight retype
OP_RETYPE_RAW = 0x1, // straight retype, trusted (void->int, Object->T)
OP_CHECK_CAST = 0x2, // ref-to-ref conversion; requires a Class argument
OP_PRIM_TO_PRIM = 0x3, // converts from one primitive to another
OP_REF_TO_PRIM = 0x4, // unboxes a wrapper to produce a primitive
OP_PRIM_TO_REF = 0x5, // boxes a primitive into a wrapper (NYI)
OP_PRIM_TO_REF = 0x5, // boxes a primitive into a wrapper
OP_SWAP_ARGS = 0x6, // swap arguments (vminfo is 2nd arg)
OP_ROT_ARGS = 0x7, // rotate arguments (vminfo is displaced arg)
OP_DUP_ARGS = 0x8, // duplicates one or more arguments (at TOS)
OP_DROP_ARGS = 0x9, // remove one or more argument slots
OP_COLLECT_ARGS = 0xA, // combine one or more arguments into a varargs (NYI)
OP_COLLECT_ARGS = 0xA, // combine arguments using an auxiliary function
OP_SPREAD_ARGS = 0xB, // expand in place a varargs array (of known size)
OP_FLYBY = 0xC, // operate first on reified argument list (NYI)
OP_RICOCHET = 0xD, // run an adapter chain on the return value (NYI)
OP_FOLD_ARGS = 0xC, // combine but do not remove arguments; prepend result
//OP_UNUSED_13 = 0xD, // unused code, perhaps for reified argument lists
CONV_OP_LIMIT = 0xE; // limit of CONV_OP enumeration
/** Shift and mask values for decoding the AMH.conversion field.
* These numbers are shared with the JVM for creating AMHs.
*/
static final int
CONV_OP_MASK = 0xF00, // this nybble contains the conversion op field
CONV_TYPE_MASK = 0x0F, // fits T_ADDRESS and below
CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
CONV_VMINFO_SHIFT = 0, // position of bits in CONV_VMINFO_MASK
CONV_OP_SHIFT = 8, // position of bits in CONV_OP_MASK
......@@ -244,8 +248,9 @@ class MethodHandleNatives {
T_LONG = 11,
T_OBJECT = 12,
//T_ARRAY = 13
T_VOID = 14;
T_VOID = 14,
//T_ADDRESS = 15
T_ILLEGAL = 99;
/**
* Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
......@@ -273,16 +278,29 @@ class MethodHandleNatives {
try {
Field con = Constants.class.getDeclaredField(name);
int jval = con.getInt(null);
if (jval != vmval)
throw new InternalError(name+": JVM has "+vmval+" while Java has "+jval);
if (jval == vmval) continue;
String err = (name+": JVM has "+vmval+" while Java has "+jval);
if (name.equals("CONV_OP_LIMIT")) {
System.err.println("warning: "+err);
continue;
}
throw new InternalError(err);
} catch (Exception ex) {
if (ex instanceof NoSuchFieldException) {
String err = (name+": JVM has "+vmval+" which Java does not define");
// ignore exotic ops the JVM cares about; we just wont issue them
if (name.startsWith("OP_") || name.startsWith("GC_")) {
System.err.println("warning: "+err);
continue;
}
}
throw new InternalError(name+": access failed, got "+ex);
}
}
return true;
}
static {
verifyConstants();
assert(verifyConstants());
}
// Up-calls from the JVM.
......@@ -313,7 +331,7 @@ class MethodHandleNatives {
}
/**
* The JVM wants to use a MethodType with invokeGeneric. Give the runtime fair warning.
* The JVM wants to use a MethodType with inexact invoke. Give the runtime fair warning.
*/
static void notifyGenericMethodType(MethodType type) {
type.form().notifyGenericMethodType();
......@@ -323,15 +341,39 @@ class MethodHandleNatives {
* The JVM wants to raise an exception. Here's the path.
*/
static void raiseException(int code, Object actual, Object required) {
String message;
String message = null;
switch (code) {
case 190: // arraylength
try {
String reqLength = "";
if (required instanceof AdapterMethodHandle) {
int conv = ((AdapterMethodHandle)required).getConversion();
int spChange = AdapterMethodHandle.extractStackMove(conv);
reqLength = " of length "+(spChange+1);
}
int actualLength = actual == null ? 0 : java.lang.reflect.Array.getLength(actual);
message = "required array"+reqLength+", but encountered wrong length "+actualLength;
break;
} catch (IllegalArgumentException ex) {
}
required = Object[].class; // should have been an array
code = 192; // checkcast
break;
}
// disregard the identity of the actual object, if it is not a class:
if (!(actual instanceof Class) && !(actual instanceof MethodType))
actual = actual.getClass();
if (actual != null)
message = "required "+required+" but encountered "+actual;
else
message = "required "+required;
if (message == null) {
if (!(actual instanceof Class) && !(actual instanceof MethodType))
actual = actual.getClass();
if (actual != null)
message = "required "+required+" but encountered "+actual;
else
message = "required "+required;
}
switch (code) {
case 190: // arraylength
throw new ArrayIndexOutOfBoundsException(message);
case 50: //_aaload
throw new ClassCastException(message);
case 192: // checkcast
throw new ClassCastException(message);
default:
......@@ -365,4 +407,13 @@ class MethodHandleNatives {
throw err;
}
}
/**
* This assertion marks code which was written before ricochet frames were implemented.
* Such code will go away when the ports catch up.
*/
static boolean workaroundWithoutRicochetFrames() {
assert(!HAVE_RICOCHET_FRAMES) : "this code should not be executed if `-XX:+UseRicochetFrames is enabled";
return true;
}
}
......@@ -63,8 +63,17 @@ package java.lang.invoke;
}
static void checkSpreadArgument(Object av, int n) {
if (av == null ? n != 0 : ((Object[])av).length != n)
throw newIllegalArgumentException("Array is not of length "+n);
if (av == null) {
if (n == 0) return;
} else if (av instanceof Object[]) {
int len = ((Object[])av).length;
if (len == n) return;
} else {
int len = java.lang.reflect.Array.getLength(av);
if (len == n) return;
}
// fall through to error:
throw newIllegalArgumentException("Array is not of length "+n);
}
// handy shared exception makers (they simplify the common case code)
......@@ -80,6 +89,9 @@ package java.lang.invoke;
/*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj) {
return new IllegalArgumentException(message(message, obj));
}
/*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj, Object obj2) {
return new IllegalArgumentException(message(message, obj, obj2));
}
/*non-public*/ static Error uncaughtException(Exception ex) {
Error err = new InternalError("uncaught exception");
err.initCause(ex);
......@@ -89,4 +101,8 @@ package java.lang.invoke;
if (obj != null) message = message + ": " + obj;
return message;
}
private static String message(String message, Object obj, Object obj2) {
if (obj != null || obj2 != null) message = message + ": " + obj + ", " + obj2;
return message;
}
}
......@@ -190,7 +190,7 @@ public class MethodHandles {
* is not symbolically accessible from the lookup class's loader,
* the lookup can still succeed.
* For example, lookups for {@code MethodHandle.invokeExact} and
* {@code MethodHandle.invokeGeneric} will always succeed, regardless of requested type.
* {@code MethodHandle.invoke} will always succeed, regardless of requested type.
* <li>If there is a security manager installed, it can forbid the lookup
* on various grounds (<a href="#secmgr">see below</a>).
* By contrast, the {@code ldc} instruction is not subject to
......@@ -590,10 +590,10 @@ public class MethodHandles {
* Because of the general equivalence between {@code invokevirtual}
* instructions and method handles produced by {@code findVirtual},
* if the class is {@code MethodHandle} and the name string is
* {@code invokeExact} or {@code invokeGeneric}, the resulting
* {@code invokeExact} or {@code invoke}, the resulting
* method handle is equivalent to one produced by
* {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
* {@link java.lang.invoke.MethodHandles#genericInvoker MethodHandles.genericInvoker}
* {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
* with the same {@code type} argument.
*
* @param refc the class or interface from which the method is accessed
......@@ -1080,7 +1080,7 @@ return mh1;
MethodType rawType = mh.type();
if (rawType.parameterType(0) == caller) return mh;
MethodType narrowType = rawType.changeParameterType(0, caller);
MethodHandle narrowMH = MethodHandleImpl.convertArguments(mh, narrowType, rawType, null);
MethodHandle narrowMH = MethodHandleImpl.convertArguments(mh, narrowType, rawType, 0);
return fixVarargs(narrowMH, mh);
}
......@@ -1148,7 +1148,7 @@ return mh1;
* <li>an {@code Object[]} array containing more arguments
* </ul>
* <p>
* The invoker will behave like a call to {@link MethodHandle#invokeGeneric invokeGeneric} with
* The invoker will behave like a call to {@link MethodHandle#invoke invoke} with
* the indicated {@code type}.
* That is, if the target is exactly of the given {@code type}, it will behave
* like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
......@@ -1166,7 +1166,7 @@ return mh1;
* <p>
* This method is equivalent to the following code (though it may be more efficient):
* <p><blockquote><pre>
MethodHandle invoker = MethodHandles.genericInvoker(type);
MethodHandle invoker = MethodHandles.invoker(type);
int spreadArgCount = type.parameterCount - objectArgCount;
invoker = invoker.asSpreader(Object[].class, spreadArgCount);
return invoker;
......@@ -1186,7 +1186,7 @@ return invoker;
/**
* Produces a special <em>invoker method handle</em> which can be used to
* invoke any method handle of the given type, as if by {@code invokeExact}.
* invoke any method handle of the given type, as if by {@link MethodHandle#invokeExact invokeExact}.
* The resulting invoker will have a type which is
* exactly equal to the desired type, except that it will accept
* an additional leading argument of type {@code MethodHandle}.
......@@ -1203,7 +1203,7 @@ publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
* For example, to emulate an {@code invokeExact} call to a variable method
* handle {@code M}, extract its type {@code T},
* look up the invoker method {@code X} for {@code T},
* and call the invoker method, as {@code X.invokeGeneric(T, A...)}.
* and call the invoker method, as {@code X.invoke(T, A...)}.
* (It would not work to call {@code X.invokeExact}, since the type {@code T}
* is unknown.)
* If spreading, collecting, or other argument transformations are required,
......@@ -1212,7 +1212,7 @@ publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
* <p>
* <em>(Note: The invoker method is not available via the Core Reflection API.
* An attempt to call {@linkplain java.lang.reflect.Method#invoke Method.invoke}
* on the declared {@code invokeExact} or {@code invokeGeneric} method will raise an
* on the declared {@code invokeExact} or {@code invoke} method will raise an
* {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
* <p>
* This method throws no reflective or security exceptions.
......@@ -1226,20 +1226,20 @@ publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
/**
* Produces a special <em>invoker method handle</em> which can be used to
* invoke any method handle of the given type, as if by {@code invokeGeneric}.
* invoke any method handle compatible with the given type, as if by {@link MethodHandle#invoke invoke}.
* The resulting invoker will have a type which is
* exactly equal to the desired type, except that it will accept
* an additional leading argument of type {@code MethodHandle}.
* <p>
* Before invoking its target, the invoker will apply reference casts as
* necessary and unbox and widen primitive arguments, as if by {@link #convertArguments convertArguments}.
* The return value of the invoker will be an {@code Object} reference,
* boxing a primitive value if the original type returns a primitive,
* and always null if the original type returns void.
* necessary and box, unbox, or widen primitive values, as if by {@link MethodHandle#asType asType}.
* Similarly, the return value will be converted as necessary.
* If the target is a {@linkplain MethodHandle#asVarargsCollector variable arity method handle},
* the required arity conversion will be made, again as if by {@link MethodHandle#asType asType}.
* <p>
* This method is equivalent to the following code (though it may be more efficient):
* <p><blockquote><pre>
publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
publicLookup().findVirtual(MethodHandle.class, "invoke", type)
* </pre></blockquote>
* <p>
* This method throws no reflective or security exceptions.
......@@ -1247,8 +1247,17 @@ publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
* @return a method handle suitable for invoking any method handle convertible to the given type
*/
static public
MethodHandle invoker(MethodType type) {
return type.invokers().generalInvoker();
}
/**
* <em>Temporary alias</em> for {@link #invoker}, for backward compatibility with some versions of JSR 292.
* @deprecated Will be removed for JSR 292 Proposed Final Draft.
*/
public static
MethodHandle genericInvoker(MethodType type) {
return type.invokers().genericInvoker();
return invoker(type);
}
/**
......@@ -1368,18 +1377,7 @@ publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
*/
public static
MethodHandle convertArguments(MethodHandle target, MethodType newType) {
MethodType oldType = target.type();
if (oldType.equals(newType))
return target;
MethodHandle res = null;
try {
res = MethodHandleImpl.convertArguments(target,
newType, oldType, null);
} catch (IllegalArgumentException ex) {
}
if (res == null)
throw new WrongMethodTypeException("cannot convert to "+newType+": "+target);
return res;
return MethodHandleImpl.convertArguments(target, newType, 1);
}
/**
......@@ -1422,7 +1420,7 @@ publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
*/
public static
MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
return convertArguments(target, newType); // FIXME!
return MethodHandleImpl.convertArguments(target, newType, 2);
}
/*
......@@ -1517,23 +1515,32 @@ assert((int)twice.invokeExact(21) == 42);
MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
MethodType oldType = target.type();
checkReorder(reorder, newType, oldType);
return MethodHandleImpl.convertArguments(target,
return MethodHandleImpl.permuteArguments(target,
newType, oldType,
reorder);
}
private static void checkReorder(int[] reorder, MethodType newType, MethodType oldType) {
if (newType.returnType() != oldType.returnType())
throw newIllegalArgumentException("return types do not match",
oldType, newType);
if (reorder.length == oldType.parameterCount()) {
int limit = newType.parameterCount();
boolean bad = false;
for (int i : reorder) {
for (int j = 0; j < reorder.length; j++) {
int i = reorder[j];
if (i < 0 || i >= limit) {
bad = true; break;
}
Class<?> src = newType.parameterType(i);
Class<?> dst = oldType.parameterType(j);
if (src != dst)
throw newIllegalArgumentException("parameter types do not match after reorder",
oldType, newType);
}
if (!bad) return;
}
throw newIllegalArgumentException("bad reorder array");
throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder));
}
/**
......@@ -1622,7 +1629,7 @@ assert((int)twice.invokeExact(21) == 42);
if (type == void.class)
throw newIllegalArgumentException("void type");
Wrapper w = Wrapper.forPrimitiveType(type);
return identity(type).bindTo(w.convert(value, type));
return insertArguments(identity(type), 0, w.convert(value, type));
} else {
return identity(type).bindTo(type.cast(value));
}
......@@ -1857,7 +1864,8 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
MethodType targetType = target.type();
MethodHandle adapter = target;
MethodType adapterType = targetType;
MethodType adapterType = null;
assert((adapterType = targetType) != null);
int maxPos = targetType.parameterCount();
if (pos + filters.length > maxPos)
throw newIllegalArgumentException("too many filters");
......@@ -1865,19 +1873,23 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
for (MethodHandle filter : filters) {
curPos += 1;
if (filter == null) continue; // ignore null elements of filters
MethodType filterType = filter.type();
if (filterType.parameterCount() != 1
|| filterType.returnType() != targetType.parameterType(curPos))
throw newIllegalArgumentException("target and filter types do not match");
adapterType = adapterType.changeParameterType(curPos, filterType.parameterType(0));
adapter = MethodHandleImpl.filterArgument(adapter, curPos, filter);
adapter = filterArgument(adapter, curPos, filter);
assert((adapterType = adapterType.changeParameterType(curPos, filter.type().parameterType(0))) != null);
}
MethodType midType = adapter.type();
if (midType != adapterType)
adapter = MethodHandleImpl.convertArguments(adapter, adapterType, midType, null);
assert(adapterType.equals(adapter.type()));
return adapter;
}
/*non-public*/ static
MethodHandle filterArgument(MethodHandle target, int pos, MethodHandle filter) {
MethodType targetType = target.type();
MethodType filterType = filter.type();
if (filterType.parameterCount() != 1
|| filterType.returnType() != targetType.parameterType(pos))
throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
return MethodHandleImpl.filterArgument(target, pos, filter);
}
/**
* Adapts a target method handle {@code target} by post-processing
* its return value with a unary filter function.
......@@ -1913,14 +1925,26 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
MethodType targetType = target.type();
MethodType filterType = filter.type();
if (filterType.parameterCount() != 1
|| filterType.parameterType(0) != targetType.returnType())
throw newIllegalArgumentException("target and filter types do not match");
Class<?> rtype = targetType.returnType();
int filterValues = filterType.parameterCount();
if (filterValues == 0
? (rtype != void.class)
: (rtype != filterType.parameterType(0)))
throw newIllegalArgumentException("target and filter types do not match", target, filter);
// result = fold( lambda(retval, arg...) { filter(retval) },
// lambda( arg...) { target(arg...) } )
MethodType newType = targetType.changeReturnType(filterType.returnType());
MethodHandle result = null;
if (AdapterMethodHandle.canCollectArguments(filterType, targetType, 0, false)) {
result = AdapterMethodHandle.makeCollectArguments(filter, target, 0, false);
if (result != null) return result;
}
// FIXME: Too many nodes here.
MethodHandle returner = dropArguments(filter, 1, targetType.parameterList());
return foldArguments(returner, target);
assert(MethodHandleNatives.workaroundWithoutRicochetFrames()); // this class is deprecated
MethodHandle returner = dropArguments(filter, filterValues, targetType.parameterList());
result = foldArguments(returner, target);
assert(result.type().equals(newType));
return result;
}
/**
......@@ -1972,16 +1996,23 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
MethodType targetType = target.type();
MethodType combinerType = combiner.type();
int foldPos = 0; // always at the head, at present
int foldArgs = combinerType.parameterCount();
boolean ok = (targetType.parameterCount() >= 1 + foldArgs);
if (ok && !combinerType.parameterList().equals(targetType.parameterList().subList(1, foldArgs+1)))
int foldVals = combinerType.returnType() == void.class ? 0 : 1;
int afterInsertPos = foldPos + foldVals;
boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
if (ok && !(combinerType.parameterList()
.equals(targetType.parameterList().subList(afterInsertPos,
afterInsertPos + foldArgs))))
ok = false;
if (ok && !combinerType.returnType().equals(targetType.parameterType(0)))
if (ok && foldVals != 0 && !combinerType.returnType().equals(targetType.parameterType(0)))
ok = false;
if (!ok)
throw misMatchedTypes("target and combiner types", targetType, combinerType);
MethodType newType = targetType.dropParameterTypes(0, 1);
return MethodHandleImpl.foldArguments(target, newType, combiner);
MethodType newType = targetType.dropParameterTypes(foldPos, afterInsertPos);
MethodHandle res = MethodHandleImpl.foldArguments(target, newType, foldPos, combiner);
if (res == null) throw newIllegalArgumentException("cannot fold from "+newType+" to " +targetType);
return res;
}
/**
......@@ -2142,7 +2173,7 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
* the given {@code target} on the incoming arguments,
* and returning or throwing whatever the {@code target}
* returns or throws. The invocation will be as if by
* {@code target.invokeGeneric}.
* {@code target.invoke}.
* The target's type will be checked before the
* instance is created, as if by a call to {@code asType},
* which may result in a {@code WrongMethodTypeException}.
......
......@@ -25,6 +25,7 @@
package java.lang.invoke;
import sun.invoke.util.Wrapper;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
......@@ -39,7 +40,7 @@ import static java.lang.invoke.MethodHandleStatics.*;
* matched between a method handle and all its callers,
* and the JVM's operations enforce this matching at, specifically
* during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
* and {@link MethodHandle#invokeGeneric MethodHandle.invokeGeneric}, and during execution
* and {@link MethodHandle#invoke MethodHandle.invoke}, and during execution
* of {@code invokedynamic} instructions.
* <p>
* The structure is a return type accompanied by any number of parameter types.
......@@ -262,18 +263,18 @@ class MethodType implements java.io.Serializable {
* Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
* Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
* All parameters and the return type will be {@code Object},
* except the final varargs parameter if any, which will be {@code Object[]}.
* @param objectArgCount number of parameters (excluding the varargs parameter if any)
* @param varargs whether there will be a varargs parameter, of type {@code Object[]}
* @return a totally generic method type, given only its count of parameters and varargs
* @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
* except the final array parameter if any, which will be {@code Object[]}.
* @param objectArgCount number of parameters (excluding the final array parameter if any)
* @param finalArray whether there will be a trailing array parameter, of type {@code Object[]}
* @return a generally applicable method type, for all calls of the given fixed argument count and a collected array of further arguments
* @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255 (or 254, if {@code finalArray})
* @see #genericMethodType(int)
*/
public static
MethodType genericMethodType(int objectArgCount, boolean varargs) {
MethodType genericMethodType(int objectArgCount, boolean finalArray) {
MethodType mt;
checkSlotCount(objectArgCount);
int ivarargs = (!varargs ? 0 : 1);
int ivarargs = (!finalArray ? 0 : 1);
int ootIndex = objectArgCount*2 + ivarargs;
if (ootIndex < objectOnlyTypes.length) {
mt = objectOnlyTypes[ootIndex];
......@@ -294,7 +295,7 @@ class MethodType implements java.io.Serializable {
* Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
* All parameters and the return type will be Object.
* @param objectArgCount number of parameters
* @return a totally generic method type, given only its count of parameters
* @return a generally applicable method type, for all calls of the given argument count
* @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
* @see #genericMethodType(int, boolean)
*/
......@@ -626,6 +627,30 @@ class MethodType implements java.io.Serializable {
return sb.toString();
}
/*non-public*/
boolean isConvertibleTo(MethodType newType) {
if (!canConvert(returnType(), newType.returnType()))
return false;
int argc = parameterCount();
if (argc != newType.parameterCount())
return false;
for (int i = 0; i < argc; i++) {
if (!canConvert(newType.parameterType(i), parameterType(i)))
return false;
}
return true;
}
private static boolean canConvert(Class<?> src, Class<?> dst) {
if (src == dst || dst == void.class) return true;
if (src.isPrimitive() && dst.isPrimitive()) {
if (!Wrapper.forPrimitiveType(dst)
.isConvertibleFrom(Wrapper.forPrimitiveType(src)))
return false;
}
return true;
}
/// Queries which have to do with the bytecode architecture
/** Reports the number of JVM stack slots required to invoke a method
......
......@@ -46,6 +46,7 @@ class MethodTypeForm {
final long argCounts; // packed slot & value counts
final long primCounts; // packed prim & double counts
final int vmslots; // total number of parameter slots
private Object vmlayout; // vm-specific information for calls
final MethodType erasedType; // the canonical erasure
/*lazy*/ MethodType primsAsBoxes; // replace prims by wrappers
......@@ -59,7 +60,7 @@ class MethodTypeForm {
/*lazy*/ FromGeneric fromGeneric; // convert cs. w/o prims to with
/*lazy*/ SpreadGeneric[] spreadGeneric; // expand one argument to many
/*lazy*/ FilterGeneric filterGeneric; // convert argument(s) on the fly
/*lazy*/ MethodHandle genericInvoker; // hook for invokeGeneric
/*lazy*/ MethodHandle genericInvoker; // hook for inexact invoke
public MethodType erasedType() {
return erasedType;
......@@ -460,9 +461,9 @@ class MethodTypeForm {
if (genericInvoker != null) return;
try {
// Trigger adapter creation.
genericInvoker = InvokeGeneric.genericInvokerOf(erasedType);
genericInvoker = InvokeGeneric.generalInvokerOf(erasedType);
} catch (Exception ex) {
Error err = new InternalError("Exception while resolving invokeGeneric");
Error err = new InternalError("Exception while resolving inexact invoke");
err.initCause(ex);
throw err;
}
......
......@@ -66,6 +66,10 @@ class SpreadGeneric {
this.entryPoint = ep[0];
}
static {
assert(MethodHandleNatives.workaroundWithoutRicochetFrames()); // this class is deprecated
}
/** From targetType remove the last spreadCount arguments, and instead
* append a simple Object argument.
*/
......
......@@ -96,7 +96,7 @@ class ToGeneric {
ToGeneric va2 = ToGeneric.of(primsAtEnd);
this.adapter = va2.adapter;
if (true) throw new UnsupportedOperationException("NYI: primitive parameters must follow references; entryType = "+entryType);
this.entryPoint = MethodHandleImpl.convertArguments(
this.entryPoint = MethodHandleImpl.permuteArguments(
va2.entryPoint, primsAtEnd, entryType, primsAtEndOrder);
// example: for entryType of (int,Object,Object), the reordered
// type is (Object,Object,int) and the order is {1,2,0},
......@@ -128,7 +128,7 @@ class ToGeneric {
assert(eptWithInts.parameterType(i) == int.class);
MethodType nextType = midType.changeParameterType(i, int.class);
rawEntryPoint = MethodHandleImpl.convertArguments(
rawEntryPoint, nextType, midType, null);
rawEntryPoint, nextType, midType, 0);
midType = nextType;
}
}
......@@ -152,6 +152,10 @@ class ToGeneric {
this.invoker = makeRawArgumentFilter(invoker0, rawEntryTypeInit, entryType);
}
static {
assert(MethodHandleNatives.workaroundWithoutRicochetFrames()); // this class is deprecated
}
/** A generic argument list will be created by a call of type 'raw'.
* The values need to be reboxed for to match 'cooked'.
* Do this on the fly.
......@@ -171,7 +175,7 @@ class ToGeneric {
invoker.type().generic(), invoker, 0, MethodHandle.class);
if (filteredInvoker == null) throw new UnsupportedOperationException("NYI");
}
MethodHandle reboxer = ValueConversions.rebox(dst, false);
MethodHandle reboxer = ValueConversions.rebox(dst);
filteredInvoker = FilterGeneric.makeArgumentFilter(1+i, reboxer, filteredInvoker);
if (filteredInvoker == null) throw new InternalError();
}
......@@ -199,13 +203,13 @@ class ToGeneric {
assert(!rret.isPrimitive());
if (rret == Object.class && !mustCast)
return null;
return ValueConversions.cast(tret, false);
return ValueConversions.cast(tret);
} else if (tret == rret) {
return ValueConversions.unbox(tret, false);
return ValueConversions.unbox(tret);
} else {
assert(rret.isPrimitive());
assert(tret == double.class ? rret == long.class : rret == int.class);
return ValueConversions.unboxRaw(tret, false);
return ValueConversions.unboxRaw(tret);
}
}
......@@ -311,7 +315,7 @@ class ToGeneric {
}
static Adapter buildAdapterFromBytecodes(MethodType entryPointType) {
throw new UnsupportedOperationException("NYI");
throw new UnsupportedOperationException("NYI: "+entryPointType);
}
/**
......
......@@ -185,7 +185,7 @@
* The method handle constant produced for such a method behaves as if
* it were created by {@link java.lang.invoke.MethodHandle#asVarargsCollector asVarargsCollector}.
* In other words, the constant method handle will exhibit variable arity,
* when invoked via {@code invokeGeneric}.
* when invoked via {@code MethodHandle.invoke}.
* On the other hand, its behavior with respect to {@code invokeExact} will be the same
* as if the {@code varargs} bit were not set.
* <p>
......@@ -243,7 +243,7 @@
* <li>optionally, one or more <a href="#args">additional static arguments</a> </li>
* </ul>
* The method handle is then applied to the other values as if by
* {@link java.lang.invoke.MethodHandle#invokeGeneric invokeGeneric}.
* {@link java.lang.invoke.MethodHandle#invoke MethodHandle.invoke}.
* The returned result must be a {@link java.lang.invoke.CallSite CallSite} (or a subclass).
* The type of the call site's target must be exactly equal to the type
* derived from the dynamic call site's type descriptor and passed to
......@@ -251,7 +251,7 @@
* The call site then becomes permanently linked to the dynamic call site.
* <p>
* As long as each bootstrap method can be correctly invoked
* by <code>invokeGeneric</code>, its detailed type is arbitrary.
* by <code>MethodHandle.invoke</code>, its detailed type is arbitrary.
* For example, the first argument could be {@code Object}
* instead of {@code MethodHandles.Lookup}, and the return type
* could also be {@code Object} instead of {@code CallSite}.
......@@ -272,7 +272,7 @@
* (i.e., a {@code CONSTANT_Class}, {@code CONSTANT_MethodType},
* or {@code CONSTANT_MethodHandle} argument cannot be linked) </li>
* <li>the bootstrap method has the wrong arity,
* causing {@code invokeGeneric} to throw {@code WrongMethodTypeException} </li>
* causing {@code MethodHandle.invoke} to throw {@code WrongMethodTypeException} </li>
* <li>the bootstrap method has a wrong argument or return type </li>
* <li>the bootstrap method invocation completes abnormally </li>
* <li>the result from the bootstrap invocation is not a reference to
......@@ -381,10 +381,10 @@
* those values will be passed as additional arguments to the method handle.
* (Note that because there is a limit of 255 arguments to any method,
* at most 252 extra arguments can be supplied.)
* The bootstrap method will be invoked as if by either {@code invokeGeneric}
* The bootstrap method will be invoked as if by either {@code MethodHandle.invoke}
* or {@code invokeWithArguments}. (There is no way to tell the difference.)
* <p>
* The normal argument conversion rules for {@code invokeGeneric} apply to all stacked arguments.
* The normal argument conversion rules for {@code MethodHandle.invoke} apply to all stacked arguments.
* For example, if a pushed value is a primitive type, it may be converted to a reference by boxing conversion.
* If the bootstrap method is a variable arity method (its modifier bit {@code 0x0080} is set),
* then some or all of the arguments specified here may be collected into a trailing array parameter.
......@@ -419,8 +419,8 @@
* For example, the fourth argument could be {@code MethodHandle},
* if that is the type of the corresponding constant in
* the {@code CONSTANT_InvokeDynamic} entry.
* In that case, the {@code invokeGeneric} call will pass the extra method handle
* constant as an {@code Object}, but the type matching machinery of {@code invokeGeneric}
* In that case, the {@code MethodHandle.invoke} call will pass the extra method handle
* constant as an {@code Object}, but the type matching machinery of {@code MethodHandle.invoke}
* will cast the reference back to {@code MethodHandle} before invoking the bootstrap method.
* (If a string constant were passed instead, by badly generated code, that cast would then fail,
* resulting in a {@code BootstrapMethodError}.)
......
......@@ -211,6 +211,20 @@ to any listeners.
<p>
<a name=optcolor><b>Optional ColorSpace support:</b></a>
Handling of PhotoYCC (YCC), PhotoYCCA (YCCA), RGBA and YCbCrA color spaces
by the standard plugin, as described below, is dependent on capabilities
of the libraries used to interpret the JPEG data. Thus all consequential
behaviors are optional. If the support is not available when decoding,
the color space will be treated as unrecognized and the appropriate
default color space for the specified number of component channels
may be used.
When writing, an Exception may be thrown if no suitable conversion
can be applied before encoding.
But where the support for these color spaces is available, the behavior
must be as documented.
<p>
When reading, the contents of the stream are interpreted by the usual
JPEG conventions, as follows:
......@@ -241,8 +255,11 @@ JPEG conventions, as follows:
2-channel images are assumed to be grayscale with an alpha channel.
For 3- and 4-channel images, the component ids are consulted. If these
values are 1-3 for a 3-channel image, then the image is assumed to be
YCbCr. If these values are 1-4 for a 4-channel image, then the image
is assumed to be YCbCrA. If these values are > 4, they are checked
YCbCr. Subject to the availability of the
<a href=#optcolor>optional color space support</a>
described above, if these values are 1-4 for a 4-channel image,
then the image is assumed to be YCbCrA.
If these values are > 4, they are checked
against the ASCII codes for 'R', 'G', 'B', 'A', 'C', 'c'. These can
encode the following colorspaces:
<p>
......@@ -346,12 +363,16 @@ If no metadata object is specified, then the following defaults apply:
component ids in the frame and scan headers are set to 1, 2, and 3.
<li> RGBA images are converted to YCbCrA, subsampled in the
<li> Subject to the <a href=#optcolor>optional library support</a>
described above,
RGBA images are converted to YCbCrA, subsampled in the
chrominance channels by half both vertically and horizontally, and
written without any special marker segments. The component ids
in the frame and scan headers are set to 1, 2, 3, and 4.
<li> PhotoYCC and YCCAimages are subsampled by half in the chrominance
<li> Subject to the <a href=#optcolor>optional library support</a>
described above,
PhotoYCC and YCCAimages are subsampled by half in the chrominance
channels both vertically and horizontally and written with an
Adobe <code>APP14</code> marker segment and 'Y','C', and 'c' (and
'A' if an alpha channel is present) as component ids in the frame
......@@ -433,6 +454,8 @@ in the frame header node of the metadata object, regardless of color space.)
</ul>
<li> RGBA images:
Subject to the <a href=#optcolor>optional library support</a>
described above,
<ul>
<li> If an <code>app0JFIF</code> node is present in the metadata object,
it is ignored and a warning is sent to listeners, as JFIF does not
......@@ -456,6 +479,8 @@ in the frame header node of the metadata object, regardless of color space.)
</ul>
<li> PhotoYCC Images:
Subject to the <a href=#optcolor>optional library support</a>
described above,
<ul>
<li> If an <code>app0JFIF</code> node is present in the metadata object,
the image is converted to sRGB, and then to YCbCr during encoding,
......@@ -471,6 +496,8 @@ in the frame header node of the metadata object, regardless of color space.)
</ul>
<li> PhotoYCCA Images:
Subject to the <a href=#optcolor>optional library support</a>
described above,
<ul>
<li> If an <code>app0JFIF</code> node is present in the metadata object,
it is ignored and a warning is sent to listeners, as JFIF does not
......
......@@ -33,9 +33,11 @@ package javax.swing;
* <code>ListModel</code>. This disjoint behavior allows for the temporary
* storage and retrieval of a selected item in the model.
*
* @param <E> the type of the elements of this model
*
* @author Arnaud Weber
*/
public interface ComboBoxModel extends ListModel {
public interface ComboBoxModel<E> extends ListModel<E> {
/**
* Set the selected item. The implementation of this method should notify
......
......@@ -24,39 +24,28 @@
*/
package javax.swing;
import java.beans.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.border.*;
import javax.accessibility.*;
/**
* The default model for combo boxes.
*
* @param <E> the type of the elements of this model
*
* @author Arnaud Weber
* @author Tom Santos
*/
public class DefaultComboBoxModel extends AbstractListModel implements MutableComboBoxModel, Serializable {
Vector objects;
public class DefaultComboBoxModel<E> extends AbstractListModel<E> implements MutableComboBoxModel<E>, Serializable {
Vector<E> objects;
Object selectedObject;
/**
* Constructs an empty DefaultComboBoxModel object.
*/
public DefaultComboBoxModel() {
objects = new Vector();
objects = new Vector<E>();
}
/**
......@@ -65,8 +54,8 @@ public class DefaultComboBoxModel extends AbstractListModel implements MutableCo
*
* @param items an array of Object objects
*/
public DefaultComboBoxModel(final Object items[]) {
objects = new Vector();
public DefaultComboBoxModel(final E items[]) {
objects = new Vector<E>();
objects.ensureCapacity( items.length );
int i,c;
......@@ -84,7 +73,7 @@ public class DefaultComboBoxModel extends AbstractListModel implements MutableCo
*
* @param v a Vector object ...
*/
public DefaultComboBoxModel(Vector<?> v) {
public DefaultComboBoxModel(Vector<E> v) {
objects = v;
if ( getSize() > 0 ) {
......@@ -117,7 +106,7 @@ public class DefaultComboBoxModel extends AbstractListModel implements MutableCo
}
// implements javax.swing.ListModel
public Object getElementAt(int index) {
public E getElementAt(int index) {
if ( index >= 0 && index < objects.size() )
return objects.elementAt(index);
else
......@@ -136,7 +125,7 @@ public class DefaultComboBoxModel extends AbstractListModel implements MutableCo
}
// implements javax.swing.MutableComboBoxModel
public void addElement(Object anObject) {
public void addElement(E anObject) {
objects.addElement(anObject);
fireIntervalAdded(this,objects.size()-1, objects.size()-1);
if ( objects.size() == 1 && selectedObject == null && anObject != null ) {
......@@ -145,7 +134,7 @@ public class DefaultComboBoxModel extends AbstractListModel implements MutableCo
}
// implements javax.swing.MutableComboBoxModel
public void insertElementAt(Object anObject,int index) {
public void insertElementAt(E anObject,int index) {
objects.insertElementAt(anObject,index);
fireIntervalAdded(this, index, index);
}
......
......@@ -69,6 +69,8 @@ import javax.accessibility.*;
* @see ComboBoxModel
* @see DefaultComboBoxModel
*
* @param <E> the type of the elements of this combo box
*
* @beaninfo
* attribute: isContainer false
* description: A combination of a text field and a drop-down list.
......@@ -76,7 +78,7 @@ import javax.accessibility.*;
* @author Arnaud Weber
* @author Mark Davidson
*/
public class JComboBox extends JComponent
public class JComboBox<E> extends JComponent
implements ItemSelectable,ListDataListener,ActionListener, Accessible {
/**
* @see #getUIClassID
......@@ -91,7 +93,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* @see #getModel
* @see #setModel
*/
protected ComboBoxModel dataModel;
protected ComboBoxModel<E> dataModel;
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the accessor methods instead.
......@@ -99,7 +101,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* @see #getRenderer
* @see #setRenderer
*/
protected ListCellRenderer renderer;
protected ListCellRenderer<? super E> renderer;
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the accessor methods instead.
......@@ -156,7 +158,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
*/
protected Object selectedItemReminder = null;
private Object prototypeDisplayValue;
private E prototypeDisplayValue;
// Flag to ensure that infinite loops do not occur with ActionEvents.
private boolean firingActionEvent = false;
......@@ -175,7 +177,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* displayed list of items
* @see DefaultComboBoxModel
*/
public JComboBox(ComboBoxModel aModel) {
public JComboBox(ComboBoxModel<E> aModel) {
super();
setModel(aModel);
init();
......@@ -189,9 +191,9 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* @param items an array of objects to insert into the combo box
* @see DefaultComboBoxModel
*/
public JComboBox(final Object items[]) {
public JComboBox(E[] items) {
super();
setModel(new DefaultComboBoxModel(items));
setModel(new DefaultComboBoxModel<E>(items));
init();
}
......@@ -203,9 +205,9 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* @param items an array of vectors to insert into the combo box
* @see DefaultComboBoxModel
*/
public JComboBox(Vector<?> items) {
public JComboBox(Vector<E> items) {
super();
setModel(new DefaultComboBoxModel(items));
setModel(new DefaultComboBoxModel<E>(items));
init();
}
......@@ -219,7 +221,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
*/
public JComboBox() {
super();
setModel(new DefaultComboBoxModel());
setModel(new DefaultComboBoxModel<E>());
init();
}
......@@ -263,7 +265,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
public void updateUI() {
setUI((ComboBoxUI)UIManager.getUI(this));
ListCellRenderer renderer = getRenderer();
ListCellRenderer<? super E> renderer = getRenderer();
if (renderer instanceof Component) {
SwingUtilities.updateComponentTreeUI((Component)renderer);
}
......@@ -302,8 +304,8 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* bound: true
* description: Model that the combo box uses to get data to display.
*/
public void setModel(ComboBoxModel aModel) {
ComboBoxModel oldModel = dataModel;
public void setModel(ComboBoxModel<E> aModel) {
ComboBoxModel<E> oldModel = dataModel;
if (oldModel != null) {
oldModel.removeListDataListener(this);
}
......@@ -322,7 +324,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* @return the <code>ComboBoxModel</code> that provides the displayed
* list of items
*/
public ComboBoxModel getModel() {
public ComboBoxModel<E> getModel() {
return dataModel;
}
......@@ -461,8 +463,8 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* expert: true
* description: The renderer that paints the item selected in the list.
*/
public void setRenderer(ListCellRenderer aRenderer) {
ListCellRenderer oldRenderer = renderer;
public void setRenderer(ListCellRenderer<? super E> aRenderer) {
ListCellRenderer<? super E> oldRenderer = renderer;
renderer = aRenderer;
firePropertyChange( "renderer", oldRenderer, renderer );
invalidate();
......@@ -475,7 +477,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* @return the <code>ListCellRenderer</code> that displays
* the selected item.
*/
public ListCellRenderer getRenderer() {
public ListCellRenderer<? super E> getRenderer() {
return renderer;
}
......@@ -558,7 +560,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
// will be rejected.
boolean found = false;
for (int i = 0; i < dataModel.getSize(); i++) {
Object element = dataModel.getElementAt(i);
E element = dataModel.getElementAt(i);
if (anObject.equals(element)) {
found = true;
objectToSelect = element;
......@@ -640,7 +642,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
public int getSelectedIndex() {
Object sObject = dataModel.getSelectedItem();
int i,c;
Object obj;
E obj;
for ( i=0,c=dataModel.getSize();i<c;i++ ) {
obj = dataModel.getElementAt(i);
......@@ -658,7 +660,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* @see #setPrototypeDisplayValue
* @since 1.4
*/
public Object getPrototypeDisplayValue() {
public E getPrototypeDisplayValue() {
return prototypeDisplayValue;
}
......@@ -683,7 +685,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* attribute: visualUpdate true
* description: The display prototype value, used to compute display width and height.
*/
public void setPrototypeDisplayValue(Object prototypeDisplayValue) {
public void setPrototypeDisplayValue(E prototypeDisplayValue) {
Object oldValue = this.prototypeDisplayValue;
this.prototypeDisplayValue = prototypeDisplayValue;
firePropertyChange("prototypeDisplayValue", oldValue, prototypeDisplayValue);
......@@ -708,12 +710,12 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* }
* </pre>
*
* @param anObject the Object to add to the list
* @param item the item to add to the list
* @see MutableComboBoxModel
*/
public void addItem(Object anObject) {
public void addItem(E item) {
checkMutableComboBoxModel();
((MutableComboBoxModel)dataModel).addElement(anObject);
((MutableComboBoxModel<E>)dataModel).addElement(item);
}
/**
......@@ -721,14 +723,14 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
* This method works only if the <code>JComboBox</code> uses a
* mutable data model.
*
* @param anObject the <code>Object</code> to add to the list
* @param item the item to add to the list
* @param index an integer specifying the position at which
* to add the item
* @see MutableComboBoxModel
*/
public void insertItemAt(Object anObject, int index) {
public void insertItemAt(E item, int index) {
checkMutableComboBoxModel();
((MutableComboBoxModel)dataModel).insertElementAt(anObject,index);
((MutableComboBoxModel<E>)dataModel).insertElementAt(item,index);
}
/**
......@@ -756,7 +758,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
*/
public void removeItemAt(int anIndex) {
checkMutableComboBoxModel();
((MutableComboBoxModel)dataModel).removeElementAt( anIndex );
((MutableComboBoxModel<E>)dataModel).removeElementAt( anIndex );
}
/**
......@@ -764,7 +766,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
*/
public void removeAllItems() {
checkMutableComboBoxModel();
MutableComboBoxModel model = (MutableComboBoxModel)dataModel;
MutableComboBoxModel<E> model = (MutableComboBoxModel<E>)dataModel;
int size = model.getSize();
if ( model instanceof DefaultComboBoxModel ) {
......@@ -772,7 +774,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
}
else {
for ( int i = 0; i < size; ++i ) {
Object element = model.getElementAt( 0 );
E element = model.getElementAt( 0 );
model.removeElement( element );
}
}
......@@ -1188,11 +1190,11 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
private static class ComboBoxActionPropertyChangeListener
extends ActionPropertyChangeListener<JComboBox> {
ComboBoxActionPropertyChangeListener(JComboBox b, Action a) {
extends ActionPropertyChangeListener<JComboBox<?>> {
ComboBoxActionPropertyChangeListener(JComboBox<?> b, Action a) {
super(b, a);
}
protected void actionPropertyChanged(JComboBox cb,
protected void actionPropertyChanged(JComboBox<?> cb,
Action action,
PropertyChangeEvent e) {
if (AbstractAction.shouldReconfigure(e)) {
......@@ -1454,10 +1456,10 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
*
* @param index an integer indicating the list position, where the first
* item starts at zero
* @return the <code>Object</code> at that list position; or
* @return the item at that list position; or
* <code>null</code> if out of range
*/
public Object getItemAt(int index) {
public E getItemAt(int index) {
return dataModel.getElementAt(index);
}
......
......@@ -27,19 +27,21 @@ package javax.swing;
/**
* A mutable version of <code>ComboBoxModel</code>.
*
* @param <E> the type of the elements of this model
*
* @author Tom Santos
*/
public interface MutableComboBoxModel extends ComboBoxModel {
public interface MutableComboBoxModel<E> extends ComboBoxModel<E> {
/**
* Adds an item at the end of the model. The implementation of this method
* should notify all registered <code>ListDataListener</code>s that the
* item has been added.
*
* @param obj the <code>Object</code> to be added
* @param item the item to be added
*/
public void addElement( Object obj );
public void addElement( E item );
/**
* Removes an item from the model. The implementation of this method should
......@@ -55,17 +57,17 @@ public interface MutableComboBoxModel extends ComboBoxModel {
* should notify all registered <code>ListDataListener</code>s that the
* item has been added.
*
* @param obj the <code>Object</code> to be added
* @param item the item to be added
* @param index location to add the object
*/
public void insertElementAt( Object obj, int index );
public void insertElementAt( E item, int index );
/**
* Removes an item at a specific index. The implementation of this method
* should notify all registered <code>ListDataListener</code>s that the
* item has been removed.
*
* @param index location of object to be removed
* @param index location of the item to be removed
*/
public void removeElementAt( int index );
}
......@@ -40,7 +40,7 @@ import sun.awt.shell.ShellFolder;
*
* @author Jeff Dinkins
*/
public class BasicDirectoryModel extends AbstractListModel implements PropertyChangeListener {
public class BasicDirectoryModel extends AbstractListModel<Object> implements PropertyChangeListener {
private JFileChooser filechooser = null;
// PENDING(jeff) pick the size more sensibly
......
......@@ -906,7 +906,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI {
/**
* Data model for a type-face selection combo-box.
*/
protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel {
protected class DirectoryComboBoxModel extends AbstractListModel<Object> implements ComboBoxModel<Object> {
Vector<File> directories = new Vector<File>();
int[] depths = null;
File selectedDirectory = null;
......@@ -1063,7 +1063,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI {
/**
* Data model for a type-face selection combo-box.
*/
protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener {
protected class FilterComboBoxModel extends AbstractListModel<Object> implements ComboBoxModel<Object>, PropertyChangeListener {
protected FileFilter[] filters;
protected FilterComboBoxModel() {
super();
......
......@@ -488,6 +488,18 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI
paintContentBorder(tabContentContext, g, tabPlacement, selectedIndex);
}
protected void paintTabArea(Graphics g, int tabPlacement,
int selectedIndex) {
// This can be invoked from ScrollabeTabPanel
Insets insets = tabPane.getInsets();
int x = insets.left;
int y = insets.top;
int width = tabPane.getWidth() - insets.left - insets.right;
int height = tabPane.getHeight() - insets.top - insets.bottom;
paintTabArea(tabAreaContext, g, tabPlacement, selectedIndex,
new Rectangle(x, y, width, height));
}
private void paintTabArea(SynthContext ss, Graphics g,
int tabPlacement, int selectedIndex,
......
......@@ -54,9 +54,15 @@ public class VerifyType {
if (dst == void.class) return true; // drop any return value
if (isNullType(src)) return !dst.isPrimitive();
if (!src.isPrimitive()) return dst.isAssignableFrom(src);
if (!dst.isPrimitive()) return false;
// Verifier allows an int to carry byte, short, char, or even boolean:
if (dst == int.class) return Wrapper.forPrimitiveType(src).isSubwordOrInt();
return false;
Wrapper sw = Wrapper.forPrimitiveType(src);
if (dst == int.class) return sw.isSubwordOrInt();
Wrapper dw = Wrapper.forPrimitiveType(dst);
if (!sw.isSubwordOrInt()) return false;
if (!dw.isSubwordOrInt()) return false;
if (!dw.isSigned() && sw.isSigned()) return false;
return dw.bitWidth() > sw.bitWidth();
}
/**
......@@ -155,6 +161,7 @@ public class VerifyType {
return -1; // truncation may be required
if (!dw.isSigned() && sw.isSigned())
return -1; // sign elimination may be required
return 1;
}
if (src == float.class || dst == float.class) {
if (src == double.class || dst == double.class)
......
......@@ -26,37 +26,47 @@
package sun.invoke.util;
public enum Wrapper {
BOOLEAN(Boolean.class, boolean.class, 'Z', (Boolean)false, Format.unsigned(1)),
BOOLEAN(Boolean.class, boolean.class, 'Z', (Boolean)false, new boolean[0], Format.unsigned(1)),
// These must be in the order defined for widening primitive conversions in JLS 5.1.2
BYTE(Byte.class, byte.class, 'B', (Byte)(byte)0, Format.signed(8)),
SHORT(Short.class, short.class, 'S', (Short)(short)0, Format.signed(16)),
CHAR(Character.class, char.class, 'C', (Character)(char)0, Format.unsigned(16)),
INT(Integer.class, int.class, 'I', (Integer)(int)0, Format.signed(32)),
LONG(Long.class, long.class, 'J', (Long)(long)0, Format.signed(64)),
FLOAT(Float.class, float.class, 'F', (Float)(float)0, Format.floating(32)),
DOUBLE(Double.class, double.class, 'D', (Double)(double)0, Format.floating(64)),
//NULL(Null.class, null.class, 'N', null, Format.other(1)),
OBJECT(Object.class, Object.class, 'L', null, Format.other(1)),
BYTE(Byte.class, byte.class, 'B', (Byte)(byte)0, new byte[0], Format.signed(8)),
SHORT(Short.class, short.class, 'S', (Short)(short)0, new short[0], Format.signed(16)),
CHAR(Character.class, char.class, 'C', (Character)(char)0, new char[0], Format.unsigned(16)),
INT(Integer.class, int.class, 'I', (Integer)(int)0, new int[0], Format.signed(32)),
LONG(Long.class, long.class, 'J', (Long)(long)0, new long[0], Format.signed(64)),
FLOAT(Float.class, float.class, 'F', (Float)(float)0, new float[0], Format.floating(32)),
DOUBLE(Double.class, double.class, 'D', (Double)(double)0, new double[0], Format.floating(64)),
//NULL(Null.class, null.class, 'N', null, null, Format.other(1)),
OBJECT(Object.class, Object.class, 'L', null, new Object[0], Format.other(1)),
// VOID must be the last type, since it is "assignable" from any other type:
VOID(Void.class, void.class, 'V', null, Format.other(0)),
VOID(Void.class, void.class, 'V', null, null, Format.other(0)),
;
private final Class<?> wrapperType;
private final Class<?> primitiveType;
private final char basicTypeChar;
private final Object zero;
private final Object emptyArray;
private final int format;
private final String simpleName;
private Wrapper(Class<?> wtype, Class<?> ptype, char tchar, Object zero, int format) {
private Wrapper(Class<?> wtype, Class<?> ptype, char tchar, Object zero, Object emptyArray, int format) {
this.wrapperType = wtype;
this.primitiveType = ptype;
this.basicTypeChar = tchar;
this.zero = zero;
this.emptyArray = emptyArray;
this.format = format;
this.simpleName = wtype.getSimpleName();
}
/** For debugging, give the details of this wrapper. */
public String detailString() {
return simpleName+
java.util.Arrays.asList(wrapperType, primitiveType,
basicTypeChar, zero,
"0x"+Integer.toHexString(format));
}
private static abstract class Format {
static final int SLOT_SHIFT = 0, SIZE_SHIFT = 2, KIND_SHIFT = 12;
static final int
......@@ -114,16 +124,18 @@ public enum Wrapper {
public boolean isUnsigned() { return format >= Format.BOOLEAN && format < Format.FLOAT; }
/** Is the wrapped type either float or double? */
public boolean isFloating() { return format >= Format.FLOAT; }
/** Is the wrapped type either void or a reference? */
public boolean isOther() { return (format & ~Format.SLOT_MASK) == 0; }
/** Does the JVM verifier allow a variable of this wrapper's
/** Does the JLS 5.1.2 allow a variable of this wrapper's
* primitive type to be assigned from a value of the given wrapper's primitive type?
* Cases:
* <ul>
* <li>unboxing followed by widening primitive conversion
* <li>any type converted to {@code void}
* <li>any type converted to {@code void} (i.e., dropping a method call's value)
* <li>boxing conversion followed by widening reference conversion to {@code Object}
* <li>conversion of {@code boolean} to any type
* </ul>
* These are the cases allowed by MethodHandle.asType and convertArguments.
*/
public boolean isConvertibleFrom(Wrapper source) {
if (this == source) return true;
......@@ -131,13 +143,75 @@ public enum Wrapper {
// At best, this is a narrowing conversion.
return false;
}
if ((this.format ^ source.format) == (Format.SHORT ^ Format.CHAR)) {
assert (this == SHORT && source == CHAR) || (this == CHAR && source == SHORT);
// All conversions are allowed in the enum order between floats and signed ints.
// First detect non-signed non-float types (boolean, char, Object, void).
boolean floatOrSigned = (((this.format & source.format) & Format.SIGNED) != 0);
if (!floatOrSigned) {
if (this.isOther()) return true;
// can convert char to int or wider, but nothing else
if (source.format == Format.CHAR) return true;
// no other conversions are classified as widening
return false;
}
// All signed and float conversions in the enum order are widening.
assert(this.isFloating() || this.isSigned());
assert(source.isFloating() || source.isSigned());
return true;
}
static { assert(checkConvertibleFrom()); }
private static boolean checkConvertibleFrom() {
// Check the matrix for correct classification of widening conversions.
for (Wrapper w : values()) {
assert(w.isConvertibleFrom(w));
assert(VOID.isConvertibleFrom(w));
if (w != VOID) {
assert(OBJECT.isConvertibleFrom(w));
assert(!w.isConvertibleFrom(VOID));
}
// check relations with unsigned integral types:
if (w != CHAR) {
assert(!CHAR.isConvertibleFrom(w));
if (!w.isConvertibleFrom(INT))
assert(!w.isConvertibleFrom(CHAR));
}
if (w != BOOLEAN) {
assert(!BOOLEAN.isConvertibleFrom(w));
if (w != VOID && w != OBJECT)
assert(!w.isConvertibleFrom(BOOLEAN));
}
// check relations with signed integral types:
if (w.isSigned()) {
for (Wrapper x : values()) {
if (w == x) continue;
if (x.isFloating())
assert(!w.isConvertibleFrom(x));
else if (x.isSigned()) {
if (w.compareTo(x) < 0)
assert(!w.isConvertibleFrom(x));
else
assert(w.isConvertibleFrom(x));
}
}
}
// check relations with floating types:
if (w.isFloating()) {
for (Wrapper x : values()) {
if (w == x) continue;
if (x.isSigned())
assert(w.isConvertibleFrom(x));
else if (x.isFloating()) {
if (w.compareTo(x) < 0)
assert(!w.isConvertibleFrom(x));
else
assert(w.isConvertibleFrom(x));
}
}
}
}
return true; // i.e., assert(true)
}
/** Produce a zero value for the given wrapper type.
* This will be a numeric zero for a number or character,
* false for a boolean, and null for a reference or void.
......@@ -549,7 +623,7 @@ public enum Wrapper {
}
private static boolean boolValue(long bits) {
//bits &= 1; // simple 31-bit zero extension
bits &= 1; // simple 31-bit zero extension
return (bits != 0);
}
......@@ -559,4 +633,31 @@ public enum Wrapper {
private static RuntimeException newIllegalArgumentException(String message) {
return new IllegalArgumentException(message);
}
// primitive array support
public Object makeArray(int len) {
return java.lang.reflect.Array.newInstance(primitiveType, len);
}
public Class<?> arrayType() {
return emptyArray.getClass();
}
public void copyArrayUnboxing(Object[] values, int vpos, Object a, int apos, int length) {
if (a.getClass() != arrayType())
arrayType().cast(a); // throw NPE or CCE if bad type
for (int i = 0; i < length; i++) {
Object value = values[i+vpos];
value = convert(value, primitiveType);
java.lang.reflect.Array.set(a, i+apos, value);
}
}
public void copyArrayBoxing(Object a, int apos, Object[] values, int vpos, int length) {
if (a.getClass() != arrayType())
arrayType().cast(a); // throw NPE or CCE if bad type
for (int i = 0; i < length; i++) {
Object value = java.lang.reflect.Array.get(a, i+apos);
//Already done: value = convert(value, primitiveType);
assert(value.getClass() == wrapperType);
values[i+vpos] = value;
}
}
}
......@@ -102,15 +102,20 @@ class OGLRenderer extends BufferedRenderPipe {
final ParallelogramPipe realpipe = oglr.getAAParallelogramPipe();
return new ParallelogramPipe() {
public void fillParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
GraphicsPrimitive.tracePrimitive("OGLFillAAParallelogram");
realpipe.fillParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2);
}
public void drawParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
......@@ -118,6 +123,7 @@ class OGLRenderer extends BufferedRenderPipe {
{
GraphicsPrimitive.tracePrimitive("OGLDrawAAParallelogram");
realpipe.drawParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2,
lw1, lw2);
}
......@@ -166,21 +172,29 @@ class OGLRenderer extends BufferedRenderPipe {
oglr.fillSpans(sg2d, si, transx, transy);
}
public void fillParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
GraphicsPrimitive.tracePrimitive("OGLFillParallelogram");
oglr.fillParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2);
oglr.fillParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2);
}
public void drawParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2)
{
GraphicsPrimitive.tracePrimitive("OGLDrawParallelogram");
oglr.drawParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2, lw1, lw2);
oglr.drawParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2, lw1, lw2);
}
public void copyArea(SunGraphics2D sg2d,
int x, int y, int w, int h, int dx, int dy)
......
......@@ -68,21 +68,23 @@ public class AAShapePipe
renderPath(sg, s, null);
}
private static Rectangle2D computeBBox(double x, double y,
double dx1, double dy1,
double dx2, double dy2)
private static Rectangle2D computeBBox(double ux1, double uy1,
double ux2, double uy2)
{
double lox, loy, hix, hiy;
lox = hix = x;
loy = hiy = y;
if (dx1 < 0) { lox += dx1; } else { hix += dx1; }
if (dy1 < 0) { loy += dy1; } else { hiy += dy1; }
if (dx2 < 0) { lox += dx2; } else { hix += dx2; }
if (dy2 < 0) { loy += dy2; } else { hiy += dy2; }
return new Rectangle2D.Double(lox, loy, hix-lox, hiy-loy);
if ((ux2 -= ux1) < 0) {
ux1 += ux2;
ux2 = -ux2;
}
if ((uy2 -= uy1) < 0) {
uy1 += uy2;
uy2 = -uy2;
}
return new Rectangle2D.Double(ux1, uy1, ux2, uy2);
}
public void fillParallelogram(SunGraphics2D sg,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
......@@ -97,10 +99,12 @@ public class AAShapePipe
return;
}
renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox);
renderTiles(sg, computeBBox(ux1, uy1, ux2, uy2), aatg, abox);
}
public void drawParallelogram(SunGraphics2D sg,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
......@@ -118,7 +122,7 @@ public class AAShapePipe
// Note that bbox is of the original shape, not the wide path.
// This is appropriate for handing to Paint methods...
renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox);
renderTiles(sg, computeBBox(ux1, uy1, ux2, uy2), aatg, abox);
}
private static byte[] theTile;
......
......@@ -66,6 +66,8 @@ public class AlphaColorPipe implements CompositePipe, ParallelogramPipe {
}
public void fillParallelogram(SunGraphics2D sg,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
......@@ -75,6 +77,8 @@ public class AlphaColorPipe implements CompositePipe, ParallelogramPipe {
}
public void drawParallelogram(SunGraphics2D sg,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
......
......@@ -408,6 +408,8 @@ public abstract class BufferedRenderPipe
}
public void fillParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
......@@ -429,6 +431,8 @@ public abstract class BufferedRenderPipe
}
public void drawParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
......@@ -454,6 +458,8 @@ public abstract class BufferedRenderPipe
private class AAParallelogramPipe implements ParallelogramPipe {
public void fillParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
......@@ -475,6 +481,8 @@ public abstract class BufferedRenderPipe
}
public void drawParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
......
......@@ -352,6 +352,8 @@ public class LoopPipe
}
public void fillParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
......@@ -362,6 +364,8 @@ public class LoopPipe
}
public void drawParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
......
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2011 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
......@@ -40,9 +40,17 @@ import sun.java2d.SunGraphics2D;
* => (x+dx2, y+dy2)
* => origin
* </pre>
* The four u[xy][12] parameters are the unsorted extreme coordinates
* of the primitive in user space. They may have been generated by a
* line or a rectangle so they could have u[xy]2 < u[xy]1 in some cases.
* They should be sorted before calculating the bounds of the original
* primitive (such as for calculating the user space bounds for the
* Paint.createContext() method).
*/
public interface ParallelogramPipe {
public void fillParallelogram(SunGraphics2D sg,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2);
......@@ -59,6 +67,8 @@ public interface ParallelogramPipe {
* difference between the outer and inner parallelograms.
*/
public void drawParallelogram(SunGraphics2D sg,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
......
......@@ -175,8 +175,8 @@ public class PixelToParallelogramConverter extends PixelToShapeConverter
}
public boolean drawGeneralLine(SunGraphics2D sg2d,
double x1, double y1,
double x2, double y2)
double ux1, double uy1,
double ux2, double uy2)
{
if (sg2d.strokeState == SunGraphics2D.STROKE_CUSTOM ||
sg2d.strokeState == SunGraphics2D.STROKE_THINDASHED)
......@@ -194,13 +194,14 @@ public class PixelToParallelogramConverter extends PixelToShapeConverter
double lw = bs.getLineWidth();
// Save the original dx, dy in case we need it to transform
// the linewidth as a perpendicular vector below
double dx = x2 - x1;
double dy = y2 - y1;
double dx = ux2 - ux1;
double dy = uy2 - uy1;
double x1, y1, x2, y2;
switch (sg2d.transformState) {
case SunGraphics2D.TRANSFORM_GENERIC:
case SunGraphics2D.TRANSFORM_TRANSLATESCALE:
{
double coords[] = {x1, y1, x2, y2};
double coords[] = {ux1, uy1, ux2, uy2};
sg2d.transform.transform(coords, 0, coords, 0, 2);
x1 = coords[0];
y1 = coords[1];
......@@ -213,13 +214,17 @@ public class PixelToParallelogramConverter extends PixelToShapeConverter
{
double tx = sg2d.transform.getTranslateX();
double ty = sg2d.transform.getTranslateY();
x1 += tx;
y1 += ty;
x2 += tx;
y2 += ty;
x1 = ux1 + tx;
y1 = uy1 + ty;
x2 = ux2 + tx;
y2 = uy2 + ty;
}
break;
case SunGraphics2D.TRANSFORM_ISIDENT:
x1 = ux1;
y1 = uy1;
x2 = ux2;
y2 = uy2;
break;
default:
throw new InternalError("unknown TRANSFORM state...");
......@@ -279,7 +284,8 @@ public class PixelToParallelogramConverter extends PixelToShapeConverter
dx += udx;
dy += udy;
}
outrenderer.fillParallelogram(sg2d, px, py, -udy, udx, dx, dy);
outrenderer.fillParallelogram(sg2d, ux1, uy1, ux2, uy2,
px, py, -udy, udx, dx, dy);
return true;
}
......@@ -313,7 +319,8 @@ public class PixelToParallelogramConverter extends PixelToShapeConverter
px = newx;
py = newy;
}
outrenderer.fillParallelogram(sg2d, px, py, dx1, dy1, dx2, dy2);
outrenderer.fillParallelogram(sg2d, rx, ry, rx+rw, ry+rh,
px, py, dx1, dy1, dx2, dy2);
}
public void drawRectangle(SunGraphics2D sg2d,
......@@ -360,10 +367,12 @@ public class PixelToParallelogramConverter extends PixelToShapeConverter
// entire hole in the middle of the parallelogram
// so we can just fill the outer parallelogram.
fillOuterParallelogram(sg2d,
rx, ry, rx+rw, ry+rh,
px, py, dx1, dy1, dx2, dy2,
len1, len2, lw1, lw2);
} else {
outrenderer.drawParallelogram(sg2d,
rx, ry, rx+rw, ry+rh,
px, py, dx1, dy1, dx2, dy2,
lw1 / len1, lw2 / len2);
}
......@@ -377,6 +386,8 @@ public class PixelToParallelogramConverter extends PixelToShapeConverter
* and issues a single fillParallelogram request to fill it.
*/
public void fillOuterParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double px, double py,
double dx1, double dy1,
double dx2, double dy2,
......@@ -412,6 +423,7 @@ public class PixelToParallelogramConverter extends PixelToShapeConverter
dx2 += udx2;
dy2 += udy2;
outrenderer.fillParallelogram(sg2d, px, py, dx1, dy1, dx2, dy2);
outrenderer.fillParallelogram(sg2d, ux1, uy1, ux2, uy2,
px, py, dx1, dy1, dx2, dy2);
}
}
......@@ -2889,10 +2889,6 @@ public class BidiBase {
verifyValidPara();
verifyRange(start, 0, limit);
verifyRange(limit, 0, length+1);
if (getParagraphIndex(start) != getParagraphIndex(limit - 1)) {
/* the line crosses a paragraph boundary */
throw new IllegalArgumentException();
}
return BidiLine.setLine(bidi, this, newBidi, newBidiBase, start, limit);
}
......
......@@ -48,7 +48,7 @@ class XRobotPeer implements RobotPeer {
}
public void dispose() {
_dispose();
// does nothing
}
public void mouseMove(int x, int y) {
......@@ -88,7 +88,6 @@ class XRobotPeer implements RobotPeer {
}
private static native synchronized void setup(int numberOfButtons, int[] buttonDownMasks);
private static native synchronized void _dispose();
private static native synchronized void mouseMoveImpl(X11GraphicsConfig xgc, int x, int y);
private static native synchronized void mousePressImpl(int buttons);
......
......@@ -48,28 +48,12 @@
#ifdef __linux__
#include <sys/socket.h>
#endif
#include <dlfcn.h>
extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
static jint * masks;
static jint num_buttons;
static unsigned int s_robotInstanceCounter = 0;
static void* xcompositeLibHandle = NULL;
static Bool xcompositeExtAvailable = False;
static Bool xcompositeExtTested = False;
typedef Status (*T_XCompositeQueryVersion)(Display *dpy, int *major_versionp, int *minor_versionp);
typedef Window (*T_XCompositeGetOverlayWindow)(Display *dpy, Window window);
typedef void (*T_XCompositeReleaseOverlayWindow)(Display *dpy, Window window);
static T_XCompositeQueryVersion XCompositeQueryVersion = NULL;
static T_XCompositeGetOverlayWindow XCompositeGetOverlayWindow = NULL;
static T_XCompositeReleaseOverlayWindow XCompositeReleaseOverlayWindow = NULL;
static int32_t isXTestAvailable() {
int32_t major_opcode, first_event, first_error;
int32_t event_basep, error_basep, majorp, minorp;
......@@ -210,80 +194,8 @@ Java_sun_awt_X11_XRobotPeer_setup (JNIEnv * env, jclass cls, jint numberOfButton
}
AWT_UNLOCK();
s_robotInstanceCounter++;
}
JNIEXPORT void JNICALL
Java_sun_awt_X11_XRobotPeer__1dispose (JNIEnv * env, jclass cls)
{
if (--s_robotInstanceCounter) {
return;
}
// This is the last instance of the XRobotPeer being released
if (xcompositeExtTested && xcompositeExtAvailable && xcompositeLibHandle) {
// The lib is loaded in IsXCompositeAvailable(). Unload under AWT_LOCK
// so that the shutdown function of the lib behaves correctly.
AWT_LOCK();
dlclose(xcompositeLibHandle);
AWT_UNLOCK();
}
xcompositeExtTested = False;
xcompositeExtAvailable = False;
xcompositeLibHandle = NULL;
}
/*
* Returns True only if XCOMPOSITE is of version 0.3 or higher.
* The functions that we need are available since that version.
*
* Must be invoked under AWT_LOCK.
*
* Leaves the library loaded if the version is correct.
*/
static Bool IsXCompositeAvailable()
{
if (!xcompositeExtTested) {
int opcode, eventb, errorb;
if (XQueryExtension(awt_display, "Composite", &opcode, &eventb, &errorb)) {
xcompositeLibHandle = dlopen("libXcomposite.so.1", RTLD_LAZY | RTLD_GLOBAL);
#ifndef __linux__ /* SOLARIS */
if (xcompositeLibHandle == NULL) {
xcompositeLibHandle = dlopen("/usr/sfw/lib/libXcomposite.so.1",
RTLD_LAZY | RTLD_GLOBAL);
}
#endif
if (xcompositeLibHandle) {
int major, minor;
XCompositeQueryVersion = (T_XCompositeQueryVersion)dlsym(xcompositeLibHandle, "XCompositeQueryVersion");
if (XCompositeQueryVersion && XCompositeQueryVersion(awt_display, &major, &minor)) {
if (major >= 0 && minor >= 3) {
XCompositeGetOverlayWindow = (T_XCompositeGetOverlayWindow)dlsym(xcompositeLibHandle, "XCompositeGetOverlayWindow");
XCompositeReleaseOverlayWindow = (T_XCompositeReleaseOverlayWindow)dlsym(xcompositeLibHandle, "XCompositeReleaseOverlayWindow");
if (XCompositeGetOverlayWindow && XCompositeReleaseOverlayWindow) {
xcompositeExtAvailable = True;
}
}
}
if (!xcompositeExtAvailable) {
dlclose(xcompositeLibHandle);
} /* else the lib is unloaded in _dispose() */
}
}
xcompositeExtTested = True;
}
return xcompositeExtAvailable;
}
JNIEXPORT void JNICALL
Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
......@@ -299,7 +211,7 @@ Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
jint *ary; /* Array of jints for sending pixel values back
* to parent process.
*/
Window window;
Window rootWindow;
AwtGraphicsConfigDataPtr adata;
DTRACE_PRINTLN6("RobotPeer: getRGBPixelsImpl(%lx, %d, %d, %d, %d, %x)", xgc, x, y, width, height, pixelArray);
......@@ -316,24 +228,14 @@ Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, xgc, x11GraphicsConfigIDs.aData);
DASSERT(adata != NULL);
window = XRootWindow(awt_display, adata->awt_visInfo.screen);
if (IsXCompositeAvailable()) {
// Use 'composite overlay window' instead of the root window.
// See 6903034 for details.
window = XCompositeGetOverlayWindow(awt_display, window);
}
image = getWindowImage(awt_display, window, x, y, width, height);
rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);
image = getWindowImage(awt_display, rootWindow, x, y, width, height);
/* Array to use to crunch around the pixel values */
ary = (jint *) malloc(width * height * sizeof (jint));
if (ary == NULL) {
JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
XDestroyImage(image);
if (IsXCompositeAvailable()) {
XCompositeReleaseOverlayWindow(awt_display, window);
}
AWT_UNLOCK();
return;
}
......@@ -354,9 +256,6 @@ Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
free(ary);
XDestroyImage(image);
if (IsXCompositeAvailable()) {
XCompositeReleaseOverlayWindow(awt_display, window);
}
AWT_UNLOCK();
}
......
......@@ -107,8 +107,16 @@ class WFramePeer extends WWindowPeer implements FramePeer {
Rectangle currentDevBounds = currentDevGC.getBounds();
Rectangle primaryDevBounds = primaryDevGC.getBounds();
b.width -= (currentDevBounds.width - primaryDevBounds.width);
b.height -= (currentDevBounds.height - primaryDevBounds.height);
boolean isCurrentDevLarger =
((currentDevBounds.width - primaryDevBounds.width > 0) ||
(currentDevBounds.height - primaryDevBounds.height > 0));
// the window manager doesn't seem to compensate for differences when
// the primary monitor is larger than the monitor that display the window
if (isCurrentDevLarger) {
b.width -= (currentDevBounds.width - primaryDevBounds.width);
b.height -= (currentDevBounds.height - primaryDevBounds.height);
}
}
}
......
......@@ -102,15 +102,20 @@ class D3DRenderer extends BufferedRenderPipe {
final ParallelogramPipe realpipe = d3dr.getAAParallelogramPipe();
return new ParallelogramPipe() {
public void fillParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
GraphicsPrimitive.tracePrimitive("D3DFillAAParallelogram");
realpipe.fillParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2);
}
public void drawParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
......@@ -118,6 +123,7 @@ class D3DRenderer extends BufferedRenderPipe {
{
GraphicsPrimitive.tracePrimitive("D3DDrawAAParallelogram");
realpipe.drawParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2,
lw1, lw2);
}
......@@ -167,21 +173,29 @@ class D3DRenderer extends BufferedRenderPipe {
d3dr.fillSpans(sg2d, si, transx, transy);
}
public void fillParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
GraphicsPrimitive.tracePrimitive("D3DFillParallelogram");
d3dr.fillParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2);
d3dr.fillParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2);
}
public void drawParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2)
{
GraphicsPrimitive.tracePrimitive("D3DDrawParallelogram");
d3dr.drawParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2, lw1, lw2);
d3dr.drawParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2, lw1, lw2);
}
public void copyArea(SunGraphics2D sg2d,
int x, int y, int w, int h, int dx, int dy)
......
......@@ -192,6 +192,14 @@ void D3DPipelineManager::NotifyAdapterEventListeners(UINT adapter,
pMgr = D3DPipelineManager::GetInstance();
RETURN_IF_NULL(pMgr);
hMon = pMgr->pd3d9->GetAdapterMonitor(adapter);
/*
* If we don't have devices initialized yet, no sense to clear them.
*/
if (!Devices::GetInstance()){
return;
}
gdiScreen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(hMon);
JNU_CallStaticMethodByName(env, NULL,
......
......@@ -364,7 +364,6 @@ AwtComponent* AwtComponent::GetComponentImpl(HWND hWnd) {
AwtComponent *component =
(AwtComponent *)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
DASSERT(!component || !IsBadReadPtr(component, sizeof(AwtComponent)) );
DASSERT(!component || component->GetHWnd() == hWnd );
return component;
}
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册