Imported Upstream version 4.2.1.36

Former-commit-id: f3008ca867fe7e4b7ae9b9a8844c0ad5798925a9
This commit is contained in:
Xamarin Public Jenkins 2015-09-24 06:06:07 -04:00 committed by Jo Shields
parent afe402035c
commit ea5caba957
172 changed files with 6570 additions and 11015 deletions

View File

@ -84,8 +84,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
$(srcdir)/config.h.in mkinstalldirs \
$(srcdir)/mono-uninstalled.pc.in COPYING.LIB ChangeLog NEWS \
compile config.guess config.rpath config.sub depcomp \
install-sh missing ltmain.sh
compile config.guess config.rpath config.sub install-sh \
missing ltmain.sh
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/iconv.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \

View File

@ -1 +1 @@
2c2c33e9b3b238b9af81df41107a0b6b0127ed10
1895650fb1b5a365ada5bcdf3fef86a448da51d2

View File

@ -1 +1 @@
fa754128cfe42ebd98f8fc68209473d8cc272fc0
2317c4f2abf300ae9f452f4dbfd8b9d63c944e1c

8
external/ikvm/HOWTO vendored
View File

@ -1,11 +1,11 @@
IKVM.NET Build Instructions
---------------------------
This IKVM.NET source bundle requires OpenJDK 7u6 b24 sources (and build artifacts).
This IKVM.NET source bundle requires OpenJDK 8u45 b14 sources (and build artifacts).
They can be downloaded from the SourceForge IKVM project, or from:
http://www.frijters.net/openjdk-7u6-b24-stripped.zip
http://www.frijters.net/openjdk-8u45-b14-stripped.zip
This file should be unzipped in the same directory as where the ikvm directory
(that contains this unzipped source bundle) lives.
@ -13,8 +13,8 @@ This file should be unzipped in the same directory as where the ikvm directory
Download ICSharpCode.SharpZipLib.dll (from http://www.icsharpcode.net/opensource/sharpziplib/
or from the ikvmbin-x.y.z.r.zip in the SourceForge IKVM project) and copy it to ikvm/bin.
Add the bin directory of NAnt 0.85 and JDK 7 to the PATH. It is recommend to use the 64 bit
version of Java 7.
Add the bin directory of NAnt 0.85 and JDK 8 to the PATH. Java 8 is required to build
the Java class library. It is recommend to use the 64 bit version.
From the ikvm directory run "nant".

View File

@ -566,7 +566,7 @@ namespace IKVM.NativeCode.sun.awt.shell
{
return;
}
Marshal.Release(pIDL);
Marshal.FreeCoTaskMem(pIDL);
}
/// <summary>
@ -608,8 +608,8 @@ namespace IKVM.NativeCode.sun.awt.shell
return (int)atts[0];
}
[System.Security.SecurityCritical]
public static String getFileSystemPath(int csidl)
[System.Security.SecuritySafeCritical]
public static String getFileSystemPath0(int csidl)
{
IntPtr pIDL = new IntPtr();
int hRes = ShellApi.SHGetSpecialFolderLocation(IntPtr.Zero, (ShellApi.CSIDL)csidl, ref pIDL);

View File

@ -1 +1 @@
a8a055aaac9ad8e98b1c9c47fcd85f5d82ba8ef1
3326c8c8b604536ceedce48c5646eef4d04d2a8f

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2002-2014 Jeroen Frijters
Copyright (C) 2002-2015 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -507,7 +507,7 @@ namespace IKVM.Internal
}
}
private static void MapModifiers(MapXml.MapModifiers mapmods, bool isConstructor, out bool setmodifiers, ref MethodAttributes attribs)
private static void MapModifiers(MapXml.MapModifiers mapmods, bool isConstructor, out bool setmodifiers, ref MethodAttributes attribs, bool isNewSlot)
{
setmodifiers = false;
Modifiers modifiers = (Modifiers)mapmods;
@ -543,6 +543,10 @@ namespace IKVM.Internal
// remove NewSlot, because it doesn't make sense on a non-virtual method
attribs &= ~MethodAttributes.NewSlot;
}
else if(((modifiers & (Modifiers.Public | Modifiers.Final)) == Modifiers.Final && isNewSlot && (attribs & MethodAttributes.Virtual) == 0))
{
// final method that doesn't need to be virtual
}
else
{
if((modifiers & Modifiers.Private) == 0)
@ -630,7 +634,7 @@ namespace IKVM.Internal
}
bool setmodifiers = false;
MethodAttributes attribs = 0;
MapModifiers(constructor.Modifiers, true, out setmodifiers, ref attribs);
MapModifiers(constructor.Modifiers, true, out setmodifiers, ref attribs, false);
Type returnType;
Type[] parameterTypes;
MapSignature(constructor.Sig, out returnType, out parameterTypes);
@ -683,7 +687,7 @@ namespace IKVM.Internal
{
bool setmodifiers = false;
MethodAttributes attribs = method.MethodAttributes;
MapModifiers(method.Modifiers, false, out setmodifiers, ref attribs);
MapModifiers(method.Modifiers, false, out setmodifiers, ref attribs, BaseTypeWrapper == null || BaseTypeWrapper.GetMethodWrapper(method.Name, method.Sig, true) == null);
if(method.body == null && (attribs & MethodAttributes.Abstract) == 0)
{
Console.Error.WriteLine("Error: Method {0}.{1}{2} in xml remap file doesn't have a body.", clazz.Name, method.Name, method.Sig);

View File

@ -838,7 +838,7 @@ sealed class IkvmcCompiler
}
else if(s == "-opt:fields")
{
options.removeUnusedFields = true;
options.codegenoptions |= CodeGenOptions.RemoveUnusedFields;
}
else if(s == "-compressresources")
{

View File

@ -1 +1 @@
c27a31eb1803a411aadc8b97ad081614b07dd615
1d6e66a3d816d572409fee7c6c4b27cc07cfb43d

View File

@ -577,6 +577,7 @@ sealed class BootstrapBootstrapClassLoader : ClassLoaderWrapper
RegisterInitiatingLoader(new StubTypeWrapper(Modifiers.Public, "java.lang.Enum", javaLangObject, false));
RegisterInitiatingLoader(new StubTypeWrapper(Modifiers.Public | Modifiers.Abstract | Modifiers.Interface, "java.lang.annotation.Annotation", null, false));
RegisterInitiatingLoader(new StubTypeWrapper(Modifiers.Public | Modifiers.Final, "java.lang.Class", javaLangObject, false));
RegisterInitiatingLoader(new StubTypeWrapper(Modifiers.Public | Modifiers.Abstract, "java.lang.invoke.MethodHandle", javaLangObject, false));
}
}
@ -607,25 +608,6 @@ sealed class StubTypeWrapper : TypeWrapper
get { throw new NotSupportedException(); }
}
internal override TypeWrapper[] Interfaces
{
get { return TypeWrapper.EmptyArray; }
}
internal override TypeWrapper[] InnerClasses
{
get { return TypeWrapper.EmptyArray; }
}
internal override TypeWrapper DeclaringTypeWrapper
{
get { return null; }
}
internal override void Finish()
{
}
internal override bool IsRemapped
{
get { return remapped; }

View File

@ -4,9 +4,9 @@
# This file list all forked OpenJDK files in their original OpenJDK location and their forked ikvm/openjdk location.
# Each line not starting with # contains a mapping: <original>=<forked>
#
build/linux-amd64/gensrc/sun/misc/Version.java=sun/misc/Version.java
build/linux-amd64/gensrc/sun/nio/ch/SocketOptionRegistry.java=sun/nio/ch/SocketOptionRegistry.java
build/linux-amd64/gensrc/sun/nio/cs/StandardCharsets.java=sun/nio/cs/StandardCharsets.java
build/linux-x86_64-normal-server-release/jdk/gensrc/sun/misc/Version.java=sun/misc/Version.java
build/linux-x86_64-normal-server-release/jdk/gensrc/sun/nio/ch/SocketOptionRegistry.java=sun/nio/ch/SocketOptionRegistry.java
build/linux-x86_64-normal-server-release/jdk/gensrc/sun/nio/cs/StandardCharsets.java=sun/nio/cs/StandardCharsets.java
jdk/src/macosx/classes/java/lang/ClassLoaderHelper.java=java/lang/ClassLoaderHelper.java
jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java=com/sun/imageio/plugins/jpeg/JPEGImageReader.java
jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java=com/sun/imageio/plugins/jpeg/JPEGImageWriter.java
@ -22,17 +22,16 @@ jdk/src/share/classes/java/awt/image/DataBufferInt.java=java/awt/image/DataBuffe
jdk/src/share/classes/java/awt/image/DataBufferShort.java=java/awt/image/DataBufferShort.java
jdk/src/share/classes/java/awt/image/DataBufferUShort.java=java/awt/image/DataBufferUShort.java
jdk/src/share/classes/java/awt/image/IndexColorModel.java=java/awt/image/IndexColorModel.java
jdk/src/share/classes/java/io/FileInputStream.java=java/io/FileInputStream.java
jdk/src/share/classes/java/io/FileOutputStream.java=java/io/FileOutputStream.java
jdk/src/share/classes/java/io/ObjectStreamClass.java=java/io/ObjectStreamClass.java
jdk/src/share/classes/java/io/ObjectStreamField.java=java/io/ObjectStreamField.java
jdk/src/share/classes/java/io/RandomAccessFile.java=java/io/RandomAccessFile.java
jdk/src/share/classes/java/lang/Class.java=java/lang/Class.java
jdk/src/share/classes/java/lang/ClassLoader.java=java/lang/ClassLoader.java
jdk/src/share/classes/java/lang/Enum.java=java/lang/Enum.java
jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java=../runtime/openjdk/NativeInvokerBytecodeGenerator.cs
jdk/src/share/classes/java/lang/management/PlatformComponent.java=java/lang/management/PlatformComponent.java
jdk/src/share/classes/java/lang/ref/SoftReference.java=java/lang/ref/SoftReference.java
jdk/src/share/classes/java/lang/reflect/Constructor.java=java/lang/reflect/Constructor.java
jdk/src/share/classes/java/lang/reflect/Executable.java=java/lang/reflect/Executable.java
jdk/src/share/classes/java/lang/reflect/Field.java=java/lang/reflect/Field.java
jdk/src/share/classes/java/lang/reflect/Method.java=java/lang/reflect/Method.java
jdk/src/share/classes/java/lang/reflect/Proxy.java=java/lang/reflect/Proxy.java
@ -41,8 +40,6 @@ jdk/src/share/classes/java/lang/String.java=java/lang/StringHelper.java
jdk/src/share/classes/java/lang/System.java=java/lang/System.java
jdk/src/share/classes/java/lang/Thread.java=java/lang/Thread.java
jdk/src/share/classes/java/lang/Throwable.java=java/lang/ThrowableHelper.java
jdk/src/share/classes/java/net/SocketInputStream.java=java/net/SocketInputStream.java
jdk/src/share/classes/java/net/SocketOutputStream.java=java/net/SocketOutputStream.java
jdk/src/share/classes/java/nio/Bits.java=java/nio/Bits.java
jdk/src/share/classes/java/security/AccessController.java=java/security/AccessController.java
jdk/src/share/classes/java/security/ProtectionDomain.java=java/security/ProtectionDomain.java
@ -53,7 +50,6 @@ jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java=../classpath/j
jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java=../classpath/java/util/concurrent/atomic/AtomicLongArray.java
jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java=../classpath/java/util/concurrent/atomic/AtomicReference.java
jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java=../classpath/java/util/concurrent/atomic/AtomicReferenceArray.java
jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java=java/util/concurrent/ForkJoinPool.java
jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java=java/util/concurrent/locks/AbstractQueuedSynchronizer.java
jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java=java/util/concurrent/locks/LockSupport.java
jdk/src/share/classes/sun/awt/EmbeddedFrame.java=sun/awt/EmbeddedFrame.java
@ -62,7 +58,6 @@ jdk/src/share/classes/sun/awt/image/ImagingLib.java=sun/awt/image/ImagingLib.jav
jdk/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java=sun/awt/image/IntegerInterleavedRaster.java
jdk/src/share/classes/sun/awt/image/SunWritableRaster.java=sun/awt/image/SunWritableRaster.java
jdk/src/share/classes/sun/awt/image/ToolkitImage.java=sun/awt/image/ToolkitImage.java
jdk/src/share/classes/sun/awt/SunToolkit.java=sun/awt/SunToolkit.java
jdk/src/share/classes/sun/font/FontManager.java=sun/font/FontManager.java
jdk/src/share/classes/sun/font/StrikeCache.java=sun/font/StrikeCache.java
jdk/src/share/classes/sun/management/ManagementFactoryHelper.java=sun/management/ManagementFactoryHelper.java
@ -99,7 +94,6 @@ jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java=sun/net/www
jdk/src/windows/classes/sun/nio/ch/DefaultSelectorProvider.java=sun/nio/ch/DefaultSelectorProvider.java
jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java=sun/nio/ch/FileDispatcherImpl.java
jdk/src/windows/classes/sun/nio/ch/Iocp.java=sun/nio/ch/Iocp.java
jdk/src/windows/classes/sun/nio/ch/PollArrayWrapper.java=sun/nio/ch/PollArrayWrapper.java
jdk/src/windows/classes/sun/nio/ch/SocketDispatcher.java=sun/nio/ch/SocketDispatcher.java
jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java=sun/nio/ch/WindowsAsynchronousFileChannelImpl.java
jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java=sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java

View File

@ -1 +1 @@
9893116e072094e4cdaec2c5e493ef7f7799c5e6
935b3a93896a85d98a39a3ab7e9795dc58c56bdf

View File

@ -138,6 +138,7 @@ public final class Winsock
public static final int IPV6_ADD_MEMBERSHIP = SocketOptionName.AddMembership;
public static final int IPV6_DROP_MEMBERSHIP = SocketOptionName.DropMembership;
public static final int IPV6_V6ONLY = 27;
public static final int IPV6_TCLASS = 39;
public static final int SIO_UDP_CONNRESET = 0x9800000C;
@ -147,6 +148,8 @@ public final class Winsock
public static final int FIONREAD = (int)IOControlCode.DataToRead;
public static final int FIONBIO = (int)IOControlCode.NonBlockingIO;
public static final int MAX_PACKET_LEN = 0xFFFF;
public static int WSAGetLastError()
{
return lastError;

View File

@ -1,451 +0,0 @@
/*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.nio.channels.FileChannel;
import sun.nio.ch.FileChannelImpl;
import sun.misc.IoTrace;
/**
* A <code>FileInputStream</code> obtains input bytes
* from a file in a file system. What files
* are available depends on the host environment.
*
* <p><code>FileInputStream</code> is meant for reading streams of raw bytes
* such as image data. For reading streams of characters, consider using
* <code>FileReader</code>.
*
* @author Arthur van Hoff
* @see java.io.File
* @see java.io.FileDescriptor
* @see java.io.FileOutputStream
* @see java.nio.file.Files#newInputStream
* @since JDK1.0
*/
public
class FileInputStream extends InputStream
{
/* File Descriptor - handle to the open file */
private final FileDescriptor fd;
/* The path of the referenced file (null if the stream is created with a file descriptor) */
private final String path;
private FileChannel channel = null;
private final Object closeLock = new Object();
private volatile boolean closed = false;
private static final ThreadLocal<Boolean> runningFinalize =
new ThreadLocal<>();
private static boolean isRunningFinalize() {
Boolean val;
if ((val = runningFinalize.get()) != null)
return val.booleanValue();
return false;
}
/**
* Creates a <code>FileInputStream</code> by
* opening a connection to an actual file,
* the file named by the path name <code>name</code>
* in the file system. A new <code>FileDescriptor</code>
* object is created to represent this file
* connection.
* <p>
* First, if there is a security
* manager, its <code>checkRead</code> method
* is called with the <code>name</code> argument
* as its argument.
* <p>
* If the named file does not exist, is a directory rather than a regular
* file, or for some other reason cannot be opened for reading then a
* <code>FileNotFoundException</code> is thrown.
*
* @param name the system-dependent file name.
* @exception FileNotFoundException if the file does not exist,
* is a directory rather than a regular file,
* or for some other reason cannot be opened for
* reading.
* @exception SecurityException if a security manager exists and its
* <code>checkRead</code> method denies read access
* to the file.
* @see java.lang.SecurityManager#checkRead(java.lang.String)
*/
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
/**
* Creates a <code>FileInputStream</code> by
* opening a connection to an actual file,
* the file named by the <code>File</code>
* object <code>file</code> in the file system.
* A new <code>FileDescriptor</code> object
* is created to represent this file connection.
* <p>
* First, if there is a security manager,
* its <code>checkRead</code> method is called
* with the path represented by the <code>file</code>
* argument as its argument.
* <p>
* If the named file does not exist, is a directory rather than a regular
* file, or for some other reason cannot be opened for reading then a
* <code>FileNotFoundException</code> is thrown.
*
* @param file the file to be opened for reading.
* @exception FileNotFoundException if the file does not exist,
* is a directory rather than a regular file,
* or for some other reason cannot be opened for
* reading.
* @exception SecurityException if a security manager exists and its
* <code>checkRead</code> method denies read access to the file.
* @see java.io.File#getPath()
* @see java.lang.SecurityManager#checkRead(java.lang.String)
*/
public FileInputStream(File file) throws FileNotFoundException {
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(name);
}
if (name == null) {
throw new NullPointerException();
}
/*
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
*/
fd = new FileDescriptor();
fd.incrementAndGetUseCount();
this.path = name;
open(name);
}
/**
* Creates a <code>FileInputStream</code> by using the file descriptor
* <code>fdObj</code>, which represents an existing connection to an
* actual file in the file system.
* <p>
* If there is a security manager, its <code>checkRead</code> method is
* called with the file descriptor <code>fdObj</code> as its argument to
* see if it's ok to read the file descriptor. If read access is denied
* to the file descriptor a <code>SecurityException</code> is thrown.
* <p>
* If <code>fdObj</code> is null then a <code>NullPointerException</code>
* is thrown.
* <p>
* This constructor does not throw an exception if <code>fdObj</code>
* is {@link java.io.FileDescriptor#valid() invalid}.
* However, if the methods are invoked on the resulting stream to attempt
* I/O on the stream, an <code>IOException</code> is thrown.
*
* @param fdObj the file descriptor to be opened for reading.
* @throws SecurityException if a security manager exists and its
* <code>checkRead</code> method denies read access to the
* file descriptor.
* @see SecurityManager#checkRead(java.io.FileDescriptor)
*/
public FileInputStream(FileDescriptor fdObj) {
SecurityManager security = System.getSecurityManager();
if (fdObj == null) {
throw new NullPointerException();
}
if (security != null) {
security.checkRead(fdObj);
}
fd = fdObj;
path = null;
/*
* FileDescriptor is being shared by streams.
* Ensure that it's GC'ed only when all the streams/channels are done
* using it.
*/
fd.incrementAndGetUseCount();
}
/**
* Opens the specified file for reading.
* @param name the name of the file
*/
private void open(String name) throws FileNotFoundException
{
fd.openReadOnly(name);
}
/**
* Reads a byte of data from this input stream. This method blocks
* if no input is yet available.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* file is reached.
* @exception IOException if an I/O error occurs.
*/
public int read() throws IOException {
Object traceContext = IoTrace.fileReadBegin(path);
int b = 0;
try {
b = fd.read();
} finally {
IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1);
}
return b;
}
/**
* Reads a subarray as a sequence of bytes.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @exception IOException If an I/O error has occurred.
*/
private int readBytes(byte b[], int off, int len) throws IOException
{
return fd.readBytes(b, off, len);
}
/**
* Reads up to <code>b.length</code> bytes of data from this input
* stream into an array of bytes. This method blocks until some input
* is available.
*
* @param b the buffer into which the data is read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the file has been reached.
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[]) throws IOException {
Object traceContext = IoTrace.fileReadBegin(path);
int bytesRead = 0;
try {
bytesRead = readBytes(b, 0, b.length);
} finally {
IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead);
}
return bytesRead;
}
/**
* Reads up to <code>len</code> bytes of data from this input stream
* into an array of bytes. If <code>len</code> is not zero, the method
* blocks until some input is available; otherwise, no
* bytes are read and <code>0</code> is returned.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array <code>b</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the file has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[], int off, int len) throws IOException {
Object traceContext = IoTrace.fileReadBegin(path);
int bytesRead = 0;
try {
bytesRead = readBytes(b, off, len);
} finally {
IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead);
}
return bytesRead;
}
/**
* Skips over and discards <code>n</code> bytes of data from the
* input stream.
*
* <p>The <code>skip</code> method may, for a variety of
* reasons, end up skipping over some smaller number of bytes,
* possibly <code>0</code>. If <code>n</code> is negative, an
* <code>IOException</code> is thrown, even though the <code>skip</code>
* method of the {@link InputStream} superclass does nothing in this case.
* The actual number of bytes skipped is returned.
*
* <p>This method may skip more bytes than are remaining in the backing
* file. This produces no exception and the number of bytes skipped
* may include some number of bytes that were beyond the EOF of the
* backing file. Attempting to read from the stream after skipping past
* the end will result in -1 indicating the end of the file.
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
* @exception IOException if n is negative, if the stream does not
* support seek, or if an I/O error occurs.
*/
public long skip(long n) throws IOException
{
return fd.skip(n);
}
/**
* Returns an estimate of the number of remaining bytes that can be read (or
* skipped over) from this input stream without blocking by the next
* invocation of a method for this input stream. The next invocation might be
* the same thread or another thread. A single read or skip of this
* many bytes will not block, but may read or skip fewer bytes.
*
* <p> In some cases, a non-blocking read (or skip) may appear to be
* blocked when it is merely slow, for example when reading large
* files over slow networks.
*
* @return an estimate of the number of remaining bytes that can be read
* (or skipped over) from this input stream without blocking.
* @exception IOException if this file input stream has been closed by calling
* {@code close} or an I/O error occurs.
*/
public int available() throws IOException
{
return fd.available();
}
/**
* Closes this file input stream and releases any system resources
* associated with the stream.
*
* <p> If this stream has an associated channel then the channel is closed
* as well.
*
* @exception IOException if an I/O error occurs.
*
* @revised 1.4
* @spec JSR-51
*/
public void close() throws IOException {
synchronized (closeLock) {
if (closed) {
return;
}
closed = true;
}
if (channel != null) {
/*
* Decrement the FD use count associated with the channel
* The use count is incremented whenever a new channel
* is obtained from this stream.
*/
fd.decrementAndGetUseCount();
channel.close();
}
/*
* Decrement the FD use count associated with this stream
*/
int useCount = fd.decrementAndGetUseCount();
/*
* If FileDescriptor is still in use by another stream, the finalizer
* will not close it.
*/
if ((useCount <= 0) || !isRunningFinalize()) {
close0();
}
}
/**
* Returns the <code>FileDescriptor</code>
* object that represents the connection to
* the actual file in the file system being
* used by this <code>FileInputStream</code>.
*
* @return the file descriptor object associated with this stream.
* @exception IOException if an I/O error occurs.
* @see java.io.FileDescriptor
*/
public final FileDescriptor getFD() throws IOException {
if (fd != null) return fd;
throw new IOException();
}
/**
* Returns the unique {@link java.nio.channels.FileChannel FileChannel}
* object associated with this file input stream.
*
* <p> The initial {@link java.nio.channels.FileChannel#position()
* </code>position<code>} of the returned channel will be equal to the
* number of bytes read from the file so far. Reading bytes from this
* stream will increment the channel's position. Changing the channel's
* position, either explicitly or by reading, will change this stream's
* file position.
*
* @return the file channel associated with this file input stream
*
* @since 1.4
* @spec JSR-51
*/
public FileChannel getChannel() {
synchronized (this) {
if (channel == null) {
channel = FileChannelImpl.open(fd, path, true, false, this);
/*
* Increment fd's use count. Invoking the channel's close()
* method will result in decrementing the use count set for
* the channel.
*/
fd.incrementAndGetUseCount();
}
return channel;
}
}
private void close0() throws IOException
{
fd.close();
}
/**
* Ensures that the <code>close</code> method of this file input stream is
* called when there are no more references to it.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FileInputStream#close()
*/
protected void finalize() throws IOException {
if ((fd != null) && (fd != FileDescriptor.in)) {
/*
* Finalizer should not release the FileDescriptor if another
* stream is still using it. If the user directly invokes
* close() then the FileDescriptor is also released.
*/
runningFinalize.set(Boolean.TRUE);
try {
close();
} finally {
runningFinalize.set(Boolean.FALSE);
}
}
}
}

View File

@ -1,491 +0,0 @@
/*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.nio.channels.FileChannel;
import sun.nio.ch.FileChannelImpl;
import sun.misc.IoTrace;
/**
* A file output stream is an output stream for writing data to a
* <code>File</code> or to a <code>FileDescriptor</code>. Whether or not
* a file is available or may be created depends upon the underlying
* platform. Some platforms, in particular, allow a file to be opened
* for writing by only one <tt>FileOutputStream</tt> (or other
* file-writing object) at a time. In such situations the constructors in
* this class will fail if the file involved is already open.
*
* <p><code>FileOutputStream</code> is meant for writing streams of raw bytes
* such as image data. For writing streams of characters, consider using
* <code>FileWriter</code>.
*
* @author Arthur van Hoff
* @see java.io.File
* @see java.io.FileDescriptor
* @see java.io.FileInputStream
* @see java.nio.file.Files#newOutputStream
* @since JDK1.0
*/
public
class FileOutputStream extends OutputStream
{
/**
* The system dependent file descriptor.
*/
private final FileDescriptor fd;
/**
* The path of the referenced file (null if the stream is created with a file descriptor)
*/
private final String path;
/**
* True if the file is opened for append.
*/
private final boolean append;
/**
* The associated channel, initalized lazily.
*/
private FileChannel channel;
private final Object closeLock = new Object();
private volatile boolean closed = false;
private static final ThreadLocal<Boolean> runningFinalize =
new ThreadLocal<>();
private static boolean isRunningFinalize() {
Boolean val;
if ((val = runningFinalize.get()) != null)
return val.booleanValue();
return false;
}
/**
* Creates a file output stream to write to the file with the
* specified name. A new <code>FileDescriptor</code> object is
* created to represent this file connection.
* <p>
* First, if there is a security manager, its <code>checkWrite</code>
* method is called with <code>name</code> as its argument.
* <p>
* If the file exists but is a directory rather than a regular file, does
* not exist but cannot be created, or cannot be opened for any other
* reason then a <code>FileNotFoundException</code> is thrown.
*
* @param name the system-dependent filename
* @exception FileNotFoundException if the file exists but is a directory
* rather than a regular file, does not exist but cannot
* be created, or cannot be opened for any other reason
* @exception SecurityException if a security manager exists and its
* <code>checkWrite</code> method denies write access
* to the file.
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
*/
public FileOutputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null, false);
}
/**
* Creates a file output stream to write to the file with the specified
* name. If the second argument is <code>true</code>, then
* bytes will be written to the end of the file rather than the beginning.
* A new <code>FileDescriptor</code> object is created to represent this
* file connection.
* <p>
* First, if there is a security manager, its <code>checkWrite</code>
* method is called with <code>name</code> as its argument.
* <p>
* If the file exists but is a directory rather than a regular file, does
* not exist but cannot be created, or cannot be opened for any other
* reason then a <code>FileNotFoundException</code> is thrown.
*
* @param name the system-dependent file name
* @param append if <code>true</code>, then bytes will be written
* to the end of the file rather than the beginning
* @exception FileNotFoundException if the file exists but is a directory
* rather than a regular file, does not exist but cannot
* be created, or cannot be opened for any other reason.
* @exception SecurityException if a security manager exists and its
* <code>checkWrite</code> method denies write access
* to the file.
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
* @since JDK1.1
*/
public FileOutputStream(String name, boolean append)
throws FileNotFoundException
{
this(name != null ? new File(name) : null, append);
}
/**
* Creates a file output stream to write to the file represented by
* the specified <code>File</code> object. A new
* <code>FileDescriptor</code> object is created to represent this
* file connection.
* <p>
* First, if there is a security manager, its <code>checkWrite</code>
* method is called with the path represented by the <code>file</code>
* argument as its argument.
* <p>
* If the file exists but is a directory rather than a regular file, does
* not exist but cannot be created, or cannot be opened for any other
* reason then a <code>FileNotFoundException</code> is thrown.
*
* @param file the file to be opened for writing.
* @exception FileNotFoundException if the file exists but is a directory
* rather than a regular file, does not exist but cannot
* be created, or cannot be opened for any other reason
* @exception SecurityException if a security manager exists and its
* <code>checkWrite</code> method denies write access
* to the file.
* @see java.io.File#getPath()
* @see java.lang.SecurityException
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
*/
public FileOutputStream(File file) throws FileNotFoundException {
this(file, false);
}
/**
* Creates a file output stream to write to the file represented by
* the specified <code>File</code> object. If the second argument is
* <code>true</code>, then bytes will be written to the end of the file
* rather than the beginning. A new <code>FileDescriptor</code> object is
* created to represent this file connection.
* <p>
* First, if there is a security manager, its <code>checkWrite</code>
* method is called with the path represented by the <code>file</code>
* argument as its argument.
* <p>
* If the file exists but is a directory rather than a regular file, does
* not exist but cannot be created, or cannot be opened for any other
* reason then a <code>FileNotFoundException</code> is thrown.
*
* @param file the file to be opened for writing.
* @param append if <code>true</code>, then bytes will be written
* to the end of the file rather than the beginning
* @exception FileNotFoundException if the file exists but is a directory
* rather than a regular file, does not exist but cannot
* be created, or cannot be opened for any other reason
* @exception SecurityException if a security manager exists and its
* <code>checkWrite</code> method denies write access
* to the file.
* @see java.io.File#getPath()
* @see java.lang.SecurityException
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
* @since 1.4
*/
public FileOutputStream(File file, boolean append)
throws FileNotFoundException
{
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(name);
}
if (name == null) {
throw new NullPointerException();
}
/*
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
*/
this.fd = new FileDescriptor();
this.append = append;
this.path = name;
fd.incrementAndGetUseCount();
open(name, append);
}
/**
* Creates a file output stream to write to the specified file
* descriptor, which represents an existing connection to an actual
* file in the file system.
* <p>
* First, if there is a security manager, its <code>checkWrite</code>
* method is called with the file descriptor <code>fdObj</code>
* argument as its argument.
* <p>
* If <code>fdObj</code> is null then a <code>NullPointerException</code>
* is thrown.
* <p>
* This constructor does not throw an exception if <code>fdObj</code>
* is {@link java.io.FileDescriptor#valid() invalid}.
* However, if the methods are invoked on the resulting stream to attempt
* I/O on the stream, an <code>IOException</code> is thrown.
*
* @param fdObj the file descriptor to be opened for writing
* @exception SecurityException if a security manager exists and its
* <code>checkWrite</code> method denies
* write access to the file descriptor
* @see java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)
*/
public FileOutputStream(FileDescriptor fdObj) {
SecurityManager security = System.getSecurityManager();
if (fdObj == null) {
throw new NullPointerException();
}
if (security != null) {
security.checkWrite(fdObj);
}
this.fd = fdObj;
this.path = null;
this.append = false;
/*
* FileDescriptor is being shared by streams.
* Ensure that it's GC'ed only when all the streams/channels are done
* using it.
*/
fd.incrementAndGetUseCount();
}
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private void open(String name, boolean append)
throws FileNotFoundException {
if (append) {
fd.openAppend(name);
} else {
fd.openWriteOnly(name);
}
}
/**
* Writes the specified byte to this file output stream.
*
* @param b the byte to be written.
* @param append {@code true} if the write operation first
* advances the position to the end of file
*/
private void write(int b, boolean append) throws IOException {
fd.write(b);
}
/**
* Writes the specified byte to this file output stream. Implements
* the <code>write</code> method of <code>OutputStream</code>.
*
* @param b the byte to be written.
* @exception IOException if an I/O error occurs.
*/
public void write(int b) throws IOException {
Object traceContext = IoTrace.fileWriteBegin(path);
int bytesWritten = 0;
try {
write(b, append);
bytesWritten = 1;
} finally {
IoTrace.fileWriteEnd(traceContext, bytesWritten);
}
}
/**
* Writes a sub array as a sequence of bytes.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @param append {@code true} to first advance the position to the
* end of file
* @exception IOException If an I/O error has occurred.
*/
private void writeBytes(byte b[], int off, int len, boolean append)
throws IOException {
fd.writeBytes(b, off, len);
}
/**
* Writes <code>b.length</code> bytes from the specified byte array
* to this file output stream.
*
* @param b the data.
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[]) throws IOException {
Object traceContext = IoTrace.fileWriteBegin(path);
int bytesWritten = 0;
try {
writeBytes(b, 0, b.length, append);
bytesWritten = b.length;
} finally {
IoTrace.fileWriteEnd(traceContext, bytesWritten);
}
}
/**
* Writes <code>len</code> bytes from the specified byte array
* starting at offset <code>off</code> to this file output stream.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[], int off, int len) throws IOException {
Object traceContext = IoTrace.fileWriteBegin(path);
int bytesWritten = 0;
try {
writeBytes(b, off, len, append);
bytesWritten = len;
} finally {
IoTrace.fileWriteEnd(traceContext, bytesWritten);
}
}
/**
* Closes this file output stream and releases any system resources
* associated with this stream. This file output stream may no longer
* be used for writing bytes.
*
* <p> If this stream has an associated channel then the channel is closed
* as well.
*
* @exception IOException if an I/O error occurs.
*
* @revised 1.4
* @spec JSR-51
*/
public void close() throws IOException {
synchronized (closeLock) {
if (closed) {
return;
}
closed = true;
}
if (channel != null) {
/*
* Decrement FD use count associated with the channel
* The use count is incremented whenever a new channel
* is obtained from this stream.
*/
fd.decrementAndGetUseCount();
channel.close();
}
/*
* Decrement FD use count associated with this stream
*/
int useCount = fd.decrementAndGetUseCount();
/*
* If FileDescriptor is still in use by another stream, the finalizer
* will not close it.
*/
if ((useCount <= 0) || !isRunningFinalize()) {
close0();
}
}
/**
* Returns the file descriptor associated with this stream.
*
* @return the <code>FileDescriptor</code> object that represents
* the connection to the file in the file system being used
* by this <code>FileOutputStream</code> object.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FileDescriptor
*/
public final FileDescriptor getFD() throws IOException {
if (fd != null) return fd;
throw new IOException();
}
/**
* Returns the unique {@link java.nio.channels.FileChannel FileChannel}
* object associated with this file output stream. </p>
*
* <p> The initial {@link java.nio.channels.FileChannel#position()
* </code>position<code>} of the returned channel will be equal to the
* number of bytes written to the file so far unless this stream is in
* append mode, in which case it will be equal to the size of the file.
* Writing bytes to this stream will increment the channel's position
* accordingly. Changing the channel's position, either explicitly or by
* writing, will change this stream's file position.
*
* @return the file channel associated with this file output stream
*
* @since 1.4
* @spec JSR-51
*/
public FileChannel getChannel() {
synchronized (this) {
if (channel == null) {
channel = FileChannelImpl.open(fd, path, false, true, append, this);
/*
* Increment fd's use count. Invoking the channel's close()
* method will result in decrementing the use count set for
* the channel.
*/
fd.incrementAndGetUseCount();
}
return channel;
}
}
/**
* Cleans up the connection to the file, and ensures that the
* <code>close</code> method of this file output stream is
* called when there are no more references to this stream.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FileInputStream#close()
*/
protected void finalize() throws IOException {
if (fd != null) {
if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
flush();
} else {
/*
* Finalizer should not release the FileDescriptor if another
* stream is still using it. If the user directly invokes
* close() then the FileDescriptor is also released.
*/
runningFinalize.set(Boolean.TRUE);
try {
close();
} finally {
runningFinalize.set(Boolean.FALSE);
}
}
}
}
private void close0() throws IOException
{
fd.close();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
07fd7bd567e5b0ae8b3ae9c32741b56f6f363b0a
b11e668d455d97412eca312477103a8e19b9b2b6

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -51,13 +51,13 @@ import java.util.Vector;
import java.util.Hashtable;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import sun.misc.ClassFileTransformer;
import sun.misc.CompoundEnumeration;
import sun.misc.Resource;
import sun.misc.URLClassPath;
import sun.misc.VM;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
import sun.security.util.SecurityConstants;
/**
@ -158,7 +158,7 @@ import sun.security.util.SecurityConstants;
* }
* </pre></blockquote>
*
* <h4> <a name="name">Binary names</a> </h4>
* <h3> <a name="name">Binary names</a> </h3>
*
* <p> Any class name provided as a {@link String} parameter to methods in
* <tt>ClassLoader</tt> must be a binary name as defined by
@ -245,7 +245,7 @@ public abstract class ClassLoader {
// Shared among all packages with unsigned classes
private static final Certificate[] nocerts = new Certificate[0];
// The classes loaded by this class loader. The only purpose of this table
// The classes loaded by this class loader. The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private final Vector<Class<?>> classes = new Vector<>();
@ -259,7 +259,7 @@ public abstract class ClassLoader {
private final Set<ProtectionDomain> domains;
// Invoked by the VM to record every loaded class with this loader.
void addClass(Class c) {
void addClass(Class<?> c) {
classes.addElement(c);
}
@ -361,7 +361,7 @@ public abstract class ClassLoader {
* #loadClass(String, boolean)} method. It is invoked by the Java virtual
* machine to resolve class references. Invoking this method is equivalent
* to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
* false)</tt>}. </p>
* false)</tt>}.
*
* @param name
* The <a href="#name">binary name</a> of the class
@ -380,7 +380,7 @@ public abstract class ClassLoader {
* default implementation of this method searches for classes in the
* following order:
*
* <p><ol>
* <ol>
*
* <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
* has already been loaded. </p></li>
@ -421,7 +421,7 @@ public abstract class ClassLoader {
{
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
@ -453,7 +453,7 @@ public abstract class ClassLoader {
* behaves as follows. If this ClassLoader object is registered as
* parallel capable, the method returns a dedicated object associated
* with the specified class name. Otherwise, the method returns this
* ClassLoader object. </p>
* ClassLoader object.
*
* @param className
* The name of the to-be-loaded class
@ -480,7 +480,7 @@ public abstract class ClassLoader {
}
// This method is invoked by the virtual machine to load a class.
final Class loadClassInternal(String name)
final Class<?> loadClassInternal(String name)
throws ClassNotFoundException
{
// For backward compatibility, explicitly lock on 'this' when
@ -495,9 +495,16 @@ public abstract class ClassLoader {
}
// Invoked by the VM after loading class with this loader.
final void checkPackageAccess(Class cls, ProtectionDomain pd) {
final void checkPackageAccess(Class<?> cls, ProtectionDomain pd) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (ReflectUtil.isNonPublicProxyClass(cls)) {
for (Class<?> intf: cls.getInterfaces()) {
checkPackageAccess(intf, pd);
}
return;
}
final String name = cls.getName();
final int i = name.lastIndexOf('.');
if (i != -1) {
@ -518,7 +525,7 @@ public abstract class ClassLoader {
* follow the delegation model for loading classes, and will be invoked by
* the {@link #loadClass <tt>loadClass</tt>} method after checking the
* parent class loader for the requested class. The default implementation
* throws a <tt>ClassNotFoundException</tt>. </p>
* throws a <tt>ClassNotFoundException</tt>.
*
* @param name
* The <a href="#name">binary name</a> of the class
@ -681,42 +688,7 @@ public abstract class ClassLoader {
return source;
}
private Class defineTransformedClass(String name, byte[] b, int off, int len,
ProtectionDomain pd,
ClassFormatError cfe, String source)
throws ClassFormatError
{
// Class format error - try to transform the bytecode and
// define the class again
//
ClassFileTransformer[] transformers =
ClassFileTransformer.getTransformers();
Class c = null;
if (transformers != null) {
for (ClassFileTransformer transformer : transformers) {
try {
// Transform byte code using transformer
byte[] tb = transformer.transform(b, off, len);
c = defineClass1(name, tb, 0, tb.length,
pd, source);
break;
} catch (ClassFormatError cfe2) {
// If ClassFormatError occurs, try next transformer
}
}
}
// Rethrow original ClassFormatError if unable to transform
// bytecode to well-formed
//
if (c == null)
throw cfe;
return c;
}
private void postDefineClass(Class c, ProtectionDomain pd)
private void postDefineClass(Class<?> c, ProtectionDomain pd)
{
if (pd.getCodeSource() != null) {
Certificate certs[] = pd.getCodeSource().getCertificates();
@ -749,7 +721,7 @@ public abstract class ClassLoader {
* bootstrap class loader. If <tt>name</tt> is not <tt>null</tt>, it
* must be equal to the <a href="#name">binary name</a> of the class
* specified by the byte array "<tt>b</tt>", otherwise a {@link
* <tt>NoClassDefFoundError</tt>} will be thrown. </p>
* NoClassDefFoundError <tt>NoClassDefFoundError</tt>} will be thrown. </p>
*
* @param name
* The expected <a href="#name">binary name</a> of the class, or
@ -796,17 +768,8 @@ public abstract class ClassLoader {
{
check();
protectionDomain = preDefineClass(name, protectionDomain);
Class c = null;
String source = defineClassSourceLocation(protectionDomain);
try {
c = defineClass1(name, b, off, len, protectionDomain, source);
} catch (ClassFormatError cfe) {
c = defineTransformedClass(name, b, off, len, protectionDomain, cfe,
source);
}
Class<?> c = defineClass1(name, b, off, len, protectionDomain, source);
postDefineClass(c, protectionDomain);
return c;
}
@ -829,16 +792,16 @@ public abstract class ClassLoader {
* <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
* result as the statements
*
* <blockquote><tt>
*<p> <tt>
* ...<br>
* byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link
* byte[] temp = new byte[bBuffer.{@link
* java.nio.ByteBuffer#remaining remaining}()];<br>
* </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[])
* bBuffer.{@link java.nio.ByteBuffer#get(byte[])
* get}(temp);<br>
* return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
* </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0,
* temp.length, </tt><i>pd</i><tt>);<br>
* </tt></blockquote>
* cl.defineClass}(name, temp, 0,
* temp.length, pd);<br>
* </tt></p>
*
* @param name
* The expected <a href="#name">binary name</a>. of the class, or
@ -896,33 +859,21 @@ public abstract class ClassLoader {
}
protectionDomain = preDefineClass(name, protectionDomain);
Class c = null;
String source = defineClassSourceLocation(protectionDomain);
try {
c = defineClass2(name, b, b.position(), len, protectionDomain,
source);
} catch (ClassFormatError cfe) {
byte[] tb = new byte[len];
b.get(tb); // get bytes out of byte buffer.
c = defineTransformedClass(name, tb, 0, len, protectionDomain, cfe,
source);
}
Class<?> c = defineClass2(name, b, b.position(), len, protectionDomain, source);
postDefineClass(c, protectionDomain);
return c;
}
private native Class defineClass0(String name, byte[] b, int off, int len,
ProtectionDomain pd);
private native Class<?> defineClass0(String name, byte[] b, int off, int len,
ProtectionDomain pd);
private native Class defineClass1(String name, byte[] b, int off, int len,
ProtectionDomain pd, String source);
private native Class<?> defineClass1(String name, byte[] b, int off, int len,
ProtectionDomain pd, String source);
private native Class defineClass2(String name, java.nio.ByteBuffer b,
int off, int len, ProtectionDomain pd,
String source);
private native Class<?> defineClass2(String name, java.nio.ByteBuffer b,
int off, int len, ProtectionDomain pd,
String source);
// true if the name is null or has the potential to be a valid binary name
static boolean checkName(String name) {
@ -1011,7 +962,6 @@ public abstract class ClassLoader {
* already been linked, then this method simply returns. Otherwise, the
* class is linked as described in the "Execution" chapter of
* <cite>The Java&trade; Language Specification</cite>.
* </p>
*
* @param c
* The class to link
@ -1026,7 +976,7 @@ public abstract class ClassLoader {
resolveClass0(c);
}
private native void resolveClass0(Class c);
private native void resolveClass0(Class<?> c);
/**
* Finds a class with the specified <a href="#name">binary name</a>,
@ -1058,7 +1008,7 @@ public abstract class ClassLoader {
if (system == null) {
if (!checkName(name))
throw new ClassNotFoundException(name);
Class cls = findBootstrapClass(name);
Class<?> cls = findBootstrapClass(name);
if (cls == null) {
throw new ClassNotFoundException(name);
}
@ -1071,7 +1021,7 @@ public abstract class ClassLoader {
* Returns a class loaded by the bootstrap class loader;
* or return null if not found.
*/
private Class findBootstrapClassOrNull(String name)
private Class<?> findBootstrapClassOrNull(String name)
{
check();
if (!checkName(name)) return null;
@ -1080,7 +1030,7 @@ public abstract class ClassLoader {
}
// return null if not found
private native Class findBootstrapClass(String name);
private native Class<?> findBootstrapClass(String name);
// Check to make sure the class loader has been initialized.
private void check() {
@ -1093,7 +1043,7 @@ public abstract class ClassLoader {
* Returns the class with the given <a href="#name">binary name</a> if this
* loader has been recorded by the Java virtual machine as an initiating
* loader of a class with that <a href="#name">binary name</a>. Otherwise
* <tt>null</tt> is returned. </p>
* <tt>null</tt> is returned.
*
* @param name
* The <a href="#name">binary name</a> of the class
@ -1110,11 +1060,11 @@ public abstract class ClassLoader {
return findLoadedClass0(name);
}
private native final Class findLoadedClass0(String name);
private native final Class<?> findLoadedClass0(String name);
/**
* Sets the signers of a class. This should be invoked after defining a
* class. </p>
* class.
*
* @param c
* The <tt>Class</tt> object
@ -1145,6 +1095,10 @@ public abstract class ClassLoader {
* built-in to the virtual machine is searched. That failing, this method
* will invoke {@link #findResource(String)} to find the resource. </p>
*
* @apiNote When overriding this method it is recommended that an
* implementation ensures that any delegation is consistent with the {@link
* #getResources(java.lang.String) getResources(String)} method.
*
* @param name
* The resource name
*
@ -1178,6 +1132,13 @@ public abstract class ClassLoader {
* <p> The search order is described in the documentation for {@link
* #getResource(String)}. </p>
*
* @apiNote When overriding this method it is recommended that an
* implementation ensures that any delegation is consistent with the {@link
* #getResource(java.lang.String) getResource(String)} method. This should
* ensure that the first element returned by the Enumeration's
* {@code nextElement} method is the same resource that the
* {@code getResource(String)} method would return.
*
* @param name
* The resource name
*
@ -1194,7 +1155,8 @@ public abstract class ClassLoader {
* @since 1.2
*/
public Enumeration<URL> getResources(String name) throws IOException {
Enumeration[] tmp = new Enumeration[2];
@SuppressWarnings("unchecked")
Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[2];
if (parent != null) {
tmp[0] = parent.getResources(name);
} else {
@ -1207,7 +1169,7 @@ public abstract class ClassLoader {
/**
* Finds the resource with the given name. Class loader implementations
* should override this method to specify where to find resources. </p>
* should override this method to specify where to find resources.
*
* @param name
* The resource name
@ -1225,7 +1187,7 @@ public abstract class ClassLoader {
* Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
* representing all the resources with the given name. Class loader
* implementations should override this method to specify where to load
* resources from. </p>
* resources from.
*
* @param name
* The resource name
@ -1243,14 +1205,16 @@ public abstract class ClassLoader {
}
/**
* Registers the caller as parallel capable.</p>
* Registers the caller as parallel capable.
* The registration succeeds if and only if all of the following
* conditions are met: <br>
* 1. no instance of the caller has been created</p>
* 2. all of the super classes (except class Object) of the caller are
* registered as parallel capable</p>
* Note that once a class loader is registered as parallel capable, there
* is no way to change it back. </p>
* conditions are met:
* <ol>
* <li> no instance of the caller has been created</li>
* <li> all of the super classes (except class Object) of the caller are
* registered as parallel capable</li>
* </ol>
* <p>Note that once a class loader is registered as parallel capable, there
* is no way to change it back.</p>
*
* @return true if the caller is successfully registered as
* parallel capable and false if otherwise.
@ -1267,7 +1231,7 @@ public abstract class ClassLoader {
/**
* Find a resource of the specified name from the search path used to load
* classes. This method locates the resource through the system class
* loader (see {@link #getSystemClassLoader()}). </p>
* loader (see {@link #getSystemClassLoader()}).
*
* @param name
* The resource name
@ -1358,7 +1322,7 @@ public abstract class ClassLoader {
/**
* Open for reading, a resource of the specified name from the search path
* used to load classes. This method locates the resource through the
* system class loader (see {@link #getSystemClassLoader()}). </p>
* system class loader (see {@link #getSystemClassLoader()}).
*
* @param name
* The resource name
@ -1411,6 +1375,9 @@ public abstract class ClassLoader {
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Check access to the parent class loader
// If the caller's class loader is same as this class loader,
// permission check is performed.
checkClassLoaderPermission(parent, Reflection.getCallerClass());
}
return parent;
@ -1554,6 +1521,11 @@ public abstract class ClassLoader {
return caller.getClassLoader0();
}
/*
* Checks RuntimePermission("getClassLoader") permission
* if caller's class loader is not null and caller's class loader
* is not the same as or an ancestor of the given cl argument.
*/
static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
@ -1581,7 +1553,7 @@ public abstract class ClassLoader {
* class loaders to define the packages for their classes. Packages must
* be created before the class is defined, and package names must be
* unique within a class loader and cannot be redefined or changed once
* created. </p>
* created.
*
* @param name
* The package name
@ -1638,7 +1610,7 @@ public abstract class ClassLoader {
/**
* Returns a <tt>Package</tt> that has been defined by this class loader
* or any of its ancestors. </p>
* or any of its ancestors.
*
* @param name
* The package name
@ -1675,7 +1647,7 @@ public abstract class ClassLoader {
/**
* Returns all of the <tt>Packages</tt> defined by this class loader and
* its ancestors. </p>
* its ancestors.
*
* @return The array of <tt>Package</tt> objects defined by this
* <tt>ClassLoader</tt>
@ -1712,7 +1684,7 @@ public abstract class ClassLoader {
* method to locate the native libraries that belong to classes loaded with
* this class loader. If this method returns <tt>null</tt>, the VM
* searches the library along the path specified as the
* "<tt>java.library.path</tt>" property. </p>
* "<tt>java.library.path</tt>" property.
*
* @param libname
* The library name
@ -1750,22 +1722,29 @@ public abstract class ClassLoader {
private int jniVersion;
// the class from which the library is loaded, also indicates
// the loader this native library belongs.
Class fromClass;
private final Class<?> fromClass;
// the canonicalized name of the native library.
// or static library name
String name;
// Indicates if the native library is linked into the VM
boolean isBuiltin;
// Indicates if the native library is loaded
boolean loaded;
native void load(String name, boolean isBuiltin);
native void load(String name);
native long find(String name);
native void unload();
native void unload(String name, boolean isBuiltin);
static native String findBuiltinLib(String name);
public NativeLibrary(Class fromClass, String name) {
public NativeLibrary(Class<?> fromClass, String name, boolean isBuiltin) {
this.name = name;
this.fromClass = fromClass;
this.isBuiltin = isBuiltin;
}
protected void finalize() {
synchronized (loadedLibraryNames) {
if (fromClass.getClassLoader() != null && handle != 0) {
if (fromClass.getClassLoader() != null && loaded) {
/* remove the native library name */
int size = loadedLibraryNames.size();
for (int i = 0; i < size; i++) {
@ -1777,7 +1756,7 @@ public abstract class ClassLoader {
/* unload the library. */
ClassLoader.nativeLibraryContext.push(this);
try {
unload();
unload(name, isBuiltin);
} finally {
ClassLoader.nativeLibraryContext.pop();
}
@ -1786,7 +1765,7 @@ public abstract class ClassLoader {
}
// Invoked in the VM to determine the context class in
// JNI_Load/JNI_Unload
static Class getFromClass() {
static Class<?> getFromClass() {
return ClassLoader.nativeLibraryContext.peek().fromClass;
}
}
@ -1849,7 +1828,7 @@ public abstract class ClassLoader {
}
// Invoked in the java.lang.Runtime class to implement load and loadLibrary.
static void loadLibrary(Class fromClass, String name,
static void loadLibrary(Class<?> fromClass, String name,
boolean isAbsolute) {
ClassLoader loader =
(fromClass == null) ? null : fromClass.getClassLoader();
@ -1882,6 +1861,10 @@ public abstract class ClassLoader {
if (loadLibrary0(fromClass, libfile)) {
return;
}
libfile = ClassLoaderHelper.mapAlternativeName(libfile);
if (libfile != null && loadLibrary0(fromClass, libfile)) {
return;
}
}
if (loader != null) {
for (int i = 0 ; i < usr_paths.length ; i++) {
@ -1890,38 +1873,35 @@ public abstract class ClassLoader {
if (loadLibrary0(fromClass, libfile)) {
return;
}
libfile = ClassLoaderHelper.mapAlternativeName(libfile);
if (libfile != null && loadLibrary0(fromClass, libfile)) {
return;
}
}
}
// Oops, it failed
throw new UnsatisfiedLinkError("no " + name + " in java.library.path");
}
private static boolean loadLibrary0(Class fromClass, final File file) {
if (loadLibrary1(fromClass, file)) {
return true;
}
final File libfile = ClassLoaderHelper.mapAlternativeName(file);
if (libfile != null && loadLibrary1(fromClass, libfile)) {
return true;
}
return false;
}
private static boolean loadLibrary1(Class fromClass, final File file) {
boolean exists = AccessController.doPrivileged(
new PrivilegedAction<Object>() {
public Object run() {
return file.exists() ? Boolean.TRUE : null;
}})
!= null;
if (!exists) {
return false;
}
String name;
try {
name = file.getCanonicalPath();
} catch (IOException e) {
return false;
private static boolean loadLibrary0(Class<?> fromClass, final File file) {
// Check to see if we're attempting to access a static library
String name = NativeLibrary.findBuiltinLib(file.getName());
boolean isBuiltin = (name != null);
if (!isBuiltin) {
boolean exists = AccessController.doPrivileged(
new PrivilegedAction<Object>() {
public Object run() {
return file.exists() ? Boolean.TRUE : null;
}})
!= null;
if (!exists) {
return false;
}
try {
name = file.getCanonicalPath();
} catch (IOException e) {
return false;
}
}
ClassLoader loader =
(fromClass == null) ? null : fromClass.getClassLoader();
@ -1969,14 +1949,14 @@ public abstract class ClassLoader {
}
}
}
NativeLibrary lib = new NativeLibrary(fromClass, name);
NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin);
nativeLibraryContext.push(lib);
try {
lib.load(name);
lib.load(name, isBuiltin);
} finally {
nativeLibraryContext.pop();
}
if (lib.handle != 0) {
if (lib.loaded) {
loadedLibraryNames.addElement(name);
libs.addElement(lib);
return true;
@ -2032,7 +2012,7 @@ public abstract class ClassLoader {
* in the future will have assertions enabled or disabled by default.
* This setting may be overridden on a per-package or per-class basis by
* invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
* #setClassAssertionStatus(String, boolean)}. </p>
* #setClassAssertionStatus(String, boolean)}.
*
* @param enabled
* <tt>true</tt> if classes loaded by this class loader will
@ -2134,7 +2114,6 @@ public abstract class ClassLoader {
* status settings associated with the class loader. This method is
* provided so that class loaders can be made to ignore any command line or
* persistent assertion status settings and "start with a clean slate."
* </p>
*
* @since 1.4
*/
@ -2251,8 +2230,8 @@ class SystemClassLoaderAction
return parent;
}
Constructor ctor = Class.forName(cls, true, parent)
.getDeclaredConstructor(new Class[] { ClassLoader.class });
Constructor<?> ctor = Class.forName(cls, true, parent)
.getDeclaredConstructor(new Class<?>[] { ClassLoader.class });
ClassLoader sys = (ClassLoader) ctor.newInstance(
new Object[] { parent });
Thread.currentThread().setContextClassLoader(sys);

View File

@ -0,0 +1,85 @@
/*
Copyright (C) 2009-2015 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
package java.lang;
import cli.System.Runtime.Serialization.IObjectReference;
import cli.System.Runtime.Serialization.SerializationException;
import cli.System.Runtime.Serialization.StreamingContext;
@cli.System.SerializableAttribute.Annotation
final class ClassSerializationProxy implements IObjectReference
{
private cli.System.Type type;
private String sig;
@cli.System.Security.SecurityCriticalAttribute.Annotation
public Object GetRealObject(StreamingContext context)
{
if (sig != null)
{
if (sig.length() == 1)
{
switch (sig.charAt(0))
{
case 'B':
return Byte.TYPE;
case 'C':
return Character.TYPE;
case 'D':
return Double.TYPE;
case 'F':
return Float.TYPE;
case 'I':
return Integer.TYPE;
case 'J':
return Long.TYPE;
case 'S':
return Short.TYPE;
case 'Z':
return Boolean.TYPE;
case 'V':
return Void.TYPE;
}
}
String className;
if (sig.charAt(0) == 'L')
{
className = sig.substring(1, sig.length() - 1);
}
else
{
className = sig;
}
try
{
return Class.forName(className, false, Thread.currentThread().getContextClassLoader());
}
catch (ClassNotFoundException x)
{
ikvm.runtime.Util.throwException(new SerializationException(x.getMessage(), x));
}
}
return ikvm.runtime.Util.getClassFromTypeHandle(type.get_TypeHandle());
}
}

View File

@ -1 +1 @@
98f7816c72a28907d154c1848447b1fda97ef6ca
de318623b06f63349c8a73909bc6fac4716b99ec

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,24 +25,30 @@
package java.lang;
import java.io.*;
import java.lang.reflect.Executable;
import java.lang.annotation.Annotation;
import java.security.AccessControlContext;
import java.util.Properties;
import java.util.PropertyPermission;
import java.util.StringTokenizer;
import java.util.Map;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.AllPermission;
import java.nio.channels.Channel;
import java.nio.channels.spi.SelectorProvider;
import sun.nio.ch.Interruptible;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
import sun.reflect.annotation.AnnotationType;
final class StdIO
{
private StdIO() { }
static InputStream in = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
static PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out), 128), true);
static PrintStream err = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err), 128), true);
static PrintStream out = System.newPrintStream(new FileOutputStream(FileDescriptor.out), Props.props.getProperty("sun.stdout.encoding"));
static PrintStream err = System.newPrintStream(new FileOutputStream(FileDescriptor.err), Props.props.getProperty("sun.stderr.encoding"));
}
final class Props
@ -85,6 +91,18 @@ final class Props
*/
public final class System {
/* register the natives via the static initializer.
*
* VM will invoke the initializeSystemClass method to complete
* the initialization for this class separated from clinit.
* Note that to use properties set by the VM, see the constraints
* described in the initializeSystemClass method.
*/
private static native void registerNatives();
static {
//registerNatives();
}
/** Don't let anyone instantiate this class */
private System() {
}
@ -96,10 +114,8 @@ public final class System {
* the host environment or user.
*/
@ikvm.lang.Property(get="get_in")
public final static InputStream in;
static { in = null; }
public final static InputStream in = null;
private static InputStream get_in()
{
return StdIO.in;
@ -131,10 +147,8 @@ public final class System {
* @see java.io.PrintStream#println(java.lang.String)
*/
@ikvm.lang.Property(get="get_out")
public final static PrintStream out;
static { out = null; }
public final static PrintStream out = null;
private static PrintStream get_out()
{
return StdIO.out;
@ -153,9 +167,7 @@ public final class System {
* destination that is typically not continuously monitored.
*/
@ikvm.lang.Property(get="get_err")
public final static PrintStream err;
static { err = null ; }
public final static PrintStream err = null;
private static PrintStream get_err()
{
@ -164,7 +176,7 @@ public final class System {
/* The security manager for the system.
*/
private static volatile SecurityManager security;
private static volatile SecurityManager security = null;
/**
* Reassigns the "standard" input stream.
@ -188,7 +200,7 @@ public final class System {
*/
public static void setIn(InputStream in) {
checkIO();
StdIO.in = in;
setIn0(in);
}
/**
@ -212,7 +224,7 @@ public final class System {
*/
public static void setOut(PrintStream out) {
checkIO();
StdIO.out = out;
setOut0(out);
}
/**
@ -236,10 +248,10 @@ public final class System {
*/
public static void setErr(PrintStream err) {
checkIO();
StdIO.err = err;
setErr0(err);
}
private static volatile Console cons;
private static volatile Console cons = null;
/**
* Returns the unique {@link java.io.Console Console} object associated
* with the current Java virtual machine, if any.
@ -293,6 +305,10 @@ public final class System {
}
}
private static native void setIn0(InputStream in);
private static native void setOut0(PrintStream out);
private static native void setErr0(PrintStream err);
/**
* Sets the System security.
*
@ -576,7 +592,12 @@ public final class System {
* </dl>
*/
//private static native Properties initProperties(Properties props);
@ikvm.lang.Property(get="get_props", set="set_props")
private static Properties props;
private static native Properties initProperties(Properties props);
private static Properties get_props() { return Props.props; }
private static void set_props(Properties value) { Props.props = value; }
/**
* Determines the current system properties.
@ -597,7 +618,7 @@ public final class System {
* <tr><td><code>java.version</code></td>
* <td>Java Runtime Environment version</td></tr>
* <tr><td><code>java.vendor</code></td>
* <td>Java Runtime Environment vendor</td></tr
* <td>Java Runtime Environment vendor</td></tr>
* <tr><td><code>java.vendor.url</code></td>
* <td>Java vendor URL</td></tr>
* <tr><td><code>java.home</code></td>
@ -631,7 +652,10 @@ public final class System {
* <tr><td><code>java.compiler</code></td>
* <td>Name of JIT compiler to use</td></tr>
* <tr><td><code>java.ext.dirs</code></td>
* <td>Path of extension directory or directories</td></tr>
* <td>Path of extension directory or directories
* <b>Deprecated.</b> <i>This property, and the mechanism
* which implements it, may be removed in a future
* release.</i> </td></tr>
* <tr><td><code>os.name</code></td>
* <td>Operating system name</td></tr>
* <tr><td><code>os.arch</code></td>
@ -674,7 +698,7 @@ public final class System {
sm.checkPropertiesAccess();
}
return Props.props;
return props;
}
/**
@ -684,11 +708,20 @@ public final class System {
*
* <p>On UNIX systems, it returns {@code "\n"}; on Microsoft
* Windows systems it returns {@code "\r\n"}.
*
* @return the system-dependent line separator string
* @since 1.7
*/
public static String lineSeparator() {
return Props.lineSeparator;
return lineSeparator;
}
@ikvm.lang.Property(get="get_lineSeparator", set="set_lineSeparator")
private static String lineSeparator;
private static String get_lineSeparator() { return Props.lineSeparator; }
private static void set_lineSeparator(String value) { Props.lineSeparator = value; }
/**
* Sets the system properties to the <code>Properties</code>
* argument.
@ -718,9 +751,9 @@ public final class System {
}
if (props == null) {
props = new Properties();
VMSystemProperties.initProperties(props);
initProperties(props);
}
Props.props = props;
System.props = props;
}
/**
@ -756,7 +789,7 @@ public final class System {
sm.checkPropertyAccess(key);
}
return Props.props.getProperty(key);
return props.getProperty(key);
}
/**
@ -792,7 +825,7 @@ public final class System {
sm.checkPropertyAccess(key);
}
return Props.props.getProperty(key, def);
return props.getProperty(key, def);
}
/**
@ -832,7 +865,7 @@ public final class System {
SecurityConstants.PROPERTY_WRITE_ACTION));
}
return (String) Props.props.setProperty(key, value);
return (String) props.setProperty(key, value);
}
/**
@ -869,7 +902,7 @@ public final class System {
sm.checkPermission(new PropertyPermission(key, "write"));
}
return (String) Props.props.remove(key);
return (String) props.remove(key);
}
private static void checkKey(String key) {
@ -1081,13 +1114,25 @@ public final class System {
*/
@Deprecated
public static void runFinalizersOnExit(boolean value) {
Runtime.getRuntime().runFinalizersOnExit(value);
Runtime.runFinalizersOnExit(value);
}
/**
* Loads a code file with the specified filename from the local file
* system as a dynamic library. The filename
* argument must be a complete path name.
* Loads the native library specified by the filename argument. The filename
* argument must be an absolute path name.
*
* If the filename argument, when stripped of any platform-specific library
* prefix, path, and file extension, indicates a library whose name is,
* for example, L, and a native library called L is statically linked
* with the VM, then the JNI_OnLoad_L function exported by the library
* is invoked rather than attempting to load a dynamic library.
* A filename matching the argument does not have to exist in the
* file system.
* See the JNI Specification for more details.
*
* Otherwise, the filename argument is mapped to a native library image in
* an implementation-dependent manner.
*
* <p>
* The call <code>System.load(name)</code> is effectively equivalent
* to the call:
@ -1099,7 +1144,10 @@ public final class System {
* @exception SecurityException if a security manager exists and its
* <code>checkLink</code> method doesn't allow
* loading of the specified dynamic library
* @exception UnsatisfiedLinkError if the file does not exist.
* @exception UnsatisfiedLinkError if either the filename is not an
* absolute path name, the native library is not statically
* linked with the VM, or the library cannot be mapped to
* a native library image by the host system.
* @exception NullPointerException if <code>filename</code> is
* <code>null</code>
* @see java.lang.Runtime#load(java.lang.String)
@ -1111,9 +1159,16 @@ public final class System {
}
/**
* Loads the system library specified by the <code>libname</code>
* argument. The manner in which a library name is mapped to the
* actual system library is system dependent.
* Loads the native library specified by the <code>libname</code>
* argument. The <code>libname</code> argument must not contain any platform
* specific prefix, file extension or path. If a native library
* called <code>libname</code> is statically linked with the VM, then the
* JNI_OnLoad_<code>libname</code> function exported by the library is invoked.
* See the JNI Specification for more details.
*
* Otherwise, the libname argument is loaded from a system library
* location and mapped to a native library image in an implementation-
* dependent manner.
* <p>
* The call <code>System.loadLibrary(name)</code> is effectively
* equivalent to the call
@ -1125,7 +1180,10 @@ public final class System {
* @exception SecurityException if a security manager exists and its
* <code>checkLink</code> method doesn't allow
* loading of the specified dynamic library
* @exception UnsatisfiedLinkError if the library does not exist.
* @exception UnsatisfiedLinkError if either the libname argument
* contains a file path, the native library is not statically
* linked with the VM, or the library cannot be mapped to a
* native library image by the host system.
* @exception NullPointerException if <code>libname</code> is
* <code>null</code>
* @see java.lang.Runtime#loadLibrary(java.lang.String)
@ -1148,21 +1206,17 @@ public final class System {
* @see java.lang.ClassLoader#findLibrary(java.lang.String)
* @since 1.2
*/
public static String mapLibraryName(String libname) {
if (libname == null) {
throw new NullPointerException();
public static native String mapLibraryName(String libname);
/**
* Create PrintStream for stdout/err based on encoding.
*/
/*private*/ static PrintStream newPrintStream(FileOutputStream fos, String enc) {
if (enc != null) {
try {
return new PrintStream(new BufferedOutputStream(fos, 128), true, enc);
} catch (UnsupportedEncodingException uee) {}
}
if (ikvm.internal.Util.WINDOWS) {
return libname + ".dll";
} else if (ikvm.internal.Util.MACOSX) {
return "lib" + libname + ".jnilib";
} else {
return "lib" + libname + ".so";
}
}
/* returns the class of the caller. */
static Class<?> getCallerClass() {
// NOTE use of more generic Reflection.getCallerClass()
return Reflection.getCallerClass(3);
return new PrintStream(new BufferedOutputStream(fos, 128), true);
}
}

View File

@ -1 +1 @@
0ed6057830f61276302f31aec193002ca38ab39a
1341a0148621a18e4c88e2815a5d0e8f837fa015

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2004-2011 Jeroen Frijters
Copyright (C) 2004-2015 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -24,6 +24,7 @@
package java.lang;
import java.util.Properties;
import cli.System.Diagnostics.FileVersionInfo;
import static ikvm.internal.Util.SafeGetEnvironmentVariable;
final class VMSystemProperties
@ -31,7 +32,7 @@ final class VMSystemProperties
private VMSystemProperties() { }
public static final String SPEC_TITLE = "Java Platform API Specification";
public static final String SPEC_VERSION = "1.7";
public static final String SPEC_VERSION = "1.8";
public static final String SPEC_VENDOR = "Oracle Corporation";
private static String getLibraryPath()
@ -114,11 +115,11 @@ final class VMSystemProperties
private static void initCommonProperties(Properties p)
{
p.setProperty("java.version", "1.7.0");
p.setProperty("java.version", "1.8.0");
p.setProperty("java.vendor", "Jeroen Frijters");
p.setProperty("java.vendor.url", "http://ikvm.net/");
p.setProperty("java.vendor.url.bug", "http://www.ikvm.net/bugs");
p.setProperty("java.vm.specification.version", "1.7");
p.setProperty("java.vm.specification.version", "1.8");
p.setProperty("java.vm.specification.vendor", "Oracle Corporation");
p.setProperty("java.vm.specification.name", "Java Virtual Machine Specification");
p.setProperty("java.vm.version", PropertyConstants.java_vm_version);
@ -129,7 +130,7 @@ final class VMSystemProperties
p.setProperty("java.specification.version", SPEC_VERSION);
p.setProperty("java.specification.vendor", SPEC_VENDOR);
p.setProperty("java.specification.name", SPEC_TITLE);
p.setProperty("java.class.version", "51.0");
p.setProperty("java.class.version", "52.0");
p.setProperty("java.class.path", "");
p.setProperty("java.library.path", getLibraryPath());
try
@ -152,6 +153,13 @@ final class VMSystemProperties
switch(os.get_Platform().Value)
{
case cli.System.PlatformID.Win32NT:
// Windows lies about the version, so we extract the real version from kernel32.dll
FileVersionInfo kernel32 = getKernel32FileVersionInfo();
if (kernel32 != null)
{
major = kernel32.get_ProductMajorPart();
minor = kernel32.get_ProductMinorPart();
}
osname = "Windows NT (unknown)";
switch(major)
{
@ -189,6 +197,23 @@ final class VMSystemProperties
osver = "6.1";
osname = "Windows 7";
break;
case 2:
osver = "6.2";
osname = "Windows 8";
break;
case 3:
osver = "6.3";
osname = "Windows 8.1";
break;
}
break;
case 10:
switch(minor)
{
case 0:
osver = "10.0";
osname = "Windows 10";
break;
}
break;
}
@ -322,12 +347,32 @@ final class VMSystemProperties
p.setProperty("sun.nio.MaxDirectMemorySize", "-1");
p.setProperty("java.awt.graphicsenv", PropertyConstants.java_awt_graphicsenv);
p.setProperty("java.awt.printerjob", "sun.awt.windows.WPrinterJob");
String stdoutEncoding = getStdoutEncoding();
if(stdoutEncoding != null)
{
p.setProperty("sun.stdout.encoding", stdoutEncoding);
}
String stderrEncoding = getStderrEncoding();
if(stderrEncoding != null)
{
p.setProperty("sun.stderr.encoding", stderrEncoding);
}
if(ikvm.internal.Util.MACOSX)
{
p.setProperty("sun.jnu.encoding", "UTF-8");
}
else
{
p.setProperty("sun.jnu.encoding", cli.System.Text.Encoding.get_Default().get_WebName());
}
// TODO
// sun.cpu.isalist:=pentium_pro+mmx pentium_pro pentium+mmx pentium i486 i386 i86
// sun.desktop:=windows
// sun.io.unicode.encoding:=UnicodeLittle
// sun.jnu.encoding:=Cp1252
// sun.management.compiler:=HotSpot Client Compiler
try
{
@ -418,4 +463,7 @@ final class VMSystemProperties
private static native String getVirtualFileSystemRoot();
private static native String getBootClassPath();
private static native String getStdoutEncoding();
private static native String getStderrEncoding();
private static native FileVersionInfo getKernel32FileVersionInfo();
}

View File

@ -0,0 +1,47 @@
/*
Copyright (C) 2015 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
package java.lang.invoke;
/*
* This class represents a MethodHandle to an IKVM specific LambdaForm.
*/
final class LightWeightMethodHandle extends MethodHandle
{
LightWeightMethodHandle(MethodType type, LambdaForm form)
{
super(type, form);
}
@Override
BoundMethodHandle rebind()
{
return BoundMethodHandle.makeReinvoker(this);
}
@Override
MethodHandle copyWith(MethodType type, LambdaForm form)
{
return new LightWeightMethodHandle(type, form);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,15 +28,14 @@ package java.lang.reflect;
import sun.reflect.CallerSensitive;
import sun.reflect.ConstructorAccessor;
import sun.reflect.Reflection;
import sun.reflect.annotation.TypeAnnotation;
import sun.reflect.annotation.TypeAnnotationParser;
import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.factory.CoreReflectionFactory;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.scope.ConstructorScope;
import java.lang.annotation.Annotation;
import java.util.Map;
import sun.reflect.annotation.AnnotationParser;
import java.lang.annotation.AnnotationFormatError;
import java.lang.reflect.Modifier;
/**
* {@code Constructor} provides information about, and access to, a single
@ -58,11 +57,7 @@ import java.lang.reflect.Modifier;
* @author Kenneth Russell
* @author Nakul Saraiya
*/
public final
class Constructor<T> extends AccessibleObject implements
GenericDeclaration,
Member {
public final class Constructor<T> extends Executable {
private Class<T> clazz;
private int slot;
private Class<?>[] parameterTypes;
@ -81,7 +76,8 @@ public final
}
// Accessor for generic info repository
private ConstructorRepository getGenericInfo() {
@Override
ConstructorRepository getGenericInfo() {
// lazily initialize repository if necessary
if (genericInfo == null) {
// create and cache generic info repository
@ -96,8 +92,19 @@ public final
// For sharing of ConstructorAccessors. This branching structure
// is currently only two levels deep (i.e., one root Constructor
// and potentially many Constructor objects pointing to it.)
//
// If this branching structure would ever contain cycles, deadlocks can
// occur in annotation code.
private Constructor<T> root;
/**
* Used by Excecutable for annotation sharing.
*/
@Override
Executable getRoot() {
return root;
}
/**
* Package-private constructor used by ReflectAccess to enable
* instantiation of these objects in Java code from the java.lang
@ -110,8 +117,7 @@ public final
int slot,
String signature,
byte[] unused1,
byte[] unused2)
{
byte[] unused2) {
this.clazz = declaringClass;
this.parameterTypes = parameterTypes;
this.exceptionTypes = checkedExceptions;
@ -133,22 +139,30 @@ public final
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects.)
if (this.root != null)
throw new IllegalArgumentException("Can not copy a non-root Constructor");
Constructor<T> res = new Constructor<>(clazz,
parameterTypes,
exceptionTypes, modifiers, slot,
signature,
null,
null);
parameterTypes,
exceptionTypes, modifiers, slot,
signature,
null,
null);
res.root = this;
// Might as well eagerly propagate this if already present
res.constructorAccessor = constructorAccessor;
return res;
}
@Override
boolean hasGenericInformation() {
return (getSignature() != null);
}
/**
* Returns the {@code Class} object representing the class that declares
* the constructor represented by this {@code Constructor} object.
* {@inheritDoc}
*/
@Override
public Class<T> getDeclaringClass() {
return clazz;
}
@ -157,36 +171,26 @@ public final
* Returns the name of this constructor, as a string. This is
* the binary name of the constructor's declaring class.
*/
@Override
public String getName() {
return getDeclaringClass().getName();
}
/**
* Returns the Java language modifiers for the constructor
* represented by this {@code Constructor} object, as an integer. The
* {@code Modifier} class should be used to decode the modifiers.
*
* @see Modifier
* {@inheritDoc}
*/
@Override
public int getModifiers() {
return modifiers;
}
/**
* Returns an array of {@code TypeVariable} objects that represent the
* type variables declared by the generic declaration represented by this
* {@code GenericDeclaration} object, in declaration order. Returns an
* array of length 0 if the underlying generic declaration declares no type
* variables.
*
* @return an array of {@code TypeVariable} objects that represent
* the type variables declared by this generic declaration
* @throws GenericSignatureFormatError if the generic
* signature of this generic declaration does not conform to
* the format specified in
* <cite>The Java&trade; Virtual Machine Specification</cite>
* {@inheritDoc}
* @throws GenericSignatureFormatError {@inheritDoc}
* @since 1.5
*/
@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public TypeVariable<Constructor<T>>[] getTypeParameters() {
if (getSignature() != null) {
return (TypeVariable<Constructor<T>>[])getGenericInfo().getTypeParameters();
@ -196,98 +200,50 @@ public final
/**
* Returns an array of {@code Class} objects that represent the formal
* parameter types, in declaration order, of the constructor
* represented by this {@code Constructor} object. Returns an array of
* length 0 if the underlying constructor takes no parameters.
*
* @return the parameter types for the constructor this object
* represents
* {@inheritDoc}
*/
@Override
public Class<?>[] getParameterTypes() {
return (Class<?>[]) parameterTypes.clone();
return parameterTypes.clone();
}
/**
* {@inheritDoc}
*/
public int getParameterCount() { return parameterTypes.length; }
/**
* Returns an array of {@code Type} objects that represent the formal
* parameter types, in declaration order, of the method represented by
* this {@code Constructor} object. Returns an array of length 0 if the
* underlying method takes no parameters.
*
* <p>If a formal parameter type is a parameterized type,
* the {@code Type} object returned for it must accurately reflect
* the actual type parameters used in the source code.
*
* <p>If a formal parameter type is a type variable or a parameterized
* type, it is created. Otherwise, it is resolved.
*
* @return an array of {@code Type}s that represent the formal
* parameter types of the underlying method, in declaration order
* @throws GenericSignatureFormatError
* if the generic method signature does not conform to the format
* specified in
* <cite>The Java&trade; Virtual Machine Specification</cite>
* @throws TypeNotPresentException if any of the parameter
* types of the underlying method refers to a non-existent type
* declaration
* @throws MalformedParameterizedTypeException if any of
* the underlying method's parameter types refer to a parameterized
* type that cannot be instantiated for any reason
* {@inheritDoc}
* @throws GenericSignatureFormatError {@inheritDoc}
* @throws TypeNotPresentException {@inheritDoc}
* @throws MalformedParameterizedTypeException {@inheritDoc}
* @since 1.5
*/
@Override
public Type[] getGenericParameterTypes() {
if (getSignature() != null)
return getGenericInfo().getParameterTypes();
else
return getParameterTypes();
return super.getGenericParameterTypes();
}
/**
* Returns an array of {@code Class} objects that represent the types
* of exceptions declared to be thrown by the underlying constructor
* represented by this {@code Constructor} object. Returns an array of
* length 0 if the constructor declares no exceptions in its {@code throws} clause.
*
* @return the exception types declared as being thrown by the
* constructor this object represents
* {@inheritDoc}
*/
@Override
public Class<?>[] getExceptionTypes() {
return (Class<?>[])exceptionTypes.clone();
return exceptionTypes.clone();
}
/**
* Returns an array of {@code Type} objects that represent the
* exceptions declared to be thrown by this {@code Constructor} object.
* Returns an array of length 0 if the underlying method declares
* no exceptions in its {@code throws} clause.
*
* <p>If an exception type is a type variable or a parameterized
* type, it is created. Otherwise, it is resolved.
*
* @return an array of Types that represent the exception types
* thrown by the underlying method
* @throws GenericSignatureFormatError
* if the generic method signature does not conform to the format
* specified in
* <cite>The Java&trade; Virtual Machine Specification</cite>
* @throws TypeNotPresentException if the underlying method's
* {@code throws} clause refers to a non-existent type declaration
* @throws MalformedParameterizedTypeException if
* the underlying method's {@code throws} clause refers to a
* parameterized type that cannot be instantiated for any reason
* {@inheritDoc}
* @throws GenericSignatureFormatError {@inheritDoc}
* @throws TypeNotPresentException {@inheritDoc}
* @throws MalformedParameterizedTypeException {@inheritDoc}
* @since 1.5
*/
public Type[] getGenericExceptionTypes() {
Type[] result;
if (getSignature() != null &&
( (result = getGenericInfo().getExceptionTypes()).length > 0 ))
return result;
else
return getExceptionTypes();
}
@Override
public Type[] getGenericExceptionTypes() {
return super.getGenericExceptionTypes();
}
/**
* Compares this {@code Constructor} against the specified object.
@ -299,16 +255,7 @@ public final
if (obj != null && obj instanceof Constructor) {
Constructor<?> other = (Constructor<?>)obj;
if (getDeclaringClass() == other.getDeclaringClass()) {
/* Avoid unnecessary cloning */
Class<?>[] params1 = parameterTypes;
Class<?>[] params2 = other.parameterTypes;
if (params1.length == params2.length) {
for (int i = 0; i < params1.length; i++) {
if (params1[i] != params2[i])
return false;
}
return true;
}
return equalParamTypes(parameterTypes, other.parameterTypes);
}
}
return false;
@ -337,36 +284,20 @@ public final
* modifiers {@code public}, {@code protected} or
* {@code private}. Only one of these may appear, or none if the
* constructor has default (package) access.
*
* @return a string describing this {@code Constructor}
* @jls 8.8.3. Constructor Modifiers
*/
public String toString() {
try {
StringBuffer sb = new StringBuffer();
int mod = getModifiers() & Modifier.constructorModifiers();
if (mod != 0) {
sb.append(Modifier.toString(mod) + " ");
}
sb.append(Field.getTypeName(getDeclaringClass()));
sb.append("(");
Class<?>[] params = parameterTypes; // avoid clone
for (int j = 0; j < params.length; j++) {
sb.append(Field.getTypeName(params[j]));
if (j < (params.length - 1))
sb.append(",");
}
sb.append(")");
Class<?>[] exceptions = exceptionTypes; // avoid clone
if (exceptions.length > 0) {
sb.append(" throws ");
for (int k = 0; k < exceptions.length; k++) {
sb.append(exceptions[k].getName());
if (k < (exceptions.length - 1))
sb.append(",");
}
}
return sb.toString();
} catch (Exception e) {
return "<" + e + ">";
}
return sharedToString(Modifier.constructorModifiers(),
false,
parameterTypes,
exceptionTypes);
}
@Override
void specificToStringHeader(StringBuilder sb) {
sb.append(getDeclaringClass().getTypeName());
}
/**
@ -401,57 +332,16 @@ public final
* include type parameters
*
* @since 1.5
* @jls 8.8.3. Constructor Modifiers
*/
@Override
public String toGenericString() {
try {
StringBuilder sb = new StringBuilder();
int mod = getModifiers() & Modifier.constructorModifiers();
if (mod != 0) {
sb.append(Modifier.toString(mod) + " ");
}
TypeVariable<?>[] typeparms = getTypeParameters();
if (typeparms.length > 0) {
boolean first = true;
sb.append("<");
for(TypeVariable<?> typeparm: typeparms) {
if (!first)
sb.append(",");
// Class objects can't occur here; no need to test
// and call Class.getName().
sb.append(typeparm.toString());
first = false;
}
sb.append("> ");
}
sb.append(Field.getTypeName(getDeclaringClass()));
sb.append("(");
Type[] params = getGenericParameterTypes();
for (int j = 0; j < params.length; j++) {
String param = (params[j] instanceof Class<?>)?
Field.getTypeName((Class<?>)params[j]):
(params[j].toString());
if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
param = param.replaceFirst("\\[\\]$", "...");
sb.append(param);
if (j < (params.length - 1))
sb.append(",");
}
sb.append(")");
Type[] exceptions = getGenericExceptionTypes();
if (exceptions.length > 0) {
sb.append(" throws ");
for (int k = 0; k < exceptions.length; k++) {
sb.append((exceptions[k] instanceof Class)?
((Class<?>)exceptions[k]).getName():
exceptions[k].toString());
if (k < (exceptions.length - 1))
sb.append(",");
}
}
return sb.toString();
} catch (Exception e) {
return "<" + e + ">";
}
return sharedToGenericString(Modifier.constructorModifiers(), false);
}
@Override
void specificToGenericStringHeader(StringBuilder sb) {
specificToStringHeader(sb);
}
/**
@ -519,33 +409,28 @@ public final
if (ca == null) {
ca = acquireConstructorAccessor();
}
return (T) ca.newInstance(initargs);
@SuppressWarnings("unchecked")
T inst = (T) ca.newInstance(initargs);
return inst;
}
/**
* Returns {@code true} if this constructor was declared to take
* a variable number of arguments; returns {@code false}
* otherwise.
*
* @return {@code true} if an only if this constructor was declared to
* take a variable number of arguments.
* {@inheritDoc}
* @since 1.5
*/
@Override
public boolean isVarArgs() {
return (getModifiers() & Modifier.VARARGS) != 0;
return super.isVarArgs();
}
/**
* Returns {@code true} if this constructor is a synthetic
* constructor; returns {@code false} otherwise.
*
* @return true if and only if this constructor is a synthetic
* constructor as defined by
* <cite>The Java&trade; Language Specification</cite>.
* {@inheritDoc}
* @jls 13.1 The Form of a Binary
* @since 1.5
*/
@Override
public boolean isSynthetic() {
return Modifier.isSynthetic(getModifiers());
return super.isSynthetic();
}
// NOTE that there is no synchronization used here. It is correct
@ -589,9 +474,9 @@ public final
return slot;
}
String getSignature() {
return signature;
}
String getSignature() {
return signature;
}
byte[] getRawAnnotations() {
return null;
@ -601,74 +486,77 @@ public final
return null;
}
/**
* @throws NullPointerException {@inheritDoc}
* {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @since 1.5
*/
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
if (annotationClass == null)
throw new NullPointerException();
return (T) declaredAnnotations().get(annotationClass);
return super.getAnnotation(annotationClass);
}
private static final Annotation[] EMPTY_ANNOTATION_ARRAY=new Annotation[0];
/**
* {@inheritDoc}
* @since 1.5
*/
public Annotation[] getDeclaredAnnotations() {
return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
}
private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
if (declaredAnnotations == null) {
declaredAnnotations = Method.getDeclaredAnnotationsImpl(this);
}
return declaredAnnotations;
return super.getDeclaredAnnotations();
}
/**
* Returns an array of arrays that represent the annotations on the formal
* parameters, in declaration order, of the method represented by
* this {@code Constructor} object. (Returns an array of length zero if the
* underlying method is parameterless. If the method has one or more
* parameters, a nested array of length zero is returned for each parameter
* with no annotations.) The annotation objects contained in the returned
* arrays are serializable. The caller of this method is free to modify
* the returned arrays; it will have no effect on the arrays returned to
* other callers.
*
* @return an array of arrays that represent the annotations on the formal
* parameters, in declaration order, of the method represented by this
* Constructor object
* {@inheritDoc}
* @since 1.5
*/
@Override
public Annotation[][] getParameterAnnotations() {
int numParameters = parameterTypes.length;
Annotation[][] result = Method.getParameterAnnotationsImpl(this);
if (result == null)
return new Annotation[numParameters][0];
if (result.length != numParameters) {
Class<?> declaringClass = getDeclaringClass();
if (declaringClass.isEnum() ||
declaringClass.isAnonymousClass() ||
declaringClass.isLocalClass() )
; // Can't do reliable parameter counting
else {
if (!declaringClass.isMemberClass() || // top-level
// Check for the enclosing instance parameter for
// non-static member classes
(declaringClass.isMemberClass() &&
((declaringClass.getModifiers() & Modifier.STATIC) == 0) &&
result.length + 1 != numParameters) ) {
throw new AnnotationFormatError(
"Parameter annotations don't match number of parameters");
}
return sharedGetParameterAnnotations(parameterTypes);
}
@Override
void handleParameterNumberMismatch(int resultLength, int numParameters) {
Class<?> declaringClass = getDeclaringClass();
if (declaringClass.isEnum() ||
declaringClass.isAnonymousClass() ||
declaringClass.isLocalClass() )
return ; // Can't do reliable parameter counting
else {
if (!declaringClass.isMemberClass() || // top-level
// Check for the enclosing instance parameter for
// non-static member classes
(declaringClass.isMemberClass() &&
((declaringClass.getModifiers() & Modifier.STATIC) == 0) &&
resultLength + 1 != numParameters) ) {
throw new AnnotationFormatError(
"Parameter annotations don't match number of parameters");
}
}
return result;
}
/**
* {@inheritDoc}
* @since 1.8
*/
@Override
public AnnotatedType getAnnotatedReturnType() {
return getAnnotatedReturnType0(getDeclaringClass());
}
/**
* {@inheritDoc}
* @since 1.8
*/
@Override
public AnnotatedType getAnnotatedReceiverType() {
if (getDeclaringClass().getEnclosingClass() == null)
return super.getAnnotatedReceiverType();
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
this,
getDeclaringClass(),
getDeclaringClass().getEnclosingClass(),
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
}
}

View File

@ -0,0 +1,720 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.reflect;
import java.lang.annotation.*;
import java.util.Map;
import java.util.Objects;
import sun.reflect.annotation.AnnotationParser;
import sun.reflect.annotation.AnnotationSupport;
import sun.reflect.annotation.TypeAnnotationParser;
import sun.reflect.annotation.TypeAnnotation;
import sun.reflect.generics.repository.ConstructorRepository;
/**
* A shared superclass for the common functionality of {@link Method}
* and {@link Constructor}.
*
* @since 1.8
*/
public abstract class Executable extends AccessibleObject
implements Member, GenericDeclaration {
/*
* Only grant package-visibility to the constructor.
*/
Executable() {}
/**
* Accessor method to allow code sharing
*/
abstract Executable getRoot();
/**
* Does the Executable have generic information.
*/
abstract boolean hasGenericInformation();
abstract ConstructorRepository getGenericInfo();
boolean equalParamTypes(Class<?>[] params1, Class<?>[] params2) {
/* Avoid unnecessary cloning */
if (params1.length == params2.length) {
for (int i = 0; i < params1.length; i++) {
if (params1[i] != params2[i])
return false;
}
return true;
}
return false;
}
void separateWithCommas(Class<?>[] types, StringBuilder sb) {
for (int j = 0; j < types.length; j++) {
sb.append(types[j].getTypeName());
if (j < (types.length - 1))
sb.append(",");
}
}
void printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault) {
int mod = getModifiers() & mask;
if (mod != 0 && !isDefault) {
sb.append(Modifier.toString(mod)).append(' ');
} else {
int access_mod = mod & Modifier.ACCESS_MODIFIERS;
if (access_mod != 0)
sb.append(Modifier.toString(access_mod)).append(' ');
if (isDefault)
sb.append("default ");
mod = (mod & ~Modifier.ACCESS_MODIFIERS);
if (mod != 0)
sb.append(Modifier.toString(mod)).append(' ');
}
}
String sharedToString(int modifierMask,
boolean isDefault,
Class<?>[] parameterTypes,
Class<?>[] exceptionTypes) {
try {
StringBuilder sb = new StringBuilder();
printModifiersIfNonzero(sb, modifierMask, isDefault);
specificToStringHeader(sb);
sb.append('(');
separateWithCommas(parameterTypes, sb);
sb.append(')');
if (exceptionTypes.length > 0) {
sb.append(" throws ");
separateWithCommas(exceptionTypes, sb);
}
return sb.toString();
} catch (Exception e) {
return "<" + e + ">";
}
}
/**
* Generate toString header information specific to a method or
* constructor.
*/
abstract void specificToStringHeader(StringBuilder sb);
String sharedToGenericString(int modifierMask, boolean isDefault) {
try {
StringBuilder sb = new StringBuilder();
printModifiersIfNonzero(sb, modifierMask, isDefault);
TypeVariable<?>[] typeparms = getTypeParameters();
if (typeparms.length > 0) {
boolean first = true;
sb.append('<');
for(TypeVariable<?> typeparm: typeparms) {
if (!first)
sb.append(',');
// Class objects can't occur here; no need to test
// and call Class.getName().
sb.append(typeparm.toString());
first = false;
}
sb.append("> ");
}
specificToGenericStringHeader(sb);
sb.append('(');
Type[] params = getGenericParameterTypes();
for (int j = 0; j < params.length; j++) {
String param = params[j].getTypeName();
if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
param = param.replaceFirst("\\[\\]$", "...");
sb.append(param);
if (j < (params.length - 1))
sb.append(',');
}
sb.append(')');
Type[] exceptions = getGenericExceptionTypes();
if (exceptions.length > 0) {
sb.append(" throws ");
for (int k = 0; k < exceptions.length; k++) {
sb.append((exceptions[k] instanceof Class)?
((Class)exceptions[k]).getName():
exceptions[k].toString());
if (k < (exceptions.length - 1))
sb.append(',');
}
}
return sb.toString();
} catch (Exception e) {
return "<" + e + ">";
}
}
/**
* Generate toGenericString header information specific to a
* method or constructor.
*/
abstract void specificToGenericStringHeader(StringBuilder sb);
/**
* Returns the {@code Class} object representing the class or interface
* that declares the executable represented by this object.
*/
public abstract Class<?> getDeclaringClass();
/**
* Returns the name of the executable represented by this object.
*/
public abstract String getName();
/**
* Returns the Java language {@linkplain Modifier modifiers} for
* the executable represented by this object.
*/
public abstract int getModifiers();
/**
* Returns an array of {@code TypeVariable} objects that represent the
* type variables declared by the generic declaration represented by this
* {@code GenericDeclaration} object, in declaration order. Returns an
* array of length 0 if the underlying generic declaration declares no type
* variables.
*
* @return an array of {@code TypeVariable} objects that represent
* the type variables declared by this generic declaration
* @throws GenericSignatureFormatError if the generic
* signature of this generic declaration does not conform to
* the format specified in
* <cite>The Java&trade; Virtual Machine Specification</cite>
*/
public abstract TypeVariable<?>[] getTypeParameters();
/**
* Returns an array of {@code Class} objects that represent the formal
* parameter types, in declaration order, of the executable
* represented by this object. Returns an array of length
* 0 if the underlying executable takes no parameters.
*
* @return the parameter types for the executable this object
* represents
*/
public abstract Class<?>[] getParameterTypes();
/**
* Returns the number of formal parameters (whether explicitly
* declared or implicitly declared or neither) for the executable
* represented by this object.
*
* @since 1.8
* @return The number of formal parameters for the executable this
* object represents
*/
public int getParameterCount() {
throw new AbstractMethodError();
}
/**
* Returns an array of {@code Type} objects that represent the formal
* parameter types, in declaration order, of the executable represented by
* this object. Returns an array of length 0 if the
* underlying executable takes no parameters.
*
* <p>If a formal parameter type is a parameterized type,
* the {@code Type} object returned for it must accurately reflect
* the actual type parameters used in the source code.
*
* <p>If a formal parameter type is a type variable or a parameterized
* type, it is created. Otherwise, it is resolved.
*
* @return an array of {@code Type}s that represent the formal
* parameter types of the underlying executable, in declaration order
* @throws GenericSignatureFormatError
* if the generic method signature does not conform to the format
* specified in
* <cite>The Java&trade; Virtual Machine Specification</cite>
* @throws TypeNotPresentException if any of the parameter
* types of the underlying executable refers to a non-existent type
* declaration
* @throws MalformedParameterizedTypeException if any of
* the underlying executable's parameter types refer to a parameterized
* type that cannot be instantiated for any reason
*/
public Type[] getGenericParameterTypes() {
if (hasGenericInformation())
return getGenericInfo().getParameterTypes();
else
return getParameterTypes();
}
/**
* Behaves like {@code getGenericParameterTypes}, but returns type
* information for all parameters, including synthetic parameters.
*/
Type[] getAllGenericParameterTypes() {
final boolean genericInfo = hasGenericInformation();
// Easy case: we don't have generic parameter information. In
// this case, we just return the result of
// getParameterTypes().
if (!genericInfo) {
return getParameterTypes();
} else {
final boolean realParamData = hasRealParameterData();
final Type[] genericParamTypes = getGenericParameterTypes();
final Type[] nonGenericParamTypes = getParameterTypes();
final Type[] out = new Type[nonGenericParamTypes.length];
final Parameter[] params = getParameters();
int fromidx = 0;
// If we have real parameter data, then we use the
// synthetic and mandate flags to our advantage.
if (realParamData) {
for (int i = 0; i < out.length; i++) {
final Parameter param = params[i];
if (param.isSynthetic() || param.isImplicit()) {
// If we hit a synthetic or mandated parameter,
// use the non generic parameter info.
out[i] = nonGenericParamTypes[i];
} else {
// Otherwise, use the generic parameter info.
out[i] = genericParamTypes[fromidx];
fromidx++;
}
}
} else {
// Otherwise, use the non-generic parameter data.
// Without method parameter reflection data, we have
// no way to figure out which parameters are
// synthetic/mandated, thus, no way to match up the
// indexes.
return genericParamTypes.length == nonGenericParamTypes.length ?
genericParamTypes : nonGenericParamTypes;
}
return out;
}
}
/**
* Returns an array of {@code Parameter} objects that represent
* all the parameters to the underlying executable represented by
* this object. Returns an array of length 0 if the executable
* has no parameters.
*
* <p>The parameters of the underlying executable do not necessarily
* have unique names, or names that are legal identifiers in the
* Java programming language (JLS 3.8).
*
* @since 1.8
* @throws MalformedParametersException if the class file contains
* a MethodParameters attribute that is improperly formatted.
* @return an array of {@code Parameter} objects representing all
* the parameters to the executable this object represents.
*/
public Parameter[] getParameters() {
// TODO: This may eventually need to be guarded by security
// mechanisms similar to those in Field, Method, etc.
//
// Need to copy the cached array to prevent users from messing
// with it. Since parameters are immutable, we can
// shallow-copy.
return privateGetParameters().clone();
}
private Parameter[] synthesizeAllParams() {
final int realparams = getParameterCount();
final Parameter[] out = new Parameter[realparams];
for (int i = 0; i < realparams; i++)
// TODO: is there a way to synthetically derive the
// modifiers? Probably not in the general case, since
// we'd have no way of knowing about them, but there
// may be specific cases.
out[i] = new Parameter("arg" + i, 0, this, i);
return out;
}
private void verifyParameters(final Parameter[] parameters) {
final int mask = Modifier.FINAL | Modifier.SYNTHETIC | Modifier.MANDATED;
if (getParameterTypes().length != parameters.length)
throw new MalformedParametersException("Wrong number of parameters in MethodParameters attribute");
for (Parameter parameter : parameters) {
final String name = parameter.getRealName();
final int mods = parameter.getModifiers();
if (name != null) {
if (name.isEmpty() || name.indexOf('.') != -1 ||
name.indexOf(';') != -1 || name.indexOf('[') != -1 ||
name.indexOf('/') != -1) {
throw new MalformedParametersException("Invalid parameter name \"" + name + "\"");
}
}
if (mods != (mods & mask)) {
throw new MalformedParametersException("Invalid parameter modifiers");
}
}
}
private Parameter[] privateGetParameters() {
// Use tmp to avoid multiple writes to a volatile.
Parameter[] tmp = parameters;
if (tmp == null) {
// Otherwise, go to the JVM to get them
try {
tmp = getParameters0();
} catch(IllegalArgumentException e) {
// Rethrow ClassFormatErrors
throw new MalformedParametersException("Invalid constant pool index");
}
// If we get back nothing, then synthesize parameters
if (tmp == null) {
hasRealParameterData = false;
tmp = synthesizeAllParams();
} else {
hasRealParameterData = true;
verifyParameters(tmp);
}
parameters = tmp;
}
return tmp;
}
boolean hasRealParameterData() {
// If this somehow gets called before parameters gets
// initialized, force it into existence.
if (parameters == null) {
privateGetParameters();
}
return hasRealParameterData;
}
private transient volatile boolean hasRealParameterData;
private transient volatile Parameter[] parameters;
private native Parameter[] getParameters0();
native byte[] getTypeAnnotationBytes0();
// Needed by reflectaccess
byte[] getTypeAnnotationBytes() {
return getTypeAnnotationBytes0();
}
/**
* Returns an array of {@code Class} objects that represent the
* types of exceptions declared to be thrown by the underlying
* executable represented by this object. Returns an array of
* length 0 if the executable declares no exceptions in its {@code
* throws} clause.
*
* @return the exception types declared as being thrown by the
* executable this object represents
*/
public abstract Class<?>[] getExceptionTypes();
/**
* Returns an array of {@code Type} objects that represent the
* exceptions declared to be thrown by this executable object.
* Returns an array of length 0 if the underlying executable declares
* no exceptions in its {@code throws} clause.
*
* <p>If an exception type is a type variable or a parameterized
* type, it is created. Otherwise, it is resolved.
*
* @return an array of Types that represent the exception types
* thrown by the underlying executable
* @throws GenericSignatureFormatError
* if the generic method signature does not conform to the format
* specified in
* <cite>The Java&trade; Virtual Machine Specification</cite>
* @throws TypeNotPresentException if the underlying executable's
* {@code throws} clause refers to a non-existent type declaration
* @throws MalformedParameterizedTypeException if
* the underlying executable's {@code throws} clause refers to a
* parameterized type that cannot be instantiated for any reason
*/
public Type[] getGenericExceptionTypes() {
Type[] result;
if (hasGenericInformation() &&
((result = getGenericInfo().getExceptionTypes()).length > 0))
return result;
else
return getExceptionTypes();
}
/**
* Returns a string describing this {@code Executable}, including
* any type parameters.
* @return a string describing this {@code Executable}, including
* any type parameters
*/
public abstract String toGenericString();
/**
* Returns {@code true} if this executable was declared to take a
* variable number of arguments; returns {@code false} otherwise.
*
* @return {@code true} if an only if this executable was declared
* to take a variable number of arguments.
*/
public boolean isVarArgs() {
return (getModifiers() & Modifier.VARARGS) != 0;
}
/**
* Returns {@code true} if this executable is a synthetic
* construct; returns {@code false} otherwise.
*
* @return true if and only if this executable is a synthetic
* construct as defined by
* <cite>The Java&trade; Language Specification</cite>.
* @jls 13.1 The Form of a Binary
*/
public boolean isSynthetic() {
return Modifier.isSynthetic(getModifiers());
}
/**
* Returns an array of arrays of {@code Annotation}s that
* represent the annotations on the formal parameters, in
* declaration order, of the {@code Executable} represented by
* this object. Synthetic and mandated parameters (see
* explanation below), such as the outer "this" parameter to an
* inner class constructor will be represented in the returned
* array. If the executable has no parameters (meaning no formal,
* no synthetic, and no mandated parameters), a zero-length array
* will be returned. If the {@code Executable} has one or more
* parameters, a nested array of length zero is returned for each
* parameter with no annotations. The annotation objects contained
* in the returned arrays are serializable. The caller of this
* method is free to modify the returned arrays; it will have no
* effect on the arrays returned to other callers.
*
* A compiler may add extra parameters that are implicitly
* declared in source ("mandated"), as well as parameters that
* are neither implicitly nor explicitly declared in source
* ("synthetic") to the parameter list for a method. See {@link
* java.lang.reflect.Parameter} for more information.
*
* @see java.lang.reflect.Parameter
* @see java.lang.reflect.Parameter#getAnnotations
* @return an array of arrays that represent the annotations on
* the formal and implicit parameters, in declaration order, of
* the executable represented by this object
*/
public abstract Annotation[][] getParameterAnnotations();
Annotation[][] sharedGetParameterAnnotations(Class<?>[] parameterTypes) {
int numParameters = parameterTypes.length;
Annotation[][] result = sharedGetParameterAnnotationsImpl();
if (result == null)
return new Annotation[numParameters][0];
if (result.length != numParameters)
handleParameterNumberMismatch(result.length, numParameters);
return result;
}
private native Annotation[][] sharedGetParameterAnnotationsImpl();
abstract void handleParameterNumberMismatch(int resultLength, int numParameters);
/**
* {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
return annotationClass.cast(declaredAnnotations().get(annotationClass));
}
/**
* {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
@Override
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
}
/**
* {@inheritDoc}
*/
public Annotation[] getDeclaredAnnotations() {
return AnnotationParser.toArray(declaredAnnotations());
}
private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
if (declaredAnnotations == null) {
Executable root = getRoot();
if (root != null) {
declaredAnnotations = root.declaredAnnotations();
} else {
declaredAnnotations = declaredAnnotationsImpl();
}
}
return declaredAnnotations;
}
private native Map<Class<? extends Annotation>, Annotation> declaredAnnotationsImpl();
/**
* Returns an {@code AnnotatedType} object that represents the use of a type to
* specify the return type of the method/constructor represented by this
* Executable.
*
* If this {@code Executable} object represents a constructor, the {@code
* AnnotatedType} object represents the type of the constructed object.
*
* If this {@code Executable} object represents a method, the {@code
* AnnotatedType} object represents the use of a type to specify the return
* type of the method.
*
* @return an object representing the return type of the method
* or constructor represented by this {@code Executable}
*
* @since 1.8
*/
public abstract AnnotatedType getAnnotatedReturnType();
/* Helper for subclasses of Executable.
*
* Returns an AnnotatedType object that represents the use of a type to
* specify the return type of the method/constructor represented by this
* Executable.
*
* @since 1.8
*/
AnnotatedType getAnnotatedReturnType0(Type returnType) {
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
this,
getDeclaringClass(),
returnType,
TypeAnnotation.TypeAnnotationTarget.METHOD_RETURN);
}
/**
* Returns an {@code AnnotatedType} object that represents the use of a
* type to specify the receiver type of the method/constructor represented
* by this Executable object. The receiver type of a method/constructor is
* available only if the method/constructor has a <em>receiver
* parameter</em> (JLS 8.4.1).
*
* If this {@code Executable} object represents a constructor or instance
* method that does not have a receiver parameter, or has a receiver
* parameter with no annotations on its type, then the return value is an
* {@code AnnotatedType} object representing an element with no
* annotations.
*
* If this {@code Executable} object represents a static method, then the
* return value is null.
*
* @return an object representing the receiver type of the method or
* constructor represented by this {@code Executable}
*
* @since 1.8
*/
public AnnotatedType getAnnotatedReceiverType() {
if (Modifier.isStatic(this.getModifiers()))
return null;
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
this,
getDeclaringClass(),
getDeclaringClass(),
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
}
/**
* Returns an array of {@code AnnotatedType} objects that represent the use
* of types to specify formal parameter types of the method/constructor
* represented by this Executable. The order of the objects in the array
* corresponds to the order of the formal parameter types in the
* declaration of the method/constructor.
*
* Returns an array of length 0 if the method/constructor declares no
* parameters.
*
* @return an array of objects representing the types of the
* formal parameters of the method or constructor represented by this
* {@code Executable}
*
* @since 1.8
*/
public AnnotatedType[] getAnnotatedParameterTypes() {
return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
this,
getDeclaringClass(),
getAllGenericParameterTypes(),
TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER);
}
/**
* Returns an array of {@code AnnotatedType} objects that represent the use
* of types to specify the declared exceptions of the method/constructor
* represented by this Executable. The order of the objects in the array
* corresponds to the order of the exception types in the declaration of
* the method/constructor.
*
* Returns an array of length 0 if the method/constructor declares no
* exceptions.
*
* @return an array of objects representing the declared
* exceptions of the method or constructor represented by this {@code
* Executable}
*
* @since 1.8
*/
public AnnotatedType[] getAnnotatedExceptionTypes() {
return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
this,
getDeclaringClass(),
getGenericExceptionTypes(),
TypeAnnotation.TypeAnnotationTarget.THROWS);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,8 +34,11 @@ import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.scope.ClassScope;
import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.Objects;
import sun.reflect.annotation.AnnotationParser;
import sun.reflect.annotation.AnnotationSupport;
import sun.reflect.annotation.TypeAnnotation;
import sun.reflect.annotation.TypeAnnotationParser;
/**
* A {@code Field} provides information about, and dynamic access to, a
@ -77,6 +80,9 @@ class Field extends AccessibleObject implements Member {
// For sharing of FieldAccessors. This branching structure is
// currently only two levels deep (i.e., one root Field and
// potentially many Field objects pointing to it.)
//
// If this branching structure would ever contain cycles, deadlocks can
// occur in annotation code.
private Field root;
// Generics infrastructure
@ -136,11 +142,15 @@ class Field extends AccessibleObject implements Member {
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects.)
if (this.root != null)
throw new IllegalArgumentException("Can not copy a non-root Field");
Field res = new Field(clazz, name, type, modifiers, slot, signature, null);
res.root = this;
// Might as well eagerly propagate this if already present
res.fieldAccessor = fieldAccessor;
res.overrideFieldAccessor = overrideFieldAccessor;
return res;
}
@ -280,12 +290,15 @@ class Field extends AccessibleObject implements Member {
* {@code protected} or {@code private} first, and then other
* modifiers in the following order: {@code static}, {@code final},
* {@code transient}, {@code volatile}.
*
* @return a string describing this {@code Field}
* @jls 8.3.1 Field Modifiers
*/
public String toString() {
int mod = getModifiers();
return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
+ getTypeName(getType()) + " "
+ getTypeName(getDeclaringClass()) + "."
+ getType().getTypeName() + " "
+ getDeclaringClass().getTypeName() + "."
+ getName());
}
@ -307,14 +320,14 @@ class Field extends AccessibleObject implements Member {
* its generic type
*
* @since 1.5
* @jls 8.3.1 Field Modifiers
*/
public String toGenericString() {
int mod = getModifiers();
Type fieldType = getGenericType();
return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
+ ((fieldType instanceof Class) ?
getTypeName((Class)fieldType): fieldType.toString())+ " "
+ getTypeName(getDeclaringClass()) + "."
+ fieldType.getTypeName() + " "
+ getDeclaringClass().getTypeName() + "."
+ getName());
}
@ -371,7 +384,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).get(obj);
@ -405,7 +419,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getBoolean(obj);
@ -439,7 +454,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getByte(obj);
@ -475,7 +491,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getChar(obj);
@ -511,7 +528,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getShort(obj);
@ -547,7 +565,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getInt(obj);
@ -583,7 +602,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getLong(obj);
@ -619,7 +639,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getFloat(obj);
@ -655,7 +676,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getDouble(obj);
@ -733,7 +755,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).set(obj, value);
@ -769,7 +792,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setBoolean(obj, z);
@ -805,7 +829,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setByte(obj, b);
@ -841,7 +866,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setChar(obj, c);
@ -877,7 +903,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setShort(obj, s);
@ -913,7 +940,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setInt(obj, i);
@ -949,7 +977,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setLong(obj, l);
@ -985,7 +1014,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setFloat(obj, f);
@ -1021,7 +1051,8 @@ class Field extends AccessibleObject implements Member {
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setDouble(obj, d);
@ -1078,57 +1109,66 @@ class Field extends AccessibleObject implements Member {
}
}
/*
* Utility routine to paper over array type names
*/
static String getTypeName(Class<?> type) {
if (type.isArray()) {
try {
Class<?> cl = type;
int dimensions = 0;
while (cl.isArray()) {
dimensions++;
cl = cl.getComponentType();
}
StringBuffer sb = new StringBuffer();
sb.append(cl.getName());
for (int i = 0; i < dimensions; i++) {
sb.append("[]");
}
return sb.toString();
} catch (Throwable e) { /*FALLTHRU*/ }
}
return type.getName();
}
/**
* @throws NullPointerException {@inheritDoc}
* @since 1.5
*/
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
if (annotationClass == null)
throw new NullPointerException();
return (T) declaredAnnotations().get(annotationClass);
Objects.requireNonNull(annotationClass);
return annotationClass.cast(declaredAnnotations().get(annotationClass));
}
private static final Annotation[] EMPTY_ANNOTATION_ARRAY=new Annotation[0];
/**
* {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
@Override
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
}
/**
* @since 1.5
* {@inheritDoc}
*/
public Annotation[] getDeclaredAnnotations() {
return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
return AnnotationParser.toArray(declaredAnnotations());
}
private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
if (declaredAnnotations == null) {
declaredAnnotations = getDeclaredAnnotationsImpl();
Field root = this.root;
if (root != null) {
declaredAnnotations = root.declaredAnnotations();
} else {
declaredAnnotations = getDeclaredAnnotationsImpl();
}
}
return declaredAnnotations;
}
private native Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationsImpl();
private native byte[] getTypeAnnotationBytes0();
/**
* Returns an AnnotatedType object that represents the use of a type to specify
* the declared type of the field represented by this Field.
* @return an object representing the declared type of the field
* represented by this Field
*
* @since 1.8
*/
public AnnotatedType getAnnotatedType() {
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
this,
getDeclaringClass(),
getGenericType(),
TypeAnnotation.TypeAnnotationTarget.FIELD);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,6 @@
package java.lang.reflect;
import ikvm.internal.CallerID;
import sun.reflect.CallerSensitive;
import sun.reflect.MethodAccessor;
import sun.reflect.Reflection;
@ -38,7 +37,6 @@ import sun.reflect.annotation.AnnotationParser;
import java.lang.annotation.Annotation;
import java.lang.annotation.AnnotationFormatError;
import java.nio.ByteBuffer;
import java.util.Map;
/**
* A {@code Method} provides information about, and access to, a single method
@ -60,9 +58,7 @@ import java.util.Map;
* @author Kenneth Russell
* @author Nakul Saraiya
*/
public final
class Method extends AccessibleObject implements GenericDeclaration,
Member {
public final class Method extends Executable {
private Class<?> clazz;
private int slot;
// This is guaranteed to be interned by the VM in the 1.4
@ -80,10 +76,12 @@ public final
// For sharing of MethodAccessors. This branching structure is
// currently only two levels deep (i.e., one root Method and
// potentially many Method objects pointing to it.)
//
// If this branching structure would ever contain cycles, deadlocks can
// occur in annotation code.
private Method root;
// Generics infrastructure
// Generics infrastructure
private String getGenericSignature() {return signature;}
// Accessor for factory
@ -93,7 +91,8 @@ public final
}
// Accessor for generic info repository
private MethodRepository getGenericInfo() {
@Override
MethodRepository getGenericInfo() {
// lazily initialize repository if necessary
if (genericInfo == null) {
// create and cache generic info repository
@ -118,8 +117,7 @@ public final
String signature,
byte[] unused1,
byte[] unused2,
byte[] unused3)
{
byte[] unused3) {
this.clazz = declaringClass;
this.name = name;
this.parameterTypes = parameterTypes;
@ -143,6 +141,9 @@ public final
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects.)
if (this.root != null)
throw new IllegalArgumentException("Can not copy a non-root Method");
Method res = new Method(clazz, name, parameterTypes, returnType,
exceptionTypes, modifiers, slot, signature,
null, null, null);
@ -153,9 +154,22 @@ public final
}
/**
* Returns the {@code Class} object representing the class or interface
* that declares the method represented by this {@code Method} object.
* Used by Excecutable for annotation sharing.
*/
@Override
Executable getRoot() {
return root;
}
@Override
boolean hasGenericInformation() {
return (getGenericSignature() != null);
}
/**
* {@inheritDoc}
*/
@Override
public Class<?> getDeclaringClass() {
return clazz;
}
@ -164,36 +178,26 @@ public final
* Returns the name of the method represented by this {@code Method}
* object, as a {@code String}.
*/
@Override
public String getName() {
return name;
}
/**
* Returns the Java language modifiers for the method represented
* by this {@code Method} object, as an integer. The {@code Modifier} class should
* be used to decode the modifiers.
*
* @see Modifier
* {@inheritDoc}
*/
@Override
public int getModifiers() {
return modifiers;
}
/**
* Returns an array of {@code TypeVariable} objects that represent the
* type variables declared by the generic declaration represented by this
* {@code GenericDeclaration} object, in declaration order. Returns an
* array of length 0 if the underlying generic declaration declares no type
* variables.
*
* @return an array of {@code TypeVariable} objects that represent
* the type variables declared by this generic declaration
* @throws GenericSignatureFormatError if the generic
* signature of this generic declaration does not conform to
* the format specified in
* <cite>The Java&trade; Virtual Machine Specification</cite>
* {@inheritDoc}
* @throws GenericSignatureFormatError {@inheritDoc}
* @since 1.5
*/
@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public TypeVariable<Method>[] getTypeParameters() {
if (getGenericSignature() != null)
return (TypeVariable<Method>[])getGenericInfo().getTypeParameters();
@ -241,99 +245,51 @@ public final
} else { return getReturnType();}
}
/**
* Returns an array of {@code Class} objects that represent the formal
* parameter types, in declaration order, of the method
* represented by this {@code Method} object. Returns an array of length
* 0 if the underlying method takes no parameters.
*
* @return the parameter types for the method this object
* represents
* {@inheritDoc}
*/
@Override
public Class<?>[] getParameterTypes() {
return (Class<?>[]) parameterTypes.clone();
return parameterTypes.clone();
}
/**
* Returns an array of {@code Type} objects that represent the formal
* parameter types, in declaration order, of the method represented by
* this {@code Method} object. Returns an array of length 0 if the
* underlying method takes no parameters.
*
* <p>If a formal parameter type is a parameterized type,
* the {@code Type} object returned for it must accurately reflect
* the actual type parameters used in the source code.
*
* <p>If a formal parameter type is a type variable or a parameterized
* type, it is created. Otherwise, it is resolved.
*
* @return an array of Types that represent the formal
* parameter types of the underlying method, in declaration order
* @throws GenericSignatureFormatError
* if the generic method signature does not conform to the format
* specified in
* <cite>The Java&trade; Virtual Machine Specification</cite>
* @throws TypeNotPresentException if any of the parameter
* types of the underlying method refers to a non-existent type
* declaration
* @throws MalformedParameterizedTypeException if any of
* the underlying method's parameter types refer to a parameterized
* type that cannot be instantiated for any reason
* {@inheritDoc}
*/
public int getParameterCount() { return parameterTypes.length; }
/**
* {@inheritDoc}
* @throws GenericSignatureFormatError {@inheritDoc}
* @throws TypeNotPresentException {@inheritDoc}
* @throws MalformedParameterizedTypeException {@inheritDoc}
* @since 1.5
*/
@Override
public Type[] getGenericParameterTypes() {
if (getGenericSignature() != null)
return getGenericInfo().getParameterTypes();
else
return getParameterTypes();
return super.getGenericParameterTypes();
}
/**
* Returns an array of {@code Class} objects that represent
* the types of the exceptions declared to be thrown
* by the underlying method
* represented by this {@code Method} object. Returns an array of length
* 0 if the method declares no exceptions in its {@code throws} clause.
*
* @return the exception types declared as being thrown by the
* method this object represents
* {@inheritDoc}
*/
@Override
public Class<?>[] getExceptionTypes() {
return (Class<?>[]) exceptionTypes.clone();
return exceptionTypes.clone();
}
/**
* Returns an array of {@code Type} objects that represent the
* exceptions declared to be thrown by this {@code Method} object.
* Returns an array of length 0 if the underlying method declares
* no exceptions in its {@code throws} clause.
*
* <p>If an exception type is a type variable or a parameterized
* type, it is created. Otherwise, it is resolved.
*
* @return an array of Types that represent the exception types
* thrown by the underlying method
* @throws GenericSignatureFormatError
* if the generic method signature does not conform to the format
* specified in
* <cite>The Java&trade; Virtual Machine Specification</cite>
* @throws TypeNotPresentException if the underlying method's
* {@code throws} clause refers to a non-existent type declaration
* @throws MalformedParameterizedTypeException if
* the underlying method's {@code throws} clause refers to a
* parameterized type that cannot be instantiated for any reason
* {@inheritDoc}
* @throws GenericSignatureFormatError {@inheritDoc}
* @throws TypeNotPresentException {@inheritDoc}
* @throws MalformedParameterizedTypeException {@inheritDoc}
* @since 1.5
*/
public Type[] getGenericExceptionTypes() {
Type[] result;
if (getGenericSignature() != null &&
((result = getGenericInfo().getExceptionTypes()).length > 0))
return result;
else
return getExceptionTypes();
}
@Override
public Type[] getGenericExceptionTypes() {
return super.getGenericExceptionTypes();
}
/**
* Compares this {@code Method} against the specified object. Returns
@ -348,16 +304,7 @@ public final
&& (getName() == other.getName())) {
if (!returnType.equals(other.getReturnType()))
return false;
/* Avoid unnecessary cloning */
Class<?>[] params1 = parameterTypes;
Class<?>[] params2 = other.parameterTypes;
if (params1.length == params2.length) {
for (int i = 0; i < params1.length; i++) {
if (params1[i] != params2[i])
return false;
}
return true;
}
return equalParamTypes(parameterTypes, other.parameterTypes);
}
}
return false;
@ -391,39 +338,25 @@ public final
* specified by "The Java Language Specification". This is
* {@code public}, {@code protected} or {@code private} first,
* and then other modifiers in the following order:
* {@code abstract}, {@code static}, {@code final},
* {@code abstract}, {@code default}, {@code static}, {@code final},
* {@code synchronized}, {@code native}, {@code strictfp}.
*
* @return a string describing this {@code Method}
*
* @jls 8.4.3 Method Modifiers
*/
public String toString() {
try {
StringBuilder sb = new StringBuilder();
int mod = getModifiers() & Modifier.methodModifiers();
if (mod != 0) {
sb.append(Modifier.toString(mod)).append(' ');
}
sb.append(Field.getTypeName(getReturnType())).append(' ');
sb.append(Field.getTypeName(getDeclaringClass())).append('.');
sb.append(getName()).append('(');
Class<?>[] params = parameterTypes; // avoid clone
for (int j = 0; j < params.length; j++) {
sb.append(Field.getTypeName(params[j]));
if (j < (params.length - 1))
sb.append(',');
}
sb.append(')');
Class<?>[] exceptions = exceptionTypes; // avoid clone
if (exceptions.length > 0) {
sb.append(" throws ");
for (int k = 0; k < exceptions.length; k++) {
sb.append(exceptions[k].getName());
if (k < (exceptions.length - 1))
sb.append(',');
}
}
return sb.toString();
} catch (Exception e) {
return "<" + e + ">";
}
return sharedToString(Modifier.methodModifiers(),
isDefault(),
parameterTypes,
exceptionTypes);
}
@Override
void specificToStringHeader(StringBuilder sb) {
sb.append(getReturnType().getTypeName()).append(' ');
sb.append(getDeclaringClass().getTypeName()).append('.');
sb.append(getName());
}
/**
@ -449,77 +382,33 @@ public final
* class name. If the method is declared to throw exceptions, the
* parameter list is followed by a space, followed by the word
* throws followed by a comma-separated list of the generic thrown
* exception types. If there are no type parameters, the type
* parameter list is elided.
* exception types.
*
* <p>The access modifiers are placed in canonical order as
* specified by "The Java Language Specification". This is
* {@code public}, {@code protected} or {@code private} first,
* and then other modifiers in the following order:
* {@code abstract}, {@code static}, {@code final},
* {@code abstract}, {@code default}, {@code static}, {@code final},
* {@code synchronized}, {@code native}, {@code strictfp}.
*
* @return a string describing this {@code Method},
* include type parameters
*
* @since 1.5
*
* @jls 8.4.3 Method Modifiers
*/
@Override
public String toGenericString() {
try {
StringBuilder sb = new StringBuilder();
int mod = getModifiers() & Modifier.methodModifiers();
if (mod != 0) {
sb.append(Modifier.toString(mod)).append(' ');
}
TypeVariable<?>[] typeparms = getTypeParameters();
if (typeparms.length > 0) {
boolean first = true;
sb.append('<');
for(TypeVariable<?> typeparm: typeparms) {
if (!first)
sb.append(',');
// Class objects can't occur here; no need to test
// and call Class.getName().
sb.append(typeparm.toString());
first = false;
}
sb.append("> ");
}
return sharedToGenericString(Modifier.methodModifiers(), isDefault());
}
Type genRetType = getGenericReturnType();
sb.append( ((genRetType instanceof Class<?>)?
Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
.append(' ');
sb.append(Field.getTypeName(getDeclaringClass())).append('.');
sb.append(getName()).append('(');
Type[] params = getGenericParameterTypes();
for (int j = 0; j < params.length; j++) {
String param = (params[j] instanceof Class)?
Field.getTypeName((Class)params[j]):
(params[j].toString());
if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
param = param.replaceFirst("\\[\\]$", "...");
sb.append(param);
if (j < (params.length - 1))
sb.append(',');
}
sb.append(')');
Type[] exceptions = getGenericExceptionTypes();
if (exceptions.length > 0) {
sb.append(" throws ");
for (int k = 0; k < exceptions.length; k++) {
sb.append((exceptions[k] instanceof Class)?
((Class)exceptions[k]).getName():
exceptions[k].toString());
if (k < (exceptions.length - 1))
sb.append(',');
}
}
return sb.toString();
} catch (Exception e) {
return "<" + e + ">";
}
@Override
void specificToGenericStringHeader(StringBuilder sb) {
Type genRetType = getGenericReturnType();
sb.append(genRetType.getTypeName()).append(' ');
sb.append(getDeclaringClass().getTypeName()).append('.');
sb.append(getName());
}
/**
@ -594,7 +483,7 @@ public final
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args, CallerID.getCallerID());
return ma.invoke(obj, args, ikvm.internal.CallerID.getCallerID());
}
/**
@ -610,28 +499,41 @@ public final
}
/**
* Returns {@code true} if this method was declared to take
* a variable number of arguments; returns {@code false}
* otherwise.
*
* @return {@code true} if an only if this method was declared to
* take a variable number of arguments.
* {@inheritDoc}
* @since 1.5
*/
@Override
public boolean isVarArgs() {
return (getModifiers() & Modifier.VARARGS) != 0;
return super.isVarArgs();
}
/**
* Returns {@code true} if this method is a synthetic
* method; returns {@code false} otherwise.
*
* @return true if and only if this method is a synthetic
* method as defined by the Java Language Specification.
* {@inheritDoc}
* @jls 13.1 The Form of a Binary
* @since 1.5
*/
@Override
public boolean isSynthetic() {
return Modifier.isSynthetic(getModifiers());
return super.isSynthetic();
}
/**
* Returns {@code true} if this method is a default
* method; returns {@code false} otherwise.
*
* A default method is a public non-abstract instance method, that
* is, a non-static method with a body, declared in an interface
* type.
*
* @return true if and only if this method is a default
* method as defined by the Java Language Specification.
* @since 1.8
*/
public boolean isDefault() {
// Default methods are public non-abstract instance methods
// declared in an interface.
return ((getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
Modifier.PUBLIC) && getDeclaringClass().isInterface();
}
// NOTE that there is no synchronization used here. It is correct
@ -670,37 +572,6 @@ public final
}
}
/**
* @throws NullPointerException {@inheritDoc}
* @since 1.5
*/
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
if (annotationClass == null)
throw new NullPointerException();
return (T) declaredAnnotations().get(annotationClass);
}
private static final Annotation[] EMPTY_ANNOTATION_ARRAY=new Annotation[0];
/**
* @since 1.5
*/
public Annotation[] getDeclaredAnnotations() {
return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
}
private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
if (declaredAnnotations == null) {
declaredAnnotations = getDeclaredAnnotationsImpl(this);
}
return declaredAnnotations;
}
static native Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationsImpl(Object methodOrConstructor);
/**
* Returns the default value for the annotation member represented by
* this {@code Method} instance. If the member is of a primitive type,
@ -718,32 +589,42 @@ public final
public native Object getDefaultValue();
/**
* Returns an array of arrays that represent the annotations on the formal
* parameters, in declaration order, of the method represented by
* this {@code Method} object. (Returns an array of length zero if the
* underlying method is parameterless. If the method has one or more
* parameters, a nested array of length zero is returned for each parameter
* with no annotations.) The annotation objects contained in the returned
* arrays are serializable. The caller of this method is free to modify
* the returned arrays; it will have no effect on the arrays returned to
* other callers.
*
* @return an array of arrays that represent the annotations on the formal
* parameters, in declaration order, of the method represented by this
* Method object
* {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @since 1.5
*/
public Annotation[][] getParameterAnnotations() {
Annotation[][] result = getParameterAnnotationsImpl(this);
int numParameters = parameterTypes.length;
if (result == null)
return new Annotation[numParameters][0];
if (result.length != numParameters)
throw new java.lang.annotation.AnnotationFormatError(
"Parameter annotations don't match number of parameters");
return result;
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
return super.getAnnotation(annotationClass);
}
static native Annotation[][] getParameterAnnotationsImpl(Object methodOrConstructor);
/**
* {@inheritDoc}
* @since 1.5
*/
public Annotation[] getDeclaredAnnotations() {
return super.getDeclaredAnnotations();
}
/**
* {@inheritDoc}
* @since 1.5
*/
@Override
public Annotation[][] getParameterAnnotations() {
return sharedGetParameterAnnotations(parameterTypes);
}
/**
* {@inheritDoc}
* @since 1.8
*/
@Override
public AnnotatedType getAnnotatedReturnType() {
return getAnnotatedReturnType0(getGenericReturnType());
}
@Override
void handleParameterNumberMismatch(int resultLength, int numParameters) {
throw new AnnotationFormatError("Parameter annotations don't match number of parameters");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,20 +25,17 @@
package java.lang.reflect;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
import java.util.List;
import java.util.WeakHashMap;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiFunction;
import sun.misc.ProxyGenerator;
import sun.misc.VM;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
@ -52,16 +49,14 @@ import sun.security.util.SecurityConstants;
* <p>To create a proxy for some interface {@code Foo}:
* <pre>
* InvocationHandler handler = new MyInvocationHandler(...);
* Class proxyClass = Proxy.getProxyClass(
* Foo.class.getClassLoader(), new Class[] { Foo.class });
* Foo f = (Foo) proxyClass.
* getConstructor(new Class[] { InvocationHandler.class }).
* newInstance(new Object[] { handler });
* Class&lt;?&gt; proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
* Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
* newInstance(handler);
* </pre>
* or more simply:
* <pre>
* Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
* new Class[] { Foo.class },
* new Class&lt;?&gt;[] { Foo.class },
* handler);
* </pre>
*
@ -90,7 +85,11 @@ import sun.security.util.SecurityConstants;
* <p>A proxy class has the following properties:
*
* <ul>
* <li>Proxy classes are public, final, and not abstract.
* <li>Proxy classes are <em>public, final, and not abstract</em> if
* all proxy interfaces are public.</li>
*
* <li>Proxy classes are <em>non-public, final, and not abstract</em> if
* any of the proxy interfaces is non-public.</li>
*
* <li>The unqualified name of a proxy class is unspecified. The space
* of class names that begin with the string {@code "$Proxy"}
@ -230,27 +229,15 @@ public class Proxy implements java.io.Serializable {
private static final long serialVersionUID = -2222568056686623797L;
/** prefix for all proxy class names */
private final static String proxyClassNamePrefix = "$Proxy";
/** parameter types of a proxy class constructor */
private final static Class[] constructorParams =
private static final Class<?>[] constructorParams =
{ InvocationHandler.class };
/** maps a class loader to the proxy class cache for that loader */
private static Map<ClassLoader, Map<List<String>, Object>> loaderToCache
= new WeakHashMap<>();
/** marks that a particular proxy class is currently being generated */
private static Object pendingGenerationMarker = new Object();
/** next number to use for generation of unique proxy class names */
private static long nextUniqueNumber = 0;
private static Object nextUniqueNumberLock = new Object();
/** set of all generated proxy classes, for isProxyClass implementation */
private static Map<Class<?>, Void> proxyClasses =
Collections.synchronizedMap(new WeakHashMap<Class<?>, Void>());
/**
* a cache of proxy classes
*/
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
/**
* the invocation handler for this proxy instance.
@ -269,77 +256,24 @@ public class Proxy implements java.io.Serializable {
* (typically, a dynamic proxy class) with the specified value
* for its invocation handler.
*
* @param h the invocation handler for this proxy instance
* @param h the invocation handler for this proxy instance
*
* @throws NullPointerException if the given invocation handler, {@code h},
* is {@code null}.
*/
protected Proxy(InvocationHandler h) {
doNewInstanceCheck();
Objects.requireNonNull(h);
this.h = h;
}
private static class ProxyAccessHelper {
// The permission is implementation specific.
static final Permission PROXY_PERMISSION =
new ReflectPermission("proxyConstructorNewInstance");
// These system properties are defined to provide a short-term
// workaround if customers need to disable the new security checks.
static final boolean allowNewInstance;
static final boolean allowNullLoader;
static {
allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance");
allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader");
}
private static boolean getBooleanProperty(final String key) {
String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty(key);
}
});
return Boolean.valueOf(s);
}
static boolean needsNewInstanceCheck(Class<?> proxyClass) {
if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) {
return false;
}
if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
for (Class<?> intf : proxyClass.getInterfaces()) {
if (!Modifier.isPublic(intf.getModifiers())) {
return true;
}
}
}
return false;
}
}
/*
* Access check on a proxy class that implements any non-public interface.
*
* @throws SecurityException if a security manager exists, and
* the caller does not have the permission.
*/
private void doNewInstanceCheck() {
SecurityManager sm = System.getSecurityManager();
Class<?> proxyClass = this.getClass();
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) {
try {
sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION);
} catch (SecurityException e) {
throw new SecurityException("Not allowed to construct a Proxy "
+ "instance that implements a non-public interface", e);
}
}
}
/**
* Returns the {@code java.lang.Class} object for a proxy class
* given a class loader and an array of interfaces. The proxy class
* will be defined by the specified class loader and will implement
* all of the supplied interfaces. If a proxy class for the same
* permutation of interfaces has already been defined by the class
* loader, then the existing proxy class will be returned; otherwise,
* all of the supplied interfaces. If any of the given interfaces
* is non-public, the proxy class will be non-public. If a proxy class
* for the same permutation of interfaces has already been defined by the
* class loader, then the existing proxy class will be returned; otherwise,
* a proxy class for those interfaces will be generated dynamically
* and defined by the class loader.
*
@ -404,6 +338,22 @@ public class Proxy implements java.io.Serializable {
* @throws IllegalArgumentException if any of the restrictions on the
* parameters that may be passed to {@code getProxyClass}
* are violated
* @throws SecurityException if a security manager, <em>s</em>, is present
* and any of the following conditions is met:
* <ul>
* <li> the given {@code loader} is {@code null} and
* the caller's class loader is not {@code null} and the
* invocation of {@link SecurityManager#checkPermission
* s.checkPermission} with
* {@code RuntimePermission("getClassLoader")} permission
* denies access.</li>
* <li> for each proxy interface, {@code intf},
* the caller's class loader is not the same as or an
* ancestor of the class loader for {@code intf} and
* invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to {@code intf}.</li>
* </ul>
* @throws NullPointerException if the {@code interfaces} array
* argument or any of its elements are {@code null}
*/
@ -412,12 +362,13 @@ public class Proxy implements java.io.Serializable {
Class<?>... interfaces)
throws IllegalArgumentException
{
SecurityManager sm = System.getSecurityManager();
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
return getProxyClass0(loader, interfaces);
return getProxyClass0(loader, intfs);
}
/*
@ -445,10 +396,8 @@ public class Proxy implements java.io.Serializable {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = caller.getClassLoader();
if (loader == null && ccl != null) {
if (!ProxyAccessHelper.allowNullLoader) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
}
@ -464,142 +413,204 @@ public class Proxy implements java.io.Serializable {
throw new IllegalArgumentException("interface limit exceeded");
}
Class<?> proxyClass = null;
// If the proxy class defined by the given loader implementing
// the given interfaces exists, this will simply return the cached copy;
// otherwise, it will create the proxy class via the ProxyClassFactory
return proxyClassCache.get(loader, interfaces);
}
/* collect interface names to use as key for proxy class cache */
String[] interfaceNames = new String[interfaces.length];
/*
* a key used for proxy class with 0 implemented interfaces
*/
private static final Object key0 = new Object();
// for detecting duplicates
Set<Class<?>> interfaceSet = new HashSet<>();
/*
* Key1 and Key2 are optimized for the common use of dynamic proxies
* that implement 1 or 2 interfaces.
*/
for (int i = 0; i < interfaces.length; i++) {
/*
* Verify that the class loader resolves the name of this
* interface to the same Class object.
*/
String interfaceName = interfaces[i].getName();
Class<?> interfaceClass = null;
try {
interfaceClass = Class.forName(interfaceName, false, loader);
} catch (ClassNotFoundException e) {
}
if (interfaceClass != interfaces[i]) {
throw new IllegalArgumentException(
interfaces[i] + " is not visible from class loader");
}
/*
* a key used for proxy class with 1 implemented interface
*/
private static final class Key1 extends WeakReference<Class<?>> {
private final int hash;
/*
* Verify that the Class object actually represents an
* interface.
*/
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
/*
* Verify that this interface is not a duplicate.
*/
if (interfaceSet.contains(interfaceClass)) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
interfaceSet.add(interfaceClass);
interfaceNames[i] = interfaceName;
Key1(Class<?> intf) {
super(intf);
this.hash = intf.hashCode();
}
/*
* Using string representations of the proxy interfaces as
* keys in the proxy class cache (instead of their Class
* objects) is sufficient because we require the proxy
* interfaces to be resolvable by name through the supplied
* class loader, and it has the advantage that using a string
* representation of a class makes for an implicit weak
* reference to the class.
*/
List<String> key = Arrays.asList(interfaceNames);
/*
* Find or create the proxy class cache for the class loader.
*/
Map<List<String>, Object> cache;
synchronized (loaderToCache) {
cache = loaderToCache.get(loader);
if (cache == null) {
cache = new HashMap<>();
loaderToCache.put(loader, cache);
}
/*
* This mapping will remain valid for the duration of this
* method, without further synchronization, because the mapping
* will only be removed if the class loader becomes unreachable.
*/
@Override
public int hashCode() {
return hash;
}
/*
* Look up the list of interfaces in the proxy class cache using
* the key. This lookup will result in one of three possible
* kinds of values:
* null, if there is currently no proxy class for the list of
* interfaces in the class loader,
* the pendingGenerationMarker object, if a proxy class for the
* list of interfaces is currently being generated,
* or a weak reference to a Class object, if a proxy class for
* the list of interfaces has already been generated.
*/
synchronized (cache) {
/*
* Note that we need not worry about reaping the cache for
* entries with cleared weak references because if a proxy class
* has been garbage collected, its class loader will have been
* garbage collected as well, so the entire cache will be reaped
* from the loaderToCache map.
*/
do {
Object value = cache.get(key);
if (value instanceof Reference) {
proxyClass = (Class<?>) ((Reference) value).get();
@Override
public boolean equals(Object obj) {
Class<?> intf;
return this == obj ||
obj != null &&
obj.getClass() == Key1.class &&
(intf = get()) != null &&
intf == ((Key1) obj).get();
}
}
/*
* a key used for proxy class with 2 implemented interfaces
*/
private static final class Key2 extends WeakReference<Class<?>> {
private final int hash;
private final WeakReference<Class<?>> ref2;
Key2(Class<?> intf1, Class<?> intf2) {
super(intf1);
hash = 31 * intf1.hashCode() + intf2.hashCode();
ref2 = new WeakReference<Class<?>>(intf2);
}
@Override
public int hashCode() {
return hash;
}
@Override
public boolean equals(Object obj) {
Class<?> intf1, intf2;
return this == obj ||
obj != null &&
obj.getClass() == Key2.class &&
(intf1 = get()) != null &&
intf1 == ((Key2) obj).get() &&
(intf2 = ref2.get()) != null &&
intf2 == ((Key2) obj).ref2.get();
}
}
/*
* a key used for proxy class with any number of implemented interfaces
* (used here for 3 or more only)
*/
private static final class KeyX {
private final int hash;
private final WeakReference<Class<?>>[] refs;
@SuppressWarnings("unchecked")
KeyX(Class<?>[] interfaces) {
hash = Arrays.hashCode(interfaces);
refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
refs[i] = new WeakReference<>(interfaces[i]);
}
}
@Override
public int hashCode() {
return hash;
}
@Override
public boolean equals(Object obj) {
return this == obj ||
obj != null &&
obj.getClass() == KeyX.class &&
equals(refs, ((KeyX) obj).refs);
}
private static boolean equals(WeakReference<Class<?>>[] refs1,
WeakReference<Class<?>>[] refs2) {
if (refs1.length != refs2.length) {
return false;
}
for (int i = 0; i < refs1.length; i++) {
Class<?> intf = refs1[i].get();
if (intf == null || intf != refs2[i].get()) {
return false;
}
if (proxyClass != null) {
// proxy class already generated: return it
return proxyClass;
} else if (value == pendingGenerationMarker) {
// proxy class being generated: wait for it
try {
cache.wait();
} catch (InterruptedException e) {
/*
* The class generation that we are waiting for should
* take a small, bounded time, so we can safely ignore
* thread interrupts here.
*/
}
continue;
} else {
/*
* No proxy class for this list of interfaces has been
* generated or is being generated, so we will go and
* generate it now. Mark it as pending generation.
*/
cache.put(key, pendingGenerationMarker);
break;
}
} while (true);
}
return true;
}
}
/**
* A function that maps an array of interfaces to an optimal key where
* Class objects representing interfaces are weakly referenced.
*/
private static final class KeyFactory
implements BiFunction<ClassLoader, Class<?>[], Object>
{
@Override
public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
switch (interfaces.length) {
case 1: return new Key1(interfaces[0]); // the most frequent
case 2: return new Key2(interfaces[0], interfaces[1]);
case 0: return key0;
default: return new KeyX(interfaces);
}
}
}
/**
* A factory function that generates, defines and returns the proxy class given
* the ClassLoader and array of interfaces.
*/
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
// prefix for all proxy class names
private static final String proxyClassNamePrefix = "$Proxy";
// next number to use for generation of unique proxy class names
private static final AtomicLong nextUniqueNumber = new AtomicLong();
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {
/*
* Verify that the class loader resolves the name of this
* interface to the same Class object.
*/
Class<?> interfaceClass = null;
try {
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
if (interfaceClass != intf) {
throw new IllegalArgumentException(
intf + " is not visible from class loader");
}
/*
* Verify that the Class object actually represents an
* interface.
*/
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
/*
* Verify that this interface is not a duplicate.
*/
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
}
try {
String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
/*
* Record the package of a non-public proxy interface so that the
* proxy class will be defined in the same package. Verify that
* all non-public proxy interfaces are in the same package.
*/
for (int i = 0; i < interfaces.length; i++) {
int flags = interfaces[i].getModifiers();
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
String name = interfaces[i].getName();
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
@ -616,77 +627,42 @@ public class Proxy implements java.io.Serializable {
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
generate: do
{
/*
* Choose a name for the proxy class to generate.
*/
long num;
synchronized (nextUniqueNumberLock) {
num = nextUniqueNumber++;
}
String proxyName = proxyPkg + proxyClassNamePrefix + num;
/*
* Verify that the class loader hasn't already
* defined a class with the chosen name.
*/
proxyClass = getPrecompiledProxy(loader, proxyName, interfaces);
if (proxyClass != null)
break generate;
/*
* Generate the specified proxy class.
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces);
try {
proxyClass = defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
/*
* A ClassFormatError here means that (barring bugs in the
* proxy class generation code) there was some other
* invalid aspect of the arguments supplied to the proxy
* class creation (such as virtual machine limitations
* exceeded).
*/
throw new IllegalArgumentException(e.toString());
}
}
while (false);
// add to set of all generated proxy classes, for isProxyClass
proxyClasses.put(proxyClass, null);
} finally {
/*
* We must clean up the "pending generation" state of the proxy
* class cache entry somehow. If a proxy class was successfully
* generated, store it in the cache (with a weak reference);
* otherwise, remove the reserved entry. In all cases, notify
* all waiters on reserved entries in this cache.
* Choose a name for the proxy class to generate.
*/
synchronized (cache) {
if (proxyClass != null) {
cache.put(key, new WeakReference<Class<?>>(proxyClass));
} else {
cache.remove(key);
}
cache.notifyAll();
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
Class precompiledProxyClass = getPrecompiledProxy(loader, proxyName, interfaces);
if (precompiledProxyClass != null) {
return precompiledProxyClass;
}
/*
* Generate the specified proxy class.
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
/*
* A ClassFormatError here means that (barring bugs in the
* proxy class generation code) there was some other
* invalid aspect of the arguments supplied to the proxy
* class creation (such as virtual machine limitations
* exceeded).
*/
throw new IllegalArgumentException(e.toString());
}
}
return proxyClass;
}
/**
* Returns an instance of a proxy class for the specified interfaces
* that dispatches method invocations to the specified invocation
* handler. This method is equivalent to:
* <pre>
* Proxy.getProxyClass(loader, interfaces).
* getConstructor(new Class[] { InvocationHandler.class }).
* newInstance(new Object[] { handler });
* </pre>
* handler.
*
* <p>{@code Proxy.newProxyInstance} throws
* {@code IllegalArgumentException} for the same reasons that
@ -702,6 +678,27 @@ generate: do
* @throws IllegalArgumentException if any of the restrictions on the
* parameters that may be passed to {@code getProxyClass}
* are violated
* @throws SecurityException if a security manager, <em>s</em>, is present
* and any of the following conditions is met:
* <ul>
* <li> the given {@code loader} is {@code null} and
* the caller's class loader is not {@code null} and the
* invocation of {@link SecurityManager#checkPermission
* s.checkPermission} with
* {@code RuntimePermission("getClassLoader")} permission
* denies access;</li>
* <li> for each proxy interface, {@code intf},
* the caller's class loader is not the same as or an
* ancestor of the class loader for {@code intf} and
* invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to {@code intf};</li>
* <li> any of the given proxy interfaces is non-public and the
* caller class is not in the same {@linkplain Package runtime package}
* as the non-public interface and the invocation of
* {@link SecurityManager#checkPermission s.checkPermission} with
* {@code ReflectPermission("newProxyInPackage.{package name}")}
* permission denies access.</li>
* </ul>
* @throws NullPointerException if the {@code interfaces} array
* argument or any of its elements are {@code null}, or
* if the invocation handler, {@code h}, is
@ -713,53 +710,70 @@ generate: do
InvocationHandler h)
throws IllegalArgumentException
{
if (h == null) {
throw new NullPointerException();
}
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass0(loader, interfaces);
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
// create proxy instance with doPrivilege as the proxy class may
// implement non-public interfaces that requires a special permission
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return newInstance(cons, ih);
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
} else {
return newInstance(cons, ih);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString());
}
}
private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
try {
return cons.newInstance(new Object[] {h} );
} catch (IllegalAccessException | InstantiationException e) {
throw new InternalError(e.toString());
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString());
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
ClassLoader ccl = caller.getClassLoader();
ClassLoader pcl = proxyClass.getClassLoader();
// do permission check if the caller is in a different runtime package
// of the proxy class
int n = proxyClass.getName().lastIndexOf('.');
String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
n = caller.getName().lastIndexOf('.');
String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
if (pcl != ccl || !pkg.equals(callerPkg)) {
sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
}
}
}
}
@ -779,11 +793,7 @@ generate: do
* @throws NullPointerException if {@code cl} is {@code null}
*/
public static boolean isProxyClass(Class<?> cl) {
if (cl == null) {
throw new NullPointerException();
}
return proxyClasses.containsKey(cl);
return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
}
/**
@ -793,7 +803,14 @@ generate: do
* @return the invocation handler for the proxy instance
* @throws IllegalArgumentException if the argument is not a
* proxy instance
* @throws SecurityException if a security manager, <em>s</em>, is present
* and the caller's class loader is not the same as or an
* ancestor of the class loader for the invocation handler
* and invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to the invocation
* handler's class.
*/
@CallerSensitive
public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException
{
@ -804,12 +821,23 @@ generate: do
throw new IllegalArgumentException("not a proxy instance");
}
Proxy p = (Proxy) proxy;
return p.h;
final Proxy p = (Proxy) proxy;
final InvocationHandler ih = p.h;
if (System.getSecurityManager() != null) {
Class<?> ihClass = ih.getClass();
Class<?> caller = Reflection.getCallerClass();
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
ihClass.getClassLoader()))
{
ReflectUtil.checkPackageAccess(ihClass);
}
}
return ih;
}
private static native Class defineClass0(ClassLoader loader, String name,
byte[] b, int off, int len);
private static native Class<?> defineClass0(ClassLoader loader, String name,
byte[] b, int off, int len);
private static native Class<?> getPrecompiledProxy(ClassLoader loader, String proxyName, Class[] interfaces);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -263,15 +263,14 @@ static int socketReceiveOrPeekData
packetBuffer = dpObj.buf;
packetBufferOffset = dpObj.offset;
packetBufferLen = dpObj.bufLength;
/* Note: the buffer needn't be greater than 65,536 (0xFFFF)
* the max size of an IP packet. Anything bigger is truncated anyway.
*-/
if (packetBufferLen > MAX_PACKET_LEN) {
packetBufferLen = MAX_PACKET_LEN;
}
/*
if (packetBufferLen > MAX_BUFFER_LEN) {
/* Note: the buffer needn't be greater than 65,536 (0xFFFF)
* the max size of an IP packet. Anything bigger is truncated anyway.
*-/
if (packetBufferLen > MAX_PACKET_LEN) {
packetBufferLen = MAX_PACKET_LEN;
}
fullPacket = (char *)malloc(packetBufferLen);
if (!fullPacket) {
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
@ -380,8 +379,10 @@ static int socketReceiveOrPeekData
int[] tmp = { port };
packetAddress = NET_SockaddrToInetAddress(sa, tmp);
port = tmp[0];
/* stuff the new Inetaddress into the packet */
dpObj.address = packetAddress;
if (packetAddress != NULL) {
/* stuff the new Inetaddress into the packet */
dpObj.address = packetAddress;
}
}
/* populate the packet */

View File

@ -1,332 +0,0 @@
/*
* Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.net;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import static ikvm.internal.Winsock.*;
import static java.net.net_util_md.*;
import sun.misc.IoTrace;
import sun.net.ConnectionResetException;
/**
* This stream extends FileInputStream to implement a
* SocketInputStream. Note that this class should <b>NOT</b> be
* public.
*
* @author Jonathan Payne
* @author Arthur van Hoff
*/
class SocketInputStream extends FileInputStream
{
private boolean eof;
private AbstractPlainSocketImpl impl = null;
private byte temp[];
private Socket socket = null;
/**
* Creates a new SocketInputStream. Can only be called
* by a Socket. This method needs to hang on to the owner Socket so
* that the fd will not be closed.
* @param impl the implemented socket input stream
*/
SocketInputStream(AbstractPlainSocketImpl impl) throws IOException {
super(impl.getFileDescriptor());
this.impl = impl;
socket = impl.getSocket();
}
/**
* Returns the unique {@link java.nio.channels.FileChannel FileChannel}
* object associated with this file input stream.</p>
*
* The <code>getChannel</code> method of <code>SocketInputStream</code>
* returns <code>null</code> since it is a socket based stream.</p>
*
* @return the file channel associated with this file input stream
*
* @since 1.4
* @spec JSR-51
*/
public final FileChannel getChannel() {
return null;
}
/**
* Reads into an array of bytes at the specified offset using
* the received socket primitive.
* @param fd the FileDescriptor
* @param b the buffer into which the data is read
* @param off the start offset of the data
* @param len the maximum number of bytes read
* @param timeout the read timeout in ms
* @return the actual number of bytes read, -1 is
* returned when the end of the stream is reached.
* @exception IOException If an I/O error has occurred.
*/
private int socketRead0(FileDescriptor fdObj, byte bufP[], int off, int len, int timeout) throws IOException
{
// [IKVM] this method is a direct port of the native code in openjdk6-b18\jdk\src\windows\native\java\net\SocketInputStream.c
cli.System.Net.Sockets.Socket fd = null;
int nread;
if (IS_NULL(fdObj)) {
throw new SocketException("socket closed");
}
fd = fdObj.getSocket();
if (fd == null) {
throw new SocketException("Socket closed");
}
if (timeout != 0) {
if (timeout <= 5000 || !isRcvTimeoutSupported) {
int ret = NET_Timeout (fd, timeout);
if (ret <= 0) {
if (ret == 0) {
throw new SocketTimeoutException("Read timed out");
} else {
// [IKVM] the OpenJDK native code is broken and always throws this exception on any failure of NET_Timeout
throw new SocketException("socket closed");
}
}
/*check if the socket has been closed while we were in timeout*/
if (fdObj.getSocket() == null) {
throw new SocketException("Socket Closed");
}
}
}
nread = recv(fd, bufP, off, len, 0);
if (nread > 0) {
// ok
} else {
if (nread < 0) {
/*
* Recv failed.
*/
switch (WSAGetLastError()) {
case WSAEINTR:
throw new SocketException("socket closed");
case WSAECONNRESET:
case WSAESHUTDOWN:
/*
* Connection has been reset - Windows sometimes reports
* the reset as a shutdown error.
*/
throw new ConnectionResetException();
case WSAETIMEDOUT :
throw new SocketTimeoutException("Read timed out");
default:
throw NET_ThrowCurrent("recv failed");
}
}
}
return nread;
}
/**
* Reads into a byte array data from the socket.
* @param b the buffer into which the data is read
* @return the actual number of bytes read, -1 is
* returned when the end of the stream is reached.
* @exception IOException If an I/O error has occurred.
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Reads into a byte array <i>b</i> at offset <i>off</i>,
* <i>length</i> bytes of data.
* @param b the buffer into which the data is read
* @param off the start offset of the data
* @param len the maximum number of bytes read
* @return the actual number of bytes read, -1 is
* returned when the end of the stream is reached.
* @exception IOException If an I/O error has occurred.
*/
public int read(byte b[], int off, int length) throws IOException {
return read(b, off, length, impl.getTimeout());
}
int read(byte b[], int off, int length, int timeout) throws IOException {
int n = 0;
// EOF already encountered
if (eof) {
return -1;
}
// connection reset
if (impl.isConnectionReset()) {
throw new SocketException("Connection reset");
}
// bounds check
if (length <= 0 || off < 0 || off + length > b.length) {
if (length == 0) {
return 0;
}
throw new ArrayIndexOutOfBoundsException();
}
boolean gotReset = false;
Object traceContext = IoTrace.socketReadBegin();
// acquire file descriptor and do the read
FileDescriptor fd = impl.acquireFD();
try {
n = socketRead0(fd, b, off, length, timeout);
if (n > 0) {
return n;
}
} catch (ConnectionResetException rstExc) {
gotReset = true;
} finally {
impl.releaseFD();
IoTrace.socketReadEnd(traceContext, impl.address, impl.port,
timeout, n > 0 ? n : 0);
}
/*
* We receive a "connection reset" but there may be bytes still
* buffered on the socket
*/
if (gotReset) {
traceContext = IoTrace.socketReadBegin();
impl.setConnectionResetPending();
impl.acquireFD();
try {
n = socketRead0(fd, b, off, length, timeout);
if (n > 0) {
return n;
}
} catch (ConnectionResetException rstExc) {
} finally {
impl.releaseFD();
IoTrace.socketReadEnd(traceContext, impl.address, impl.port,
timeout, n > 0 ? n : 0);
}
}
/*
* If we get here we are at EOF, the socket has been closed,
* or the connection has been reset.
*/
if (impl.isClosedOrPending()) {
throw new SocketException("Socket closed");
}
if (impl.isConnectionResetPending()) {
impl.setConnectionReset();
}
if (impl.isConnectionReset()) {
throw new SocketException("Connection reset");
}
eof = true;
return -1;
}
/**
* Reads a single byte from the socket.
*/
public int read() throws IOException {
if (eof) {
return -1;
}
temp = new byte[1];
int n = read(temp, 0, 1);
if (n <= 0) {
return -1;
}
return temp[0] & 0xff;
}
/**
* Skips n bytes of input.
* @param n the number of bytes to skip
* @return the actual number of bytes skipped.
* @exception IOException If an I/O error has occurred.
*/
public long skip(long numbytes) throws IOException {
if (numbytes <= 0) {
return 0;
}
long n = numbytes;
int buflen = (int) Math.min(1024, n);
byte data[] = new byte[buflen];
while (n > 0) {
int r = read(data, 0, (int) Math.min((long) buflen, n));
if (r < 0) {
break;
}
n -= r;
}
return numbytes - n;
}
/**
* Returns the number of bytes that can be read without blocking.
* @return the number of immediately available bytes
*/
public int available() throws IOException {
return impl.available();
}
/**
* Closes the stream.
*/
private boolean closing = false;
public void close() throws IOException {
// Prevent recursion. See BugId 4484411
if (closing)
return;
closing = true;
if (socket != null) {
if (!socket.isClosed())
socket.close();
} else
impl.close();
closing = false;
}
void setEOF(boolean eof) {
this.eof = eof;
}
/**
* Overrides finalize, the fd is closed by the Socket.
*/
protected void finalize() {}
}

View File

@ -1,254 +0,0 @@
/*
* Copyright (c) 1995, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.net;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import static ikvm.internal.Winsock.*;
import static java.net.net_util_md.*;
import sun.misc.IoTrace;
/**
* This stream extends FileOutputStream to implement a
* SocketOutputStream. Note that this class should <b>NOT</b> be
* public.
*
* @author Jonathan Payne
* @author Arthur van Hoff
*/
class SocketOutputStream extends FileOutputStream
{
private AbstractPlainSocketImpl impl = null;
private byte temp[] = new byte[1];
private Socket socket = null;
/**
* Creates a new SocketOutputStream. Can only be called
* by a Socket. This method needs to hang on to the owner Socket so
* that the fd will not be closed.
* @param impl the socket output stream inplemented
*/
SocketOutputStream(AbstractPlainSocketImpl impl) throws IOException {
super(impl.getFileDescriptor());
this.impl = impl;
socket = impl.getSocket();
}
/**
* Returns the unique {@link java.nio.channels.FileChannel FileChannel}
* object associated with this file output stream. </p>
*
* The <code>getChannel</code> method of <code>SocketOutputStream</code>
* returns <code>null</code> since it is a socket based stream.</p>
*
* @return the file channel associated with this file output stream
*
* @since 1.4
* @spec JSR-51
*/
public final FileChannel getChannel() {
return null;
}
/**
* Writes to the socket.
* @param fd the FileDescriptor
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @exception IOException If an I/O error has occurred.
*/
private void socketWrite0(FileDescriptor fdObj, byte[] data, int off, int len) throws IOException
{
// [IKVM] this method is a direct port of the native code in openjdk6-b18\jdk\src\windows\native\java\net\SocketOutputStream.c
final int MAX_BUFFER_LEN = 2048;
cli.System.Net.Sockets.Socket fd;
int buflen = 65536; // MAX_HEAP_BUFFER_LEN
int n;
if (IS_NULL(fdObj)) {
throw new SocketException("socket closed");
} else {
fd = fdObj.getSocket();
}
if (IS_NULL(data)) {
throw new NullPointerException("data argument");
}
while(len > 0) {
int loff = 0;
int chunkLen = Math.min(buflen, len);
int llen = chunkLen;
int retry = 0;
while(llen > 0) {
n = send(fd, data, off + loff, llen, 0);
if (n > 0) {
llen -= n;
loff += n;
continue;
}
/*
* Due to a bug in Windows Sockets (observed on NT and Windows
* 2000) it may be necessary to retry the send. The issue is that
* on blocking sockets send/WSASend is supposed to block if there
* is insufficient buffer space available. If there are a large
* number of threads blocked on write due to congestion then it's
* possile to hit the NT/2000 bug whereby send returns WSAENOBUFS.
* The workaround we use is to retry the send. If we have a
* large buffer to send (>2k) then we retry with a maximum of
* 2k buffer. If we hit the issue with <=2k buffer then we backoff
* for 1 second and retry again. We repeat this up to a reasonable
* limit before bailing out and throwing an exception. In load
* conditions we've observed that the send will succeed after 2-3
* attempts but this depends on network buffers associated with
* other sockets draining.
*/
if (WSAGetLastError() == WSAENOBUFS) {
if (llen > MAX_BUFFER_LEN) {
buflen = MAX_BUFFER_LEN;
chunkLen = MAX_BUFFER_LEN;
llen = MAX_BUFFER_LEN;
continue;
}
if (retry >= 30) {
throw new SocketException("No buffer space available - exhausted attempts to queue buffer");
}
cli.System.Threading.Thread.Sleep(1000);
retry++;
continue;
}
/*
* Send failed - can be caused by close or write error.
*/
if (WSAGetLastError() == WSAENOTSOCK) {
throw new SocketException("Socket closed");
} else {
throw NET_ThrowCurrent("socket write error");
}
}
len -= chunkLen;
off += chunkLen;
}
}
/**
* Writes to the socket with appropriate locking of the
* FileDescriptor.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @exception IOException If an I/O error has occurred.
*/
private void socketWrite(byte b[], int off, int len) throws IOException {
if (len <= 0 || off < 0 || off + len > b.length) {
if (len == 0) {
return;
}
throw new ArrayIndexOutOfBoundsException();
}
Object traceContext = IoTrace.socketWriteBegin();
int bytesWritten = 0;
FileDescriptor fd = impl.acquireFD();
try {
socketWrite0(fd, b, off, len);
bytesWritten = len;
} catch (SocketException se) {
if (se instanceof sun.net.ConnectionResetException) {
impl.setConnectionResetPending();
se = new SocketException("Connection reset");
}
if (impl.isClosedOrPending()) {
throw new SocketException("Socket closed");
} else {
throw se;
}
} finally {
impl.releaseFD();
IoTrace.socketWriteEnd(traceContext, impl.address, impl.port, bytesWritten);
}
}
/**
* Writes a byte to the socket.
* @param b the data to be written
* @exception IOException If an I/O error has occurred.
*/
public void write(int b) throws IOException {
temp[0] = (byte)b;
socketWrite(temp, 0, 1);
}
/**
* Writes the contents of the buffer <i>b</i> to the socket.
* @param b the data to be written
* @exception SocketException If an I/O error has occurred.
*/
public void write(byte b[]) throws IOException {
socketWrite(b, 0, b.length);
}
/**
* Writes <i>length</i> bytes from buffer <i>b</i> starting at
* offset <i>len</i>.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @exception SocketException If an I/O error has occurred.
*/
public void write(byte b[], int off, int len) throws IOException {
socketWrite(b, off, len);
}
/**
* Closes the stream.
*/
private boolean closing = false;
public void close() throws IOException {
// Prevent recursion. See BugId 4484411
if (closing)
return;
closing = true;
if (socket != null) {
if (!socket.isClosed())
socket.close();
} else
impl.close();
closing = false;
}
/**
* Overrides finalize, the fd is closed by the Socket.
*/
protected void finalize() {}
}

View File

@ -515,6 +515,9 @@ static void bind0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this,
}
}
} else {
/* NET_BindV6() closes both sockets upon a failure */
_this.fd = null;
_this.fd1 = null;
NET_ThrowCurrent (env, "Cannot bind");
return;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -58,7 +58,6 @@ static final int java_net_SocketOptions_SO_LINGER = SocketOptions.SO_LINGER;
#include "java_net_SocketOptions.h"
#include "java_net_TwoStacksPlainSocketImpl.h"
#include "java_net_SocketImpl.h"
#include "java_net_InetAddress.h"
#include "java_io_FileDescriptor.h"
#include "java_lang_Integer.h"
@ -486,6 +485,10 @@ static void socketBind(JNIEnv env, TwoStacksPlainSocketImpl _this,
/* socket was re-created */
fd1Obj.setSocket(fd1);
}
} else {
/* NET_BindV6() closes both sockets upon a failure */
_this.fd = null;
_this.fd1 = null;
}
}
} else {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -318,6 +318,11 @@ final class net_util_md
{
int rv;
if (level == IPPROTO_IPV6 && optname == IPV6_TCLASS) {
((int[])optval)[0] = 0;
return 0;
}
rv = getsockopt(s, level, optname, optval);
@ -645,17 +650,17 @@ final class net_util_md
* structure for an IPv4 InetAddress.
*/
static int NET_InetAddressToSockaddr(JNIEnv env, InetAddress iaObj, int port, SOCKETADDRESS him, boolean v4MappedAddress) {
if (iaObj.family == InetAddress.IPv4) {
him.set(new IPEndPoint(new IPAddress(htonl(iaObj.address) & 0xFFFFFFFFL), port));
if (iaObj.holder().family == InetAddress.IPv4) {
him.set(new IPEndPoint(new IPAddress(htonl(iaObj.holder().address) & 0xFFFFFFFFL), port));
return 0;
} else {
Inet6Address v6addr = (Inet6Address)iaObj;
int scope = v6addr.getScopeId();
if (scope == 0) {
him.set(new IPEndPoint(new IPAddress(v6addr.ipaddress), port));
him.set(new IPEndPoint(new IPAddress(v6addr.getAddress()), port));
return 0;
} else {
him.set(new IPEndPoint(new IPAddress(v6addr.ipaddress, scope & 0xFFFFFFFFL), port));
him.set(new IPEndPoint(new IPAddress(v6addr.getAddress(), scope & 0xFFFFFFFFL), port));
return 0;
}
}
@ -725,7 +730,7 @@ final class net_util_md
}
static boolean NET_SockaddrEqualsInetAddress(SOCKETADDRESS him, InetAddress iaObj) {
int family = iaObj.family == InetAddress.IPv4 ? AF_INET : AF_INET6;
int family = iaObj.holder().family == InetAddress.IPv4 ? AF_INET : AF_INET6;
if (him.sa_family == AF_INET6) {
byte[] caddrNew = him.him6.sin6_addr;
@ -736,7 +741,7 @@ final class net_util_md
return false;
}
addrNew = NET_IPv4MappedToIPv4(caddrNew);
addrCur = iaObj.address;
addrCur = iaObj.holder().address;
if (addrNew == addrCur) {
return true;
} else {
@ -750,7 +755,7 @@ final class net_util_md
return false;
}
scope = ((Inet6Address)iaObj).getScopeId();
caddrCur = ((Inet6Address)iaObj).ipaddress;
caddrCur = ((Inet6Address)iaObj).getAddress();
if (NET_IsEqual(caddrNew, caddrCur) && cmpScopeID(scope, him)) {
return true;
} else {
@ -763,7 +768,7 @@ final class net_util_md
return false;
}
addrNew = ntohl(him.him4.sin_addr.s_addr);
addrCur = iaObj.address;
addrCur = iaObj.holder().address;
if (addrNew == addrCur) {
return true;
} else {
@ -875,10 +880,10 @@ final class net_util_md
}
static int getInetAddress_addr(JNIEnv env, InetAddress iaObj) {
return iaObj.address;
return iaObj.holder().address;
}
static int getInetAddress_family(JNIEnv env, InetAddress iaObj) {
return iaObj.family;
return iaObj.holder().family;
}
}

View File

@ -1 +0,0 @@
4b1579622418fcea5533553de4bd441a4303f8e7

View File

@ -1 +1 @@
21beaab3280677891e9c48e06d9a2bcbd21e7c24
2ce91edd530b14ec4a26b27fa65026fec0f867e1

View File

@ -27,11 +27,11 @@
<property name="pathsep" value=":" />
<property overwrite="false" name="signoption" value="" />
<property overwrite="false" name="SkipSystemCoreDependency" value="false" />
<property name="OPENJDK_VERSION" value="OpenJDK 8 b132" />
<property name="OPENJDK_VERSION" value="OpenJDK 8u45 b14" />
<property name="IMPLEMENTATION_VERSION" value="1.8.0" />
<property name="SPECIFICATION_VERSION" value="1.8" />
<property name="FULL_VERSION" value="1.8.0-b132" />
<property name="OpenJDK.dir" value="${project::get-base-directory()}/../../openjdk-8-b132" />
<property name="FULL_VERSION" value="1.8.0_45-b14" />
<property name="OpenJDK.dir" value="${project::get-base-directory()}/../../openjdk-8u45-b14" />
<if test="${platform::is-win32()}">
<property name="pathsep" value=";" />
</if>
@ -192,7 +192,7 @@
</target>
<target name="classpath">
<property name="CLASSPATH" value="mscorlib.jar${pathsep}System.Xml.jar${pathsep}${OpenJDK.dir}/jdk/src/share/classes/${pathsep}${OpenJDK.dir}/corba/src/share/classes" />
<property name="CLASSPATH" value="mscorlib.jar${pathsep}System.Xml.jar${pathsep}${OpenJDK.dir}/jdk/src/share/classes/${pathsep}${OpenJDK.dir}/corba/src/share/classes${pathsep}${OpenJDK.dir}/build/linux-x86_64-normal-server-release/jdk/gensrc" />
</target>
<target name="rmi" depends="classpath">

View File

@ -1 +1 @@
409d55c92d6f811ce77f595beba1d76dc74392f2
9bc69a05416bbd6824ff761bb41aef2e63e5d28b

View File

@ -0,0 +1,30 @@
/*
Copyright (C) 2015 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
package sun.awt;
final class DebugSettings
{
static void init() { }
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (C) 2009 Volker Berlin (i-net software)
* Copyright (C) 2010 Karsten Heinrich (i-net software)
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@ -596,8 +596,23 @@ final class Win32ShellFolder2 extends ShellFolder {
}
// Needs to be accessible to Win32ShellFolderManager2
@cli.System.Security.SecurityCriticalAttribute.Annotation
static native String getFileSystemPath(int csidl) throws IOException, InterruptedException;
static String getFileSystemPath(final int csidl) throws IOException, InterruptedException {
String path = invoke(new Callable<String>() {
public String call() throws IOException {
return getFileSystemPath0(csidl);
}
}, IOException.class);
if (path != null) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
}
return path;
}
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private static native String getFileSystemPath0(int csidl) throws IOException;
// Return whether the path is a network root.
// Path is assumed to be non-null

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2014, 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
@ -36,14 +36,15 @@ import java.security.PrivilegedAction;
import java.util.*;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Stream;
import cli.System.IntPtr;
import cli.System.Drawing.Bitmap;
import cli.System.Drawing.SystemIcons;
import sun.security.action.LoadLibraryAction;
import static sun.awt.shell.Win32ShellFolder2.*;
import sun.awt.OSInfo;
import sun.misc.ThreadGroupUtils;
// NOTE: This class supersedes Win32ShellFolderManager, which was removed
// from distribution after version 1.4.2.
@ -139,6 +140,8 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
if (desktop == null) {
try {
desktop = new Win32ShellFolder2(DESKTOP);
} catch (SecurityException e) {
// Ignore error
} catch (IOException e) {
// Ignore error
} catch (InterruptedException e) {
@ -152,6 +155,8 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
if (drives == null) {
try {
drives = new Win32ShellFolder2(DRIVES);
} catch (SecurityException e) {
// Ignore error
} catch (IOException e) {
// Ignore error
} catch (InterruptedException e) {
@ -169,6 +174,8 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
if (path != null) {
recent = createShellFolder(getDesktop(), new File(path));
}
} catch (SecurityException e) {
// Ignore error
} catch (InterruptedException e) {
// Ignore error
} catch (IOException e) {
@ -182,6 +189,8 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
if (network == null) {
try {
network = new Win32ShellFolder2(NETWORK);
} catch (SecurityException e) {
// Ignore error
} catch (IOException e) {
// Ignore error
} catch (InterruptedException e) {
@ -206,6 +215,8 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
personal.setIsPersonal();
}
}
} catch (SecurityException e) {
// Ignore error
} catch (InterruptedException e) {
// Ignore error
} catch (IOException e) {
@ -246,7 +257,7 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
if (file == null) {
file = getDesktop();
}
return file;
return checkFile(file);
} else if (key.equals("roots")) {
// Should be "History" and "Desktop" ?
if (roots == null) {
@ -257,11 +268,11 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
roots = (File[])super.get(key);
}
}
return roots;
return checkFiles(roots);
} else if (key.equals("fileChooserComboBoxFolders")) {
Win32ShellFolder2 desktop = getDesktop();
if (desktop != null) {
if (desktop != null && checkFile(desktop) != null) {
ArrayList<File> folders = new ArrayList<File>();
Win32ShellFolder2 drives = getDrives();
@ -272,15 +283,15 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
folders.add(desktop);
// Add all second level folders
File[] secondLevelFolders = desktop.listFiles();
File[] secondLevelFolders = checkFiles(desktop.listFiles());
Arrays.sort(secondLevelFolders);
for (File secondLevelFolder : secondLevelFolders) {
Win32ShellFolder2 folder = (Win32ShellFolder2) secondLevelFolder;
if (!folder.isFileSystem() || (folder.isDirectory() && !folder.isLink()) ) {
if (!folder.isFileSystem() || (folder.isDirectory() && !folder.isLink())) {
folders.add(folder);
// Add third level for "My Computer"
if (folder.equals(drives)) {
File[] thirdLevelFolders = folder.listFiles();
File[] thirdLevelFolders = checkFiles(folder.listFiles());
if (thirdLevelFolders != null && thirdLevelFolders.length > 0) {
List<File> thirdLevelFoldersList = Arrays.asList(thirdLevelFolders);
@ -290,7 +301,7 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
}
}
}
return folders.toArray(new File[folders.size()]);
return checkFiles(folders);
} else {
return super.get(key);
}
@ -327,7 +338,7 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
}
}
}
return folders.toArray(new File[folders.size()]);
return checkFiles(folders);
} else if (key.startsWith("fileChooserIcon ")) {
String name = key.substring(key.indexOf(" ") + 1);
@ -373,6 +384,41 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
return null;
}
private File checkFile(File file) {
SecurityManager sm = System.getSecurityManager();
return (sm == null || file == null) ? file : checkFile(file, sm);
}
private File checkFile(File file, SecurityManager sm) {
try {
sm.checkRead(file.getPath());
return file;
} catch (SecurityException se) {
return null;
}
}
private File[] checkFiles(File[] files) {
SecurityManager sm = System.getSecurityManager();
if (sm == null || files == null || files.length == 0) {
return files;
}
return checkFiles(Arrays.stream(files), sm);
}
private File[] checkFiles(List<File> files) {
SecurityManager sm = System.getSecurityManager();
if (sm == null || files.isEmpty()) {
return files.toArray(new File[files.size()]);
}
return checkFiles(files.stream(), sm);
}
private File[] checkFiles(Stream<File> filesStream, SecurityManager sm) {
return filesStream.filter((file) -> checkFile(file, sm) != null)
.toArray(File[]::new);
}
/**
* Does <code>dir</code> represent a "computer" such as a node on the network, or
* "My Computer" on the desktop.

View File

@ -0,0 +1,27 @@
/*
Copyright (C) 2015 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
package sun.java2d.loops;
// only needed at compile time, to satisfy import statement
public class TransformHelper { }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2014, 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
@ -48,6 +48,7 @@ public class VM {
return suspended;
}
@SuppressWarnings("deprecation")
public static boolean allowThreadSuspension(ThreadGroup g, boolean b) {
return g.allowThreadSuspension(b);
}
@ -145,7 +146,9 @@ public class VM {
*/
// public native static void writeJavaProfilerReport();
private static volatile boolean booted = false;
private static final Object lock = new Object();
static {
// [IKVM] force System properties initialization ("booting")
@ -163,13 +166,27 @@ public class VM {
// the booted flag to determine whether it is safe to query the system
// properties).
public static void booted() {
booted = true;
synchronized (lock) {
booted = true;
lock.notifyAll();
}
}
public static boolean isBooted() {
return booted;
}
// Waits until VM completes initialization
//
// This method is invoked by the Finalizer thread
public static void awaitBooted() throws InterruptedException {
synchronized (lock) {
while (!booted) {
lock.wait();
}
}
}
// Returns the maximum amount of allocatable direct buffer memory.
// The directMemory variable is initialized during system initialization
// in the saveAndRemoveProperties method.
@ -216,6 +233,14 @@ public class VM {
return allowArraySyntax;
}
/**
* Returns true if the given class loader is in the system domain
* in which all permissions are granted.
*/
public static boolean isSystemDomainLoader(ClassLoader loader) {
return loader == null;
}
/**
* Returns the system property of the specified key saved at
* system initialization time. This method should only be used
@ -282,6 +307,9 @@ public class VM {
// used by sun.launcher.LauncherHelper
props.remove("sun.java.launcher.diag");
// used by sun.misc.URLClassPath
props.remove("sun.cds.enableSharedLookupCache");
}
// Initialize any miscellenous operating system settings that need to be
@ -361,6 +389,12 @@ public class VM {
private final static int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;
private final static int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
/*
* Returns the first non-null class loader up the execution stack,
* or null if only code from the null class loader is on the stack.
*/
public static native ClassLoader latestUserDefinedLoader();
static {
initialize();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,13 +33,16 @@ public class Version {
"openjdk";
private static final String java_version =
"1.7.0-internal";
"1.8.0-internal";
private static final String java_runtime_name =
"OpenJDK Runtime Environment";
"OpenJDK Runtime Environment";
private static final String java_profile_name =
"";
private static final String java_runtime_version =
"1.7.0-internal-jeroen_2012_05_22_06_05-b00";
"1.8.0-internal-jeroen_2015_06_02_10_38-b00";
static {
init();
@ -87,23 +90,28 @@ public class Version {
boolean isHeadless = false;
/* Report that we're running headless if the property is true */
String headless = System.getProperty("java.awt.headless");
if ( (headless != null) && (headless.equalsIgnoreCase("true")) ) {
String headless = System.getProperty("java.awt.headless");
if ( (headless != null) && (headless.equalsIgnoreCase("true")) ) {
isHeadless = true;
}
}
/* First line: platform version. */
ps.println(launcher_name + " version \"" + java_version + "\"");
/* Second line: runtime version (ie, libraries). */
ps.print(java_runtime_name + " (build " + java_runtime_version);
ps.print(java_runtime_name + " (build " + java_runtime_version);
if (java_runtime_name.indexOf("Embedded") != -1 && isHeadless) {
// embedded builds report headless state
ps.print(", headless");
}
ps.println(')');
if (java_profile_name.length() > 0) {
// profile name
ps.print(", profile " + java_profile_name);
}
if (java_runtime_name.indexOf("Embedded") != -1 && isHeadless) {
// embedded builds report headless state
ps.print(", headless");
}
ps.println(')');
/* Third line: JVM information. */
String java_vm_name = System.getProperty("java.vm.name");
@ -328,7 +336,6 @@ public class Version {
// Return false if not available which implies an old VM (Tiger or before).
private static native boolean getJvmVersionInfo();
private static native void getJdkVersionInfo();
}
// Help Emacs a little because this file doesn't end in .java.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,7 +33,7 @@ import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.util.*;
import sun.net.ResourceManager;
import sun.net.ExtendedOptionsImpl;
/**
* An implementation of DatagramChannels.
@ -169,6 +169,7 @@ class DatagramChannelImpl
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
// Perform security check before returning address
return Net.getRevealedLocalAddress(localAddress);
}
}
@ -194,15 +195,8 @@ class DatagramChannelImpl
synchronized (stateLock) {
ensureOpen();
if (name == StandardSocketOptions.IP_TOS) {
// IPv4 only; no-op for IPv6
if (family == StandardProtocolFamily.INET) {
Net.setSocketOption(fd, family, name, value);
}
return this;
}
if (name == StandardSocketOptions.IP_MULTICAST_TTL ||
if (name == StandardSocketOptions.IP_TOS ||
name == StandardSocketOptions.IP_MULTICAST_TTL ||
name == StandardSocketOptions.IP_MULTICAST_LOOP)
{
// options are protocol dependent
@ -255,16 +249,8 @@ class DatagramChannelImpl
synchronized (stateLock) {
ensureOpen();
if (name == StandardSocketOptions.IP_TOS) {
// IPv4 only; always return 0 on IPv6
if (family == StandardProtocolFamily.INET) {
return (T) Net.getSocketOption(fd, family, name);
} else {
return (T) Integer.valueOf(0);
}
}
if (name == StandardSocketOptions.IP_MULTICAST_TTL ||
if (name == StandardSocketOptions.IP_TOS ||
name == StandardSocketOptions.IP_MULTICAST_TTL ||
name == StandardSocketOptions.IP_MULTICAST_LOOP)
{
return (T) Net.getSocketOption(fd, family, name);
@ -317,6 +303,9 @@ class DatagramChannelImpl
set.add(StandardSocketOptions.IP_MULTICAST_IF);
set.add(StandardSocketOptions.IP_MULTICAST_TTL);
set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
if (ExtendedOptionsImpl.flowSupported()) {
set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
}
return Collections.unmodifiableSet(set);
}
}
@ -553,7 +542,7 @@ class DatagramChannelImpl
return 0;
readerThread = NativeThread.current();
do {
n = IOUtil.read(fd, buf, -1, nd, readLock);
n = IOUtil.read(fd, buf, -1, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
@ -609,7 +598,7 @@ class DatagramChannelImpl
return 0;
writerThread = NativeThread.current();
do {
n = IOUtil.write(fd, buf, -1, nd, writeLock);
n = IOUtil.write(fd, buf, -1, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
@ -747,6 +736,26 @@ class DatagramChannelImpl
// set or refresh local address
localAddress = Net.localAddress(fd);
// flush any packets already received.
boolean blocking = false;
synchronized (blockingLock()) {
try {
blocking = isBlocking();
// remainder of each packet thrown away
ByteBuffer tmpBuf = ByteBuffer.allocate(1);
if (blocking) {
configureBlocking(false);
}
do {
tmpBuf.clear();
} while (receive(tmpBuf) != null);
} finally {
if (blocking) {
configureBlocking(true);
}
}
}
}
}
}
@ -1032,25 +1041,24 @@ class DatagramChannelImpl
int oldOps = sk.nioReadyOps();
int newOps = initialOps;
if ((ops & PollArrayWrapper.POLLNVAL) != 0) {
if ((ops & Net.POLLNVAL) != 0) {
// This should only happen if this channel is pre-closed while a
// selection operation is in progress
// ## Throw an error if this channel has not been pre-closed
return false;
}
if ((ops & (PollArrayWrapper.POLLERR
| PollArrayWrapper.POLLHUP)) != 0) {
if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
newOps = intOps;
sk.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
if (((ops & PollArrayWrapper.POLLIN) != 0) &&
if (((ops & Net.POLLIN) != 0) &&
((intOps & SelectionKey.OP_READ) != 0))
newOps |= SelectionKey.OP_READ;
if (((ops & PollArrayWrapper.POLLOUT) != 0) &&
if (((ops & Net.POLLOUT) != 0) &&
((intOps & SelectionKey.OP_WRITE) != 0))
newOps |= SelectionKey.OP_WRITE;
@ -1066,6 +1074,28 @@ class DatagramChannelImpl
return translateReadyOps(ops, 0, sk);
}
// package-private
int poll(int events, long timeout) throws IOException {
assert Thread.holdsLock(blockingLock()) && !isBlocking();
synchronized (readLock) {
int n = 0;
try {
begin();
synchronized (stateLock) {
if (!isOpen())
return 0;
readerThread = NativeThread.current();
}
n = Net.poll(fd, events, timeout);
} finally {
readerThread = 0;
end(n > 0);
}
return n;
}
}
/**
* Translates an interest operation set into a native poll event set
*/
@ -1073,11 +1103,11 @@ class DatagramChannelImpl
int newOps = 0;
if ((ops & SelectionKey.OP_READ) != 0)
newOps |= PollArrayWrapper.POLLIN;
newOps |= Net.POLLIN;
if ((ops & SelectionKey.OP_WRITE) != 0)
newOps |= PollArrayWrapper.POLLOUT;
newOps |= Net.POLLOUT;
if ((ops & SelectionKey.OP_CONNECT) != 0)
newOps |= PollArrayWrapper.POLLIN;
newOps |= Net.POLLIN;
sk.selector.putEventOps(sk, newOps);
}
@ -1106,7 +1136,7 @@ class DatagramChannelImpl
throws IOException;
static {
Util.load();
IOUtil.load();
initIDs();
}

View File

@ -165,9 +165,9 @@ final class DotNetSelectorImpl extends SelectorImpl
private int updateSelectedKeys(ArrayList read, ArrayList write, ArrayList error)
{
updateCount++;
int keys = processFDSet(updateCount, read, PollArrayWrapper.POLLIN);
keys += processFDSet(updateCount, write, PollArrayWrapper.POLLCONN | PollArrayWrapper.POLLOUT);
keys += processFDSet(updateCount, error, PollArrayWrapper.POLLIN | PollArrayWrapper.POLLCONN | PollArrayWrapper.POLLOUT);
int keys = processFDSet(updateCount, read, Net.POLLIN);
keys += processFDSet(updateCount, write, Net.POLLCONN | Net.POLLOUT);
keys += processFDSet(updateCount, error, Net.POLLIN | Net.POLLCONN | Net.POLLOUT);
return keys;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,12 +33,21 @@ import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.*;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.FileLockInterruptionException;
import java.nio.channels.NonReadableChannelException;
import java.nio.channels.NonWritableChannelException;
import java.nio.channels.OverlappingFileLockException;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.List;
import java.security.AccessController;
import sun.misc.Cleaner;
import sun.misc.IoTrace;
import sun.security.action.GetPropertyAction;
public class FileChannelImpl
@ -63,7 +72,8 @@ public class FileChannelImpl
// Required to prevent finalization of creating stream (immutable)
private final Object parent;
// The path of the referenced file (null if the parent stream is created with a file descriptor)
// The path of the referenced file
// (null if the parent stream is created with a file descriptor)
private final String path;
// Thread-safe set of IDs of native threads, for signalling
@ -121,7 +131,7 @@ public class FileChannelImpl
}
}
nd.preClose(fd);
// signal any threads blocked on this channel
threads.signalAndWait();
if (parent != null) {
@ -145,19 +155,17 @@ public class FileChannelImpl
synchronized (positionLock) {
int n = 0;
int ti = -1;
Object traceContext = IoTrace.fileReadBegin(path);
try {
begin();
ti = threads.add();
if (!isOpen())
return 0;
do {
n = IOUtil.read(fd, dst, -1, nd, positionLock);
n = IOUtil.read(fd, dst, -1, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0);
end(n > 0);
assert IOStatus.check(n);
}
@ -175,7 +183,6 @@ public class FileChannelImpl
synchronized (positionLock) {
long n = 0;
int ti = -1;
Object traceContext = IoTrace.fileReadBegin(path);
try {
begin();
ti = threads.add();
@ -187,7 +194,6 @@ public class FileChannelImpl
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0);
end(n > 0);
assert IOStatus.check(n);
}
@ -201,20 +207,18 @@ public class FileChannelImpl
synchronized (positionLock) {
int n = 0;
int ti = -1;
Object traceContext = IoTrace.fileWriteBegin(path);
try {
begin();
ti = threads.add();
if (!isOpen())
return 0;
do {
n = IOUtil.write(fd, src, -1, nd, positionLock);
n = IOUtil.write(fd, src, -1, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
end(n > 0);
IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0);
assert IOStatus.check(n);
}
}
@ -231,7 +235,6 @@ public class FileChannelImpl
synchronized (positionLock) {
long n = 0;
int ti = -1;
Object traceContext = IoTrace.fileWriteBegin(path);
try {
begin();
ti = threads.add();
@ -243,7 +246,6 @@ public class FileChannelImpl
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0);
end(n > 0);
assert IOStatus.check(n);
}
@ -321,12 +323,10 @@ public class FileChannelImpl
}
}
public FileChannel truncate(long size) throws IOException {
public FileChannel truncate(long newSize) throws IOException {
ensureOpen();
if (size < 0)
throw new IllegalArgumentException();
if (size > size())
return this;
if (newSize < 0)
throw new IllegalArgumentException("Negative size");
if (!writable)
throw new NonWritableChannelException();
synchronized (positionLock) {
@ -339,6 +339,14 @@ public class FileChannelImpl
if (!isOpen())
return null;
// get current size
long size;
do {
size = nd.size(fd);
} while ((size == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
// get current position
do {
p = position0(fd, -1);
@ -347,20 +355,22 @@ public class FileChannelImpl
return null;
assert p >= 0;
// truncate file
do {
rv = nd.truncate(fd, size);
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
// truncate file if given size is less than the current size
if (newSize < size) {
do {
rv = nd.truncate(fd, newSize);
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
}
// [IKVM] in append mode we're not allowed to seek backwards, but the atomic append will honor the new file size
if (append)
return this;
// set position to size if greater than size
if (p > size)
p = size;
// if position is beyond new size then adjust it
if (p > newSize)
p = newSize;
do {
rv = (int)position0(fd, p);
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
@ -522,21 +532,30 @@ public class FileChannelImpl
if (!readable)
throw new NonReadableChannelException();
ensureOpen();
if (nd.needsPositionLock()) {
synchronized (positionLock) {
return readInternal(dst, position);
}
} else {
return readInternal(dst, position);
}
}
private int readInternal(ByteBuffer dst, long position) throws IOException {
assert !nd.needsPositionLock() || Thread.holdsLock(positionLock);
int n = 0;
int ti = -1;
Object traceContext = IoTrace.fileReadBegin(path);
try {
begin();
ti = threads.add();
if (!isOpen())
return -1;
do {
n = IOUtil.read(fd, dst, position, nd, positionLock);
n = IOUtil.read(fd, dst, position, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0);
end(n > 0);
assert IOStatus.check(n);
}
@ -550,22 +569,31 @@ public class FileChannelImpl
if (!writable)
throw new NonWritableChannelException();
ensureOpen();
if (nd.needsPositionLock()) {
synchronized (positionLock) {
return writeInternal(src, position);
}
} else {
return writeInternal(src, position);
}
}
private int writeInternal(ByteBuffer src, long position) throws IOException {
assert !nd.needsPositionLock() || Thread.holdsLock(positionLock);
int n = 0;
int ti = -1;
Object traceContext = IoTrace.fileWriteBegin(path);
try {
begin();
ti = threads.add();
if (!isOpen())
return -1;
do {
n = IOUtil.write(fd, src, position, nd, positionLock);
n = IOUtil.write(fd, src, position, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
end(n > 0);
IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0);
assert IOStatus.check(n);
}
}
@ -642,6 +670,8 @@ public class FileChannelImpl
throws IOException
{
ensureOpen();
if (mode == null)
throw new NullPointerException("Mode is null");
if (position < 0L)
throw new IllegalArgumentException("Negative position");
if (size < 0L)
@ -650,6 +680,7 @@ public class FileChannelImpl
throw new IllegalArgumentException("Position + size overflow");
if (size > Integer.MAX_VALUE)
throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE");
int imode = -1;
if (mode == MapMode.READ_ONLY)
imode = MAP_RO;
@ -670,7 +701,15 @@ public class FileChannelImpl
ti = threads.add();
if (!isOpen())
return null;
if (size() < position + size) { // Extend file size
long filesize;
do {
filesize = nd.size(fd);
} while ((filesize == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
if (filesize < position + size) { // Extend file size
if (!writable) {
throw new IOException("Channel not open for writing " +
"- cannot extend file to required size");
@ -679,6 +718,8 @@ public class FileChannelImpl
do {
rv = nd.truncate(fd, position + size);
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
}
if (size == 0) {
addr = 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,14 +27,16 @@ package sun.nio.ch;
import java.io.*;
import java.net.*;
import jdk.net.*;
import java.nio.channels.*;
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import sun.net.ExtendedOptionsImpl;
class Net { // package-private
public class Net {
private Net() { }
@ -45,12 +47,6 @@ class Net { // package-private
}
};
// Value of jdk.net.revealLocalAddress
private static boolean revealLocalAddress;
// True if jdk.net.revealLocalAddress had been read
private static volatile boolean propRevealLocalAddress;
// set to true if exclusive binding is on for Windows
private static final boolean exclusiveBind;
@ -59,8 +55,8 @@ class Net { // package-private
if (availLevel >= 0) {
String exclBindProp =
java.security.AccessController.doPrivileged(
new PrivilegedAction<String>() {
@Override
new PrivilegedAction<String>() {
@Override
public String run() {
return System.getProperty(
"sun.net.useExclusiveBind");
@ -117,7 +113,7 @@ class Net { // package-private
return canJoin6WithIPv4Group0();
}
static InetSocketAddress checkAddress(SocketAddress sa) {
public static InetSocketAddress checkAddress(SocketAddress sa) {
if (sa == null)
throw new NullPointerException();
if (!(sa instanceof InetSocketAddress))
@ -197,43 +193,19 @@ class Net { // package-private
if (addr == null || sm == null)
return addr;
if (!getRevealLocalAddress()) {
try{
sm.checkConnect(addr.getAddress().getHostAddress(), -1);
// Security check passed
} catch (SecurityException e) {
// Return loopback address only if security check fails
try{
sm.checkConnect(addr.getAddress().getHostAddress(), -1);
//Security check passed
} catch (SecurityException e) {
//Return loopback address
addr = getLoopbackAddress(addr.getPort());
}
addr = getLoopbackAddress(addr.getPort());
}
return addr;
}
static String getRevealedLocalAddressAsString(InetSocketAddress addr) {
if (!getRevealLocalAddress() && System.getSecurityManager() != null)
addr = getLoopbackAddress(addr.getPort());
return addr.toString();
}
private static boolean getRevealLocalAddress() {
if (!propRevealLocalAddress) {
try {
revealLocalAddress = Boolean.parseBoolean(
AccessController.doPrivileged(
new PrivilegedExceptionAction<String>() {
public String run() {
return System.getProperty(
"jdk.net.revealLocalAddress");
}
}));
} catch (Exception e) {
// revealLocalAddress is false
}
propRevealLocalAddress = true;
}
return revealLocalAddress;
return System.getSecurityManager() == null ? addr.toString() :
getLoopbackAddress(addr.getPort()).toString();
}
private static InetSocketAddress getLoopbackAddress(int port) {
@ -327,6 +299,16 @@ class Net { // package-private
// only simple values supported by this method
Class<?> type = name.type();
if (type == SocketFlow.class) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new NetworkPermission("setOption.SO_FLOW_SLA"));
}
ExtendedOptionsImpl.setFlowOption(fd, (SocketFlow)value);
return;
}
if (type != Integer.class && type != Boolean.class)
throw new AssertionError("Should not reach here");
@ -370,7 +352,8 @@ class Net { // package-private
}
boolean mayNeedConversion = (family == UNSPEC);
setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg);
boolean isIPv6 = (family == StandardProtocolFamily.INET6);
setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg, isIPv6);
}
static Object getSocketOption(FileDescriptor fd, ProtocolFamily family,
@ -379,6 +362,16 @@ class Net { // package-private
{
Class<?> type = name.type();
if (type == SocketFlow.class) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new NetworkPermission("getOption.SO_FLOW_SLA"));
}
SocketFlow flow = SocketFlow.create();
ExtendedOptionsImpl.getFlowOption(fd, flow);
return flow;
}
// only simple values supported by this method
if (type != Integer.class && type != Boolean.class)
throw new AssertionError("Should not reach here");
@ -430,7 +423,7 @@ class Net { // package-private
// Due to oddities SO_REUSEADDR on windows reuse is ignored
private static native FileDescriptor socket0(boolean preferIPv6, boolean stream, boolean reuse);
static void bind(FileDescriptor fd, InetAddress addr, int port)
public static void bind(FileDescriptor fd, InetAddress addr, int port)
throws IOException
{
bind(UNSPEC, fd, addr, port);
@ -484,7 +477,7 @@ class Net { // package-private
private static native InetAddress localInetAddress(FileDescriptor fd)
throws IOException;
static InetSocketAddress localAddress(FileDescriptor fd)
public static InetSocketAddress localAddress(FileDescriptor fd)
throws IOException
{
return new InetSocketAddress(localInetAddress(fd), localPort(fd));
@ -507,7 +500,10 @@ class Net { // package-private
throws IOException;
private static native void setIntOption0(FileDescriptor fd, boolean mayNeedConversion,
int level, int opt, int arg)
int level, int opt, int arg, boolean isIPv6)
throws IOException;
static native int poll(FileDescriptor fd, int events, long timeout)
throws IOException;
// -- Multicast support --
@ -606,4 +602,15 @@ class Net { // package-private
static native int getInterface6(FileDescriptor fd) throws IOException;
/**
* Event masks for the various poll system calls.
* They will be set platform dependant in the static initializer below.
*/
public static final short POLLIN = 0x0001;
public static final short POLLCONN = 0x0002;
public static final short POLLOUT = 0x0004;
public static final short POLLERR = 0x0008;
public static final short POLLHUP = 0x0010;
public static final short POLLNVAL = 0x0020;
public static final short POLLREMOVE = 0x0800;
}

View File

@ -1,37 +0,0 @@
/*
* Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch;
class PollArrayWrapper
{
static final short POLLIN = 0x0001;
static final short POLLCONN = 0x0002;
static final short POLLOUT = 0x0004;
static final short POLLERR = 0x0008;
static final short POLLHUP = 0x0010;
static final short POLLNVAL = 0x0020;
static final short POLLREMOVE = 0x0800;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -24,7 +24,7 @@
* questions.
*
*/
// AUTOMATICALLY GENERATED FILE - DO NOT EDIT
package sun.nio.ch;
import java.net.SocketOption;
import java.net.StandardSocketOptions;
@ -34,7 +34,6 @@ import java.util.Map;
import java.util.HashMap;
import cli.System.Net.Sockets.SocketOptionLevel;
import cli.System.Net.Sockets.SocketOptionName;
class SocketOptionRegistry {
private SocketOptionRegistry() { }
private static class RegistryKey {
@ -72,6 +71,7 @@ class SocketOptionRegistry {
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_IF, StandardProtocolFamily.INET), new OptionKey(SocketOptionLevel.IP, SocketOptionName.MulticastInterface));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_TTL, StandardProtocolFamily.INET), new OptionKey(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_LOOP, StandardProtocolFamily.INET), new OptionKey(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback));
map.put(new RegistryKey(StandardSocketOptions.IP_TOS, StandardProtocolFamily.INET6), new OptionKey(SocketOptionLevel.IPv6, ikvm.internal.Winsock.IPV6_TCLASS));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_IF, StandardProtocolFamily.INET6), new OptionKey(SocketOptionLevel.IPv6, SocketOptionName.MulticastInterface));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_TTL, StandardProtocolFamily.INET6), new OptionKey(SocketOptionLevel.IPv6, SocketOptionName.IpTimeToLive));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_LOOP, StandardProtocolFamily.INET6), new OptionKey(SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback));

View File

@ -36,6 +36,8 @@ import cli.System.IO.FileMode;
import cli.System.IO.FileShare;
import cli.System.IO.FileStream;
import cli.System.IO.FileOptions;
import cli.System.Runtime.InteropServices.DllImportAttribute;
import cli.System.Runtime.InteropServices.Marshal;
import cli.System.Security.AccessControl.FileSystemRights;
import com.sun.nio.file.ExtendedOpenOption;
import java.io.FileDescriptor;
@ -338,7 +340,7 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider
}
}
return FileChannelImpl.open(open(npath.path, mode, rights, share, options), read, write, append, null);
return FileChannelImpl.open(open(npath.path, mode, rights, share, options), npath.path, read, write, append, null);
}
private static FileDescriptor open(String path, int mode, int rights, int share, int options) throws IOException
@ -628,6 +630,7 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider
NetPath nsource = NetPath.from(source);
NetPath ntarget = NetPath.from(target);
boolean overwrite = false;
boolean atomicMove = false;
for (CopyOption opt : options)
{
if (opt == StandardCopyOption.REPLACE_EXISTING)
@ -636,7 +639,14 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider
}
else if (opt == StandardCopyOption.ATOMIC_MOVE)
{
throw new AtomicMoveNotSupportedException(nsource.path, ntarget.path, "Unsupported copy option");
if (WINDOWS)
{
atomicMove = true;
}
else
{
throw new AtomicMoveNotSupportedException(nsource.path, ntarget.path, "Unsupported copy option");
}
}
else
{
@ -651,6 +661,36 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider
sm.checkRead(nsource.path);
sm.checkWrite(ntarget.path);
}
if (atomicMove)
{
int MOVEFILE_REPLACE_EXISTING = 1;
if (MoveFileEx(nsource.path, ntarget.path, MOVEFILE_REPLACE_EXISTING) == 0)
{
final int ERROR_FILE_NOT_FOUND = 2;
final int ERROR_PATH_NOT_FOUND = 3;
final int ERROR_ACCESS_DENIED = 5;
final int ERROR_NOT_SAME_DEVICE = 17;
final int ERROR_FILE_EXISTS = 80;
final int ERROR_ALREADY_EXISTS = 183;
int lastError = Marshal.GetLastWin32Error();
switch (lastError)
{
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
throw new NoSuchFileException(nsource.path, ntarget.path, null);
case ERROR_ACCESS_DENIED:
throw new AccessDeniedException(nsource.path, ntarget.path, null);
case ERROR_NOT_SAME_DEVICE:
throw new AtomicMoveNotSupportedException(nsource.path, ntarget.path, "Unsupported copy option");
case ERROR_FILE_EXISTS:
case ERROR_ALREADY_EXISTS:
throw new FileAlreadyExistsException(nsource.path, ntarget.path, null);
default:
throw new FileSystemException(nsource.path, ntarget.path, "Error " + lastError);
}
}
return;
}
try
{
if (false) throw new cli.System.ArgumentException();
@ -711,6 +751,9 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider
}
}
@DllImportAttribute.Annotation(value="kernel32", SetLastError=true)
private static native int MoveFileEx(String lpExistingFileName, String lpNewFileName, int dwFlags);
public boolean isSameFile(Path path, Path path2) throws IOException
{
if (path.equals(path2))

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,7 +34,6 @@
package sun.reflect;
import java.lang.reflect.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ -47,17 +46,18 @@ public class Reflection {
view, where they are sensitive or they may contain VM-internal objects.
These Maps are updated very rarely. Rather than synchronize on
each access, we use copy-on-write */
private static volatile Map<Class,String[]> fieldFilterMap;
private static volatile Map<Class,String[]> methodFilterMap;
private static volatile Map<Class<?>,String[]> fieldFilterMap;
private static volatile Map<Class<?>,String[]> methodFilterMap;
static {
Map<Class,String[]> map = new HashMap<Class,String[]>();
Map<Class<?>,String[]> map = new HashMap<Class<?>,String[]>();
map.put(Reflection.class,
new String[] {"fieldFilterMap", "methodFilterMap"});
map.put(System.class, new String[] {"security"});
map.put(Class.class, new String[] {"classLoader"});
fieldFilterMap = map;
methodFilterMap = new HashMap<Class,String[]>();
methodFilterMap = new HashMap<>();
// [IKVM] to avoid initialization order issues, we actually add
// Unsafe.getUnsafe() here, instead of in Unsafe's class initializer
methodFilterMap.put(sun.misc.Unsafe.class, new String[] {"getUnsafe"});
@ -67,21 +67,15 @@ public class Reflection {
ignoring frames associated with java.lang.reflect.Method.invoke()
and its implementation. */
@CallerSensitive
public static Class getCallerClass() {
return getCallerClass(2);
}
public static native Class<?> getCallerClass();
/** Returns the class of the method <code>realFramesToSkip</code>
frames up the stack (zero-based), ignoring frames associated
with java.lang.reflect.Method.invoke() and its implementation.
The first frame is that associated with this method, so
<code>getCallerClass(0)</code> returns the Class object for
sun.reflect.Reflection. Frames associated with
java.lang.reflect.Method.invoke() and its implementation are
completely ignored and do not count toward the number of "real"
frames skipped. */
@CallerSensitive
public static native Class getCallerClass(int realFramesToSkip);
/**
* @deprecated This method will be removed in JDK 9.
* This method is a private JDK API and retained temporarily for
* existing code to run until a replacement API is defined.
*/
@Deprecated
public static native Class<?> getCallerClass(int depth);
/** Retrieves the access flags written to the class file. For
inner classes these flags may differ from those returned by
@ -91,18 +85,18 @@ public class Reflection {
to compatibility reasons; see 4471811. Only the values of the
low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
valid. */
private static native int getClassAccessFlags(Class c);
public static native int getClassAccessFlags(Class<?> c);
/** A quick "fast-path" check to try to avoid getCallerClass()
calls. */
public static boolean quickCheckMemberAccess(Class memberClass,
public static boolean quickCheckMemberAccess(Class<?> memberClass,
int modifiers)
{
return Modifier.isPublic(getClassAccessFlags(memberClass) & modifiers);
}
public static void ensureMemberAccess(Class currentClass,
Class memberClass,
public static void ensureMemberAccess(Class<?> currentClass,
Class<?> memberClass,
Object target,
int modifiers)
throws IllegalAccessException
@ -124,13 +118,13 @@ public class Reflection {
/*IKVM*/
private static native boolean checkInternalAccess(Class currentClass, Class memberClass);
public static boolean verifyMemberAccess(Class currentClass,
public static boolean verifyMemberAccess(Class<?> currentClass,
// Declaring class of field
// or method
Class memberClass,
Class<?> memberClass,
// May be NULL in case of statics
Object target,
int modifiers)
Object target,
int modifiers)
{
// Verify that currentClass can access a field, method, or
// constructor of memberClass, where that member's access bits are
@ -192,7 +186,7 @@ public class Reflection {
if (Modifier.isProtected(modifiers)) {
// Additional test for protected members: JLS 6.6.2
Class targetClass = (target == null ? memberClass : target.getClass());
Class<?> targetClass = (target == null ? memberClass : target.getClass());
if (targetClass != currentClass) {
if (!gotIsSameClassPackage) {
isSameClassPackage = isSameClassPackage(currentClass, memberClass);
@ -209,7 +203,7 @@ public class Reflection {
return true;
}
private static boolean isSameClassPackage(Class c1, Class c2) {
private static boolean isSameClassPackage(Class<?> c1, Class<?> c2) {
return isSameClassPackage(c1.getClassLoader(), c1.getName(),
c2.getClassLoader(), c2.getName());
}
@ -264,8 +258,8 @@ public class Reflection {
}
}
static boolean isSubclassOf(Class queryClass,
Class ofClass)
static boolean isSubclassOf(Class<?> queryClass,
Class<?> ofClass)
{
while (queryClass != null) {
if (queryClass == ofClass) {
@ -277,31 +271,31 @@ public class Reflection {
}
// fieldNames must contain only interned Strings
public static synchronized void registerFieldsToFilter(Class containingClass,
public static synchronized void registerFieldsToFilter(Class<?> containingClass,
String ... fieldNames) {
fieldFilterMap =
registerFilter(fieldFilterMap, containingClass, fieldNames);
}
// methodNames must contain only interned Strings
public static synchronized void registerMethodsToFilter(Class containingClass,
public static synchronized void registerMethodsToFilter(Class<?> containingClass,
String ... methodNames) {
methodFilterMap =
registerFilter(methodFilterMap, containingClass, methodNames);
}
private static Map<Class,String[]> registerFilter(Map<Class,String[]> map,
Class containingClass, String ... names) {
private static Map<Class<?>,String[]> registerFilter(Map<Class<?>,String[]> map,
Class<?> containingClass, String ... names) {
if (map.get(containingClass) != null) {
throw new IllegalArgumentException
("Filter already registered: " + containingClass);
}
map = new HashMap<Class,String[]>(map);
map = new HashMap<Class<?>,String[]>(map);
map.put(containingClass, names);
return map;
}
public static Field[] filterFields(Class containingClass,
public static Field[] filterFields(Class<?> containingClass,
Field[] fields) {
if (fieldFilterMap == null) {
// Bootstrapping
@ -310,7 +304,7 @@ public class Reflection {
return (Field[])filter(fields, fieldFilterMap.get(containingClass));
}
public static Method[] filterMethods(Class containingClass, Method[] methods) {
public static Method[] filterMethods(Class<?> containingClass, Method[] methods) {
if (methodFilterMap == null) {
// Bootstrapping
return methods;
@ -352,4 +346,27 @@ public class Reflection {
}
return newMembers;
}
/**
* Tests if the given method is caller-sensitive and the declaring class
* is defined by either the bootstrap class loader or extension class loader.
*/
public static boolean isCallerSensitive(Method m) {
final ClassLoader loader = m.getDeclaringClass().getClassLoader();
if (sun.misc.VM.isSystemDomainLoader(loader) || isExtClassLoader(loader)) {
return m.isAnnotationPresent(CallerSensitive.class);
}
return false;
}
private static boolean isExtClassLoader(ClassLoader loader) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
while (cl != null) {
if (cl.getParent() == null && cl == loader) {
return true;
}
cl = cl.getParent();
}
return false;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,12 +32,14 @@
package sun.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import sun.reflect.misc.ReflectUtil;
/** <P> The master factory for all reflective objects, both those in
java.lang.reflect (Fields, Methods, Constructors) as well as their
@ -53,9 +55,9 @@ import java.security.PrivilegedAction;
public class ReflectionFactory {
private static Permission reflectionFactoryAccessPerm
private static final Permission reflectionFactoryAccessPerm
= new RuntimePermission("reflectionFactoryAccess");
private static ReflectionFactory soleInstance = new ReflectionFactory();
private static final ReflectionFactory soleInstance = new ReflectionFactory();
// Provides access to package-private mechanisms in java.lang.reflect
private static volatile LangReflectAccess langReflectAccess;
@ -129,7 +131,7 @@ public class ReflectionFactory {
private native ConstructorAccessor newConstructorAccessor0(Constructor c);
public ConstructorAccessor newConstructorAccessor(Constructor c) {
public ConstructorAccessor newConstructorAccessor(Constructor<?> c) {
Class<?> declaringClass = c.getDeclaringClass();
if (Modifier.isAbstract(declaringClass.getModifiers())) {
return new InstantiationExceptionConstructorAccessorImpl(null);
@ -195,14 +197,14 @@ public class ReflectionFactory {
/** Creates a new java.lang.reflect.Constructor. Access checks as
per java.lang.reflect.AccessibleObject are not overridden. */
public Constructor newConstructor(Class<?> declaringClass,
Class<?>[] parameterTypes,
Class<?>[] checkedExceptions,
int modifiers,
int slot,
String signature,
byte[] annotations,
byte[] parameterAnnotations)
public Constructor<?> newConstructor(Class<?> declaringClass,
Class<?>[] parameterTypes,
Class<?>[] checkedExceptions,
int modifiers,
int slot,
String signature,
byte[] annotations,
byte[] parameterAnnotations)
{
return langReflectAccess().newConstructor(declaringClass,
parameterTypes,
@ -226,13 +228,13 @@ public class ReflectionFactory {
/** Gets the ConstructorAccessor object for a
java.lang.reflect.Constructor */
public ConstructorAccessor getConstructorAccessor(Constructor c) {
public ConstructorAccessor getConstructorAccessor(Constructor<?> c) {
return langReflectAccess().getConstructorAccessor(c);
}
/** Sets the ConstructorAccessor object for a
java.lang.reflect.Constructor */
public void setConstructorAccessor(Constructor c,
public void setConstructorAccessor(Constructor<?> c,
ConstructorAccessor accessor)
{
langReflectAccess().setConstructorAccessor(c, accessor);
@ -259,6 +261,12 @@ public class ReflectionFactory {
return langReflectAccess().copyConstructor(arg);
}
/** Gets the byte[] that encodes TypeAnnotations on an executable.
*/
public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
return langReflectAccess().getExecutableTypeAnnotationBytes(ex);
}
//--------------------------------------------------------------------------
//
// Routines used by serialization
@ -267,8 +275,8 @@ public class ReflectionFactory {
private static native ConstructorAccessor newConstructorAccessorForSerialization(Class classToInstantiate, Constructor constructorToCall);
public Constructor newConstructorForSerialization
(Class<?> classToInstantiate, Constructor constructorToCall)
public Constructor<?> newConstructorForSerialization
(Class<?> classToInstantiate, Constructor<?> constructorToCall)
{
// Fast path
if (constructorToCall.getDeclaringClass() == classToInstantiate) {
@ -276,18 +284,18 @@ public class ReflectionFactory {
}
ConstructorAccessor acc = newConstructorAccessorForSerialization(classToInstantiate, constructorToCall);
Constructor c = newConstructor(constructorToCall.getDeclaringClass(),
constructorToCall.getParameterTypes(),
constructorToCall.getExceptionTypes(),
constructorToCall.getModifiers(),
langReflectAccess().
getConstructorSlot(constructorToCall),
langReflectAccess().
getConstructorSignature(constructorToCall),
langReflectAccess().
getConstructorAnnotations(constructorToCall),
langReflectAccess().
getConstructorParameterAnnotations(constructorToCall));
Constructor<?> c = newConstructor(constructorToCall.getDeclaringClass(),
constructorToCall.getParameterTypes(),
constructorToCall.getExceptionTypes(),
constructorToCall.getModifiers(),
langReflectAccess().
getConstructorSlot(constructorToCall),
langReflectAccess().
getConstructorSignature(constructorToCall),
langReflectAccess().
getConstructorAnnotations(constructorToCall),
langReflectAccess().
getConstructorParameterAnnotations(constructorToCall));
setConstructorAccessor(c, acc);
return c;
}

View File

@ -1133,7 +1133,7 @@ namespace IKVM.Reflection.Emit
}
}
internal void WriteMetadata(MetadataWriter mw, out int guidHeapOffset)
internal void WriteMetadata(MetadataWriter mw, out uint guidHeapOffset)
{
mw.Write(0x424A5342); // Signature ("BSJB")
mw.Write((ushort)1); // MajorVersion

View File

@ -142,6 +142,11 @@ namespace IKVM.Reflection.Emit
throw new NotImplementedException();
}
public override CustomModifiers[] __GetGenericParameterConstraintCustomModifiers()
{
throw new NotImplementedException();
}
public override GenericParameterAttributes GenericParameterAttributes
{
get

View File

@ -239,6 +239,11 @@ namespace IKVM.Reflection.Reader
throw new InvalidOperationException();
}
public override CustomModifiers[] __GetGenericParameterConstraintCustomModifiers()
{
throw new InvalidOperationException();
}
public override GenericParameterAttributes GenericParameterAttributes
{
get { throw new InvalidOperationException(); }
@ -331,6 +336,24 @@ namespace IKVM.Reflection.Reader
return list.ToArray();
}
public override CustomModifiers[] __GetGenericParameterConstraintCustomModifiers()
{
IGenericContext context = (this.DeclaringMethod as IGenericContext) ?? this.DeclaringType;
List<CustomModifiers> list = new List<CustomModifiers>();
foreach (int i in module.GenericParamConstraint.Filter(this.MetadataToken))
{
CustomModifiers mods = new CustomModifiers();
int metadataToken = module.GenericParamConstraint.records[i].Constraint;
if ((metadataToken >> 24) == TypeSpecTable.Index)
{
int index = (metadataToken & 0xFFFFFF) - 1;
mods = CustomModifiers.Read(module, module.GetBlob(module.TypeSpec.records[index]), context);
}
list.Add(mods);
}
return list.ToArray();
}
public override GenericParameterAttributes GenericParameterAttributes
{
get { return (GenericParameterAttributes)module.GenericParam.records[index].Flags; }

View File

@ -150,6 +150,7 @@ namespace IKVM.Reflection
Type[] args = new Type[br.ReadCompressedUInt()];
for (int i = 0; i < args.Length; i++)
{
CustomModifiers.Skip(br);
args[i] = ReadType(module, br, context);
}
return args;

View File

@ -459,6 +459,11 @@ namespace IKVM.Reflection
throw new InvalidOperationException();
}
public virtual CustomModifiers[] __GetGenericParameterConstraintCustomModifiers()
{
throw new InvalidOperationException();
}
public virtual GenericParameterAttributes GenericParameterAttributes
{
get { throw new InvalidOperationException(); }

View File

@ -36,7 +36,7 @@ namespace IKVM.Reflection.Writer
internal void Write(MetadataWriter mw)
{
int pos = mw.Position;
uint pos = mw.Position;
WriteImpl(mw);
Debug.Assert(mw.Position == pos + unalignedlength);
int align = Length - unalignedlength;
@ -136,7 +136,7 @@ namespace IKVM.Reflection.Writer
{
if (table != null && table.RowCount > 0)
{
int pos = mw.Position;
uint pos = mw.Position;
table.Write(mw);
Debug.Assert(mw.Position - pos == table.GetLength(mw));
}

View File

@ -48,9 +48,9 @@ namespace IKVM.Reflection.Writer
get { return moduleBuilder; }
}
internal int Position
internal uint Position
{
get { return (int)stream.Position; }
get { return (uint)stream.Position; }
}
internal void Write(ByteBuffer bb)

View File

@ -313,7 +313,7 @@ namespace IKVM.Reflection.Writer
}
stream.Seek(text.PointerToRawData, SeekOrigin.Begin);
int guidHeapOffset;
uint guidHeapOffset;
code.Write(mw, sdata.VirtualAddress, out guidHeapOffset);
if (sdata.SizeOfRawData != 0)

View File

@ -275,7 +275,7 @@ namespace IKVM.Reflection.Writer
}
}
internal void Write(MetadataWriter mw, uint sdataRVA, out int guidHeapOffset)
internal void Write(MetadataWriter mw, uint sdataRVA, out uint guidHeapOffset)
{
// Now that we're ready to start writing, we need to do some fix ups
moduleBuilder.TypeRef.Fixup(moduleBuilder);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
9752fe830196d3033a76e68effb74af89c700164

View File

@ -53,6 +53,7 @@ namespace IKVM.Internal
NoAutomagicSerialization = 32,
DisableDynamicBinding = 64,
NoRefEmitHelpers = 128,
RemoveUnusedFields = 256,
}
[Flags]
@ -329,6 +330,14 @@ namespace IKVM.Internal
}
}
internal bool RemoveUnusedFields
{
get
{
return (codegenoptions & CodeGenOptions.RemoveUnusedFields) != 0;
}
}
internal bool WorkaroundAbstractMethodWidening
{
get
@ -1486,6 +1495,10 @@ namespace IKVM.Internal
{
cfp |= ClassFileParseOptions.TrustedAnnotations;
}
if (RemoveAsserts)
{
cfp |= ClassFileParseOptions.RemoveAssertions;
}
return cfp;
#else
ClassFileParseOptions cfp = ClassFileParseOptions.LineNumberTable;

View File

@ -2376,11 +2376,15 @@ namespace IKVM.Internal
{
Console.Write(" label" + labelIndexes[code[i].Label]);
}
else if (code[i].opcode == OpCodes.Ldarg)
else if (code[i].opcode == OpCodes.Ldarg_S || code[i].opcode == OpCodes.Ldarga_S)
{
Console.Write(" " + code[i].ValueByte);
}
else if (code[i].opcode == OpCodes.Ldarg || code[i].opcode == OpCodes.Ldarga)
{
Console.Write(" " + code[i].ValueInt16);
}
else if (code[i].opcode == OpCodes.Isinst)
else if (code[i].opcode == OpCodes.Isinst || code[i].opcode == OpCodes.Castclass || code[i].opcode == OpCodes.Box || code[i].opcode == OpCodes.Unbox || code[i].opcode == OpCodes.Ldobj || code[i].opcode == OpCodes.Newarr)
{
Console.Write(" " + code[i].Type);
}
@ -2388,12 +2392,28 @@ namespace IKVM.Internal
{
Console.Write(" " + code[i].MethodBase);
}
else if (code[i].opcode == OpCodes.Ldfld || code[i].opcode == OpCodes.Ldsfld || code[i].opcode == OpCodes.Stfld || code[i].opcode == OpCodes.Stsfld)
{
Console.Write(" " + code[i].FieldInfo);
}
else if (code[i].opcode == OpCodes.Ldc_I4)
{
Console.Write(" " + code[i].ValueInt32);
}
else if (code[i].opcode == OpCodes.Ldloc || code[i].opcode == OpCodes.Stloc)
{
Console.Write(" " + code[i].Local.__LocalIndex);
}
Console.WriteLine();
}
else if (code[i].pseudo == CodeType.Label)
{
Console.WriteLine("label{0}: // temp = {1}", i, code[i].Label.Temp);
}
else if (code[i].pseudo == CodeType.DeclareLocal)
{
Console.WriteLine("local #{0} = {1}", code[i].Local.__LocalIndex, code[i].Local.LocalType);
}
else
{
Console.WriteLine(code[i]);

View File

@ -57,7 +57,6 @@ namespace IKVM.Internal
private volatile TypeWrapper[] innerClasses;
private TypeWrapper outerClass;
private volatile TypeWrapper[] interfaces;
private volatile bool finished;
private static Modifiers GetModifiers(Type type)
{
@ -313,30 +312,11 @@ namespace IKVM.Internal
get { return type.IsInterface ? null : CoreClasses.java.lang.Object.Wrapper; }
}
internal override TypeWrapper DeclaringTypeWrapper
{
get { return null; }
}
internal override TypeWrapper[] InnerClasses
{
get { return TypeWrapper.EmptyArray; }
}
internal override TypeWrapper[] Interfaces
{
get { return TypeWrapper.EmptyArray; }
}
internal override Type TypeAsTBD
{
get { return type; }
}
internal override void Finish()
{
}
internal override ClassLoaderWrapper GetClassLoader()
{
return AssemblyClassLoader.FromAssembly(type.Assembly);
@ -418,31 +398,11 @@ namespace IKVM.Internal
}
}
internal override void Finish()
{
}
internal override ClassLoaderWrapper GetClassLoader()
{
return DeclaringTypeWrapper.GetClassLoader();
}
internal override TypeWrapper[] InnerClasses
{
get
{
return TypeWrapper.EmptyArray;
}
}
internal override TypeWrapper[] Interfaces
{
get
{
return TypeWrapper.EmptyArray;
}
}
internal override Type TypeAsTBD
{
get
@ -655,31 +615,11 @@ namespace IKVM.Internal
}
}
internal override void Finish()
{
}
internal override ClassLoaderWrapper GetClassLoader()
{
return DeclaringTypeWrapper.GetClassLoader();
}
internal override TypeWrapper[] InnerClasses
{
get
{
return TypeWrapper.EmptyArray;
}
}
internal override TypeWrapper[] Interfaces
{
get
{
return TypeWrapper.EmptyArray;
}
}
internal override Type TypeAsTBD
{
get
@ -701,10 +641,6 @@ namespace IKVM.Internal
{
}
internal sealed override void Finish()
{
}
internal sealed override ClassLoaderWrapper GetClassLoader()
{
return DeclaringTypeWrapper.GetClassLoader();
@ -1089,14 +1025,6 @@ namespace IKVM.Internal
}
}
internal override TypeWrapper[] InnerClasses
{
get
{
return TypeWrapper.EmptyArray;
}
}
internal override Type TypeAsTBD
{
get
@ -1233,14 +1161,6 @@ namespace IKVM.Internal
}
}
internal override TypeWrapper[] InnerClasses
{
get
{
return TypeWrapper.EmptyArray;
}
}
internal override Type TypeAsTBD
{
get
@ -2782,32 +2702,6 @@ namespace IKVM.Internal
}
#endif // EMITTERS
internal override void Finish()
{
// we don't need locking, because Finish and Link are idempotent
if (finished)
{
return;
}
if (BaseTypeWrapper != null)
{
BaseTypeWrapper.Finish();
}
foreach (TypeWrapper tw in this.Interfaces)
{
tw.Finish();
}
foreach (MethodWrapper mw in GetMethods())
{
mw.Link();
}
foreach (FieldWrapper fw in GetFields())
{
fw.Link();
}
finished = true;
}
internal override MethodParametersEntry[] GetMethodParameters(MethodWrapper mw)
{
MethodBase mb = mw.GetMethod();

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2010 Jeroen Frijters
Copyright (C) 2010-2014 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -53,10 +53,9 @@ namespace java
namespace invoke
{
public class MemberName { }
public class AdapterMethodHandle { }
public class BoundMethodHandle { }
public class DirectMethodHandle { }
public class LambdaForm { }
public class MemberName { }
public class MethodType { }
public class MethodHandle { }
public class CallSite { }
@ -64,8 +63,10 @@ namespace java
namespace reflect
{
public class Constructor { }
public class Method { }
public class Constructor : Executable { }
public class Executable { }
public class Field { }
public class Method : Executable { }
}
}
@ -92,3 +93,10 @@ namespace java
public class Vector { }
}
}
namespace sun.reflect
{
public interface ConstructorAccessor { }
public interface FieldAccessor { }
public interface MethodAccessor { }
}

View File

@ -1 +1 @@
1aa34b686a8e309033b7934a16238a455a6696f5
72685c14a95305ab5cef323c82245442b4620449

View File

@ -155,11 +155,13 @@
<Compile Include="openjdk\java.lang.invoke.cs" />
<Compile Include="openjdk\java.lang.reflect.cs" />
<Compile Include="openjdk\java.net.cs" />
<Compile Include="openjdk\java.net.SocketInputStream.cs" />
<Compile Include="openjdk\java.nio.cs" />
<Compile Include="openjdk\java.security.cs" />
<Compile Include="openjdk\java.util.cs" />
<Compile Include="openjdk\java.util.prefs.cs" />
<Compile Include="openjdk\misc.cs" />
<Compile Include="openjdk\NativeInvokerBytecodeGenerator.cs" />
<Compile Include="openjdk\sun.management.cs" />
<Compile Include="openjdk\sun.misc.cs" />
<Compile Include="openjdk\sun.nio.ch.cs" />

View File

@ -53,6 +53,7 @@ namespace IKVM.Internal
NonPublicTypeInSignature = 512, // this flag is only available after linking and is not set for access stubs
DelegateInvokeWithByRefParameter = 1024,
Type2FinalField = 2048,
NoOp = 4096, // empty static initializer
}
abstract class MemberWrapper
@ -296,6 +297,11 @@ namespace IKVM.Internal
get { return (flags & MemberFlags.DelegateInvokeWithByRefParameter) != 0; }
}
internal bool IsNoOp
{
get { return (flags & MemberFlags.NoOp) != 0; }
}
internal Modifiers Modifiers
{
get
@ -853,6 +859,11 @@ namespace IKVM.Internal
get { return (object)Name == (object)StringConstants.INIT; }
}
internal bool IsClassInitializer
{
get { return (object)Name == (object)StringConstants.CLINIT; }
}
internal bool IsVirtual
{
get
@ -873,22 +884,6 @@ namespace IKVM.Internal
}
}
// placeholder for <clinit> method that exist in ClassFile but not in TypeWrapper
// (because it is optimized away)
sealed class DummyMethodWrapper : MethodWrapper
{
internal DummyMethodWrapper(TypeWrapper tw)
: base(tw, StringConstants.CLINIT, StringConstants.SIG_VOID, null, PrimitiveTypeWrapper.VOID, TypeWrapper.EmptyArray, Modifiers.Static, MemberFlags.None)
{
}
protected override void DoLinkMethod()
{
// we're pre-linked (because we pass the signature types to the base constructor)
throw new InvalidOperationException();
}
}
abstract class SmartMethodWrapper : MethodWrapper
{
internal SmartMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
@ -1526,6 +1521,21 @@ namespace IKVM.Internal
}
}
internal bool IsSerialVersionUID
{
get
{
// a serialVersionUID field must be static and final to be recognized (see ObjectStreamClass.getDeclaredSUID())
return (Modifiers & (Modifiers.Static | Modifiers.Final)) == (Modifiers.Static | Modifiers.Final)
&& Name == "serialVersionUID"
&& (FieldTypeWrapper == PrimitiveTypeWrapper.LONG
|| FieldTypeWrapper == PrimitiveTypeWrapper.INT
|| FieldTypeWrapper == PrimitiveTypeWrapper.CHAR
|| FieldTypeWrapper == PrimitiveTypeWrapper.SHORT
|| FieldTypeWrapper == PrimitiveTypeWrapper.BYTE);
}
}
internal static FieldWrapper Create(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers)
{
// volatile long & double field accesses must be made atomic
@ -1799,7 +1809,7 @@ namespace IKVM.Internal
{
if(getter == null)
{
EmitThrowNoSuchMethodErrorForGetter(ilgen, this.FieldTypeWrapper, this.IsStatic);
EmitThrowNoSuchMethodErrorForGetter(ilgen, this.FieldTypeWrapper, this);
}
else if(getter.IsStatic)
{
@ -1811,15 +1821,18 @@ namespace IKVM.Internal
}
}
internal static void EmitThrowNoSuchMethodErrorForGetter(CodeEmitter ilgen, TypeWrapper type, bool isStatic)
internal static void EmitThrowNoSuchMethodErrorForGetter(CodeEmitter ilgen, TypeWrapper type, MemberWrapper member)
{
#if STATIC_COMPILER
StaticCompiler.IssueMessage(Message.EmittedNoSuchMethodError, "<unknown>", member.DeclaringType.Name + "." + member.Name + member.Signature);
#endif
// HACK the branch around the throw is to keep the verifier happy
CodeEmitterLabel label = ilgen.DefineLabel();
ilgen.Emit(OpCodes.Ldc_I4_0);
ilgen.EmitBrtrue(label);
ilgen.EmitThrow("java.lang.NoSuchMethodError");
ilgen.MarkLabel(label);
if (!isStatic)
if (!member.IsStatic)
{
ilgen.Emit(OpCodes.Pop);
}
@ -1840,7 +1853,7 @@ namespace IKVM.Internal
}
else
{
EmitThrowNoSuchMethodErrorForSetter(ilgen, this.IsStatic);
EmitThrowNoSuchMethodErrorForSetter(ilgen, this);
}
}
else if(setter.IsStatic)
@ -1853,8 +1866,11 @@ namespace IKVM.Internal
}
}
internal static void EmitThrowNoSuchMethodErrorForSetter(CodeEmitter ilgen, bool isStatic)
internal static void EmitThrowNoSuchMethodErrorForSetter(CodeEmitter ilgen, MemberWrapper member)
{
#if STATIC_COMPILER
StaticCompiler.IssueMessage(Message.EmittedNoSuchMethodError, "<unknown>", member.DeclaringType.Name + "." + member.Name + member.Signature);
#endif
// HACK the branch around the throw is to keep the verifier happy
CodeEmitterLabel label = ilgen.DefineLabel();
ilgen.Emit(OpCodes.Ldc_I4_0);
@ -1862,7 +1878,7 @@ namespace IKVM.Internal
ilgen.EmitThrow("java.lang.NoSuchMethodError");
ilgen.MarkLabel(label);
ilgen.Emit(OpCodes.Pop);
if (!isStatic)
if (!member.IsStatic)
{
ilgen.Emit(OpCodes.Pop);
}
@ -1908,7 +1924,7 @@ namespace IKVM.Internal
MethodInfo getter = property.GetGetMethod(true);
if(getter == null)
{
DynamicPropertyFieldWrapper.EmitThrowNoSuchMethodErrorForGetter(ilgen, this.FieldTypeWrapper, this.IsStatic);
DynamicPropertyFieldWrapper.EmitThrowNoSuchMethodErrorForGetter(ilgen, this.FieldTypeWrapper, this);
}
else if(getter.IsStatic)
{
@ -1935,7 +1951,7 @@ namespace IKVM.Internal
}
else
{
DynamicPropertyFieldWrapper.EmitThrowNoSuchMethodErrorForSetter(ilgen, this.IsStatic);
DynamicPropertyFieldWrapper.EmitThrowNoSuchMethodErrorForSetter(ilgen, this);
}
}
else if(setter.IsStatic)

View File

@ -1 +1 @@
31d3db8cd9de088ded6bcee11ef1d8e9d7e6d546
1afb52fe351bf417f16ab65bbad26a8f7fbd19b8

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2002-2014 Jeroen Frijters
Copyright (C) 2002-2015 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -23,6 +23,7 @@
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
@ -131,6 +132,24 @@ namespace IKVM.NativeCode.java.lang
return IsWindowsConsole(false) ? GetConsoleEncoding() : null;
}
public static FileVersionInfo getKernel32FileVersionInfo()
{
try
{
foreach (ProcessModule module in Process.GetCurrentProcess().Modules)
{
if (string.Compare(module.ModuleName, "kernel32.dll", StringComparison.OrdinalIgnoreCase) == 0)
{
return module.FileVersionInfo;
}
}
}
catch
{
}
return null;
}
private static bool IsWindowsConsole(bool stdout)
{
if (Environment.OSVersion.Platform != PlatformID.Win32NT)

View File

@ -1 +1 @@
69bf1f5c084614078ccfa239cff97cb90cb122b2
08c2bc38900a0011bb0d7efcdfb52672f225f95a

View File

@ -616,7 +616,7 @@ namespace IKVM.Internal
{
// it is only valid to replace a ThreadLocal instantiation by our ThreadStatic based version, if we can prove that the instantiation only happens once
// (which is the case when we're in <clinit> and there aren't any branches that lead to the current position)
if (eic.Caller.Name != StringConstants.CLINIT)
if (!eic.Caller.IsClassInitializer)
{
return false;
}

File diff suppressed because it is too large Load Diff

View File

@ -185,6 +185,105 @@ static class Java_java_io_FileDescriptor
}
}
static class Java_java_io_FileInputStream
{
public static void open0(object _this, string name, [In] java.io.FileDescriptor fd)
{
#if !FIRST_PASS
fd.openReadOnly(name);
#endif
}
public static int read0(object _this, [In] java.io.FileDescriptor fd)
{
#if FIRST_PASS
return 0;
#else
return fd.read();
#endif
}
public static int readBytes(object _this, byte[] b, int off, int len, [In] java.io.FileDescriptor fd)
{
#if FIRST_PASS
return 0;
#else
return fd.readBytes(b, off, len);
#endif
}
public static long skip(object _this, long n, [In] java.io.FileDescriptor fd)
{
#if FIRST_PASS
return 0;
#else
return fd.skip(n);
#endif
}
public static int available(object _this, [In] java.io.FileDescriptor fd)
{
#if FIRST_PASS
return 0;
#else
return fd.available();
#endif
}
public static void close0(object _this, [In] java.io.FileDescriptor fd)
{
#if !FIRST_PASS
fd.close();
#endif
}
public static void initIDs()
{
}
}
static class Java_java_io_FileOutputStream
{
public static void open0(object _this, string name, bool append, [In] java.io.FileDescriptor fd)
{
#if !FIRST_PASS
if (append)
{
fd.openAppend(name);
}
else
{
fd.openWriteOnly(name);
}
#endif
}
public static void write(object _this, int b, bool append, [In] java.io.FileDescriptor fd)
{
#if !FIRST_PASS
fd.write(b);
#endif
}
public static void writeBytes(object _this, byte[] b, int off, int len, bool append, [In] java.io.FileDescriptor fd)
{
#if !FIRST_PASS
fd.writeBytes(b, off, len);
#endif
}
public static void close0(object _this, [In] java.io.FileDescriptor fd)
{
#if !FIRST_PASS
fd.close();
#endif
}
public static void initIDs()
{
}
}
static class Java_java_io_ObjectInputStream
{
public static void bytesToFloats(byte[] src, int srcpos, float[] dst, int dstpos, int nfloats)
@ -667,6 +766,98 @@ static class Java_java_io_ObjectStreamClass
}
}
static class Java_java_io_RandomAccessFile
{
public static void open0(object _this, string name, int mode, [In] java.io.FileDescriptor fd, [In] int O_RDWR)
{
#if !FIRST_PASS
if ((mode & O_RDWR) == O_RDWR)
{
fd.openReadWrite(name);
}
else
{
fd.openReadOnly(name);
}
#endif
}
public static int read0(object _this, [In] java.io.FileDescriptor fd)
{
#if FIRST_PASS
return 0;
#else
return fd.read();
#endif
}
public static int readBytes(object _this, byte[] b, int off, int len, [In] java.io.FileDescriptor fd)
{
#if FIRST_PASS
return 0;
#else
return fd.readBytes(b, off, len);
#endif
}
public static void write0(object _this, int b, [In] java.io.FileDescriptor fd)
{
#if !FIRST_PASS
fd.write(b);
#endif
}
public static void writeBytes(object _this, byte[] b, int off, int len, [In] java.io.FileDescriptor fd)
{
#if !FIRST_PASS
fd.writeBytes(b, off, len);
#endif
}
public static long getFilePointer(object _this, [In] java.io.FileDescriptor fd)
{
#if FIRST_PASS
return 0;
#else
return fd.getFilePointer();
#endif
}
public static void seek0(object _this, long pos, [In] java.io.FileDescriptor fd)
{
#if !FIRST_PASS
fd.seek(pos);
#endif
}
public static long length(object _this, [In] java.io.FileDescriptor fd)
{
#if FIRST_PASS
return 0;
#else
return fd.length();
#endif
}
public static void setLength(object _this, long newLength, [In] java.io.FileDescriptor fd)
{
#if !FIRST_PASS
fd.setLength(newLength);
#endif
}
public static void close0(object _this, [In] java.io.FileDescriptor fd)
{
#if !FIRST_PASS
fd.close();
#endif
}
public static void initIDs()
{
}
}
static class Java_java_io_WinNTFileSystem
{
internal const int ACCESS_READ = 0x04;

View File

@ -34,7 +34,7 @@ using IKVM.Internal;
static class Java_java_lang_Class
{
public static java.lang.Class forName0(string name, bool initialize, java.lang.ClassLoader loader)
public static java.lang.Class forName0(string name, bool initialize, java.lang.ClassLoader loader, java.lang.Class caller)
{
#if FIRST_PASS
return null;
@ -80,6 +80,11 @@ static class Java_java_lang_Class
throw x.ToJava();
}
}
java.security.ProtectionDomain pd;
if (loader != null && caller != null && (pd = getProtectionDomain0(caller)) != null)
{
loader.checkPackageAccess(tw.ClassObject, pd);
}
if (initialize && !tw.IsArray)
{
try
@ -538,13 +543,14 @@ static class Java_java_lang_Class
throw new ClassFormatError(wrapper.Name);
}
MethodWrapper[] methods = wrapper.GetMethods();
List<java.lang.reflect.Method> list = new List<java.lang.reflect.Method>();
List<java.lang.reflect.Method> list = new List<java.lang.reflect.Method>(methods.Length);
for (int i = 0; i < methods.Length; i++)
{
// we don't want to expose "hideFromReflection" methods (one reason is that it would
// mess up the serialVersionUID computation)
if (!methods[i].IsHideFromReflection
&& methods[i].Name != "<clinit>" && methods[i].Name != "<init>"
&& !methods[i].IsConstructor
&& !methods[i].IsClassInitializer
&& (!publicOnly || methods[i].IsPublic))
{
list.Add((java.lang.reflect.Method)methods[i].ToMethodOrConstructor(false));
@ -590,7 +596,7 @@ static class Java_java_lang_Class
// we don't want to expose "hideFromReflection" methods (one reason is that it would
// mess up the serialVersionUID computation)
if (!methods[i].IsHideFromReflection
&& methods[i].Name == "<init>"
&& methods[i].IsConstructor
&& (!publicOnly || methods[i].IsPublic))
{
list.Add((java.lang.reflect.Constructor)methods[i].ToMethodOrConstructor(false));
@ -1168,6 +1174,65 @@ static class Java_java_lang_StrictMath
static class Java_java_lang_System
{
public static void registerNatives()
{
}
public static void setIn0(object @in)
{
#if !FIRST_PASS
java.lang.StdIO.@in = (java.io.InputStream)@in;
#endif
}
public static void setOut0(object @out)
{
#if !FIRST_PASS
java.lang.StdIO.@out = (java.io.PrintStream)@out;
#endif
}
public static void setErr0(object err)
{
#if !FIRST_PASS
java.lang.StdIO.err = (java.io.PrintStream)err;
#endif
}
public static object initProperties(object props)
{
#if FIRST_PASS
return null;
#else
java.lang.VMSystemProperties.initProperties((java.util.Properties)props);
return props;
#endif
}
public static string mapLibraryName(string libname)
{
#if FIRST_PASS
return null;
#else
if (libname == null)
{
throw new java.lang.NullPointerException();
}
if (ikvm.@internal.Util.WINDOWS)
{
return libname + ".dll";
}
else if (ikvm.@internal.Util.MACOSX)
{
return "lib" + libname + ".jnilib";
}
else
{
return "lib" + libname + ".so";
}
#endif
}
public static void arraycopy(object src, int srcPos, object dest, int destPos, int length)
{
IKVM.Runtime.ByteCodeHelper.arraycopy(src, srcPos, dest, destPos, length);

View File

@ -22,6 +22,7 @@
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
@ -30,6 +31,26 @@ using IKVM.Internal;
using java.lang.invoke;
using jlClass = java.lang.Class;
static class Java_java_lang_invoke_DirectMethodHandle
{
// this is called from DirectMethodHandle.makeAllocator() via a map.xml prologue patch
public static DirectMethodHandle makeStringAllocator(MemberName member)
{
#if FIRST_PASS
return null;
#else
// we cannot construct strings via the standard two-pass approach (allocateObject followed by constructor invocation),
// so we special case string construction here (to call our static factory method instead)
if (member.getDeclaringClass() == CoreClasses.java.lang.String.Wrapper.ClassObject)
{
MethodType mt = member.getMethodType().changeReturnType(CoreClasses.java.lang.String.Wrapper.ClassObject);
return new DirectMethodHandle(mt, DirectMethodHandle._preparedLambdaForm(mt, MethodTypeForm.LF_INVSTATIC), member, null);
}
return null;
#endif
}
}
static class Java_java_lang_invoke_MethodHandle
{
public static object invokeExact(MethodHandle thisObject, object[] args)
@ -76,36 +97,64 @@ static class Java_java_lang_invoke_MethodHandle
}
}
static class Java_java_lang_invoke_MethodHandleNatives
static class Java_java_lang_invoke_MethodHandleImpl
{
// called from Lookup.revealDirect() (instead of MethodHandle.internalMemberName()) via map.xml replace-method-call
public static MemberName internalMemberName(MethodHandle mh)
// hooked up via map.xml (as a replacement for makePairwiseConvertByEditor)
public static MethodHandle makePairwiseConvert(MethodHandle target, MethodType srcType, bool strict, bool monobox)
{
#if FIRST_PASS
return null;
#else
MemberName mn = mh.internalMemberName();
if (mn.isStatic() && mn.getName() == "<init>")
object[] convSpecs = MethodHandleImpl.computeValueConversions(srcType, target.type(), strict, monobox);
List<LambdaForm.Name> names = new List<LambdaForm.Name>();
names.Add(new LambdaForm.Name(0, LambdaForm.BasicType.L_TYPE));
for (int i = 0; i < srcType.parameterCount(); i++)
{
// HACK since we convert String constructors into static methods, we have to undo that here
// Note that the MemberName we return is only used for a security check and by InfoFromMemberName (a MethodHandleInfo implementation),
// so we don't need to make it actually invokable.
MemberName alt = new MemberName();
typeof(MemberName).GetField("clazz", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(alt, mn.getDeclaringClass());
typeof(MemberName).GetField("name", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(alt, mn.getName());
typeof(MemberName).GetField("type", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(alt, mn.getMethodType().changeReturnType(typeof(void)));
int flags = mn._flags();
flags -= MethodHandleNatives.Constants.MN_IS_METHOD;
flags += MethodHandleNatives.Constants.MN_IS_CONSTRUCTOR;
flags &= ~(MethodHandleNatives.Constants.MN_REFERENCE_KIND_MASK << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT);
flags |= MethodHandleNatives.Constants.REF_newInvokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
flags &= ~MethodHandleNatives.Constants.ACC_STATIC;
alt._flags(flags);
return alt;
names.Add(new LambdaForm.Name(i + 1, LambdaForm.BasicType.basicType(srcType.parameterType(i))));
}
return mn;
LambdaForm.Name[] invokeArgs = new LambdaForm.Name[srcType.parameterCount()];
for (int i = 0; i < invokeArgs.Length; i++)
{
object convSpec = convSpecs[i];
if (convSpec == null)
{
invokeArgs[i] = names[i + 1];
}
else
{
LambdaForm.Name temp = new LambdaForm.Name(convSpec as MethodHandle ?? MethodHandleImpl.Lazy.MH_castReference.bindTo(convSpec), names[i + 1]);
names.Add(temp);
invokeArgs[i] = temp;
}
}
names.Add(new LambdaForm.Name(target, invokeArgs));
if (convSpecs[convSpecs.Length - 1] != null)
{
object convSpec = convSpecs[convSpecs.Length - 1];
if (convSpec != java.lang.Void.TYPE)
{
names.Add(new LambdaForm.Name(convSpec as MethodHandle ?? MethodHandleImpl.Lazy.MH_castReference.bindTo(convSpec), names[names.Count - 1]));
}
}
if (target.type().returnType() == java.lang.Void.TYPE && srcType.returnType() != java.lang.Void.TYPE)
{
names.Add(new LambdaForm.Name(LambdaForm.constantZero(LambdaForm.BasicType.basicType(srcType.returnType()))));
}
LambdaForm form = new LambdaForm("PairwiseConvert", srcType.parameterCount() + 1, names.ToArray(), srcType.returnType() == java.lang.Void.TYPE ? LambdaForm.VOID_RESULT : LambdaForm.LAST_RESULT, false);
return new LightWeightMethodHandle(srcType, form);
#endif
}
}
static class Java_java_lang_invoke_MethodHandleNatives
{
// called from map.xml as a replacement for Class.isInstance() in java.lang.invoke.MethodHandleImpl.castReference()
public static bool Class_isInstance(java.lang.Class clazz, object obj)
{
TypeWrapper tw = TypeWrapper.FromClass(clazz);
// handle the type system hole that is caused by arrays being both derived from cli.System.Array and directly from java.lang.Object
return tw.IsInstance(obj) || (tw == CoreClasses.cli.System.Object.Wrapper && obj is Array);
}
public static void init(MemberName self, object refObj)
{
@ -151,6 +200,10 @@ static class Java_java_lang_invoke_MethodHandleNatives
{
flags |= MethodHandleNatives.Constants.REF_invokeStatic << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
}
else if (mw.IsConstructor && !wantSpecial)
{
flags |= MethodHandleNatives.Constants.REF_newInvokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
}
else if (mw.IsPrivate || mw.IsFinal || mw.IsConstructor || wantSpecial)
{
flags |= MethodHandleNatives.Constants.REF_invokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
@ -174,16 +227,11 @@ static class Java_java_lang_invoke_MethodHandleNatives
{
parameters1[i] = mw.GetParameters()[i].ClassObject;
}
MethodType mt = MethodType.methodType(typeof(string), parameters1);
typeof(MemberName).GetField("type", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(self, mt);
self.vmtarget = CreateMemberNameDelegate(mw, null, false, mt);
flags -= MethodHandleNatives.Constants.REF_invokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
flags += MethodHandleNatives.Constants.REF_invokeStatic << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
flags -= MethodHandleNatives.Constants.MN_IS_CONSTRUCTOR;
flags += MethodHandleNatives.Constants.MN_IS_METHOD;
flags += MethodHandleNatives.Constants.ACC_STATIC;
MethodType mt = MethodType.methodType(PrimitiveTypeWrapper.VOID.ClassObject, parameters1);
self._type(mt);
self._flags(flags);
self._clazz(mw.DeclaringType.ClassObject);
self.vmtarget = CreateMemberNameDelegate(mw, null, false, self.getMethodType().changeReturnType(CoreClasses.java.lang.String.Wrapper.ClassObject));
return;
}
self._flags(flags);
@ -311,8 +359,7 @@ static class Java_java_lang_invoke_MethodHandleNatives
}
if (mw.IsConstructor && mw.DeclaringType == CoreClasses.java.lang.String.Wrapper)
{
typeof(MemberName).GetField("type", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(self, self.getMethodType().changeReturnType(typeof(string)));
self.vmtarget = CreateMemberNameDelegate(mw, caller, false, self.getMethodType());
self.vmtarget = CreateMemberNameDelegate(mw, caller, false, self.getMethodType().changeReturnType(CoreClasses.java.lang.String.Wrapper.ClassObject));
}
else if (!mw.IsConstructor || invokeSpecial || newInvokeSpecial)
{
@ -340,16 +387,6 @@ static class Java_java_lang_invoke_MethodHandleNatives
{
self._flags(self._flags() | MemberName.CALLER_SENSITIVE);
}
if (mw.IsConstructor && mw.DeclaringType == CoreClasses.java.lang.String.Wrapper)
{
int flags = self._flags();
flags -= MethodHandleNatives.Constants.REF_invokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
flags += MethodHandleNatives.Constants.REF_invokeStatic << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
flags -= MethodHandleNatives.Constants.MN_IS_CONSTRUCTOR;
flags += MethodHandleNatives.Constants.MN_IS_METHOD;
flags += MethodHandleNatives.Constants.ACC_STATIC;
self._flags(flags);
}
}
private static void ResolveField(MemberName self)
@ -470,7 +507,7 @@ static class Java_java_lang_invoke_MethodHandleNatives
MethodWrapper[] methods = TypeWrapper.FromClass(defc).GetMethods();
for (int i = skip, len = Math.Min(results.Length, methods.Length - skip); i < len; i++)
{
if (!methods[i].IsConstructor && methods[i].Name != StringConstants.CLINIT)
if (!methods[i].IsConstructor && !methods[i].IsClassInitializer)
{
results[i - skip] = new MemberName((java.lang.reflect.Method)methods[i].ToMethodOrConstructor(true), false);
}
@ -608,7 +645,7 @@ static partial class MethodHandleUtil
return args;
}
private static Type[] GetParameterTypes(Type thisType, MethodBase mb)
internal static Type[] GetParameterTypes(Type thisType, MethodBase mb)
{
ParameterInfo[] pi = mb.GetParameters();
Type[] args = new Type[pi.Length + 1];
@ -1027,25 +1064,7 @@ static partial class MethodHandleUtil
internal void Ldarg(int i)
{
i += firstArg;
if (i >= packedArgPos)
{
ilgen.EmitLdarga(packedArgPos);
int fieldPos = i - packedArgPos;
Type type = packedArgType;
while (fieldPos >= MaxArity || (fieldPos == MaxArity - 1 && IsPackedArgsContainer(type.GetField("t8").FieldType)))
{
FieldInfo field = type.GetField("t8");
type = field.FieldType;
ilgen.Emit(OpCodes.Ldflda, field);
fieldPos -= MaxArity - 1;
}
ilgen.Emit(OpCodes.Ldfld, type.GetField("t" + (1 + fieldPos)));
}
else
{
ilgen.EmitLdarg(i);
}
LoadPackedArg(ilgen, i, firstArg, packedArgPos, packedArgType);
}
internal void LoadCallerID()
@ -1232,5 +1251,28 @@ static partial class MethodHandleUtil
}
return type.voidAdapter;
}
internal static void LoadPackedArg(CodeEmitter ilgen, int index, int firstArg, int packedArgPos, Type packedArgType)
{
index += firstArg;
if (index >= packedArgPos)
{
ilgen.EmitLdarga(packedArgPos);
int fieldPos = index - packedArgPos;
Type type = packedArgType;
while (fieldPos >= MaxArity || (fieldPos == MaxArity - 1 && IsPackedArgsContainer(type.GetField("t8").FieldType)))
{
FieldInfo field = type.GetField("t8");
type = field.FieldType;
ilgen.Emit(OpCodes.Ldflda, field);
fieldPos -= MaxArity - 1;
}
ilgen.Emit(OpCodes.Ldfld, type.GetField("t" + (1 + fieldPos)));
}
else
{
ilgen.EmitLdarg(index);
}
}
#endif
}

View File

@ -0,0 +1,216 @@
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#if !FIRST_PASS
using Winsock = ikvm.@internal.Winsock;
using java.net;
#endif
static class Java_java_net_SocketInputStream
{
public static int socketRead0(object _this, java.io.FileDescriptor fd, byte[] b, int off, int len, int timeout)
{
#if FIRST_PASS
return 0;
#else
// [IKVM] this method is a direct port of the native code in openjdk6-b18\jdk\src\windows\native\java\net\SocketInputStream.c
System.Net.Sockets.Socket socket = null;
int nread;
if (fd == null)
{
throw new SocketException("socket closed");
}
socket = fd.getSocket();
if (socket == null)
{
throw new SocketException("Socket closed");
}
if (timeout != 0)
{
if (timeout <= 5000 || !net_util_md.isRcvTimeoutSupported)
{
int ret = net_util_md.NET_Timeout(socket, timeout);
if (ret <= 0)
{
if (ret == 0)
{
throw new SocketTimeoutException("Read timed out");
}
else
{
// [IKVM] the OpenJDK native code is broken and always throws this exception on any failure of NET_Timeout
throw new SocketException("socket closed");
}
}
/*check if the socket has been closed while we were in timeout*/
if (fd.getSocket() == null)
{
throw new SocketException("Socket Closed");
}
}
}
nread = Winsock.recv(socket, b, off, len, 0);
if (nread > 0)
{
// ok
}
else
{
if (nread < 0)
{
/*
* Recv failed.
*/
switch (Winsock.WSAGetLastError())
{
case Winsock.WSAEINTR:
throw new SocketException("socket closed");
case Winsock.WSAECONNRESET:
case Winsock.WSAESHUTDOWN:
/*
* Connection has been reset - Windows sometimes reports
* the reset as a shutdown error.
*/
throw new sun.net.ConnectionResetException();
case Winsock.WSAETIMEDOUT:
throw new SocketTimeoutException("Read timed out");
default:
throw net_util_md.NET_ThrowCurrent("recv failed");
}
}
}
return nread;
#endif
}
public static void init()
{
}
}
static class Java_java_net_SocketOutputStream
{
public static void socketWrite0(object _this, java.io.FileDescriptor fd, byte[] data, int off, int len)
{
#if !FIRST_PASS
// [IKVM] this method is a direct port of the native code in openjdk6-b18\jdk\src\windows\native\java\net\SocketOutputStream.c
const int MAX_BUFFER_LEN = 2048;
System.Net.Sockets.Socket socket;
int buflen = 65536; // MAX_HEAP_BUFFER_LEN
int n;
if (fd == null)
{
throw new SocketException("socket closed");
}
else
{
socket = fd.getSocket();
}
if (data == null)
{
throw new java.lang.NullPointerException("data argument");
}
while (len > 0)
{
int loff = 0;
int chunkLen = java.lang.Math.min(buflen, len);
int llen = chunkLen;
int retry = 0;
while (llen > 0)
{
n = Winsock.send(socket, data, off + loff, llen, 0);
if (n > 0)
{
llen -= n;
loff += n;
continue;
}
/*
* Due to a bug in Windows Sockets (observed on NT and Windows
* 2000) it may be necessary to retry the send. The issue is that
* on blocking sockets send/WSASend is supposed to block if there
* is insufficient buffer space available. If there are a large
* number of threads blocked on write due to congestion then it's
* possile to hit the NT/2000 bug whereby send returns WSAENOBUFS.
* The workaround we use is to retry the send. If we have a
* large buffer to send (>2k) then we retry with a maximum of
* 2k buffer. If we hit the issue with <=2k buffer then we backoff
* for 1 second and retry again. We repeat this up to a reasonable
* limit before bailing out and throwing an exception. In load
* conditions we've observed that the send will succeed after 2-3
* attempts but this depends on network buffers associated with
* other sockets draining.
*/
if (Winsock.WSAGetLastError() == Winsock.WSAENOBUFS)
{
if (llen > MAX_BUFFER_LEN)
{
buflen = MAX_BUFFER_LEN;
chunkLen = MAX_BUFFER_LEN;
llen = MAX_BUFFER_LEN;
continue;
}
if (retry >= 30)
{
throw new SocketException("No buffer space available - exhausted attempts to queue buffer");
}
System.Threading.Thread.Sleep(1000);
retry++;
continue;
}
/*
* Send failed - can be caused by close or write error.
*/
if (Winsock.WSAGetLastError() == Winsock.WSAENOTSOCK)
{
throw new SocketException("Socket closed");
}
else
{
throw net_util_md.NET_ThrowCurrent("socket write error");
}
}
len -= chunkLen;
off += chunkLen;
}
#endif
}
public static void init()
{
}
}

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2007-2013 Jeroen Frijters
Copyright (C) 2007-2015 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -28,6 +28,36 @@ using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Security;
static class Java_java_net_AbstractPlainDatagramSocketImpl
{
public static void init()
{
}
public static int dataAvailable(object _this)
{
#if FIRST_PASS
return 0;
#else
try
{
java.net.AbstractPlainDatagramSocketImpl obj = (java.net.AbstractPlainDatagramSocketImpl)_this;
if (obj.fd != null)
{
return obj.fd.getSocket().Available;
}
}
catch (ObjectDisposedException)
{
}
catch (SocketException)
{
}
throw new java.net.SocketException("Socket closed");
#endif
}
}
static class Java_java_net_DatagramPacket
{
public static void init()
@ -436,6 +466,7 @@ static class Java_java_net_NetworkInterface
int lo = 0;
int ppp = 0;
int sl = 0;
int wlan = 0;
int net = 0;
for (int i = 0; i < ifaces.Length; i++)
{
@ -465,6 +496,9 @@ static class Java_java_net_NetworkInterface
case NetworkInterfaceType.Slip:
name = "sl" + sl++;
break;
case NetworkInterfaceType.Wireless80211:
name = "wlan" + wlan++;
break;
default:
name = "net" + net++;
break;
@ -480,6 +514,13 @@ static class Java_java_net_NetworkInterface
IPAddress addr = uipaic[j].Address;
if (addr.AddressFamily == AddressFamily.InterNetwork)
{
if (ifaces[i].OperationalStatus != OperationalStatus.Up)
{
// HACK on Windows, OpenJDK seems to only return IPv4 addresses for interfaces that are up.
// This is possibly the result of their usage of the (legacy) Win32 API GetIpAddrTable.
// Not doing this filtering causes some OpenJDK tests to fail.
continue;
}
java.net.Inet4Address address = new java.net.Inet4Address(null, addr.GetAddressBytes());
java.net.InterfaceAddress binding = new java.net.InterfaceAddress();
short mask = 32;

View File

@ -0,0 +1,339 @@
/*
Copyright (C) 2007-2013 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
using System;
static class Java_java_util_TimeZone
{
private static string GetCurrentTimeZoneID()
{
#if NET_4_0
return TimeZoneInfo.Local.Id;
#else
// we don't want a static dependency on System.Core (to be able to run on .NET 2.0)
Type typeofTimeZoneInfo = Type.GetType("System.TimeZoneInfo, System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
if (typeofTimeZoneInfo != null)
{
try
{
return (string)typeofTimeZoneInfo.GetProperty("Id").GetValue(typeofTimeZoneInfo.GetProperty("Local").GetValue(null, null), null);
}
catch (Exception x)
{
// older Mono versions did not wrap the exception in a TargetInvocationExcception,
// so we check both x and x.InnerException
if (typeofTimeZoneInfo.Assembly.GetType("System.TimeZoneNotFoundException").IsInstanceOfType(x)
|| typeofTimeZoneInfo.Assembly.GetType("System.TimeZoneNotFoundException").IsInstanceOfType(x.InnerException))
{
// MONOBUG Mono's TimeZoneInfo.Local property throws a TimeZoneNotFoundException on Windows
// (https://bugzilla.novell.com/show_bug.cgi?id=622524)
return TimeZone.CurrentTimeZone.StandardName;
}
else
{
throw;
}
}
}
else
{
// HACK this is very lame and probably won't work on localized windows versions
return TimeZone.CurrentTimeZone.StandardName;
}
#endif
}
public static string getSystemTimeZoneID(string javaHome)
{
// (the switch was generated from the contents of $JAVA_HOME/lib/tzmappings)
switch (GetCurrentTimeZoneID())
{
case "Romance":
case "Romance Standard Time":
return "Europe/Paris";
case "Warsaw":
return "Europe/Warsaw";
case "Central Europe":
case "Central Europe Standard Time":
case "Prague Bratislava":
return "Europe/Prague";
case "W. Central Africa Standard Time":
return "Africa/Luanda";
case "FLE":
case "FLE Standard Time":
return "Europe/Helsinki";
case "GFT":
case "GFT Standard Time":
case "GTB":
case "GTB Standard Time":
return "Europe/Athens";
case "Israel":
case "Israel Standard Time":
return "Asia/Jerusalem";
case "Arab":
case "Arab Standard Time":
return "Asia/Riyadh";
case "Arabic Standard Time":
return "Asia/Baghdad";
case "E. Africa":
case "E. Africa Standard Time":
return "Africa/Nairobi";
case "Saudi Arabia":
case "Saudi Arabia Standard Time":
return "Asia/Riyadh";
case "Iran":
case "Iran Standard Time":
return "Asia/Tehran";
case "Afghanistan":
case "Afghanistan Standard Time":
return "Asia/Kabul";
case "India":
case "India Standard Time":
return "Asia/Calcutta";
case "Myanmar Standard Time":
return "Asia/Rangoon";
case "Nepal Standard Time":
return "Asia/Katmandu";
case "Sri Lanka":
case "Sri Lanka Standard Time":
return "Asia/Colombo";
case "Beijing":
case "China":
case "China Standard Time":
return "Asia/Shanghai";
case "AUS Central":
case "AUS Central Standard Time":
return "Australia/Darwin";
case "Cen. Australia":
case "Cen. Australia Standard Time":
return "Australia/Adelaide";
case "Vladivostok":
case "Vladivostok Standard Time":
return "Asia/Vladivostok";
case "West Pacific":
case "West Pacific Standard Time":
return "Pacific/Guam";
case "E. South America":
case "E. South America Standard Time":
return "America/Sao_Paulo";
case "Greenland Standard Time":
return "America/Godthab";
case "Newfoundland":
case "Newfoundland Standard Time":
return "America/St_Johns";
case "Pacific SA":
case "Pacific SA Standard Time":
return "America/Santiago";
case "SA Western":
case "SA Western Standard Time":
return "America/Caracas";
case "SA Pacific":
case "SA Pacific Standard Time":
return "America/Bogota";
case "US Eastern":
case "US Eastern Standard Time":
return "America/Indianapolis";
case "Central America Standard Time":
return "America/Regina";
case "Mexico":
case "Mexico Standard Time":
return "America/Mexico_City";
case "Canada Central":
case "Canada Central Standard Time":
return "America/Regina";
case "US Mountain":
case "US Mountain Standard Time":
return "America/Phoenix";
case "GMT":
case "GMT Standard Time":
return "Europe/London";
case "Ekaterinburg":
case "Ekaterinburg Standard Time":
return "Asia/Yekaterinburg";
case "West Asia":
case "West Asia Standard Time":
return "Asia/Karachi";
case "Central Asia":
case "Central Asia Standard Time":
return "Asia/Dhaka";
case "N. Central Asia Standard Time":
return "Asia/Novosibirsk";
case "Bangkok":
case "Bangkok Standard Time":
return "Asia/Bangkok";
case "North Asia Standard Time":
return "Asia/Krasnoyarsk";
case "SE Asia":
case "SE Asia Standard Time":
return "Asia/Bangkok";
case "North Asia East Standard Time":
return "Asia/Ulaanbaatar";
case "Singapore":
case "Singapore Standard Time":
return "Asia/Singapore";
case "Taipei":
case "Taipei Standard Time":
return "Asia/Taipei";
case "W. Australia":
case "W. Australia Standard Time":
return "Australia/Perth";
case "Korea":
case "Korea Standard Time":
return "Asia/Seoul";
case "Tokyo":
case "Tokyo Standard Time":
return "Asia/Tokyo";
case "Yakutsk":
case "Yakutsk Standard Time":
return "Asia/Yakutsk";
case "Central European":
case "Central European Standard Time":
return "Europe/Belgrade";
case "W. Europe":
case "W. Europe Standard Time":
return "Europe/Berlin";
case "Tasmania":
case "Tasmania Standard Time":
return "Australia/Hobart";
case "AUS Eastern":
case "AUS Eastern Standard Time":
return "Australia/Sydney";
case "E. Australia":
case "E. Australia Standard Time":
return "Australia/Brisbane";
case "Sydney Standard Time":
return "Australia/Sydney";
case "Central Pacific":
case "Central Pacific Standard Time":
return "Pacific/Guadalcanal";
case "Dateline":
case "Dateline Standard Time":
return "GMT-1200";
case "Fiji":
case "Fiji Standard Time":
return "Pacific/Fiji";
case "Samoa":
case "Samoa Standard Time":
return "Pacific/Apia";
case "Hawaiian":
case "Hawaiian Standard Time":
return "Pacific/Honolulu";
case "Alaskan":
case "Alaskan Standard Time":
return "America/Anchorage";
case "Pacific":
case "Pacific Standard Time":
return "America/Los_Angeles";
case "Mexico Standard Time 2":
return "America/Chihuahua";
case "Mountain":
case "Mountain Standard Time":
return "America/Denver";
case "Central":
case "Central Standard Time":
return "America/Chicago";
case "Eastern":
case "Eastern Standard Time":
return "America/New_York";
case "E. Europe":
case "E. Europe Standard Time":
return "Europe/Minsk";
case "Egypt":
case "Egypt Standard Time":
return "Africa/Cairo";
case "South Africa":
case "South Africa Standard Time":
return "Africa/Harare";
case "Atlantic":
case "Atlantic Standard Time":
return "America/Halifax";
case "SA Eastern":
case "SA Eastern Standard Time":
return "America/Buenos_Aires";
case "Mid-Atlantic":
case "Mid-Atlantic Standard Time":
return "Atlantic/South_Georgia";
case "Azores":
case "Azores Standard Time":
return "Atlantic/Azores";
case "Cape Verde Standard Time":
return "Atlantic/Cape_Verde";
case "Russian":
case "Russian Standard Time":
return "Europe/Moscow";
case "New Zealand":
case "New Zealand Standard Time":
return "Pacific/Auckland";
case "Tonga Standard Time":
return "Pacific/Tongatapu";
case "Arabian":
case "Arabian Standard Time":
return "Asia/Muscat";
case "Caucasus":
case "Caucasus Standard Time":
return "Asia/Yerevan";
case "Greenwich":
case "Greenwich Standard Time":
return "GMT";
case "Central Brazilian Standard Time":
return "America/Manaus";
case "Central Standard Time (Mexico)":
return "America/Mexico_City";
case "Georgian Standard Time":
return "Asia/Tbilisi";
case "Mountain Standard Time (Mexico)":
return "America/Chihuahua";
case "Namibia Standard Time":
return "Africa/Windhoek";
case "Pacific Standard Time (Mexico)":
return "America/Tijuana";
case "Western Brazilian Standard Time":
return "America/Rio_Branco";
case "Azerbaijan Standard Time":
return "Asia/Baku";
case "Jordan Standard Time":
return "Asia/Amman";
case "Middle East Standard Time":
return "Asia/Beirut";
default:
// this means fall back to GMT offset
return getSystemGMTOffsetID();
}
}
public static string getSystemGMTOffsetID()
{
TimeSpan sp = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
int hours = sp.Hours;
int mins = sp.Minutes;
if (hours >= 0 && mins >= 0)
{
return String.Format("GMT+{0:D2}:{1:D2}", hours, mins);
}
else
{
return String.Format("GMT-{0:D2}:{1:D2}", -hours, -mins);
}
}
}

View File

@ -0,0 +1,359 @@
/*
Copyright (C) 2007-2013 Jeroen Frijters
Copyright (C) 2009 Volker Berlin (i-net software)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using System.Text;
static class Java_java_util_prefs_FileSystemPreferences
{
public static int chmod(string filename, int permission)
{
// TODO
return 0;
}
public static int[] lockFile0(string filename, int permission, bool shared)
{
// TODO
return new int[] { 1, 0 };
}
public static int unlockFile0(int fd)
{
// TODO
return 0;
}
}
static class Java_java_util_prefs_WindowsPreferences
{
// HACK we currently support only 16 handles at a time
private static readonly Microsoft.Win32.RegistryKey[] keys = new Microsoft.Win32.RegistryKey[16];
private static Microsoft.Win32.RegistryKey MapKey(int hKey)
{
switch (hKey)
{
case unchecked((int)0x80000001):
return Microsoft.Win32.Registry.CurrentUser;
case unchecked((int)0x80000002):
return Microsoft.Win32.Registry.LocalMachine;
default:
return keys[hKey - 1];
}
}
private static int AllocHandle(Microsoft.Win32.RegistryKey key)
{
lock (keys)
{
if (key != null)
{
for (int i = 0; i < keys.Length; i++)
{
if (keys[i] == null)
{
keys[i] = key;
return i + 1;
}
}
}
return 0;
}
}
private static string BytesToString(byte[] bytes)
{
int len = bytes.Length;
if (bytes[len - 1] == 0)
{
len--;
}
return Encoding.ASCII.GetString(bytes, 0, len);
}
private static byte[] StringToBytes(string str)
{
if (str.Length == 0 || str[str.Length - 1] != 0)
{
str += '\u0000';
}
return Encoding.ASCII.GetBytes(str);
}
public static int[] WindowsRegOpenKey(int hKey, byte[] subKey, int securityMask)
{
// writeable = DELETE == 0x10000 || KEY_SET_VALUE == 2 || KEY_CREATE_SUB_KEY == 4 || KEY_WRITE = 0x20006;
// !writeable : KEY_ENUMERATE_SUB_KEYS == 8 || KEY_READ == 0x20019 || KEY_QUERY_VALUE == 1
bool writable = (securityMask & 0x10006) != 0;
Microsoft.Win32.RegistryKey resultKey = null;
int error = 0;
try
{
Microsoft.Win32.RegistryKey parent = MapKey(hKey);
// HACK we check if we can write in the system preferences
// we want not user registry virtualization for compatibility
if (writable && parent.Name.StartsWith("HKEY_LOCAL_MACHINE", StringComparison.Ordinal) && UACVirtualization.Enabled)
{
resultKey = parent.OpenSubKey(BytesToString(subKey), false);
if (resultKey != null)
{
// error only if key exists
resultKey.Close();
error = 5;
resultKey = null;
}
}
else
{
resultKey = parent.OpenSubKey(BytesToString(subKey), writable);
}
}
catch (SecurityException)
{
error = 5;
}
catch (UnauthorizedAccessException)
{
error = 5;
}
return new int[] { AllocHandle(resultKey), error };
}
public static int WindowsRegCloseKey(int hKey)
{
keys[hKey - 1].Close();
lock (keys)
{
keys[hKey - 1] = null;
}
return 0;
}
public static int[] WindowsRegCreateKeyEx(int hKey, byte[] subKey)
{
Microsoft.Win32.RegistryKey resultKey = null;
int error = 0;
int disposition = -1;
try
{
Microsoft.Win32.RegistryKey key = MapKey(hKey);
string name = BytesToString(subKey);
resultKey = key.OpenSubKey(name);
disposition = 2;
if (resultKey == null)
{
resultKey = key.CreateSubKey(name);
disposition = 1;
}
}
catch (SecurityException)
{
error = 5;
}
catch (UnauthorizedAccessException)
{
error = 5;
}
return new int[] { AllocHandle(resultKey), error, disposition };
}
public static int WindowsRegDeleteKey(int hKey, byte[] subKey)
{
try
{
MapKey(hKey).DeleteSubKey(BytesToString(subKey), false);
return 0;
}
catch (SecurityException)
{
return 5;
}
}
public static int WindowsRegFlushKey(int hKey)
{
MapKey(hKey).Flush();
return 0;
}
public static byte[] WindowsRegQueryValueEx(int hKey, byte[] valueName)
{
try
{
string value = MapKey(hKey).GetValue(BytesToString(valueName)) as string;
if (value == null)
{
return null;
}
return StringToBytes(value);
}
catch (SecurityException)
{
return null;
}
catch (UnauthorizedAccessException)
{
return null;
}
}
public static int WindowsRegSetValueEx(int hKey, byte[] valueName, byte[] data)
{
if (valueName == null || data == null)
{
return -1;
}
try
{
MapKey(hKey).SetValue(BytesToString(valueName), BytesToString(data));
return 0;
}
catch (SecurityException)
{
return 5;
}
catch (UnauthorizedAccessException)
{
return 5;
}
}
public static int WindowsRegDeleteValue(int hKey, byte[] valueName)
{
try
{
MapKey(hKey).DeleteValue(BytesToString(valueName));
return 0;
}
catch (System.ArgumentException)
{
return 2; //ERROR_FILE_NOT_FOUND
}
catch (SecurityException)
{
return 5; //ERROR_ACCESS_DENIED
}
catch (UnauthorizedAccessException)
{
return 5; //ERROR_ACCESS_DENIED
}
}
public static int[] WindowsRegQueryInfoKey(int hKey)
{
int[] result = new int[5] { -1, -1, -1, -1, -1 };
try
{
Microsoft.Win32.RegistryKey key = MapKey(hKey);
result[0] = key.SubKeyCount;
result[1] = 0;
result[2] = key.ValueCount;
foreach (string s in key.GetSubKeyNames())
{
result[3] = Math.Max(result[3], s.Length);
}
foreach (string s in key.GetValueNames())
{
result[4] = Math.Max(result[4], s.Length);
}
}
catch (SecurityException)
{
result[1] = 5;
}
catch (UnauthorizedAccessException)
{
result[1] = 5;
}
return result;
}
public static byte[] WindowsRegEnumKeyEx(int hKey, int subKeyIndex, int maxKeyLength)
{
try
{
return StringToBytes(MapKey(hKey).GetSubKeyNames()[subKeyIndex]);
}
catch (SecurityException)
{
return null;
}
catch (UnauthorizedAccessException)
{
return null;
}
}
public static byte[] WindowsRegEnumValue(int hKey, int valueIndex, int maxValueNameLength)
{
try
{
return StringToBytes(MapKey(hKey).GetValueNames()[valueIndex]);
}
catch (SecurityException)
{
return null;
}
catch (UnauthorizedAccessException)
{
return null;
}
}
}
static class UACVirtualization
{
private enum TOKEN_INFORMATION_CLASS
{
TokenVirtualizationEnabled = 24
}
[DllImport("advapi32.dll")]
private static extern int GetTokenInformation(
IntPtr TokenHandle,
TOKEN_INFORMATION_CLASS TokenInformationClass,
out int TokenInformation,
int TokenInformationLength,
out int ReturnLength);
internal static bool Enabled
{
[SecuritySafeCritical]
get
{
OperatingSystem os = Environment.OSVersion;
if (os.Platform != PlatformID.Win32NT || os.Version.Major < 6)
{
return false;
}
int enabled, length;
return GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled, out enabled, 4, out length) != 0
&& enabled != 0;
}
}
}

View File

@ -197,17 +197,6 @@ static class Java_sun_invoke_anon_AnonymousClassLoader
}
}
static class Java_sun_invoke_util_ValueConversions
{
// called from map.xml as a replacement for Class.isInstance() in sun.invoke.util.ValueConversions.castReference()
public static bool Class_isInstance(java.lang.Class clazz, object obj)
{
TypeWrapper tw = TypeWrapper.FromClass(clazz);
// handle the type system hole that is caused by arrays being both derived from cli.System.Array and directly from java.lang.Object
return tw.IsInstance(obj) || (tw == CoreClasses.cli.System.Object.Wrapper && obj is Array);
}
}
static class Java_sun_invoke_util_VerifyAccess
{
// called from map.xml as a replacement for Class.getClassLoader() in sun.invoke.util.VerifyAccess.isTypeVisible()
@ -311,6 +300,9 @@ static class Java_sun_security_provider_NativeSeedGenerator
{
RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider();
csp.GetBytes(result);
#if NET_4_0
csp.Dispose();
#endif
return true;
}
catch (CryptographicException)
@ -359,27 +351,22 @@ static class Java_com_sun_java_util_jar_pack_NativeUnpack
static class Java_com_sun_security_auth_module_NTSystem
{
public static void getCurrent(object thisObj, bool debug)
public static void getCurrent(object thisObj, bool debug, ref string userName, ref string domain, ref string domainSID, ref string userSID, ref string[] groupIDs, ref string primaryGroupID)
{
WindowsIdentity id = WindowsIdentity.GetCurrent();
string[] name = id.Name.Split('\\');
SetField(thisObj, "userName", name[1]);
SetField(thisObj, "domain", name[0]);
SetField(thisObj, "domainSID", id.User.AccountDomainSid.Value);
SetField(thisObj, "userSID", id.User.Value);
userName = name[1];
domain = name[0];
domainSID = id.User.AccountDomainSid.Value;
userSID = id.User.Value;
string[] groups = new string[id.Groups.Count];
for (int i = 0; i < groups.Length; i++)
{
groups[i] = id.Groups[i].Value;
}
SetField(thisObj, "groupIDs", groups);
groupIDs = groups;
// HACK it turns out that Groups[0] is the primary group, but AFAIK this is not documented anywhere
SetField(thisObj, "primaryGroupID", groups[0]);
}
private static void SetField(object thisObj, string field, object value)
{
thisObj.GetType().GetField(field, BindingFlags.NonPublic | BindingFlags.Instance).SetValue(thisObj, value);
primaryGroupID = groups[0];
}
public static long getImpersonationToken0(object thisObj)
@ -547,6 +534,7 @@ static class Java_java_awt_SplashScreen
public static String _getImageFileName(long splashPtr) { return null; }
public static String _getImageJarName(long splashPtr) { return null; }
public static bool _setImageData(long splashPtr, byte[] data) { return false; }
public static float _getScaleFactor(long SplashPtr) { return 1; }
}
static class Java_java_awt_TextArea
@ -618,3 +606,30 @@ static class Java_java_awt_image_SampleModel
{
public static void initIDs() { }
}
static class Java_sun_net_ExtendedOptionsImpl
{
public static void init()
{
}
public static void setFlowOption(java.io.FileDescriptor fd, object f)
{
#if !FIRST_PASS
throw new java.lang.UnsupportedOperationException();
#endif
}
public static void getFlowOption(java.io.FileDescriptor fd, object f)
{
#if !FIRST_PASS
throw new java.lang.UnsupportedOperationException();
#endif
}
public static bool flowSupported()
{
// We don't support this. Solaris only functionality.
return false;
}
}

View File

@ -733,6 +733,24 @@ static class Java_sun_misc_Unsafe
}
}
static class Java_sun_misc_URLClassPath
{
public static java.net.URL[] getLookupCacheURLs(java.lang.ClassLoader loader)
{
return null;
}
public static int[] getLookupCacheForClassLoader(java.lang.ClassLoader loader, string name)
{
return null;
}
public static bool knownToNotExist0(java.lang.ClassLoader loader, string className)
{
return false;
}
}
static class Java_sun_misc_Version
{
public static string getJvmSpecialVersion()
@ -803,4 +821,9 @@ static class Java_sun_misc_VMSupport
{
return props;
}
public static string getVMTemporaryDirectory()
{
return System.IO.Path.GetTempPath();
}
}

View File

@ -646,6 +646,10 @@ namespace IKVM.NativeCode.sun.nio.ch
#if FIRST_PASS
return 0;
#else
if (level == global::ikvm.@internal.Winsock.IPPROTO_IPV6 && opt == global::ikvm.@internal.Winsock.IPV6_TCLASS)
{
return 0;
}
System.Net.Sockets.SocketOptionLevel sol = (System.Net.Sockets.SocketOptionLevel)level;
System.Net.Sockets.SocketOptionName son = (System.Net.Sockets.SocketOptionName)opt;
try
@ -678,9 +682,13 @@ namespace IKVM.NativeCode.sun.nio.ch
#endif
}
public static void setIntOption0(FileDescriptor fd, bool mayNeedConversion, int level, int opt, int arg)
public static void setIntOption0(FileDescriptor fd, bool mayNeedConversion, int level, int opt, int arg, bool isIPv6)
{
#if !FIRST_PASS
if (level == global::ikvm.@internal.Winsock.IPPROTO_IPV6 && opt == global::ikvm.@internal.Winsock.IPV6_TCLASS)
{
return;
}
System.Net.Sockets.SocketOptionLevel sol = (System.Net.Sockets.SocketOptionLevel)level;
System.Net.Sockets.SocketOptionName son = (System.Net.Sockets.SocketOptionName)opt;
if (mayNeedConversion)
@ -998,8 +1006,7 @@ namespace IKVM.NativeCode.sun.nio.ch
{
if (useExclBind)
{
// TODO enable this after we merge OpenJDK 7u40
//global::java.net.net_util_md.setExclusiveBind(fd.getSocket());
global::java.net.net_util_md.setExclusiveBind(fd.getSocket());
}
fd.getSocket().Bind(new System.Net.IPEndPoint(global::java.net.SocketUtil.getAddressFromInetAddress(addr, preferIPv6), port));
}
@ -1076,6 +1083,44 @@ namespace IKVM.NativeCode.sun.nio.ch
{
throw new global::java.net.SocketException("Socket is closed");
}
#endif
}
public static int poll(FileDescriptor fd, int events, long timeout)
{
#if FIRST_PASS
return 0;
#else
System.Net.Sockets.SelectMode selectMode;
switch (events)
{
case global::sun.nio.ch.Net.POLLCONN:
case global::sun.nio.ch.Net.POLLOUT:
selectMode = System.Net.Sockets.SelectMode.SelectWrite;
break;
case global::sun.nio.ch.Net.POLLIN:
selectMode = System.Net.Sockets.SelectMode.SelectRead;
break;
default:
throw new NotSupportedException();
}
int microSeconds = timeout >= Int32.MaxValue / 1000 ? Int32.MaxValue : (int)(timeout * 1000);
try
{
if (fd.getSocket().Poll(microSeconds, selectMode))
{
return events;
}
}
catch (System.Net.Sockets.SocketException x)
{
throw new global::java.net.SocketException(x.Message);
}
catch (System.ObjectDisposedException)
{
throw new global::java.net.SocketException("Socket is closed");
}
return 0;
#endif
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
Copyright (C) 2002-2013 Jeroen Frijters
Copyright (C) 2002-2015 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -190,11 +190,13 @@
<include name="openjdk/java.lang.invoke.cs" />
<include name="openjdk/java.lang.reflect.cs" />
<include name="openjdk/java.net.cs" />
<include name="openjdk/java.net.SocketInputStream.cs" />
<include name="openjdk/java.nio.cs" />
<include name="openjdk/java.security.cs" />
<include name="openjdk/java.util.cs" />
<include name="openjdk/java.util.prefs.cs" />
<include name="openjdk/misc.cs" />
<include name="openjdk/NativeInvokerBytecodeGenerator.cs" />
<include name="openjdk/sun.management.cs" />
<include name="openjdk/sun.misc.cs" />
<include name="openjdk/sun.nio.ch.cs" />

View File

@ -81,7 +81,7 @@ namespace IKVM.StubGen
{
foreach (MethodWrapper mw in tw.GetMethods())
{
if (!mw.IsHideFromReflection && mw.Name != StringConstants.CLINIT)
if (!mw.IsHideFromReflection && !mw.IsClassInitializer)
{
return true;
}

View File

@ -228,7 +228,7 @@ namespace IKVM.StubGen
{
if (!fw.IsHideFromReflection)
{
bool isSerialVersionUID = includeSerialVersionUID && fw.Name == "serialVersionUID" && fw.FieldTypeWrapper == PrimitiveTypeWrapper.LONG;
bool isSerialVersionUID = includeSerialVersionUID && fw.IsSerialVersionUID;
hasSerialVersionUID |= isSerialVersionUID;
if (fw.IsPublic || fw.IsProtected || isSerialVersionUID || includeNonPublicMembers)
{

View File

@ -1 +1 @@
b9c5991af89f8c044d6c9356ea09fcdfd7dea0c8
fdeb809dae4761f008efd4d27dfa9629ec76572a

View File

@ -34,7 +34,7 @@ static class Consts
// Use these assembly version constants to make code more maintainable.
//
public const string MonoVersion = "4.2.0.0";
public const string MonoVersion = "4.2.1.0";
public const string MonoCompany = "Mono development team";
public const string MonoProduct = "Mono Common Language Infrastructure";
public const string MonoCopyright = "(c) Various Mono authors";

View File

@ -908,10 +908,6 @@ public class Tests : TestsBase, ITest2
public void invoke2 () {
}
[MethodImplAttribute (MethodImplOptions.NoInlining)]
public void invoke3 () {
}
[MethodImplAttribute (MethodImplOptions.NoInlining)]
public void invoke_ex () {
invoke_ex_inner ();

View File

@ -1 +1 @@
3c62a78ee4f20b1751753ce79842028dd874ffad
0b47f1fbeb2c75de4f83067cd1412c5298cd8c63

View File

@ -442,8 +442,10 @@ namespace System.Net.NetworkInformation {
unsafe void OnDataAvailable (object sender, SocketAsyncEventArgs args)
{
if (nl_sock == null) // Recent changes in Mono cause MaybeCloseSocket to be called before OnDataAvailable
return;
EventType type;
fixed (byte *ptr = args.Buffer) {
fixed (byte *ptr = args.Buffer) {
type = ReadEvents (nl_sock.Handle, new IntPtr (ptr), args.BytesTransferred, 8192);
}
nl_sock.ReceiveAsync (nl_args);

View File

@ -96,6 +96,12 @@ namespace System {
set { s_IriParsing = value; }
}
// Do not rename this.
// User code might set this to true with reflection.
// When set to true an Uri constructed with UriKind.RelativeOrAbsolute
// and paths such as "/foo" is assumed relative.
private static bool useDotNetRelativeOrAbsolute;
#if BOOTSTRAP_BASIC
private static readonly string hexUpperChars = "0123456789ABCDEF";
private static readonly string [] Empty = new string [0];
@ -147,6 +153,8 @@ namespace System {
IriParsing = true;
else if (iriparsingVar == "false")
IriParsing = false;
useDotNetRelativeOrAbsolute = Environment.GetEnvironmentVariable ("MONO_URI_DOTNETRELATIVEORABSOLUTE") == "true";
}
public Uri (string uriString) : this (uriString, false)
@ -173,12 +181,21 @@ namespace System {
// When used instead of UriKind.RelativeOrAbsolute paths such as "/foo" are assumed relative.
const UriKind DotNetRelativeOrAbsolute = (UriKind) 300;
private void ProcessUriKind (string uriString, ref UriKind uriKind)
{
if (uriString == null)
return;
if (uriKind == DotNetRelativeOrAbsolute ||
(uriKind == UriKind.RelativeOrAbsolute && useDotNetRelativeOrAbsolute))
uriKind = (uriString.StartsWith ("/", StringComparison.Ordinal))? UriKind.Relative : UriKind.RelativeOrAbsolute;
}
public Uri (string uriString, UriKind uriKind)
{
source = uriString;
if (uriString != null && uriKind == DotNetRelativeOrAbsolute)
uriKind = (uriString.StartsWith ("/", StringComparison.Ordinal))? UriKind.Relative : UriKind.RelativeOrAbsolute;
ProcessUriKind (uriString, ref uriKind);
ParseUri (uriKind);
@ -212,8 +229,7 @@ namespace System {
return;
}
if (uriKind == DotNetRelativeOrAbsolute)
uriKind = (uriString.StartsWith ("/", StringComparison.Ordinal))? UriKind.Relative : UriKind.RelativeOrAbsolute;
ProcessUriKind (uriString, ref uriKind);
if (uriKind != UriKind.RelativeOrAbsolute &&
uriKind != UriKind.Absolute &&

View File

@ -263,7 +263,12 @@ namespace System
builder.Append (scheme);
// note: mailto and news use ':', not "://", as their delimiter
builder.Append (Uri.GetSchemeDelimiter (scheme));
if (UriParser.IsKnownScheme(scheme)) {
builder.Append (Uri.GetSchemeDelimiter (scheme));
}
else {
builder.Append (host.Length > 0 ? Uri.SchemeDelimiter : ":");
}
if (username != String.Empty) {
builder.Append (username);
@ -280,7 +285,8 @@ namespace System
if (path != String.Empty &&
builder [builder.Length - 1] != '/' &&
path.Length > 0 && path [0] != '/')
path.Length > 0 && path [0] != '/' &&
host.Length > 0)
builder.Append ('/');
builder.Append (path);
builder.Append (query);

View File

@ -387,6 +387,13 @@ namespace MonoTests.System
// this is what ASP.NET really means (the ?)
Assert.AreEqual ("http://192.168.0.21/error404.aspx?aspxerrorpath=/WebResource.axd", ub.Uri.ToString ());
}
[Test]
public void NoHostname ()
{
UriBuilder ub = new UriBuilder ("about", null, -1, "config");
Assert.AreEqual ("about:config", ub.ToString ());
}
}
}

View File

@ -1946,12 +1946,44 @@ namespace MonoTests.System
[Test]
public void DotNetRelativeOrAbsoluteTest ()
{
var uri1 = new Uri ("/foo", DotNetRelativeOrAbsolute);
Assert.IsFalse (uri1.IsAbsoluteUri);
Uri uri2;
Uri.TryCreate("/foo", DotNetRelativeOrAbsolute, out uri2);
Assert.IsFalse (uri2.IsAbsoluteUri);
FieldInfo useDotNetRelativeOrAbsoluteField = null;
bool useDotNetRelativeOrAbsoluteOld = false;
if (Type.GetType ("Mono.Runtime") != null) {
useDotNetRelativeOrAbsoluteField = typeof (Uri).GetField ("useDotNetRelativeOrAbsolute",
BindingFlags.Static | BindingFlags.GetField | BindingFlags.NonPublic);
useDotNetRelativeOrAbsoluteOld = (bool) useDotNetRelativeOrAbsoluteField.GetValue (null);
useDotNetRelativeOrAbsoluteField.SetValue (null, false);
}
try {
Uri uri;
uri = new Uri ("/foo", DotNetRelativeOrAbsolute);
Assert.IsFalse (uri.IsAbsoluteUri);
Uri.TryCreate("/foo", DotNetRelativeOrAbsolute, out uri);
Assert.IsFalse (uri.IsAbsoluteUri);
if (useDotNetRelativeOrAbsoluteField != null) {
uri = new Uri ("/foo", UriKind.RelativeOrAbsolute);
Assert.IsTrue (uri.IsAbsoluteUri);
Uri.TryCreate("/foo", UriKind.RelativeOrAbsolute, out uri);
Assert.IsTrue (uri.IsAbsoluteUri);
useDotNetRelativeOrAbsoluteField.SetValue (null, true);
}
uri = new Uri ("/foo", UriKind.RelativeOrAbsolute);
Assert.IsFalse (uri.IsAbsoluteUri);
Uri.TryCreate("/foo", DotNetRelativeOrAbsolute, out uri);
Assert.IsFalse (uri.IsAbsoluteUri);
} finally {
if (useDotNetRelativeOrAbsoluteField != null)
useDotNetRelativeOrAbsoluteField.SetValue (null, useDotNetRelativeOrAbsoluteOld);
}
}
[Test]

Some files were not shown because too many files have changed in this diff Show More