diff --git a/Makefile.in b/Makefile.in index b419fadcd2..dad2e1f88f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -85,7 +85,7 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/config.h.in mkinstalldirs \ $(srcdir)/mono-core.spec.in $(srcdir)/mono-uninstalled.pc.in \ AUTHORS COPYING.LIB ChangeLog NEWS compile config.guess \ - config.rpath config.sub depcomp install-sh missing ltmain.sh + 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 \ diff --git a/README.md b/README.md index d600ce4ad1..609b9fa466 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Mono is a software platform designed to allow developers to easily create cross platform applications. Mono is an open source implementation of Microsoft's .NET Framework based on the ECMA standards for C# and the Common Language Runtime. -[![Build Status](http://monojenkins.cloudapp.net/job/Mono/badge/icon)](http://monojenkins.cloudapp.net/job/Mono/) +[![Build Status](http://jenkins.mono-project.com/job/test-mono-mainline/badge/icon/)](http://jenkins.mono-project.com/job/test-mono-mainline/) 1. [Installation](#compilation-and-installation) 2. [Using Mono](#using-mono) diff --git a/autogen.sh b/autogen.sh index 5213ecffd3..d4a6ecaccb 100755 --- a/autogen.sh +++ b/autogen.sh @@ -123,7 +123,6 @@ if test x$has_ext_mod = xtrue; then popd else cat mono/mini/Makefile.am.in > mono/mini/Makefile.am - cat mono/metadata/Makefile.am.in > mono/metadata/Makefile.am fi diff --git a/configure.REMOVED.git-id b/configure.REMOVED.git-id index d901c34140..5526f189a3 100644 --- a/configure.REMOVED.git-id +++ b/configure.REMOVED.git-id @@ -1 +1 @@ -e2d46ae5f394ada396886d241225ad895d4fa194 \ No newline at end of file +f98bd1e8bf7b203688329a408624ecaaf8192c9a \ No newline at end of file diff --git a/configure.ac.REMOVED.git-id b/configure.ac.REMOVED.git-id index aefe5b6d2e..c4a1fd294d 100644 --- a/configure.ac.REMOVED.git-id +++ b/configure.ac.REMOVED.git-id @@ -1 +1 @@ -9ad91a3e3e9b4a437dedfc1a32a3c9092d967f5e \ No newline at end of file +6792b0c1cb1e40049a4610645db04eb603741561 \ No newline at end of file diff --git a/docs/deploy/mono-api-class.html b/docs/deploy/mono-api-class.html index f6320d90c9..287cba06d0 100644 --- a/docs/deploy/mono-api-class.html +++ b/docs/deploy/mono-api-class.html @@ -377,7 +377,7 @@ mono_class_get_method_from_name (MonoClass *klass, const char *name, int param_c

Parameters -

klass:
where to look for the method
name_space:
name of the method
param_count:
number of parameters. -1 for any number.
+
klass:
where to look for the method
name:
name of the method
param_count:
number of parameters. -1 for any number.
Remarks

Obtains a MonoMethod with a given name and number of parameters. diff --git a/docs/deploy/mono-api-wapi.html b/docs/deploy/mono-api-wapi.html index b1b8fe8dc8..778f9f9731 100644 --- a/docs/deploy/mono-api-wapi.html +++ b/docs/deploy/mono-api-wapi.html @@ -283,15 +283,8 @@

DeleteCriticalSection
-
void DeleteCriticalSection(WapiCriticalSection *section) - -
+
Prototype: DeleteCriticalSection

-Parameters -

section:
The critical section to delete.
-Remarks -

- Releases all resources owned by critical section section.

@@ -764,35 +757,15 @@ gpointer GetStdHandle(WapiStdHandle stdhandle)
InitializeCriticalSectionAndSpinCount
-
gboolean InitializeCriticalSectionAndSpinCount(WapiCriticalSection *section, - guint32 spincount G_GNUC_UNUSED) - -
+
Prototype: InitializeCriticalSectionAndSpinCount

-Parameters -

section:
The critical section to initialise.
spincount:
The spin count for this critical section. Not
-Remarks -

currently used. - - Initialises a critical section and sets the spin count. This - implementation just calls InitializeCriticalSection(). - - Return value: %TRUE on success, %FALSE otherwise. (%FALSE never - happens).

InitializeCriticalSection
-
void InitializeCriticalSection(WapiCriticalSection *section) - -
+
Prototype: InitializeCriticalSection

-Parameters -

section:
The critical section to initialise
-Remarks -

- Initialises a critical section.

@@ -1046,19 +1019,8 @@ gpointer GetStdHandle(WapiStdHandle stdhandle)
SetCriticalSectionSpinCount
-
guint32 SetCriticalSectionSpinCount(WapiCriticalSection *section G_GNUC_UNUSED, guint32 spincount G_GNUC_UNUSED) - -
+
Prototype: SetCriticalSectionSpinCount

-Parameters -

section:
The critical section to set
spincount:
The new spin count for this critical section. Not
-Remarks -

currently used. - - Sets the spin count for the critical section section. The spin - count is currently ignored, and set to zero. - - Return value: The previous spin count. (Currently always zero).

@@ -1356,24 +1318,8 @@ SleepEx (guint32 ms, gboolean alertable)
TryEnterCriticalSection
-
gboolean TryEnterCriticalSection(WapiCriticalSection *section) - -
+
Prototype: TryEnterCriticalSection

-Parameters -

section:
The critical section to try and enter
-Remarks -

- Attempts to enter a critical section without blocking. If - successful the calling thread takes ownership of the critical - section. - - A thread can recursively call EnterCriticalSection() and - TryEnterCriticalSection(), but must call LeaveCriticalSection() an - equal number of times. - - Return value: %TRUE if the thread successfully locked the critical - section, %FALSE otherwise.

diff --git a/eglib/src/eglib-remap.h b/eglib/src/eglib-remap.h index 9b4ecf1aeb..5c918d25da 100644 --- a/eglib/src/eglib-remap.h +++ b/eglib/src/eglib-remap.h @@ -273,3 +273,9 @@ #define g_utf8_get_char_validated monoeg_utf8_get_char_validated #define g_utf8_prev_char monoeg_utf8_prev_char #define g_utf8_to_ucs4 monoeg_utf8_to_ucs4 + + +#define g_log_default_handler monoeg_log_default_handler +#define g_log_set_default_handler monoeg_log_set_default_handler +#define g_set_print_handler monoeg_set_print_handler +#define g_set_printerr_handler monoeg_set_printerr_handler diff --git a/eglib/src/glib.h b/eglib/src/glib.h index 7cb8e6179c..533c84116c 100644 --- a/eglib/src/glib.h +++ b/eglib/src/glib.h @@ -603,10 +603,14 @@ void g_assertion_message (const gchar *format, ...) G_GNUC_NORETURN #define g_message(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __VA_ARGS__) #define g_debug(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, __VA_ARGS__) #endif /* ndef HAVE_C99_SUPPORT */ -#define g_log_set_handler(a,b,c,d) -#define G_GNUC_INTERNAL +typedef void (*GLogFunc) (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data); +typedef void (*GPrintFunc) (const gchar *string); +void g_log_default_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data); +GLogFunc g_log_set_default_handler (GLogFunc log_func, gpointer user_data); +GPrintFunc g_set_print_handler (GPrintFunc func); +GPrintFunc g_set_printerr_handler (GPrintFunc func); /* * Conversions */ diff --git a/eglib/src/goutput.c b/eglib/src/goutput.c index 73ef1f383d..1dc8bd6faf 100644 --- a/eglib/src/goutput.c +++ b/eglib/src/goutput.c @@ -35,85 +35,47 @@ /* The current fatal levels, error is always fatal */ static GLogLevelFlags fatal = G_LOG_LEVEL_ERROR; +static GLogFunc default_log_func; +static gpointer default_log_func_user_data; +static GPrintFunc stdout_handler, stderr_handler; -#if PLATFORM_ANDROID -#include - -static android_LogPriority -to_android_priority (GLogLevelFlags log_level) -{ - switch (log_level & G_LOG_LEVEL_MASK) - { - case G_LOG_LEVEL_ERROR: return ANDROID_LOG_FATAL; - case G_LOG_LEVEL_CRITICAL: return ANDROID_LOG_ERROR; - case G_LOG_LEVEL_WARNING: return ANDROID_LOG_WARN; - case G_LOG_LEVEL_MESSAGE: return ANDROID_LOG_INFO; - case G_LOG_LEVEL_INFO: return ANDROID_LOG_DEBUG; - case G_LOG_LEVEL_DEBUG: return ANDROID_LOG_VERBOSE; - } - return ANDROID_LOG_UNKNOWN; -} - -static void -out_vfprintf (FILE *ignore, const gchar *format, va_list args) -{ - /* TODO: provide a proper app name */ - __android_log_vprint (ANDROID_LOG_ERROR, "mono", format, args); -} -#elif MONOTOUCH && defined(__arm__) -#include - -static int -to_asl_priority (GLogLevelFlags log_level) -{ - switch (log_level & G_LOG_LEVEL_MASK) - { - case G_LOG_LEVEL_ERROR: return ASL_LEVEL_CRIT; - case G_LOG_LEVEL_CRITICAL: return ASL_LEVEL_ERR; - case G_LOG_LEVEL_WARNING: return ASL_LEVEL_WARNING; - case G_LOG_LEVEL_MESSAGE: return ASL_LEVEL_NOTICE; - case G_LOG_LEVEL_INFO: return ASL_LEVEL_INFO; - case G_LOG_LEVEL_DEBUG: return ASL_LEVEL_DEBUG; - } - return ASL_LEVEL_ERR; -} - -static void -out_vfprintf (FILE *ignore, const gchar *format, va_list args) -{ - asl_vlog (NULL, NULL, ASL_LEVEL_WARNING, format, args); -} - -#else -static void -out_vfprintf (FILE *file, const gchar *format, va_list args) -{ - vfprintf (file, format, args); -} -#endif +static void default_stdout_handler (const gchar *string); +static void default_stderr_handler (const gchar *string); void g_print (const gchar *format, ...) { + char *msg; va_list args; va_start (args, format); - - out_vfprintf (stdout, format, args); - + if (vasprintf (&msg, format, args) < 0) + return; va_end (args); + + if (!stdout_handler) + stdout_handler = default_stdout_handler; + + stdout_handler (msg); + free (msg); } void g_printerr (const gchar *format, ...) { + char *msg; va_list args; va_start (args, format); - - out_vfprintf (stderr, format, args); - + if (vasprintf (&msg, format, args) < 0) + return; va_end (args); + + if (!stderr_handler) + stderr_handler = default_stderr_handler; + + stderr_handler (msg); + free (msg); } GLogLevelFlags @@ -140,42 +102,16 @@ g_log_set_fatal_mask (const gchar *log_domain, GLogLevelFlags fatal_mask) void g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args) { -#if PLATFORM_ANDROID - __android_log_vprint (to_android_priority (log_level), log_domain, format, args); -#elif MONOTOUCH && defined(__arm__) - asl_vlog (NULL, NULL, to_asl_priority (log_level), format, args); -#else char *msg; + + if (!default_log_func) + default_log_func = g_log_default_handler; if (vasprintf (&msg, format, args) < 0) return; -#ifdef G_OS_WIN32 - printf ("%s%s%s\n", - log_domain != NULL ? log_domain : "", - log_domain != NULL ? ": " : "", - msg); -#else -#if MONOTOUCH - FILE *target = stderr; -#else - FILE *target = stdout; -#endif - - fprintf (target, "%s%s%s\n", - log_domain != NULL ? log_domain : "", - log_domain != NULL ? ": " : "", - msg); -#endif + default_log_func (log_domain, log_level, msg, default_log_func_user_data); free (msg); - if (log_level & fatal){ - fflush (stdout); - fflush (stderr); - } -#endif - if (log_level & fatal){ - abort (); - } } void @@ -196,6 +132,143 @@ g_assertion_message (const gchar *format, ...) va_start (args, format); g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args); va_end (args); - abort (); +} + + +#if PLATFORM_ANDROID +#include + +static android_LogPriority +to_android_priority (GLogLevelFlags log_level) +{ + switch (log_level & G_LOG_LEVEL_MASK) + { + case G_LOG_LEVEL_ERROR: return ANDROID_LOG_FATAL; + case G_LOG_LEVEL_CRITICAL: return ANDROID_LOG_ERROR; + case G_LOG_LEVEL_WARNING: return ANDROID_LOG_WARN; + case G_LOG_LEVEL_MESSAGE: return ANDROID_LOG_INFO; + case G_LOG_LEVEL_INFO: return ANDROID_LOG_DEBUG; + case G_LOG_LEVEL_DEBUG: return ANDROID_LOG_VERBOSE; + } + return ANDROID_LOG_UNKNOWN; +} + +void +g_log_default_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data) +{ + __android_log_write (to_android_priority (log_level), log_domain, message); + if (log_level & fatal) + abort (); +} + +static void +default_stdout_handler (const gchar *message) +{ + /* TODO: provide a proper app name */ + __android_log_write (ANDROID_LOG_ERROR, "mono", message); +} + +static void +default_stderr_handler (const gchar *message) +{ + /* TODO: provide a proper app name */ + __android_log_write (ANDROID_LOG_ERROR, "mono", message); +} + + +#elif MONOTOUCH +#include + +static int +to_asl_priority (GLogLevelFlags log_level) +{ + switch (log_level & G_LOG_LEVEL_MASK) + { + case G_LOG_LEVEL_ERROR: return ASL_LEVEL_CRIT; + case G_LOG_LEVEL_CRITICAL: return ASL_LEVEL_ERR; + case G_LOG_LEVEL_WARNING: return ASL_LEVEL_WARNING; + case G_LOG_LEVEL_MESSAGE: return ASL_LEVEL_NOTICE; + case G_LOG_LEVEL_INFO: return ASL_LEVEL_INFO; + case G_LOG_LEVEL_DEBUG: return ASL_LEVEL_DEBUG; + } + return ASL_LEVEL_ERR; +} + +void +g_log_default_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data) +{ + asl_log (NULL, NULL, to_asl_priority (log_level), "%s", message); + if (log_level & fatal) + abort (); +} + +static void +default_stdout_handler (const gchar *message) +{ + asl_log (NULL, NULL, ASL_LEVEL_WARNING, "%s", message); +} + +static void +default_stderr_handler (const gchar *message) +{ + asl_log (NULL, NULL, ASL_LEVEL_WARNING, "%s", message); +} + +#else + +void +g_log_default_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data) +{ + FILE *target = stdout; + + fprintf (target, "%s%s%s\n", + log_domain != NULL ? log_domain : "", + log_domain != NULL ? ": " : "", + message); + + if (log_level & fatal) { + fflush (stdout); + fflush (stderr); + abort (); + } +} + +static void +default_stdout_handler (const gchar *string) +{ + fprintf (stdout, "%s", string); +} + +static void +default_stderr_handler (const gchar *string) +{ + fprintf (stderr, "%s", string); +} + +#endif + +GLogFunc +g_log_set_default_handler (GLogFunc log_func, gpointer user_data) +{ + GLogFunc old = default_log_func; + default_log_func = log_func; + default_log_func_user_data = user_data; + return old; +} + +GPrintFunc +g_set_print_handler (GPrintFunc func) +{ + GPrintFunc old = stdout_handler; + stdout_handler = func; + return old; +} + +GPrintFunc +g_set_printerr_handler (GPrintFunc func) +{ + GPrintFunc old = stderr_handler; + stderr_handler = func; + return old; } diff --git a/external/cecil/Mono.Cecil.PE/Image.cs b/external/cecil/Mono.Cecil.PE/Image.cs index a11cf1c404..fdecbbeb40 100644 --- a/external/cecil/Mono.Cecil.PE/Image.cs +++ b/external/cecil/Mono.Cecil.PE/Image.cs @@ -150,6 +150,11 @@ namespace Mono.Cecil.PE { PointerToRawData = buffer.ReadInt32 (), }; + if (directory.SizeOfData == 0 || directory.PointerToRawData == 0) { + header = Empty.Array; + return directory; + } + buffer.position = (int) (directory.PointerToRawData - section.PointerToRawData); header = new byte [directory.SizeOfData]; diff --git a/external/cecil/Mono.Cecil/AssemblyReader.cs b/external/cecil/Mono.Cecil/AssemblyReader.cs index a9f0b6a1d0..569475b573 100644 --- a/external/cecil/Mono.Cecil/AssemblyReader.cs +++ b/external/cecil/Mono.Cecil/AssemblyReader.cs @@ -3099,9 +3099,29 @@ namespace Mono.Cecil { } } + string UnescapeTypeName (string name) + { + StringBuilder sb = new StringBuilder (name.Length); + for (int i = 0; i < name.Length; i++) { + char c = name [i]; + if (name [i] == '\\') { + if ((i < name.Length - 1) && (name [i + 1] == '\\')) { + sb.Append (c); + i++; + } + } else { + sb.Append (c); + } + } + return sb.ToString (); + } + public TypeReference ReadTypeReference () { - return TypeParser.ParseType (reader.module, ReadUTF8String ()); + string s = ReadUTF8String (); + if (s != null && s.IndexOf ('\\') != -1) + s = UnescapeTypeName (s); + return TypeParser.ParseType (reader.module, s); } object ReadCustomAttributeEnum (TypeReference enum_type) diff --git a/external/cecil/Mono.Cecil/AssemblyWriter.cs b/external/cecil/Mono.Cecil/AssemblyWriter.cs index 0597bc0b5d..f1026eed0d 100644 --- a/external/cecil/Mono.Cecil/AssemblyWriter.cs +++ b/external/cecil/Mono.Cecil/AssemblyWriter.cs @@ -1164,9 +1164,14 @@ namespace Mono.Cecil { MetadataToken GetTypeRefToken (TypeReference type) { + MetadataToken token; + if (module.CustomMetadataWriter != null) { + if (module.CustomMetadataWriter.CreateTypeRefToken (ref type, out token)) + return token; + } + var row = CreateTypeRefRow (type); - MetadataToken token; if (type_ref_map.TryGetValue (row, out token)) return token; diff --git a/external/cecil/Mono.Cecil/Import.cs b/external/cecil/Mono.Cecil/Import.cs index a32eb3c241..93040101c9 100644 --- a/external/cecil/Mono.Cecil/Import.cs +++ b/external/cecil/Mono.Cecil/Import.cs @@ -437,7 +437,7 @@ namespace Mono.Cecil { } #endif - public TypeReference ImportType (TypeReference type, ImportGenericContext context) + public virtual TypeReference ImportType (TypeReference type, ImportGenericContext context) { if (type.IsTypeSpecification ()) return ImportTypeSpecification (type, context); @@ -466,6 +466,7 @@ namespace Mono.Cecil { case MetadataScopeType.AssemblyNameReference: return ImportAssemblyName ((AssemblyNameReference) scope); case MetadataScopeType.ModuleDefinition: + if (scope == module) return scope; return ImportAssemblyName (((ModuleDefinition) scope).Assembly.Name); case MetadataScopeType.ModuleReference: throw new NotImplementedException (); @@ -474,7 +475,7 @@ namespace Mono.Cecil { throw new NotSupportedException (); } - AssemblyNameReference ImportAssemblyName (AssemblyNameReference name) + protected virtual AssemblyNameReference ImportAssemblyName (AssemblyNameReference name) { AssemblyNameReference reference; if (TryGetAssemblyNameReference (name, out reference)) diff --git a/external/cecil/Mono.Cecil/ModuleDefinition.cs b/external/cecil/Mono.Cecil/ModuleDefinition.cs index 7f75cbd17e..61870cdbb5 100644 --- a/external/cecil/Mono.Cecil/ModuleDefinition.cs +++ b/external/cecil/Mono.Cecil/ModuleDefinition.cs @@ -157,6 +157,22 @@ namespace Mono.Cecil { } } + interface ICustomMetadataWriter + { + /* + * Remap TypeReference or create custom TypeRef token. + * + * Return true to use the returned custom 'token'. + * + * Return false to create a TypeRef token for 'type' + * (which may have been replaced with a different TypeReference). + * + * This is necessary when types are moved from one assembly to another + * to either adjust the scope or replace a TypeRef with a TypeDef token. + */ + bool CreateTypeRefToken (ref TypeReference type, out MetadataToken token); + } + public sealed class WriterParameters { Stream symbol_stream; @@ -216,6 +232,7 @@ namespace Mono.Cecil { #if !READ_ONLY MetadataImporter importer; + ICustomMetadataWriter custom_writer; #endif Collection custom_attributes; Collection references; @@ -286,6 +303,18 @@ namespace Mono.Cecil { internal MetadataImporter MetadataImporter { get { return importer ?? (importer = new MetadataImporter (this)); } } + + internal void SetMetadataImporter (MetadataImporter importer) + { + if (this.importer != null) + throw new InvalidOperationException (); + this.importer = importer; + } + + internal ICustomMetadataWriter CustomMetadataWriter { + get { return custom_writer; } + set { custom_writer = value; } + } #endif public IAssemblyResolver AssemblyResolver { diff --git a/external/ikvm/awt/graphics.cs b/external/ikvm/awt/graphics.cs index 2d4f05398b..11b1ed89d6 100644 --- a/external/ikvm/awt/graphics.cs +++ b/external/ikvm/awt/graphics.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2002, 2004, 2005, 2006, 2007 Jeroen Frijters Copyright (C) 2006 Active Endpoints, Inc. - Copyright (C) 2006 - 2013 Volker Berlin (i-net software) + Copyright (C) 2006 - 2014 Volker Berlin (i-net software) Copyright (C) 2011 Karsten Heinrich (i-net software) This software is provided 'as-is', without any express or implied @@ -40,17 +40,29 @@ namespace ikvm.awt internal class BitmapGraphics : NetGraphics { private readonly Bitmap bitmap; + private readonly BufferedImage image; - internal BitmapGraphics(Bitmap bitmap, java.awt.Font font, Color fgcolor, Color bgcolor) - : base(createGraphics(bitmap), font, fgcolor, bgcolor) + internal BitmapGraphics(Bitmap bitmap, Object destination, java.awt.Font font, Color fgcolor, Color bgcolor) + : base(createGraphics(bitmap), destination, font, fgcolor, bgcolor) { this.bitmap = bitmap; + image = destination as BufferedImage; } - internal BitmapGraphics(Bitmap bitmap) - : base(createGraphics(bitmap), null, Color.White, Color.Black) + internal BitmapGraphics(Bitmap bitmap, Object destination) + : this(bitmap, destination, null, Color.White, Color.Black) { - this.bitmap = bitmap; + } + + internal override Graphics g + { + get { + if (image != null) + { + image.toBitmap(); + } + return base.g; + } } protected override SizeF GetSize() { @@ -89,8 +101,8 @@ namespace ikvm.awt { private readonly Control control; - internal ComponentGraphics(Control control, java.awt.Color fgColor, java.awt.Color bgColor, java.awt.Font font) - : base(control.CreateGraphics(), font, J2C.ConvertColor(fgColor), J2C.ConvertColor(bgColor)) + internal ComponentGraphics(Control control, java.awt.Component target, java.awt.Color fgColor, java.awt.Color bgColor, java.awt.Font font) + : base(control.CreateGraphics(), target, font, J2C.ConvertColor(fgColor), J2C.ConvertColor(bgColor)) { this.control = control; } @@ -116,12 +128,17 @@ namespace ikvm.awt return (Point)this.control.Invoke(new Converter(getPointToScreenImpl),point); } - public override void copyArea(int x, int y, int width, int height, int dx, int dy) - { - Point src = getPointToScreen(new Point(x + (int)this.g.Transform.OffsetX, y + (int)this.g.Transform.OffsetY)); - Point dest = new Point(x + (int)this.g.Transform.OffsetX + dx, y + (int)this.g.Transform.OffsetY + dy); - this.g.CopyFromScreen(src, dest, new Size(width, height)); - } + public override void copyArea(int x, int y, int width, int height, int dx, int dy) + { + Matrix t = g.Transform; + Point src = getPointToScreen(new Point(x + (int)t.OffsetX, y + (int)t.OffsetY)); + Bitmap copy = new Bitmap(width, height); + using (Graphics gCopy = Graphics.FromImage(copy)) + { + gCopy.CopyFromScreen(src, new Point(0, 0), new Size(width, height)); + } + g.DrawImageUnscaled(copy, x + dx, y + dy); + } public override void clip(java.awt.Shape shape) { @@ -150,7 +167,7 @@ namespace ikvm.awt private bool isBase = true; internal PrintGraphics(Graphics g) - : base(g, null, Color.White, Color.Black) + : base(g, null, null, Color.White, Color.Black) { baseContext = new PrintGraphicsContext(); baseContext.Current = this; @@ -744,7 +761,7 @@ namespace ikvm.awt netG.g.Clip = Clip; netG.g.SmoothingMode = SmoothingMode; netG.g.PixelOffsetMode = PixelOffsetMode; - netG.g.TextRenderingHint = TextRenderingHint; + netG.setTextRenderingHint(TextRenderingHint); netG.g.InterpolationMode = InterpolationMode; netG.g.CompositingMode = CompositingMode; } @@ -768,10 +785,9 @@ namespace ikvm.awt } } - internal abstract class NetGraphics : java.awt.Graphics2D + internal abstract class NetGraphics : java.awt.Graphics2D//sun.java2d.SunGraphics2D { - internal Graphics g; - internal Graphics JGraphics { get { return g; } } + private Graphics graphics; private java.awt.Color javaColor; private java.awt.Paint javaPaint; internal Color color; @@ -780,6 +796,7 @@ namespace ikvm.awt private java.awt.Stroke stroke; private static java.awt.BasicStroke defaultStroke = new java.awt.BasicStroke(); private Font netfont; + private int baseline; internal Brush brush; internal Pen pen; private CompositeHelper composite; @@ -787,7 +804,16 @@ namespace ikvm.awt private Object textAntialiasHint; private Object fractionalHint = java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT; - protected NetGraphics(Graphics g, java.awt.Font font, Color fgcolor, Color bgcolor) + private static System.Collections.Generic.Dictionary baselines = new System.Collections.Generic.Dictionary(); + + internal static readonly StringFormat FORMAT = new StringFormat(StringFormat.GenericTypographic); + static NetGraphics() + { + FORMAT.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox; + FORMAT.Trimming = StringTrimming.None; + } + + protected NetGraphics(Graphics g, Object destination, java.awt.Font font, Color fgcolor, Color bgcolor) //: base( new sun.java2d.SurfaceData(destination) ) { if (font == null) { @@ -801,12 +827,21 @@ namespace ikvm.awt init(g); } + /// + /// The current C# Graphics + /// + internal virtual Graphics g + { + get { return graphics; } + set { graphics = value; } + } + protected void init(Graphics graphics) { NetGraphicsState state = new NetGraphicsState(); state.saveGraphics(this); g = graphics; - state.restoreGraphics(this); + state.restoreGraphics(this); } /// @@ -850,7 +885,7 @@ namespace ikvm.awt { if (pen!=null) pen.Dispose(); if (brush!=null) brush.Dispose(); - g.Dispose(); + graphics.Dispose(); //for dispose we does not need to synchronize the buffer of a bitmap } public override void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) @@ -1190,6 +1225,7 @@ namespace ikvm.awt { netfont = f.getNetFont(); font = f; + baseline = getBaseline( netfont, g.TextRenderingHint ); } } @@ -1278,30 +1314,33 @@ namespace ikvm.awt drawString(str, (float)x, (float)y); } - public override void drawString(String text, float x, float y) - { - if (text.Length == 0) - { + public override void drawString(String text, float x, float y) { + if (text.Length == 0) { return; } - bool fractional = isFractionalMetrics(); - StringFormat format = new StringFormat(StringFormat.GenericTypographic); - format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox; - format.Trimming = StringTrimming.None; - if (fractional || !sun.font.StandardGlyphVector.isSimpleString(font, text)) - { - g.DrawString(text, netfont, brush, x, y - font.getSize(), format); - } - else - { - // fixed metric for simple text, we position every character to simulate the Java behaviour - java.awt.font.FontRenderContext frc = new java.awt.font.FontRenderContext(null, isAntiAlias(), fractional); - sun.font.FontDesignMetrics metrics = sun.font.FontDesignMetrics.getMetrics(font, frc); - y -= font.getSize(); - for (int i = 0; i < text.Length; i++) - { - g.DrawString(text.Substring(i, 1), netfont, brush, x, y, format); - x += metrics.charWidth(text[i]); + CompositingMode origCM = g.CompositingMode; + try { + if (origCM != CompositingMode.SourceOver) { + // Java has a different behaviar for AlphaComposite and Text Antialiasing + g.CompositingMode = CompositingMode.SourceOver; + } + + bool fractional = isFractionalMetrics(); + if (fractional || !sun.font.StandardGlyphVector.isSimpleString(font, text)) { + g.DrawString(text, netfont, brush, x, y - baseline, FORMAT); + } else { + // fixed metric for simple text, we position every character to simulate the Java behaviour + java.awt.font.FontRenderContext frc = new java.awt.font.FontRenderContext(null, isAntiAlias(), fractional); + sun.font.FontDesignMetrics metrics = sun.font.FontDesignMetrics.getMetrics(font, frc); + y -= baseline; + for (int i = 0; i < text.Length; i++) { + g.DrawString(text.Substring(i, 1), netfont, brush, x, y, FORMAT); + x += metrics.charWidth(text[i]); + } + } + } finally { + if (origCM != CompositingMode.SourceOver) { + g.CompositingMode = origCM; } } } @@ -1345,6 +1384,9 @@ namespace ikvm.awt public override void setComposite(java.awt.Composite comp) { + if (javaComposite == comp) { + return; + } if (comp == null) { throw new java.lang.IllegalArgumentException("null Composite"); @@ -1750,13 +1792,13 @@ namespace ikvm.awt if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT || hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF) { - g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; + setTextRenderingHint(TextRenderingHint.SingleBitPerPixelGridFit); textAntialiasHint = hintValue; return; } if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON) { - g.TextRenderingHint = TextRenderingHint.AntiAlias; + setTextRenderingHint(TextRenderingHint.AntiAlias); textAntialiasHint = hintValue; return; } @@ -1933,6 +1975,71 @@ namespace ikvm.awt return stroke; } + internal void setTextRenderingHint(TextRenderingHint hint) + { + g.TextRenderingHint = hint; + baseline = getBaseline(netfont, hint); + } + + /// + /// Caclulate the baseline from a font and a TextRenderingHint + /// + /// the font + /// the used TextRenderingHint + /// + private static int getBaseline(Font font, TextRenderingHint hint) + { + lock (baselines) + { + String key = font.ToString() + hint.ToString(); + int baseline; + if (!baselines.TryGetValue(key, out baseline)) + { + FontFamily family = font.FontFamily; + FontStyle style = font.Style; + float ascent = family.GetCellAscent(style); + float lineSpace = family.GetLineSpacing(style); + + baseline = (int)Math.Round(font.GetHeight() * ascent / lineSpace); + + // Until this point the calulation use only the Font. But with different TextRenderingHint there are smal differences. + // There is no API that calulate the offset from TextRenderingHint that we messure it. + const int w = 3; + const int h = 3; + + Bitmap bitmap = new Bitmap(w, h); + Graphics g = Graphics.FromImage(bitmap); + g.TextRenderingHint = hint; + g.FillRectangle(new SolidBrush(Color.White), 0, 0, w, h); + g.DrawString("A", font, new SolidBrush(Color.Black), 0, -baseline, FORMAT); + g.DrawString("X", font, new SolidBrush(Color.Black), 0, -baseline, FORMAT); + g.Dispose(); + + int y = 0; + LINE: + while (y < h) + { + for (int x = 0; x < w; x++) + { + Color color = bitmap.GetPixel(x, y); + if (color.GetBrightness() < 0.5) + { + //there is a black pixel, we continue in the next line. + baseline++; + y++; + goto LINE; + } + } + break; // there was a line without black pixel + } + + + baselines[key] = baseline; + } + return baseline; + } + } + private bool isAntiAlias() { switch (g.TextRenderingHint) @@ -1962,6 +2069,7 @@ namespace ikvm.awt Matrix currentMatrix = null; Font currentFont = netfont; TextRenderingHint currentHint = g.TextRenderingHint; + int currentBaseline = baseline; try { java.awt.Font javaFont = gv.getFont(); @@ -1969,19 +2077,22 @@ namespace ikvm.awt { netfont = javaFont.getNetFont(); } + TextRenderingHint hint; if (frc.isAntiAliased()) { if( frc.usesFractionalMetrics() ){ - g.TextRenderingHint = TextRenderingHint.AntiAlias; + hint = TextRenderingHint.AntiAlias; } else { - g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; + hint = TextRenderingHint.AntiAliasGridFit; } } else { if (frc.usesFractionalMetrics()) { - g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel; + hint = TextRenderingHint.SingleBitPerPixel; } else { - g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; + hint = TextRenderingHint.SingleBitPerPixelGridFit; } } + g.TextRenderingHint = hint; + baseline = getBaseline(netfont, hint); if (!frc.getTransform().equals(getTransform())) { // save the old context and use the transformation from the renderContext @@ -1994,6 +2105,7 @@ namespace ikvm.awt { // Restore the old context if needed g.TextRenderingHint = currentHint; + baseline = currentBaseline; netfont = currentFont; if (currentMatrix != null) { @@ -2144,14 +2256,20 @@ namespace ikvm.awt } } - public class NetGraphicsEnvironment : java.awt.GraphicsEnvironment + public class NetGraphicsEnvironment : sun.java2d.SunGraphicsEnvironment { + + public override bool isDisplayLocal() + { + return true; + } + // Create a bitmap with the dimensions of the argument image. Then // create a graphics objects from the bitmap. All paint operations will // then paint the bitmap. public override java.awt.Graphics2D createGraphics(BufferedImage bi) { - return new BitmapGraphics(bi.getBitmap()); + return new BitmapGraphics(bi.getBitmap(), bi ); } public override java.awt.Font[] getAllFonts() diff --git a/external/ikvm/awt/toolkit-0.95.cs.REMOVED.git-id b/external/ikvm/awt/toolkit-0.95.cs.REMOVED.git-id index a8c1fa49f2..8a677abac1 100644 --- a/external/ikvm/awt/toolkit-0.95.cs.REMOVED.git-id +++ b/external/ikvm/awt/toolkit-0.95.cs.REMOVED.git-id @@ -1 +1 @@ -4341b9c30b528a9c448533ed715fc437369b3561 \ No newline at end of file +474cfafc92a8fad74e36e71fb612ebd44209bce8 \ No newline at end of file diff --git a/external/ikvm/bin/ikvm.exe.manifest b/external/ikvm/bin/ikvm.exe.manifest new file mode 100644 index 0000000000..3dbbfde966 --- /dev/null +++ b/external/ikvm/bin/ikvm.exe.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/external/ikvm/classpath/java/util/concurrent/atomic/Striped64.java b/external/ikvm/classpath/java/util/concurrent/atomic/Striped64.java new file mode 100644 index 0000000000..1fea75bed6 --- /dev/null +++ b/external/ikvm/classpath/java/util/concurrent/atomic/Striped64.java @@ -0,0 +1,380 @@ +/* + * 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. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +package java.util.concurrent.atomic; +import java.util.function.LongBinaryOperator; +import java.util.function.DoubleBinaryOperator; +import java.util.concurrent.ThreadLocalRandom; + +/** + * A package-local class holding common representation and mechanics + * for classes supporting dynamic striping on 64bit values. The class + * extends Number so that concrete subclasses must publicly do so. + */ +@SuppressWarnings("serial") +abstract class Striped64 extends Number { + /* + * This class maintains a lazily-initialized table of atomically + * updated variables, plus an extra "base" field. The table size + * is a power of two. Indexing uses masked per-thread hash codes. + * Nearly all declarations in this class are package-private, + * accessed directly by subclasses. + * + * Table entries are of class Cell; a variant of AtomicLong padded + * (via @sun.misc.Contended) to reduce cache contention. Padding + * is overkill for most Atomics because they are usually + * irregularly scattered in memory and thus don't interfere much + * with each other. But Atomic objects residing in arrays will + * tend to be placed adjacent to each other, and so will most + * often share cache lines (with a huge negative performance + * impact) without this precaution. + * + * In part because Cells are relatively large, we avoid creating + * them until they are needed. When there is no contention, all + * updates are made to the base field. Upon first contention (a + * failed CAS on base update), the table is initialized to size 2. + * The table size is doubled upon further contention until + * reaching the nearest power of two greater than or equal to the + * number of CPUS. Table slots remain empty (null) until they are + * needed. + * + * A single spinlock ("cellsBusy") is used for initializing and + * resizing the table, as well as populating slots with new Cells. + * There is no need for a blocking lock; when the lock is not + * available, threads try other slots (or the base). During these + * retries, there is increased contention and reduced locality, + * which is still better than alternatives. + * + * The Thread probe fields maintained via ThreadLocalRandom serve + * as per-thread hash codes. We let them remain uninitialized as + * zero (if they come in this way) until they contend at slot + * 0. They are then initialized to values that typically do not + * often conflict with others. Contention and/or table collisions + * are indicated by failed CASes when performing an update + * operation. Upon a collision, if the table size is less than + * the capacity, it is doubled in size unless some other thread + * holds the lock. If a hashed slot is empty, and lock is + * available, a new Cell is created. Otherwise, if the slot + * exists, a CAS is tried. Retries proceed by "double hashing", + * using a secondary hash (Marsaglia XorShift) to try to find a + * free slot. + * + * The table size is capped because, when there are more threads + * than CPUs, supposing that each thread were bound to a CPU, + * there would exist a perfect hash function mapping threads to + * slots that eliminates collisions. When we reach capacity, we + * search for this mapping by randomly varying the hash codes of + * colliding threads. Because search is random, and collisions + * only become known via CAS failures, convergence can be slow, + * and because threads are typically not bound to CPUS forever, + * may not occur at all. However, despite these limitations, + * observed contention rates are typically low in these cases. + * + * It is possible for a Cell to become unused when threads that + * once hashed to it terminate, as well as in the case where + * doubling the table causes no thread to hash to it under + * expanded mask. We do not try to detect or remove such cells, + * under the assumption that for long-running instances, observed + * contention levels will recur, so the cells will eventually be + * needed again; and for short-lived ones, it does not matter. + */ + + /** + * Padded variant of AtomicLong supporting only raw accesses plus CAS. + * + * JVM intrinsics note: It would be possible to use a release-only + * form of CAS here, if it were provided. + */ + @sun.misc.Contended static final class Cell { + volatile long value; + Cell(long x) { value = x; } + @ikvm.internal.InterlockedCompareAndSet("value") + final native boolean cas(long cmp, long val); + } + + /** Number of CPUS, to place bound on table size */ + static final int NCPU = Runtime.getRuntime().availableProcessors(); + + /** + * Table of cells. When non-null, size is a power of 2. + */ + transient volatile Cell[] cells; + + /** + * Base value, used mainly when there is no contention, but also as + * a fallback during table initialization races. Updated via CAS. + */ + transient volatile long base; + + /** + * Spinlock (locked via CAS) used when resizing and/or creating Cells. + */ + transient volatile int cellsBusy; + + /** + * Package-private default constructor + */ + Striped64() { + } + + /** + * CASes the base field. + */ + @ikvm.internal.InterlockedCompareAndSet("base") + final native boolean casBase(long cmp, long val); + + /** + * CASes the cellsBusy field from 0 to 1 to acquire lock. + */ + final boolean casCellsBusy() { + return casCellsBusy(0, 1); + } + + @ikvm.internal.InterlockedCompareAndSet("cellsBusy") + private native boolean casCellsBusy(int cmp, int newVal); + + /** + * Returns the probe value for the current thread. + * Duplicated from ThreadLocalRandom because of packaging restrictions. + */ + static final int getProbe() { + return Thread.currentThread().threadLocalRandomProbe; + } + + /** + * Pseudo-randomly advances and records the given probe value for the + * given thread. + * Duplicated from ThreadLocalRandom because of packaging restrictions. + */ + static final int advanceProbe(int probe) { + probe ^= probe << 13; // xorshift + probe ^= probe >>> 17; + probe ^= probe << 5; + Thread.currentThread().threadLocalRandomProbe = probe; + return probe; + } + + /** + * Handles cases of updates involving initialization, resizing, + * creating new Cells, and/or contention. See above for + * explanation. This method suffers the usual non-modularity + * problems of optimistic retry code, relying on rechecked sets of + * reads. + * + * @param x the value + * @param fn the update function, or null for add (this convention + * avoids the need for an extra field or function in LongAdder). + * @param wasUncontended false if CAS failed before call + */ + final void longAccumulate(long x, LongBinaryOperator fn, + boolean wasUncontended) { + int h; + if ((h = getProbe()) == 0) { + ThreadLocalRandom.current(); // force initialization + h = getProbe(); + wasUncontended = true; + } + boolean collide = false; // True if last slot nonempty + for (;;) { + Cell[] as; Cell a; int n; long v; + if ((as = cells) != null && (n = as.length) > 0) { + if ((a = as[(n - 1) & h]) == null) { + if (cellsBusy == 0) { // Try to attach new Cell + Cell r = new Cell(x); // Optimistically create + if (cellsBusy == 0 && casCellsBusy()) { + boolean created = false; + try { // Recheck under lock + Cell[] rs; int m, j; + if ((rs = cells) != null && + (m = rs.length) > 0 && + rs[j = (m - 1) & h] == null) { + rs[j] = r; + created = true; + } + } finally { + cellsBusy = 0; + } + if (created) + break; + continue; // Slot is now non-empty + } + } + collide = false; + } + else if (!wasUncontended) // CAS already known to fail + wasUncontended = true; // Continue after rehash + else if (a.cas(v = a.value, ((fn == null) ? v + x : + fn.applyAsLong(v, x)))) + break; + else if (n >= NCPU || cells != as) + collide = false; // At max size or stale + else if (!collide) + collide = true; + else if (cellsBusy == 0 && casCellsBusy()) { + try { + if (cells == as) { // Expand table unless stale + Cell[] rs = new Cell[n << 1]; + for (int i = 0; i < n; ++i) + rs[i] = as[i]; + cells = rs; + } + } finally { + cellsBusy = 0; + } + collide = false; + continue; // Retry with expanded table + } + h = advanceProbe(h); + } + else if (cellsBusy == 0 && cells == as && casCellsBusy()) { + boolean init = false; + try { // Initialize table + if (cells == as) { + Cell[] rs = new Cell[2]; + rs[h & 1] = new Cell(x); + cells = rs; + init = true; + } + } finally { + cellsBusy = 0; + } + if (init) + break; + } + else if (casBase(v = base, ((fn == null) ? v + x : + fn.applyAsLong(v, x)))) + break; // Fall back on using base + } + } + + /** + * Same as longAccumulate, but injecting long/double conversions + * in too many places to sensibly merge with long version, given + * the low-overhead requirements of this class. So must instead be + * maintained by copy/paste/adapt. + */ + final void doubleAccumulate(double x, DoubleBinaryOperator fn, + boolean wasUncontended) { + int h; + if ((h = getProbe()) == 0) { + ThreadLocalRandom.current(); // force initialization + h = getProbe(); + wasUncontended = true; + } + boolean collide = false; // True if last slot nonempty + for (;;) { + Cell[] as; Cell a; int n; long v; + if ((as = cells) != null && (n = as.length) > 0) { + if ((a = as[(n - 1) & h]) == null) { + if (cellsBusy == 0) { // Try to attach new Cell + Cell r = new Cell(Double.doubleToRawLongBits(x)); + if (cellsBusy == 0 && casCellsBusy()) { + boolean created = false; + try { // Recheck under lock + Cell[] rs; int m, j; + if ((rs = cells) != null && + (m = rs.length) > 0 && + rs[j = (m - 1) & h] == null) { + rs[j] = r; + created = true; + } + } finally { + cellsBusy = 0; + } + if (created) + break; + continue; // Slot is now non-empty + } + } + collide = false; + } + else if (!wasUncontended) // CAS already known to fail + wasUncontended = true; // Continue after rehash + else if (a.cas(v = a.value, + ((fn == null) ? + Double.doubleToRawLongBits + (Double.longBitsToDouble(v) + x) : + Double.doubleToRawLongBits + (fn.applyAsDouble + (Double.longBitsToDouble(v), x))))) + break; + else if (n >= NCPU || cells != as) + collide = false; // At max size or stale + else if (!collide) + collide = true; + else if (cellsBusy == 0 && casCellsBusy()) { + try { + if (cells == as) { // Expand table unless stale + Cell[] rs = new Cell[n << 1]; + for (int i = 0; i < n; ++i) + rs[i] = as[i]; + cells = rs; + } + } finally { + cellsBusy = 0; + } + collide = false; + continue; // Retry with expanded table + } + h = advanceProbe(h); + } + else if (cellsBusy == 0 && cells == as && casCellsBusy()) { + boolean init = false; + try { // Initialize table + if (cells == as) { + Cell[] rs = new Cell[2]; + rs[h & 1] = new Cell(Double.doubleToRawLongBits(x)); + cells = rs; + init = true; + } + } finally { + cellsBusy = 0; + } + if (init) + break; + } + else if (casBase(v = base, + ((fn == null) ? + Double.doubleToRawLongBits + (Double.longBitsToDouble(v) + x) : + Double.doubleToRawLongBits + (fn.applyAsDouble + (Double.longBitsToDouble(v), x))))) + break; // Fall back on using base + } + } + + +} diff --git a/external/ikvm/ikvmc.8.csproj b/external/ikvm/ikvmc.8.csproj index 71a657cd61..188dba9fe0 100644 --- a/external/ikvm/ikvmc.8.csproj +++ b/external/ikvm/ikvmc.8.csproj @@ -35,7 +35,7 @@ false - TRACE;DEBUG;STATIC_COMPILER;IKVM_REF_EMIT + TRACE;DEBUG;STATIC_COMPILER;EMITTERS true @@ -91,6 +91,7 @@ Code + Code @@ -119,10 +120,12 @@ Code + Code + Code diff --git a/external/ikvm/ikvmc/AotTypeWrapper.cs b/external/ikvm/ikvmc/AotTypeWrapper.cs index 60e519eb68..20a2f726f1 100644 --- a/external/ikvm/ikvmc/AotTypeWrapper.cs +++ b/external/ikvm/ikvmc/AotTypeWrapper.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2009 Jeroen Frijters + Copyright (C) 2002-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 @@ -48,14 +48,14 @@ namespace IKVM.Internal private WorkaroundBaseClass workaroundBaseClass; internal AotTypeWrapper(ClassFile f, CompilerClassLoader loader) - : base(f, loader, null) + : base(null, f, loader, null) { } protected override Type GetBaseTypeForDefineType() { TypeWrapper baseTypeWrapper = BaseTypeWrapper; - if (this.IsPublic && this.IsAbstract && baseTypeWrapper.IsPublic && baseTypeWrapper.IsAbstract) + if (this.IsPublic && this.IsAbstract && baseTypeWrapper.IsPublic && baseTypeWrapper.IsAbstract && classLoader.WorkaroundAbstractMethodWidening) { // FXBUG // if the current class widens access on an abstract base class method, @@ -78,7 +78,7 @@ namespace IKVM.Internal } if (methods != null) { - string name = "__WorkaroundBaseClass__." + Name; + string name = "__WorkaroundBaseClass__." + UnicodeUtil.EscapeInvalidSurrogates(Name); while (!classLoader.ReserveName(name)) { name = "_" + name; @@ -297,10 +297,7 @@ namespace IKVM.Internal } if(!found) { - FieldWrapper[] newFields = new FieldWrapper[fields.Length + 1]; - Array.Copy(fields, newFields, fields.Length); - fields = newFields; - fields[fields.Length - 1] = FieldWrapper.Create(this, null, null, field.Name, field.Sig, new ExModifiers((Modifiers)field.Modifiers, false)); + fields = ArrayUtil.Concat(fields, FieldWrapper.Create(this, null, null, field.Name, field.Sig, new ExModifiers((Modifiers)field.Modifiers, false))); } } } @@ -471,9 +468,7 @@ namespace IKVM.Internal if(setter != null) { MethodWrapper mw = setter; - Type[] args = new Type[indexer.Length + 1]; - indexer.CopyTo(args, 0); - args[args.Length - 1] = typeWrapper.TypeAsSignatureType; + Type[] args = ArrayUtil.Concat(indexer, typeWrapper.TypeAsSignatureType); if(!CheckPropertyArgs(args, mw.GetParametersForDefineMethod())) { Console.Error.WriteLine("Warning: ignoring invalid property setter for {0}::{1}", clazz.Name, prop.Name); @@ -512,36 +507,6 @@ namespace IKVM.Internal } } - protected override bool IsPInvokeMethod(ClassFile.Method m) - { - Dictionary mapxml = classLoader.GetMapXmlClasses(); - if(mapxml != null) - { - IKVM.Internal.MapXml.Class clazz; - if(mapxml.TryGetValue(this.Name, out clazz) && clazz.Methods != null) - { - foreach(IKVM.Internal.MapXml.Method method in clazz.Methods) - { - if(method.Name == m.Name && method.Sig == m.Signature) - { - if(method.Attributes != null) - { - foreach(IKVM.Internal.MapXml.Attribute attr in method.Attributes) - { - if(StaticCompiler.GetType(classLoader, attr.Type) == JVM.Import(typeof(System.Runtime.InteropServices.DllImportAttribute))) - { - return true; - } - } - } - break; - } - } - } - } - return base.IsPInvokeMethod(m); - } - private static void MapModifiers(MapXml.MapModifiers mapmods, bool isConstructor, out bool setmodifiers, ref MethodAttributes attribs) { setmodifiers = false; @@ -716,14 +681,14 @@ namespace IKVM.Internal // are we adding a new method? if(GetMethodWrapper(method.Name, method.Sig, false) == null) { - if(method.body == null) + bool setmodifiers = false; + MethodAttributes attribs = method.MethodAttributes; + MapModifiers(method.Modifiers, false, out setmodifiers, ref attribs); + 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); continue; } - bool setmodifiers = false; - MethodAttributes attribs = method.MethodAttributes; - MapModifiers(method.Modifiers, false, out setmodifiers, ref attribs); Type returnType; Type[] parameterTypes; MapSignature(method.Sig, out returnType, out parameterTypes); @@ -739,9 +704,12 @@ namespace IKVM.Internal typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); } CompilerClassLoader.AddDeclaredExceptions(mb, method.throws); - CodeEmitter ilgen = CodeEmitter.Create(mb); - method.Emit(classLoader, ilgen); - ilgen.DoEmit(); + if(method.body != null) + { + CodeEmitter ilgen = CodeEmitter.Create(mb); + method.Emit(classLoader, ilgen); + ilgen.DoEmit(); + } if(method.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute attr in method.Attributes) @@ -804,11 +772,14 @@ namespace IKVM.Internal } } - protected override MethodBuilder DefineGhostMethod(string name, MethodAttributes attribs, MethodWrapper mw) + protected override MethodBuilder DefineGhostMethod(TypeBuilder typeBuilder, string name, MethodAttributes attribs, MethodWrapper mw) { - if(typeBuilderGhostInterface != null) + if(typeBuilderGhostInterface != null && mw.IsVirtual) { - return mw.GetDefineMethodHelper().DefineMethod(this, typeBuilderGhostInterface, name, attribs); + DefineMethodHelper helper = mw.GetDefineMethodHelper(); + MethodBuilder stub = helper.DefineMethod(this, typeBuilder, name, MethodAttributes.Public); + ((GhostMethodWrapper)mw).SetGhostMethod(stub); + return helper.DefineMethod(this, typeBuilderGhostInterface, name, attribs); } return null; } @@ -820,11 +791,12 @@ namespace IKVM.Internal // TODO consider adding methods from base interface and java.lang.Object as well for(int i = 0; i < methods.Length; i++) { - // skip - if(!methods[i].IsStatic) + // skip and non-virtual interface methods introduced in Java 8 + GhostMethodWrapper gmw = methods[i] as GhostMethodWrapper; + if(gmw != null) { TypeWrapper[] args = methods[i].GetParameters(); - MethodBuilder stub = methods[i].GetDefineMethodHelper().DefineMethod(this, typeBuilder, methods[i].Name, MethodAttributes.Public); + MethodBuilder stub = gmw.GetGhostMethod(); AddParameterMetadata(stub, methods[i]); AttributeHelper.SetModifiers(stub, methods[i].Modifiers, methods[i].IsInternal); CodeEmitter ilgen = CodeEmitter.Create(stub); @@ -850,13 +822,32 @@ namespace IKVM.Internal ilgen.Emit(OpCodes.Isinst, implementers[j].TypeAsTBD); label = ilgen.DefineLabel(); ilgen.EmitBrfalse(label); - ilgen.Emit(OpCodes.Castclass, implementers[j].TypeAsTBD); - for(int k = 0; k < args.Length; k++) - { - ilgen.EmitLdarg(k + 1); - } MethodWrapper mw = implementers[j].GetMethodWrapper(methods[i].Name, methods[i].Signature, true); - mw.EmitCallvirt(ilgen); + if(mw == null) + { + if(methods[i].IsAbstract) + { + // This should only happen for remapped types (defined in map.xml), because normally you'd get a miranda method. + throw new FatalCompilerErrorException(Message.GhostInterfaceMethodMissing, implementers[j].Name, Name, methods[i].Name, methods[i].Signature); + } + // We're inheriting a default method + ilgen.Emit(OpCodes.Pop); + ilgen.Emit(OpCodes.Ldarg_0); + for (int k = 0; k < args.Length; k++) + { + ilgen.EmitLdarg(k + 1); + } + ilgen.Emit(OpCodes.Call, DefaultInterfaceMethodWrapper.GetImpl(methods[i])); + } + else + { + ilgen.Emit(OpCodes.Castclass, implementers[j].TypeAsTBD); + for (int k = 0; k < args.Length; k++) + { + ilgen.EmitLdarg(k + 1); + } + mw.EmitCallvirt(ilgen); + } ilgen.EmitBr(end); ilgen.MarkLabel(label); } diff --git a/external/ikvm/ikvmc/Compiler.cs b/external/ikvm/ikvmc/Compiler.cs index f824b029d1..bf37e60046 100644 --- a/external/ikvm/ikvmc/Compiler.cs +++ b/external/ikvm/ikvmc/Compiler.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2013 Jeroen Frijters + Copyright (C) 2002-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 @@ -156,6 +156,13 @@ sealed class FatalCompilerErrorException : Exception return "The type '{0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{1}'"; case IKVM.Internal.Message.FileNotFound: return "File not found: {0}"; + case IKVM.Internal.Message.RuntimeMethodMissing: + return "Runtime method '{0}' not found"; + case IKVM.Internal.Message.MapFileFieldNotFound: + return "Field '{0}' referenced in remap file was not found in class '{1}'"; + case IKVM.Internal.Message.GhostInterfaceMethodMissing: + return "Remapped class '{0}' does not implement ghost interface method\n" + + "\t({1}.{2}{3})"; default: return "Missing Error Message. Please file a bug."; } @@ -167,7 +174,6 @@ sealed class IkvmcCompiler private bool nonleaf; private string manifestMainClass; private string defaultAssemblyName; - private List classesToExclude = new List(); private static bool time; private static string runtimeAssembly; private static bool nostdlib; @@ -515,6 +521,8 @@ sealed class IkvmcCompiler Console.Error.WriteLine("-lib: Additional directories to search for references"); Console.Error.WriteLine("-highentropyva Enable high entropy ASLR"); Console.Error.WriteLine("-static Disable dynamic binding"); + Console.Error.WriteLine("-assemblyattributes: Read assembly custom attributes from specified"); + Console.Error.WriteLine(" class file."); } void ParseCommandLine(IEnumerator arglist, List targets, CompilerOptions options) @@ -543,7 +551,6 @@ sealed class IkvmcCompiler IkvmcCompiler nestedLevel = new IkvmcCompiler(); nestedLevel.manifestMainClass = manifestMainClass; nestedLevel.defaultAssemblyName = defaultAssemblyName; - nestedLevel.classesToExclude = new List(classesToExclude); nestedLevel.ContinueParseCommandLine(arglist, targets, options.Copy()); } else if(s == "}") @@ -775,7 +782,7 @@ sealed class IkvmcCompiler } else if(s.StartsWith("-exclude:")) { - ProcessExclusionFile(classesToExclude, s.Substring(9)); + ProcessExclusionFile(ref options.classesToExclude, s.Substring(9)); } else if(s.StartsWith("-version:")) { @@ -977,12 +984,25 @@ sealed class IkvmcCompiler } else if(s == "-static") { - options.codegenoptions |= CodeGenOptions.DisableDynamicBinding; + // we abuse -static to also enable support for NoRefEmit scenarios + options.codegenoptions |= CodeGenOptions.DisableDynamicBinding | CodeGenOptions.NoRefEmitHelpers; } else if(s == "-nojarstubs") // undocumented temporary option to mitigate risk { options.nojarstubs = true; } + else if(s.StartsWith("-assemblyattributes:", StringComparison.Ordinal)) + { + ProcessAttributeAnnotationsClass(ref options.assemblyAttributeAnnotations, s.Substring(20)); + } + else if(s == "-w4") // undocumented option to always warn if a class isn't found + { + options.warningLevelHigh = true; + } + else if(s == "-noparameterreflection") // undocumented option to compile core class libraries with, to disable MethodParameter attribute + { + options.noParameterReflection = true; + } else { throw new FatalCompilerErrorException(Message.UnrecognizedOption, s); @@ -1032,7 +1052,6 @@ sealed class IkvmcCompiler StaticCompiler.IssueMessage(options, Message.MainMethodFromManifest, manifestMainClass); options.mainClass = manifestMainClass; } - options.classesToExclude = classesToExclude.ToArray(); targets.Add(options); } @@ -1180,7 +1199,7 @@ sealed class IkvmcCompiler { foreach (CompilerOptions peer in targets) { - if (peer.assembly.Equals(reference, StringComparison.InvariantCultureIgnoreCase)) + if (peer.assembly.Equals(reference, StringComparison.OrdinalIgnoreCase)) { ArrayAppend(ref target.peerReferences, peer.assembly); goto next_reference; @@ -1238,10 +1257,22 @@ sealed class IkvmcCompiler } else { - T[] temp = new T[array.Length + 1]; - Array.Copy(array, 0, temp, 0, array.Length); - temp[temp.Length - 1] = element; - array = temp; + array = ArrayUtil.Concat(array, element); + } + } + + private static void ArrayAppend(ref T[] array, T[] append) + { + if (array == null) + { + array = append; + } + else if (append != null) + { + T[] tmp = new T[array.Length + append.Length]; + Array.Copy(array, tmp, array.Length); + Array.Copy(append, 0, tmp, array.Length, append.Length); + array = tmp; } } @@ -1262,7 +1293,7 @@ sealed class IkvmcCompiler ClassFile cf; try { - cf = new ClassFile(buf, 0, buf.Length, "", ClassFileParseOptions.None); + cf = new ClassFile(buf, 0, buf.Length, "", ClassFileParseOptions.None, null); } catch (ClassFormatError) { @@ -1290,7 +1321,7 @@ sealed class IkvmcCompiler return true; } - private static bool IsStubLegacy(CompilerOptions options, ZipEntry ze, byte[] data) + private static bool IsExcludedOrStubLegacy(CompilerOptions options, ZipEntry ze, byte[] data) { if (ze.Name.EndsWith(".class", StringComparison.OrdinalIgnoreCase)) { @@ -1298,7 +1329,7 @@ sealed class IkvmcCompiler { bool stub; string name = ClassFile.GetClassName(data, 0, data.Length, out stub); - if (stub && EmitStubWarning(options, data)) + if (options.IsExcludedClass(name) || (stub && EmitStubWarning(options, data))) { // we use stubs to add references, but otherwise ignore them return true; @@ -1356,7 +1387,7 @@ sealed class IkvmcCompiler { found = true; byte[] data = ReadFromZip(zf, ze); - if (IsStubLegacy(options, ze, data)) + if (IsExcludedOrStubLegacy(options, ze, data)) { continue; } @@ -1405,6 +1436,10 @@ sealed class IkvmcCompiler { bool stub; string name = ClassFile.GetClassName(data, 0, data.Length, out stub); + if (options.IsExcludedClass(name)) + { + return; + } if (stub && EmitStubWarning(options, data)) { // we use stubs to add references, but otherwise ignore them @@ -1474,10 +1509,11 @@ sealed class IkvmcCompiler } //This processes an exclusion file with a single regular expression per line - private static void ProcessExclusionFile(List classesToExclude, String filename) + private static void ProcessExclusionFile(ref string[] classesToExclude, string filename) { try { + List list = classesToExclude == null ? new List() : new List(classesToExclude); using(StreamReader file = new StreamReader(filename)) { String line; @@ -1486,14 +1522,29 @@ sealed class IkvmcCompiler line = line.Trim(); if(!line.StartsWith("//") && line.Length != 0) { - classesToExclude.Add(line); + list.Add(line); } } } + classesToExclude = list.ToArray(); } catch(Exception x) { throw new FatalCompilerErrorException(Message.ErrorReadingFile, filename, x.Message); } } + + private static void ProcessAttributeAnnotationsClass(ref object[] annotations, string filename) + { + try + { + byte[] buf = File.ReadAllBytes(filename); + ClassFile cf = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None, null); + ArrayAppend(ref annotations, cf.Annotations); + } + catch (Exception x) + { + throw new FatalCompilerErrorException(Message.ErrorReadingFile, filename, x.Message); + } + } } diff --git a/external/ikvm/ikvmc/CompilerClassLoader.cs.REMOVED.git-id b/external/ikvm/ikvmc/CompilerClassLoader.cs.REMOVED.git-id index 52ef2043ca..479732fb1a 100644 --- a/external/ikvm/ikvmc/CompilerClassLoader.cs.REMOVED.git-id +++ b/external/ikvm/ikvmc/CompilerClassLoader.cs.REMOVED.git-id @@ -1 +1 @@ -e7247c17ca6a6a7139699d9fdb9ddf15796f40b4 \ No newline at end of file +b71e0f94bba2f37126b0c66cbd774ef9d76cd588 \ No newline at end of file diff --git a/external/ikvm/ikvmc/Proxy.cs b/external/ikvm/ikvmc/Proxy.cs index 14f87273e9..4bd2a4fb6f 100644 --- a/external/ikvm/ikvmc/Proxy.cs +++ b/external/ikvm/ikvmc/Proxy.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Jeroen Frijters + Copyright (C) 2011-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 @@ -23,6 +23,7 @@ */ using System; using System.Collections.Generic; +using IKVM.Attributes; using IKVM.Reflection; using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; @@ -143,6 +144,7 @@ namespace IKVM.Internal // Check for duplicates if (!MethodExists(methods, mw)) { + mw.Link(); methods.Add(mw); } } @@ -220,9 +222,20 @@ namespace IKVM.Internal private static void CreateNoFail(CompilerClassLoader loader, TypeWrapper[] interfaces, List methods) { + bool ispublic = true; + Type[] interfaceTypes = new Type[interfaces.Length]; + for (int i = 0; i < interfaceTypes.Length; i++) + { + ispublic &= interfaces[i].IsPublic; + interfaceTypes[i] = interfaces[i].TypeAsBaseType; + } + TypeAttributes attr = TypeAttributes.Class | TypeAttributes.Sealed; + attr |= ispublic ? TypeAttributes.NestedPublic : TypeAttributes.NestedAssembly; DynamicClassLoader factory = (DynamicClassLoader)loader.GetTypeWrapperFactory(); - TypeBuilder tb = factory.DefineProxy(proxyClass, interfaces); + TypeBuilder tb = factory.DefineProxy(TypeNameUtil.GetProxyNestedName(interfaces), attr, proxyClass.TypeAsBaseType, interfaceTypes); AttributeHelper.SetImplementsAttribute(tb, interfaces); + // we apply an InnerClass attribute to avoid the CompiledTypeWrapper heuristics for figuring out the modifiers + AttributeHelper.SetInnerClass(tb, null, ispublic ? Modifiers.Public | Modifiers.Final : Modifiers.Final); CreateConstructor(tb); for (int i = 0; i < methods.Count; i++) { @@ -232,7 +245,7 @@ namespace IKVM.Internal { CreateMethod(loader, tb, method); } - CreateStaticInitializer(tb, methods); + CreateStaticInitializer(tb, methods, loader); } private static void CreateConstructor(TypeBuilder tb) @@ -297,7 +310,7 @@ namespace IKVM.Internal } else if (returnType.IsPrimitive) { - Boxer.EmitUnbox(ilgen, returnType); + Boxer.EmitUnbox(ilgen, returnType, true); } else if (returnType != CoreClasses.java.lang.Object.Wrapper) { @@ -341,9 +354,9 @@ namespace IKVM.Internal ilgen.DoEmit(); } - private static void CreateStaticInitializer(TypeBuilder tb, List methods) + private static void CreateStaticInitializer(TypeBuilder tb, List methods, CompilerClassLoader loader) { - CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineTypeInitializer(tb)); + CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineTypeInitializer(tb, loader)); CodeEmitterLocal callerID = ilgen.DeclareLocal(CoreClasses.ikvm.@internal.CallerID.Wrapper.TypeAsSignatureType); TypeBuilder tbCallerID = DynamicTypeWrapper.FinishContext.EmitCreateCallerID(tb, ilgen); ilgen.Emit(OpCodes.Stloc, callerID); @@ -401,7 +414,10 @@ namespace IKVM.Internal Dictionary methods = new Dictionary(); foreach (MethodWrapper mw in tw.GetMethods()) { - methods.Add(mw.Name + mw.Signature, mw); + if (mw.IsVirtual) + { + methods.Add(mw.Name + mw.Signature, mw); + } } foreach (TypeWrapper iface in tw.Interfaces) { @@ -438,165 +454,4 @@ namespace IKVM.Internal } } } - - static class Boxer - { - private static readonly TypeWrapper javaLangByte; - private static readonly MethodWrapper byteValue; - private static readonly MethodWrapper valueOfByte; - private static readonly TypeWrapper javaLangBoolean; - private static readonly MethodWrapper booleanValue; - private static readonly MethodWrapper valueOfBoolean; - private static readonly TypeWrapper javaLangShort; - private static readonly MethodWrapper shortValue; - private static readonly MethodWrapper valueOfShort; - private static readonly TypeWrapper javaLangCharacter; - private static readonly MethodWrapper charValue; - private static readonly MethodWrapper valueOfCharacter; - private static readonly TypeWrapper javaLangInteger; - private static readonly MethodWrapper intValue; - private static readonly MethodWrapper valueOfInteger; - private static readonly TypeWrapper javaLangFloat; - private static readonly MethodWrapper floatValue; - private static readonly MethodWrapper valueOfFloat; - private static readonly TypeWrapper javaLangLong; - private static readonly MethodWrapper longValue; - private static readonly MethodWrapper valueOfLong; - private static readonly TypeWrapper javaLangDouble; - private static readonly MethodWrapper doubleValue; - private static readonly MethodWrapper valueOfDouble; - - static Boxer() - { - ClassLoaderWrapper bootClassLoader = ClassLoaderWrapper.GetBootstrapClassLoader(); - javaLangByte = bootClassLoader.LoadClassByDottedNameFast("java.lang.Byte"); - byteValue = javaLangByte.GetMethodWrapper("byteValue", "()B", false); - byteValue.Link(); - valueOfByte = javaLangByte.GetMethodWrapper("valueOf", "(B)Ljava.lang.Byte;", false); - valueOfByte.Link(); - javaLangBoolean = bootClassLoader.LoadClassByDottedNameFast("java.lang.Boolean"); - booleanValue = javaLangBoolean.GetMethodWrapper("booleanValue", "()Z", false); - booleanValue.Link(); - valueOfBoolean = javaLangBoolean.GetMethodWrapper("valueOf", "(Z)Ljava.lang.Boolean;", false); - valueOfBoolean.Link(); - javaLangShort = bootClassLoader.LoadClassByDottedNameFast("java.lang.Short"); - shortValue = javaLangShort.GetMethodWrapper("shortValue", "()S", false); - shortValue.Link(); - valueOfShort = javaLangShort.GetMethodWrapper("valueOf", "(S)Ljava.lang.Short;", false); - valueOfShort.Link(); - javaLangCharacter = bootClassLoader.LoadClassByDottedNameFast("java.lang.Character"); - charValue = javaLangCharacter.GetMethodWrapper("charValue", "()C", false); - charValue.Link(); - valueOfCharacter = javaLangCharacter.GetMethodWrapper("valueOf", "(C)Ljava.lang.Character;", false); - valueOfCharacter.Link(); - javaLangInteger = bootClassLoader.LoadClassByDottedNameFast("java.lang.Integer"); - intValue = javaLangInteger.GetMethodWrapper("intValue", "()I", false); - intValue.Link(); - valueOfInteger = javaLangInteger.GetMethodWrapper("valueOf", "(I)Ljava.lang.Integer;", false); - valueOfInteger.Link(); - javaLangFloat = bootClassLoader.LoadClassByDottedNameFast("java.lang.Float"); - floatValue = javaLangFloat.GetMethodWrapper("floatValue", "()F", false); - floatValue.Link(); - valueOfFloat = javaLangFloat.GetMethodWrapper("valueOf", "(F)Ljava.lang.Float;", false); - valueOfFloat.Link(); - javaLangLong = bootClassLoader.LoadClassByDottedNameFast("java.lang.Long"); - longValue = javaLangLong.GetMethodWrapper("longValue", "()J", false); - longValue.Link(); - valueOfLong = javaLangLong.GetMethodWrapper("valueOf", "(J)Ljava.lang.Long;", false); - valueOfLong.Link(); - javaLangDouble = bootClassLoader.LoadClassByDottedNameFast("java.lang.Double"); - doubleValue = javaLangDouble.GetMethodWrapper("doubleValue", "()D", false); - doubleValue.Link(); - valueOfDouble = javaLangDouble.GetMethodWrapper("valueOf", "(D)Ljava.lang.Double;", false); - valueOfDouble.Link(); - } - - internal static void EmitUnbox(CodeEmitter ilgen, TypeWrapper tw) - { - if (tw == PrimitiveTypeWrapper.BYTE) - { - javaLangByte.EmitCheckcast(ilgen); - byteValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.BOOLEAN) - { - javaLangBoolean.EmitCheckcast(ilgen); - booleanValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.SHORT) - { - javaLangShort.EmitCheckcast(ilgen); - shortValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.CHAR) - { - javaLangCharacter.EmitCheckcast(ilgen); - charValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.INT) - { - javaLangInteger.EmitCheckcast(ilgen); - intValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.FLOAT) - { - javaLangFloat.EmitCheckcast(ilgen); - floatValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.LONG) - { - javaLangLong.EmitCheckcast(ilgen); - longValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.DOUBLE) - { - javaLangDouble.EmitCheckcast(ilgen); - doubleValue.EmitCall(ilgen); - } - else - { - throw new InvalidOperationException(); - } - } - - internal static void EmitBox(CodeEmitter ilgen, TypeWrapper tw) - { - if (tw == PrimitiveTypeWrapper.BYTE) - { - valueOfByte.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.BOOLEAN) - { - valueOfBoolean.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.SHORT) - { - valueOfShort.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.CHAR) - { - valueOfCharacter.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.INT) - { - valueOfInteger.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.FLOAT) - { - valueOfFloat.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.LONG) - { - valueOfLong.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.DOUBLE) - { - valueOfDouble.EmitCall(ilgen); - } - else - { - throw new InvalidOperationException(); - } - } - } } diff --git a/external/ikvm/ikvmc/ikvmc.build b/external/ikvm/ikvmc/ikvmc.build index af5dcb9cb9..06dda99f52 100644 --- a/external/ikvm/ikvmc/ikvmc.build +++ b/external/ikvm/ikvmc/ikvmc.build @@ -1,9 +1,32 @@ + - + @@ -25,6 +48,7 @@ + @@ -37,8 +61,10 @@ + + diff --git a/external/ikvm/openjdk/FORKED b/external/ikvm/openjdk/FORKED index 64e8faf23a..5260658227 100644 --- a/external/ikvm/openjdk/FORKED +++ b/external/ikvm/openjdk/FORKED @@ -30,18 +30,7 @@ jdk/src/share/classes/java/io/RandomAccessFile.java=java/io/RandomAccessFile.jav 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/AdapterMethodHandle.java=java/lang/invoke/AdapterMethodHandle.java -jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java=java/lang/invoke/BoundMethodHandle.java -jdk/src/share/classes/java/lang/invoke/CallSite.java=java/lang/invoke/CallSite.java -jdk/src/share/classes/java/lang/invoke/ConstantCallSite.java=java/lang/invoke/ConstantCallSite.java -jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java=java/lang/invoke/DirectMethodHandle.java -jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java=java/lang/invoke/MethodHandleImpl.java -jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java=java/lang/invoke/MethodHandleNatives.java -jdk/src/share/classes/java/lang/invoke/MethodHandles.java=java/lang/invoke/MethodHandles.java -jdk/src/share/classes/java/lang/invoke/MutableCallSite.java=java/lang/invoke/MutableCallSite.java -jdk/src/share/classes/java/lang/invoke/VolatileCallSite.java=java/lang/invoke/VolatileCallSite.java jdk/src/share/classes/java/lang/management/PlatformComponent.java=java/lang/management/PlatformComponent.java -jdk/src/share/classes/java/lang/Package.java=java/lang/Package.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/Field.java=java/lang/reflect/Field.java @@ -57,7 +46,6 @@ jdk/src/share/classes/java/net/SocketOutputStream.java=java/net/SocketOutputStre 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 -jdk/src/share/classes/java/sql/DriverManager.java=java/sql/DriverManager.java jdk/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java=../classpath/java/util/concurrent/atomic/AtomicBoolean.java jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java=../classpath/java/util/concurrent/atomic/AtomicInteger.java jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java=../classpath/java/util/concurrent/atomic/AtomicIntegerArray.java @@ -67,9 +55,6 @@ jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java=../classp jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java=../classpath/java/util/concurrent/atomic/AtomicReferenceArray.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/java/util/ResourceBundle.java=java/util/ResourceBundle.java -jdk/src/share/classes/java/util/TimeZone.java=java/util/TimeZone.java -jdk/src/share/classes/sun/awt/AppContext.java=sun/awt/AppContext.java jdk/src/share/classes/sun/awt/EmbeddedFrame.java=sun/awt/EmbeddedFrame.java jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java=sun/awt/image/ByteInterleavedRaster.java jdk/src/share/classes/sun/awt/image/ImagingLib.java=sun/awt/image/ImagingLib.java @@ -79,11 +64,8 @@ jdk/src/share/classes/sun/awt/image/ToolkitImage.java=sun/awt/image/ToolkitImage 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/GcInfoBuilder.java=sun/management/GcInfoBuilder.java jdk/src/share/classes/sun/management/ManagementFactoryHelper.java=sun/management/ManagementFactoryHelper.java jdk/src/share/classes/sun/management/VMManagementImpl.java=sun/management/VMManagementImpl.java -jdk/src/share/classes/sun/misc/IoTrace.java=sun/misc/IoTrace.java -jdk/src/share/classes/sun/misc/JavaAWTAccess.java=sun/misc/JavaAWTAccess.java jdk/src/share/classes/sun/misc/SharedSecrets.java=sun/misc/SharedSecrets.java jdk/src/share/classes/sun/misc/VM.java=sun/misc/VM.java jdk/src/share/classes/sun/net/sdp/SdpSupport.java=sun/net/sdp/SdpSupport.java @@ -94,9 +76,8 @@ jdk/src/share/classes/sun/nio/ch/IOUtil.java=sun/nio/ch/IOUtil.java jdk/src/share/classes/sun/nio/ch/NativeDispatcher.java=sun/nio/ch/NativeDispatcher.java jdk/src/share/classes/sun/nio/ch/Net.java=sun/nio/ch/Net.java jdk/src/share/classes/sun/nio/ch/Util.java=sun/nio/ch/Util.java -jdk/src/share/classes/sun/reflect/CallerSensitive.java=sun/reflect/CallerSensitive.java +jdk/src/share/classes/sun/reflect/annotation/AnnotationType.java=sun/reflect/annotation/AnnotationType.java jdk/src/share/classes/sun/reflect/MethodAccessor.java=sun/reflect/MethodAccessor.java -jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java=sun/reflect/misc/ReflectUtil.java jdk/src/share/classes/sun/reflect/Reflection.java=sun/reflect/Reflection.java jdk/src/share/classes/sun/reflect/ReflectionFactory.java=sun/reflect/ReflectionFactory.java jdk/src/solaris/classes/sun/nio/fs/UnixUriUtils.java=sun/nio/fs/UnixUriUtils.java diff --git a/external/ikvm/openjdk/allsources.lst.REMOVED.git-id b/external/ikvm/openjdk/allsources.lst.REMOVED.git-id index 2083ba76e0..11b74df61c 100644 --- a/external/ikvm/openjdk/allsources.lst.REMOVED.git-id +++ b/external/ikvm/openjdk/allsources.lst.REMOVED.git-id @@ -1 +1 @@ -533d7645e2bb496cbbac8996759c133993dcc1bb \ No newline at end of file +4911d54d998b7a044246f97683fb62901e9dc052 \ No newline at end of file diff --git a/external/ikvm/openjdk/ikvm/internal/AnnotationAttributeBase.java b/external/ikvm/openjdk/ikvm/internal/AnnotationAttributeBase.java index f2359e5498..6b77d2f356 100644 --- a/external/ikvm/openjdk/ikvm/internal/AnnotationAttributeBase.java +++ b/external/ikvm/openjdk/ikvm/internal/AnnotationAttributeBase.java @@ -236,12 +236,14 @@ public abstract class AnnotationAttributeBase { // TODO consider checking that the type matches // (or better yet (?), remove the first two redundant elements from the array) - decodeValues(values, annotationType, annotationType.getClassLoader(), definition); + decodeValues(values, annotationType, annotationType.getClassLoader(), unescapeInvalidSurrogates(definition)); definition = null; } } } + private static native Object[] unescapeInvalidSurrogates(Object[] definition); + private static void decodeValues(HashMap map, Class annotationClass, ClassLoader loader, Object[] array) { for (int i = 2; i < array.length; i += 2) diff --git a/external/ikvm/openjdk/java/lang/Class.java.REMOVED.git-id b/external/ikvm/openjdk/java/lang/Class.java.REMOVED.git-id index b69294ee34..dd598adddb 100644 --- a/external/ikvm/openjdk/java/lang/Class.java.REMOVED.git-id +++ b/external/ikvm/openjdk/java/lang/Class.java.REMOVED.git-id @@ -1 +1 @@ -bbc1d241f632078e8ecf146e9398406c5719dd2f \ No newline at end of file +07fd7bd567e5b0ae8b3ae9c32741b56f6f363b0a \ No newline at end of file diff --git a/external/ikvm/openjdk/java/lang/LangHelper.java b/external/ikvm/openjdk/java/lang/LangHelper.java index cc62d2cbd6..8d725d4374 100644 --- a/external/ikvm/openjdk/java/lang/LangHelper.java +++ b/external/ikvm/openjdk/java/lang/LangHelper.java @@ -1,5 +1,5 @@ /* - Copyright (C) 2007-2011 Jeroen Frijters + Copyright (C) 2007-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 @@ -24,80 +24,40 @@ package java.lang; -import ikvm.runtime.AssemblyClassLoader; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.security.AccessController; -import java.util.Enumeration; +import java.lang.annotation.Annotation; +import java.lang.reflect.Executable; +import java.security.AccessControlContext; import java.util.Map; import sun.nio.ch.Interruptible; import sun.reflect.annotation.AnnotationType; -import sun.security.action.GetPropertyAction; @ikvm.lang.Internal public class LangHelper { - private static boolean addedSystemPackages; - - private static void addSystemPackage(Map pkgMap) - { - // NOTE caller must have acquired lock on pkgMap - if (!addedSystemPackages) - { - addedSystemPackages = true; - String[] pkgs = getBootClassPackages(); - for (int i = 0; i < pkgs.length; i++) - { - pkgMap.put(pkgs[i], - new Package(pkgs[i], - VMSystemProperties.SPEC_TITLE, // specTitle - VMSystemProperties.SPEC_VERSION, // specVersion - VMSystemProperties.SPEC_VENDOR, // specVendor - "IKVM.NET OpenJDK", // implTitle - PropertyConstants.openjdk_version, // implVersion - "Oracle Corporation & others", // implVendor - null, // sealBase - null)); // class loader - } - } - } - - private static native String[] getBootClassPackages(); - - /* this method gets called by Package.getSystemPackage() via a redefined method in map.xml */ - static Package getSystemPackage(Map pkgs, String name) - { - synchronized (pkgs) - { - addSystemPackage(pkgs); - return (Package)pkgs.get(name); - } - } - - /* this method gets called by Package.getSystemPackages() via a redefined method in map.xml */ - static Package[] getSystemPackages(Map pkgs) - { - synchronized (pkgs) - { - addSystemPackage(pkgs); - return (Package[])pkgs.values().toArray(new Package[pkgs.size()]); - - } - } - public static sun.misc.JavaLangAccess getJavaLangAccess() { return new sun.misc.JavaLangAccess() { public sun.reflect.ConstantPool getConstantPool(Class klass) { - return null; + return klass.getConstantPool(); } - public void setAnnotationType(Class klass, AnnotationType type) { - klass.setAnnotationType(type); + public boolean casAnnotationType(Class klass, AnnotationType oldType, AnnotationType newType) { + return klass.casAnnotationType(oldType, newType); } public AnnotationType getAnnotationType(Class klass) { return klass.getAnnotationType(); } + public Map, Annotation> getDeclaredAnnotationMap(Class klass) { + return klass.getDeclaredAnnotationMap(); + } + public byte[] getRawClassAnnotations(Class klass) { + throw new InternalError(); + } + public byte[] getRawClassTypeAnnotations(Class klass) { + return klass.getRawTypeAnnotations(); + } + public byte[] getRawExecutableTypeAnnotations(Executable executable) { + return Class.getExecutableTypeAnnotationBytes(executable); + } public > E[] getEnumConstantsShared(Class klass) { return klass.getEnumConstantsShared(); @@ -114,8 +74,14 @@ public class LangHelper public StackTraceElement getStackTraceElement(Throwable t, int i) { return t.getStackTraceElement(i); } - public int getStringHash32(String string) { - return StringHelper.hash32(string); + public String newStringUnsafe(char[] chars) { + return String.valueOf(chars); + } + public Thread newThreadWithAcc(Runnable target, AccessControlContext acc) { + return new Thread(target, acc); + } + public void invokeFinalize(Object o) throws Throwable { + // we don't actually support invoking the finalize method explicitly } }; } diff --git a/external/ikvm/openjdk/java/lang/ProcessImpl.java b/external/ikvm/openjdk/java/lang/ProcessImpl.java index 9147b345ac..0624dc1784 100644 --- a/external/ikvm/openjdk/java/lang/ProcessImpl.java +++ b/external/ikvm/openjdk/java/lang/ProcessImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -42,9 +42,15 @@ import java.io.BufferedOutputStream; import java.lang.ProcessBuilder.Redirect; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import cli.System.AsyncCallback; import cli.System.IAsyncResult; import cli.System.Diagnostics.ProcessStartInfo; +import cli.System.EventArgs; +import cli.System.EventHandler; import cli.System.IO.FileAccess; import cli.System.IO.FileShare; import cli.System.IO.FileMode; @@ -146,8 +152,17 @@ final class ProcessImpl extends Process { return new ProcessImpl(cmdarray, environment, dir, stdHandles, redirectErrorStream); + } catch (Throwable t) { + if (f0 != null) + f0.close(); + if (f1 != null) + f1.close(); + if (f2 != null) + f2.close(); + throw t; } finally { // HACK prevent the File[In|Out]putStream objects from closing the streams + // (the System.IO.FileStream will eventually be closed explicitly or by its finalizer) if (f0 != null) cli.System.GC.SuppressFinalize(f0); if (f1 != null) @@ -158,50 +173,240 @@ final class ProcessImpl extends Process { } + private static class LazyPattern { + // Escape-support version: + // "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)"; + private static final Pattern PATTERN = + Pattern.compile("[^\\s\"]+|\"[^\"]*\""); + }; + + /* Parses the command string parameter into the executable name and + * program arguments. + * + * The command string is broken into tokens. The token separator is a space + * or quota character. The space inside quotation is not a token separator. + * There are no escape sequences. + */ + private static String[] getTokensFromCommand(String command) { + ArrayList matchList = new ArrayList<>(8); + Matcher regexMatcher = LazyPattern.PATTERN.matcher(command); + while (regexMatcher.find()) + matchList.add(regexMatcher.group()); + return matchList.toArray(new String[matchList.size()]); + } + + private static final int VERIFICATION_CMD_BAT = 0; + private static final int VERIFICATION_WIN32 = 1; + private static final int VERIFICATION_LEGACY = 2; + private static final char ESCAPE_VERIFICATION[][] = { + // We guarantee the only command file execution for implicit [cmd.exe] run. + // http://technet.microsoft.com/en-us/library/bb490954.aspx + {' ', '\t', '<', '>', '&', '|', '^'}, + + {' ', '\t', '<', '>'}, + {' ', '\t'} + }; + + private static String createCommandLine(int verificationType, + final String executablePath, + final String cmd[]) + { + StringBuilder cmdbuf = new StringBuilder(80); + + cmdbuf.append(executablePath); + + for (int i = 1; i < cmd.length; ++i) { + cmdbuf.append(' '); + String s = cmd[i]; + if (needsEscaping(verificationType, s)) { + cmdbuf.append('"').append(s); + + // The code protects the [java.exe] and console command line + // parser, that interprets the [\"] combination as an escape + // sequence for the ["] char. + // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + // + // If the argument is an FS path, doubling of the tail [\] + // char is not a problem for non-console applications. + // + // The [\"] sequence is not an escape sequence for the [cmd.exe] + // command line parser. The case of the [""] tail escape + // sequence could not be realized due to the argument validation + // procedure. + if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) { + cmdbuf.append('\\'); + } + cmdbuf.append('"'); + } else { + cmdbuf.append(s); + } + } + return cmdbuf.toString(); + } + + private static boolean isQuoted(boolean noQuotesInside, String arg, + String errorMessage) { + int lastPos = arg.length() - 1; + if (lastPos >=1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') { + // The argument has already been quoted. + if (noQuotesInside) { + if (arg.indexOf('"', 1) != lastPos) { + // There is ["] inside. + throw new IllegalArgumentException(errorMessage); + } + } + return true; + } + if (noQuotesInside) { + if (arg.indexOf('"') >= 0) { + // There is ["] inside. + throw new IllegalArgumentException(errorMessage); + } + } + return false; + } + + private static boolean needsEscaping(int verificationType, String arg) { + // Switch off MS heuristic for internal ["]. + // Please, use the explicit [cmd.exe] call + // if you need the internal ["]. + // Example: "cmd.exe", "/C", "Extended_MS_Syntax" + + // For [.exe] or [.com] file the unpaired/internal ["] + // in the argument is not a problem. + boolean argIsQuoted = isQuoted( + (verificationType == VERIFICATION_CMD_BAT), + arg, "Argument has embedded quote, use the explicit CMD.EXE call."); + + if (!argIsQuoted) { + char testEscape[] = ESCAPE_VERIFICATION[verificationType]; + for (int i = 0; i < testEscape.length; ++i) { + if (arg.indexOf(testEscape[i]) >= 0) { + return true; + } + } + } + return false; + } + + private static String getExecutablePath(String path) + throws IOException + { + boolean pathIsQuoted = isQuoted(true, path, + "Executable name has embedded quote, split the arguments"); + + // Win32 CreateProcess requires path to be normalized + File fileToRun = new File(pathIsQuoted + ? path.substring(1, path.length() - 1) + : path); + + // From the [CreateProcess] function documentation: + // + // "If the file name does not contain an extension, .exe is appended. + // Therefore, if the file name extension is .com, this parameter + // must include the .com extension. If the file name ends in + // a period (.) with no extension, or if the file name contains a path, + // .exe is not appended." + // + // "If the file name !does not contain a directory path!, + // the system searches for the executable file in the following + // sequence:..." + // + // In practice ANY non-existent path is extended by [.exe] extension + // in the [CreateProcess] funcion with the only exception: + // the path ends by (.) + + return fileToRun.getPath(); + } + + + private boolean isShellFile(String executablePath) { + String upPath = executablePath.toUpperCase(); + return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT")); + } + + private String quoteString(String arg) { + StringBuilder argbuf = new StringBuilder(arg.length() + 2); + return argbuf.append('"').append(arg).append('"').toString(); + } + + private cli.System.Diagnostics.Process handle; private OutputStream stdin_stream; private InputStream stdout_stream; private InputStream stderr_stream; - private ProcessImpl(final String cmd[], + private ProcessImpl(String cmd[], final java.util.Map envblock, final String path, final Stream[] stdHandles, final boolean redirectErrorStream) throws IOException { - // Win32 CreateProcess requires cmd[0] to be normalized - cmd[0] = new File(cmd[0]).getPath(); - - // give the runtime an opportunity to map executables from VFS to a real executable - cmd[0] = mapVfsExecutable(cmd[0]); - - StringBuilder cmdbuf = new StringBuilder(80); - for (int i = 0; i < cmd.length; i++) { - if (i > 0) { - cmdbuf.append(' '); - } - String s = cmd[i]; - if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) { - if (s.charAt(0) != '"') { - cmdbuf.append('"'); - cmdbuf.append(s); - if (s.endsWith("\\")) { - cmdbuf.append("\\"); - } - cmdbuf.append('"'); - } else if (s.endsWith("\"")) { - /* The argument has already been quoted. */ - cmdbuf.append(s); - } else { - /* Unmatched quote for the argument. */ - throw new IllegalArgumentException(); - } - } else { - cmdbuf.append(s); - } + String cmdstr; + SecurityManager security = System.getSecurityManager(); + boolean allowAmbiguousCommands = false; + if (security == null) { + allowAmbiguousCommands = true; + String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands"); + if (value != null) + allowAmbiguousCommands = !"false".equalsIgnoreCase(value); + } + if (allowAmbiguousCommands) { + // Legacy mode. + + // Normalize path if possible. + String executablePath = new File(cmd[0]).getPath(); + + // No worry about internal, unpaired ["], and redirection/piping. + if (needsEscaping(VERIFICATION_LEGACY, executablePath) ) + executablePath = quoteString(executablePath); + + cmdstr = createCommandLine( + //legacy mode doesn't worry about extended verification + VERIFICATION_LEGACY, + executablePath, + cmd); + } else { + String executablePath; + try { + executablePath = getExecutablePath(cmd[0]); + } catch (IllegalArgumentException e) { + // Workaround for the calls like + // Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar") + + // No chance to avoid CMD/BAT injection, except to do the work + // right from the beginning. Otherwise we have too many corner + // cases from + // Runtime.getRuntime().exec(String[] cmd [, ...]) + // calls with internal ["] and escape sequences. + + // Restore original command line. + StringBuilder join = new StringBuilder(); + // terminal space in command line is ok + for (String s : cmd) + join.append(s).append(' '); + + // Parse the command line again. + cmd = getTokensFromCommand(join.toString()); + executablePath = getExecutablePath(cmd[0]); + + // Check new executable name once more + if (security != null) + security.checkExec(executablePath); + } + + // Quotation protects from interpretation of the [path] argument as + // start of longer path with spaces. Quotation has no influence to + // [.exe] extension heuristic. + cmdstr = createCommandLine( + // We need the extended verification procedure for CMD files. + isShellFile(executablePath) + ? VERIFICATION_CMD_BAT + : VERIFICATION_WIN32, + quoteString(executablePath), + cmd); } - String cmdstr = cmdbuf.toString(); handle = create(cmdstr, envblock, path, stdHandles, redirectErrorStream); @@ -261,6 +466,7 @@ final class ProcessImpl extends Process { throw new InterruptedException(); return exitValue(); } + private static void waitForInterruptibly(cli.System.Diagnostics.Process handle) throws InterruptedException { // to be interruptable we have to use polling // (on .NET 2.0 WaitForExit is actually interruptible, but this isn't documented) @@ -269,7 +475,53 @@ final class ProcessImpl extends Process { ; } + @Override + public boolean waitFor(long timeout, TimeUnit unit) + throws InterruptedException + { + if (handle.get_HasExited()) return true; + if (timeout <= 0) return false; + + long msTimeout = unit.toMillis(timeout); + + waitForTimeoutInterruptibly(handle, msTimeout); + if (Thread.interrupted()) + throw new InterruptedException(); + return handle.get_HasExited(); + } + + private static void waitForTimeoutInterruptibly( + cli.System.Diagnostics.Process handle, long timeout) { + long now = System.currentTimeMillis(); + long exp = now + timeout; + if (exp < now) { + // if we overflowed, just wait for a really long time + exp = Long.MAX_VALUE; + } + Thread current = Thread.currentThread(); + for (;;) { + if (current.isInterrupted()) { + return; + } + // wait for a maximum of 100 ms to be interruptible + if (handle.WaitForExit((int)Math.min(100, exp - now))) { + return; + } + now = System.currentTimeMillis(); + if (now >= exp) { + return; + } + } + } + public void destroy() { terminateProcess(handle); } + + @Override + public Process destroyForcibly() { + destroy(); + return this; + } + private static void terminateProcess(cli.System.Diagnostics.Process handle) { try { if (false) throw new cli.System.ComponentModel.Win32Exception(); @@ -280,10 +532,21 @@ final class ProcessImpl extends Process { } } + @Override + public boolean isAlive() { + return isProcessAlive(handle); + } + + private static boolean isProcessAlive(cli.System.Diagnostics.Process handle) { + return !handle.get_HasExited(); + } + /** * Create a process using the win32 function CreateProcess. + * The method is synchronized due to MS kb315939 problem. + * All native handles should restore the inherit flag at the end of call. * - * @param cmdstr the Windows commandline + * @param cmdstr the Windows command line * @param envblock NUL-separated, double-NUL-terminated list of * environment strings in VAR=VALUE form * @param dir the working directory of the process, or null if @@ -312,7 +575,8 @@ final class ProcessImpl extends Process { argumentsStart++; } - ProcessStartInfo si = new ProcessStartInfo(cmdstr.substring(0, programEnd), cmdstr.substring(argumentsStart)); + String fileName = cmdstr.substring(0, programEnd); + ProcessStartInfo si = new ProcessStartInfo(mapVfsExecutable(fileName), cmdstr.substring(argumentsStart)); si.set_UseShellExecute(false); si.set_RedirectStandardError(true); si.set_RedirectStandardOutput(true); @@ -338,6 +602,27 @@ final class ProcessImpl extends Process { } catch (cli.System.InvalidOperationException x2) { throw new IOException(x2.getMessage()); } + + // if any of the handles is redirected to/from a file, + // we need to close the files as soon as the process exits + if (stdHandles[0] instanceof FileStream + || stdHandles[1] instanceof FileStream + || stdHandles[2] instanceof FileStream) { + final Stream s0 = stdHandles[0]; + final Stream s1 = stdHandles[1]; + final Stream s2 = stdHandles[2]; + proc.set_EnableRaisingEvents(true); + proc.add_Exited(new EventHandler(new EventHandler.Method() { + public void Invoke(Object sender, EventArgs e) { + if (s0 instanceof FileStream) + s0.Close(); + if (s1 instanceof FileStream) + s1.Close(); + if (s2 instanceof FileStream) + s2.Close(); + } + })); + } Stream stdin = proc.get_StandardInput().get_BaseStream(); Stream stdout = proc.get_StandardOutput().get_BaseStream(); diff --git a/external/ikvm/openjdk/java/lang/Thread.java b/external/ikvm/openjdk/java/lang/Thread.java deleted file mode 100644 index e8f57d065a..0000000000 --- a/external/ikvm/openjdk/java/lang/Thread.java +++ /dev/null @@ -1,2578 +0,0 @@ -/* - * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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; - -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.security.AccessController; -import java.security.AccessControlContext; -import java.security.PrivilegedAction; -import java.util.Map; -import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.locks.LockSupport; -import sun.nio.ch.Interruptible; -import sun.reflect.CallerSensitive; -import sun.reflect.Reflection; -import sun.security.util.SecurityConstants; - - -/** - * A thread is a thread of execution in a program. The Java - * Virtual Machine allows an application to have multiple threads of - * execution running concurrently. - *

- * Every thread has a priority. Threads with higher priority are - * executed in preference to threads with lower priority. Each thread - * may or may not also be marked as a daemon. When code running in - * some thread creates a new Thread object, the new - * thread has its priority initially set equal to the priority of the - * creating thread, and is a daemon thread if and only if the - * creating thread is a daemon. - *

- * When a Java Virtual Machine starts up, there is usually a single - * non-daemon thread (which typically calls the method named - * main of some designated class). The Java Virtual - * Machine continues to execute threads until either of the following - * occurs: - *

    - *
  • The exit method of class Runtime has been - * called and the security manager has permitted the exit operation - * to take place. - *
  • All threads that are not daemon threads have died, either by - * returning from the call to the run method or by - * throwing an exception that propagates beyond the run - * method. - *
- *

- * There are two ways to create a new thread of execution. One is to - * declare a class to be a subclass of Thread. This - * subclass should override the run method of class - * Thread. An instance of the subclass can then be - * allocated and started. For example, a thread that computes primes - * larger than a stated value could be written as follows: - *


- *     class PrimeThread extends Thread {
- *         long minPrime;
- *         PrimeThread(long minPrime) {
- *             this.minPrime = minPrime;
- *         }
- *
- *         public void run() {
- *             // compute primes larger than minPrime
- *              . . .
- *         }
- *     }
- * 

- *

- * The following code would then create a thread and start it running: - *

- *     PrimeThread p = new PrimeThread(143);
- *     p.start();
- * 
- *

- * The other way to create a thread is to declare a class that - * implements the Runnable interface. That class then - * implements the run method. An instance of the class can - * then be allocated, passed as an argument when creating - * Thread, and started. The same example in this other - * style looks like the following: - *


- *     class PrimeRun implements Runnable {
- *         long minPrime;
- *         PrimeRun(long minPrime) {
- *             this.minPrime = minPrime;
- *         }
- *
- *         public void run() {
- *             // compute primes larger than minPrime
- *              . . .
- *         }
- *     }
- * 

- *

- * The following code would then create a thread and start it running: - *

- *     PrimeRun p = new PrimeRun(143);
- *     new Thread(p).start();
- * 
- *

- * Every thread has a name for identification purposes. More than - * one thread may have the same name. If a name is not specified when - * a thread is created, a new name is generated for it. - *

- * Unless otherwise noted, passing a {@code null} argument to a constructor - * or method in this class will cause a {@link NullPointerException} to be - * thrown. - * - * @author unascribed - * @see Runnable - * @see Runtime#exit(int) - * @see #run() - * @see #stop() - * @since JDK1.0 - */ -public -class Thread implements Runnable { - // [IKVM] - static { - // force the set/getContextClassLoader methods to be JIT compiled, because isCCLOverridden(Thread) depends on it - // (we don't want to use RuntimeHelpers.PrepareMethod() because it requires full trust) - Thread dummy = new Thread((Void)null); - dummy.getContextClassLoader(); - dummy.setContextClassLoader(ClassLoader.DUMMY); - } - private Thread(Void _) { - // body replaced in map.xml - } - final class Cleanup { - private final Thread thread; - - Cleanup(Thread thread) { - this.thread = thread; - } - - protected void finalize() { - thread.die(); - } - } - /* --- start IKVM specific state --- */ - static final int[] nonDaemonCount = new int[1]; - @cli.System.ThreadStaticAttribute.Annotation - static Thread current; - @cli.System.ThreadStaticAttribute.Annotation - private static Cleanup cleanup; - private final Object lock = new Object(); - private cli.System.Threading.Thread nativeThread; - private Throwable stillborn; - private boolean running; // used only for coordination with stop0(), is never set to false - private volatile boolean interruptPending; - private volatile boolean nativeInterruptPending; - private volatile boolean interruptableWait; - private boolean timedWait; - volatile Object parkLock; // used by get/setParkLock in map.xml - int parkState; // used by cmpxchgParkState in map.xml - /* --- end IKVM specific state --- */ - - private char name[]; - private int priority; - private Thread threadQ; - private long eetop; - - /* Whether or not to single_step this thread. */ - private boolean single_step; - - /* Whether or not the thread is a daemon thread. */ - private boolean daemon = false; - - /* What will be run. */ - private Runnable target; - - /* The group of this thread */ - private ThreadGroup group; - - /* The context ClassLoader for this thread */ - private volatile ClassLoader contextClassLoader; - - /* The inherited AccessControlContext of this thread */ - AccessController.LazyContext lazyInheritedAccessControlContext; - - /* For autonumbering anonymous threads. */ - private static int threadInitNumber; - private static synchronized int nextThreadNum() { - return threadInitNumber++; - } - - /* ThreadLocal values pertaining to this thread. This map is maintained - * by the ThreadLocal class. */ - ThreadLocal.ThreadLocalMap threadLocals = null; - - /* - * InheritableThreadLocal values pertaining to this thread. This map is - * maintained by the InheritableThreadLocal class. - */ - ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; - - /* - * The requested stack size for this thread, or 0 if the creator did - * not specify a stack size. It is up to the VM to do whatever it - * likes with this number; some VMs will ignore it. - */ - private long stackSize; - - /* - * JVM-private state that persists after native thread termination. - */ - private long nativeParkEventPointer; - - /* - * Thread ID - */ - private long tid; - - /* For generating thread ID */ - private static long threadSeqNumber; - - /* Java thread status for tools, - * initialized to indicate thread 'not yet started' - */ - - private volatile int threadStatus = 0; - - - private static synchronized long nextThreadID() { - return ++threadSeqNumber; - } - - /** - * The argument supplied to the current call to - * java.util.concurrent.locks.LockSupport.park. - * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker - * Accessed using java.util.concurrent.locks.LockSupport.getBlocker - */ - volatile Object parkBlocker; - - /* The object in which this thread is blocked in an interruptible I/O - * operation, if any. The blocker's interrupt method should be invoked - * after setting this thread's interrupt status. - */ - private volatile Interruptible blocker; - private final Object blockerLock = new Object(); - - /* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code - */ - void blockedOn(Interruptible b) { - synchronized (blockerLock) { - blocker = b; - } - } - - /** - * The minimum priority that a thread can have. - */ - public final static int MIN_PRIORITY = 1; - - /** - * The default priority that is assigned to a thread. - */ - public final static int NORM_PRIORITY = 5; - - /** - * The maximum priority that a thread can have. - */ - public final static int MAX_PRIORITY = 10; - - /** - * Returns a reference to the currently executing thread object. - * - * @return the currently executing thread. - */ - public static Thread currentThread() { - Thread c = current; - if (c == null) { - c = new Thread(getMainThreadGroup()); - } - return c; - } - - private static native ThreadGroup getMainThreadGroup(); - - /** - * A hint to the scheduler that the current thread is willing to yield - * its current use of a processor. The scheduler is free to ignore this - * hint. - * - *

Yield is a heuristic attempt to improve relative progression - * between threads that would otherwise over-utilise a CPU. Its use - * should be combined with detailed profiling and benchmarking to - * ensure that it actually has the desired effect. - * - *

It is rarely appropriate to use this method. It may be useful - * for debugging or testing purposes, where it may help to reproduce - * bugs due to race conditions. It may also be useful when designing - * concurrency control constructs such as the ones in the - * {@link java.util.concurrent.locks} package. - */ - public static void yield() { - cli.System.Threading.Thread.Sleep(0); - } - - private void enterInterruptableWait(boolean timedWait) throws InterruptedException { - synchronized (lock) { - if (interruptPending) { - interruptPending = false; - throw new InterruptedException(); - } - interruptableWait = true; - this.timedWait = timedWait; - } - } - - private void leaveInterruptableWait() throws InterruptedException { - cli.System.Threading.ThreadInterruptedException dotnetInterrupt = null; - interruptableWait = false; - for (; ; ) { - try { - if (false) throw new cli.System.Threading.ThreadInterruptedException(); - synchronized (lock) { - if (nativeInterruptPending) { - nativeInterruptPending = false; - // HACK if there is a pending Interrupt (on the .NET thread), we need to consume that - // (if there was no contention on "lock (this)" above the interrupted state isn't checked) - try { - if (false) throw new cli.System.Threading.ThreadInterruptedException(); - cli.System.Threading.Thread t = cli.System.Threading.Thread.get_CurrentThread(); - // the obvious thing to do would be t.Interrupt() / t.Join(), - // but for some reason that causes a regression in JSR166TestCase (probably a CLR bug) - // so we waste a time slice... sigh. - t.Join(1); - } - catch (cli.System.Threading.ThreadInterruptedException _) { - } - } - if (interruptPending) { - interruptPending = false; - throw new InterruptedException(); - } - } - break; - } - catch (cli.System.Threading.ThreadInterruptedException x) { - dotnetInterrupt = x; - nativeInterruptPending = false; - } - } - if (dotnetInterrupt != null) { - ikvm.runtime.Util.throwException(dotnetInterrupt); - } - } - - /** - * Causes the currently executing thread to sleep (temporarily cease - * execution) for the specified number of milliseconds, subject to - * the precision and accuracy of system timers and schedulers. The thread - * does not lose ownership of any monitors. - * - * @param millis - * the length of time to sleep in milliseconds - * - * @throws IllegalArgumentException - * if the value of {@code millis} is negative - * - * @throws InterruptedException - * if any thread has interrupted the current thread. The - * interrupted status of the current thread is - * cleared when this exception is thrown. - */ - public static void sleep(long millis) throws InterruptedException { - if (millis < 0) { - throw new IllegalArgumentException("timeout value is negative"); - } - Thread c = currentThread(); - c.enterInterruptableWait(true); - try { - if (false) throw new cli.System.Threading.ThreadInterruptedException(); - for (long iter = millis / Integer.MAX_VALUE; iter != 0; iter--) - { - cli.System.Threading.Thread.Sleep(Integer.MAX_VALUE); - } - cli.System.Threading.Thread.Sleep((int)(millis % Integer.MAX_VALUE)); - } - catch (cli.System.Threading.ThreadInterruptedException _) { - } - finally { - c.leaveInterruptableWait(); - } - } - - /** - * Causes the currently executing thread to sleep (temporarily cease - * execution) for the specified number of milliseconds plus the specified - * number of nanoseconds, subject to the precision and accuracy of system - * timers and schedulers. The thread does not lose ownership of any - * monitors. - * - * @param millis - * the length of time to sleep in milliseconds - * - * @param nanos - * {@code 0-999999} additional nanoseconds to sleep - * - * @throws IllegalArgumentException - * if the value of {@code millis} is negative, or the value of - * {@code nanos} is not in the range {@code 0-999999} - * - * @throws InterruptedException - * if any thread has interrupted the current thread. The - * interrupted status of the current thread is - * cleared when this exception is thrown. - */ - public static void sleep(long millis, int nanos) - throws InterruptedException { - if (millis < 0) { - throw new IllegalArgumentException("timeout value is negative"); - } - - if (nanos < 0 || nanos > 999999) { - throw new IllegalArgumentException( - "nanosecond timeout value out of range"); - } - - if (nanos >= 500000 || (nanos != 0 && millis == 0)) { - millis++; - } - - sleep(millis); - } - - /** - * Initializes a Thread. - * - * @param g the Thread group - * @param target the object whose run() method gets called - * @param name the name of the new Thread - * @param stackSize the desired stack size for the new thread, or - * zero to indicate that this parameter is to be ignored. - */ - private void init(ThreadGroup g, Runnable target, String name, - long stackSize) { - if (name == null) { - throw new NullPointerException("name cannot be null"); - } - - Thread parent = currentThread(); - SecurityManager security = System.getSecurityManager(); - if (g == null) { - /* Determine if it's an applet or not */ - - /* If there is a security manager, ask the security manager - what to do. */ - if (security != null) { - g = security.getThreadGroup(); - } - - /* If the security doesn't have a strong opinion of the matter - use the parent thread group. */ - if (g == null) { - g = parent.getThreadGroup(); - } - } - - /* checkAccess regardless of whether or not threadgroup is - explicitly passed in. */ - g.checkAccess(); - - /* - * Do we have the required permissions? - */ - if (security != null) { - if (isCCLOverridden(this)) { - security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); - } - } - - - g.addUnstarted(); - - this.group = g; - this.daemon = parent.isDaemon(); - this.priority = parent.getPriority(); - this.name = name.toCharArray(); - if (isCCLOverridden(parent)) - this.contextClassLoader = parent.getContextClassLoader(); - else - this.contextClassLoader = parent.contextClassLoader; - this.lazyInheritedAccessControlContext = AccessController.getLazyContext(parent.lazyInheritedAccessControlContext); - this.target = target; - setPriority(priority); - if (parent.inheritableThreadLocals != null) - this.inheritableThreadLocals = - ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); - /* Stash the specified stack size in case the VM cares */ - this.stackSize = stackSize; - - /* Set thread ID */ - tid = nextThreadID(); - } - - // [IKVM] constructor for attaching to a .NET thread - Thread(ThreadGroup g) { - this.running = true; - cli.System.Threading.Thread thread = cli.System.Threading.Thread.get_CurrentThread(); - nativeThread = thread; - String name = thread.get_Name(); - if (name == null) { - name = "Thread-" + nextThreadNum(); - } - - this.group = g; - this.daemon = thread.get_IsBackground(); - this.priority = mapClrPriorityToJava(thread.get_Priority().Value); - this.name = name.toCharArray(); - this.contextClassLoader = ClassLoader.DUMMY; - this.threadStatus = 0x0005; /* JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_RUNNABLE */ - - /* Set thread ID */ - tid = nextThreadID(); - - synchronized (g) { - g.addUnstarted(); - g.add(this); - } - - current = this; - cleanup = new Cleanup(this); - - if (!daemon) { - cli.System.Threading.Interlocked.Increment(nonDaemonCount); - } - } - - private static int mapClrPriorityToJava(int priority) { - // TODO consider supporting -XX:JavaPriorityX_To_OSPriority settings - switch (priority) { - case cli.System.Threading.ThreadPriority.Lowest: - return MIN_PRIORITY; - case cli.System.Threading.ThreadPriority.BelowNormal: - return 3; - default: - case cli.System.Threading.ThreadPriority.Normal: - return NORM_PRIORITY; - case cli.System.Threading.ThreadPriority.AboveNormal: - return 7; - case cli.System.Threading.ThreadPriority.Highest: - return MAX_PRIORITY; - } - } - - private static int mapJavaPriorityToClr(int priority) { - // TODO consider supporting -XX:JavaPriorityX_To_OSPriority settings - if (priority == MIN_PRIORITY) { - return cli.System.Threading.ThreadPriority.Lowest; - } - else if (priority > Thread.MIN_PRIORITY && priority < Thread.NORM_PRIORITY) { - return cli.System.Threading.ThreadPriority.BelowNormal; - } - else if (priority == Thread.NORM_PRIORITY) { - return cli.System.Threading.ThreadPriority.Normal; - } - else if (priority > Thread.NORM_PRIORITY && priority < Thread.MAX_PRIORITY) { - return cli.System.Threading.ThreadPriority.AboveNormal; - } - else if (priority == Thread.MAX_PRIORITY) { - return cli.System.Threading.ThreadPriority.Highest; - } - else { - // can't happen - return cli.System.Threading.ThreadPriority.Normal; - } - } - - /** - * Throws CloneNotSupportedException as a Thread can not be meaningfully - * cloned. Construct a new Thread instead. - * - * @throws CloneNotSupportedException - * always - */ - @Override - protected Object clone() throws CloneNotSupportedException { - throw new CloneNotSupportedException(); - } - - /** - * Allocates a new {@code Thread} object. This constructor has the same - * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} - * {@code (null, null, gname)}, where {@code gname} is a newly generated - * name. Automatically generated names are of the form - * {@code "Thread-"+}n, where n is an integer. - */ - public Thread() { - init(null, null, "Thread-" + nextThreadNum(), 0); - } - - /** - * Allocates a new {@code Thread} object. This constructor has the same - * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} - * {@code (null, target, gname)}, where {@code gname} is a newly generated - * name. Automatically generated names are of the form - * {@code "Thread-"+}n, where n is an integer. - * - * @param target - * the object whose {@code run} method is invoked when this thread - * is started. If {@code null}, this classes {@code run} method does - * nothing. - */ - public Thread(Runnable target) { - init(null, target, "Thread-" + nextThreadNum(), 0); - } - - /** - * Allocates a new {@code Thread} object. This constructor has the same - * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} - * {@code (group, target, gname)} ,where {@code gname} is a newly generated - * name. Automatically generated names are of the form - * {@code "Thread-"+}n, where n is an integer. - * - * @param group - * the thread group. If {@code null} and there is a security - * manager, the group is determined by {@linkplain - * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}. - * If there is not a security manager or {@code - * SecurityManager.getThreadGroup()} returns {@code null}, the group - * is set to the current thread's thread group. - * - * @param target - * the object whose {@code run} method is invoked when this thread - * is started. If {@code null}, this thread's run method is invoked. - * - * @throws SecurityException - * if the current thread cannot create a thread in the specified - * thread group - */ - public Thread(ThreadGroup group, Runnable target) { - init(group, target, "Thread-" + nextThreadNum(), 0); - } - - /** - * Allocates a new {@code Thread} object. This constructor has the same - * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} - * {@code (null, null, name)}. - * - * @param name - * the name of the new thread - */ - public Thread(String name) { - init(null, null, name, 0); - } - - /** - * Allocates a new {@code Thread} object. This constructor has the same - * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} - * {@code (group, null, name)}. - * - * @param group - * the thread group. If {@code null} and there is a security - * manager, the group is determined by {@linkplain - * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}. - * If there is not a security manager or {@code - * SecurityManager.getThreadGroup()} returns {@code null}, the group - * is set to the current thread's thread group. - * - * @param name - * the name of the new thread - * - * @throws SecurityException - * if the current thread cannot create a thread in the specified - * thread group - */ - public Thread(ThreadGroup group, String name) { - init(group, null, name, 0); - } - - /** - * Allocates a new {@code Thread} object. This constructor has the same - * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} - * {@code (null, target, name)}. - * - * @param target - * the object whose {@code run} method is invoked when this thread - * is started. If {@code null}, this thread's run method is invoked. - * - * @param name - * the name of the new thread - */ - public Thread(Runnable target, String name) { - init(null, target, name, 0); - } - - /** - * Allocates a new {@code Thread} object so that it has {@code target} - * as its run object, has the specified {@code name} as its name, - * and belongs to the thread group referred to by {@code group}. - * - *

If there is a security manager, its - * {@link SecurityManager#checkAccess(ThreadGroup) checkAccess} - * method is invoked with the ThreadGroup as its argument. - * - *

In addition, its {@code checkPermission} method is invoked with - * the {@code RuntimePermission("enableContextClassLoaderOverride")} - * permission when invoked directly or indirectly by the constructor - * of a subclass which overrides the {@code getContextClassLoader} - * or {@code setContextClassLoader} methods. - * - *

The priority of the newly created thread is set equal to the - * priority of the thread creating it, that is, the currently running - * thread. The method {@linkplain #setPriority setPriority} may be - * used to change the priority to a new value. - * - *

The newly created thread is initially marked as being a daemon - * thread if and only if the thread creating it is currently marked - * as a daemon thread. The method {@linkplain #setDaemon setDaemon} - * may be used to change whether or not a thread is a daemon. - * - * @param group - * the thread group. If {@code null} and there is a security - * manager, the group is determined by {@linkplain - * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}. - * If there is not a security manager or {@code - * SecurityManager.getThreadGroup()} returns {@code null}, the group - * is set to the current thread's thread group. - * - * @param target - * the object whose {@code run} method is invoked when this thread - * is started. If {@code null}, this thread's run method is invoked. - * - * @param name - * the name of the new thread - * - * @throws SecurityException - * if the current thread cannot create a thread in the specified - * thread group or cannot override the context class loader methods. - */ - public Thread(ThreadGroup group, Runnable target, String name) { - init(group, target, name, 0); - } - - /** - * Allocates a new {@code Thread} object so that it has {@code target} - * as its run object, has the specified {@code name} as its name, - * and belongs to the thread group referred to by {@code group}, and has - * the specified stack size. - * - *

This constructor is identical to {@link - * #Thread(ThreadGroup,Runnable,String)} with the exception of the fact - * that it allows the thread stack size to be specified. The stack size - * is the approximate number of bytes of address space that the virtual - * machine is to allocate for this thread's stack. The effect of the - * {@code stackSize} parameter, if any, is highly platform dependent. - * - *

On some platforms, specifying a higher value for the - * {@code stackSize} parameter may allow a thread to achieve greater - * recursion depth before throwing a {@link StackOverflowError}. - * Similarly, specifying a lower value may allow a greater number of - * threads to exist concurrently without throwing an {@link - * OutOfMemoryError} (or other internal error). The details of - * the relationship between the value of the stackSize parameter - * and the maximum recursion depth and concurrency level are - * platform-dependent. On some platforms, the value of the - * {@code stackSize} parameter may have no effect whatsoever. - * - *

The virtual machine is free to treat the {@code stackSize} - * parameter as a suggestion. If the specified value is unreasonably low - * for the platform, the virtual machine may instead use some - * platform-specific minimum value; if the specified value is unreasonably - * high, the virtual machine may instead use some platform-specific - * maximum. Likewise, the virtual machine is free to round the specified - * value up or down as it sees fit (or to ignore it completely). - * - *

Specifying a value of zero for the {@code stackSize} parameter will - * cause this constructor to behave exactly like the - * {@code Thread(ThreadGroup, Runnable, String)} constructor. - * - *

Due to the platform-dependent nature of the behavior of this - * constructor, extreme care should be exercised in its use. - * The thread stack size necessary to perform a given computation will - * likely vary from one JRE implementation to another. In light of this - * variation, careful tuning of the stack size parameter may be required, - * and the tuning may need to be repeated for each JRE implementation on - * which an application is to run. - * - *

Implementation note: Java platform implementers are encouraged to - * document their implementation's behavior with respect to the - * {@code stackSize} parameter. - * - * - * @param group - * the thread group. If {@code null} and there is a security - * manager, the group is determined by {@linkplain - * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}. - * If there is not a security manager or {@code - * SecurityManager.getThreadGroup()} returns {@code null}, the group - * is set to the current thread's thread group. - * - * @param target - * the object whose {@code run} method is invoked when this thread - * is started. If {@code null}, this thread's run method is invoked. - * - * @param name - * the name of the new thread - * - * @param stackSize - * the desired stack size for the new thread, or zero to indicate - * that this parameter is to be ignored. - * - * @throws SecurityException - * if the current thread cannot create a thread in the specified - * thread group - * - * @since 1.4 - */ - public Thread(ThreadGroup group, Runnable target, String name, - long stackSize) { - init(group, target, name, stackSize); - } - - /** - * Causes this thread to begin execution; the Java Virtual Machine - * calls the run method of this thread. - *

- * The result is that two threads are running concurrently: the - * current thread (which returns from the call to the - * start method) and the other thread (which executes its - * run method). - *

- * It is never legal to start a thread more than once. - * In particular, a thread may not be restarted once it has completed - * execution. - * - * @exception IllegalThreadStateException if the thread was already - * started. - * @see #run() - * @see #stop() - */ - public synchronized void start() { - /** - * This method is not invoked for the main method thread or "system" - * group threads created/set up by the VM. Any new functionality added - * to this method in the future may have to also be added to the VM. - * - * A zero status value corresponds to state "NEW". - */ - if (threadStatus != 0) - throw new IllegalThreadStateException(); - - /* Notify the group that this thread is about to be started - * so that it can be added to the group's list of threads - * and the group's unstarted count can be decremented. */ - group.add(this); - - boolean started = false; - try { - start0(); - started = true; - } finally { - try { - if (!started) { - group.threadStartFailed(this); - } - } catch (Throwable ignore) { - /* do nothing. If start0 threw a Throwable then - it will be passed up the call stack */ - } - } - } - - private void start0() { - cli.System.Threading.ThreadStart threadStart = new cli.System.Threading.ThreadStart(new cli.System.Threading.ThreadStart.Method() { - @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation - public void Invoke() { - threadProc(); - } - }); - if (stackSize <= 0) { - nativeThread = new cli.System.Threading.Thread(threadStart); - } - else { - int maxStackSize = (int)Math.min(Math.max(128 * 1024, stackSize), Integer.MAX_VALUE); - nativeThread = new cli.System.Threading.Thread(threadStart, maxStackSize); - } - nativeThread.set_Name(getName()); - nativeThread.set_IsBackground(daemon); - nativeThread.set_Priority(cli.System.Threading.ThreadPriority.wrap(mapJavaPriorityToClr(priority))); - String apartment = Props.props.getProperty("ikvm.apartmentstate", "").toLowerCase(); - if ("mta".equals(apartment)) { - nativeThread.SetApartmentState(cli.System.Threading.ApartmentState.wrap(cli.System.Threading.ApartmentState.MTA)); - } - else if ("sta".equals(apartment)) { - nativeThread.SetApartmentState(cli.System.Threading.ApartmentState.wrap(cli.System.Threading.ApartmentState.STA)); - } - threadStatus = 0x0005; // JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_RUNNABLE - nativeThread.Start(); - if (!daemon) { - cli.System.Threading.Interlocked.Increment(nonDaemonCount); - } - } - - /** - * If this thread was constructed using a separate - * Runnable run object, then that - * Runnable object's run method is called; - * otherwise, this method does nothing and returns. - *

- * Subclasses of Thread should override this method. - * - * @see #start() - * @see #stop() - * @see #Thread(ThreadGroup, Runnable, String) - */ - @Override - public void run() { - if (target != null) { - target.run(); - } - } - - // [IKVM] for threads started from Java, this method is called on the thread itself, - // but for .NET threads it will be called by the finalizer of the Cleanup object. - // NOTE there might be a race condition here (when the thread's Cleanup object - // is finalized during AppDomain shutdown while the thread is also exiting on its own), - // but that doesn't matter because Thread.exit() is safe to call multiple times. - void die() { - exit(); - synchronized (lock) { - nativeThread = null; - threadStatus = 0x0002; // JVMTI_THREAD_STATE_TERMINATED - } - wakeupJoinedThreads(); - if (!daemon) { - // TODO there is a race condition in the non-daemon counting - // (setDaemon() isn't synchronized so it may clear/set the daemon flag without the count being affected) - cli.System.Threading.Interlocked.Decrement(nonDaemonCount); - } - if (current == this) { - current = null; - // check if we have a cleanup object, this happens if we attach and subsequently detach from JNI code - if (cleanup != null) { - cli.System.GC.SuppressFinalize(cleanup); - cleanup = null; - } - } - } - - private void wakeupJoinedThreads() { - // HACK locking this here isn't ideal, because we might be invoked from - // the Cleanup object's finalizer and some user code might own the lock and hence - // block the finalizer thread. - // A second scenario is that another thread is currently blocking inside stop() - // (the Thread.Abort() call will block while we are running the finally block) - // and that thread will own the lock on our thread object. - boolean locked = false; - try { - locked = cli.System.Threading.Monitor.TryEnter(this); - if (locked) { - notifyAll(); - } else { - // HACK schedule an asynchronous notification - cli.System.Threading.ThreadPool.QueueUserWorkItem( - new cli.System.Threading.WaitCallback( - new cli.System.Threading.WaitCallback.Method() { - public void Invoke(Object thread) { - synchronized (thread) { - thread.notifyAll(); - } - } - }), this); - } - } - finally { - if (locked) - cli.System.Threading.Monitor.Exit(this); - } - } - - /** - * This method is called by the system to give a Thread - * a chance to clean up before it actually exits. - */ - private void exit() { - if (group != null) { - group.threadTerminated(this); - group = null; - } - /* Aggressively null out all reference fields: see bug 4006245 */ - target = null; - /* Speed the release of some of these resources */ - threadLocals = null; - inheritableThreadLocals = null; - lazyInheritedAccessControlContext = null; - blocker = null; - uncaughtExceptionHandler = null; - } - - /** - * Forces the thread to stop executing. - *

- * If there is a security manager installed, its checkAccess - * method is called with this - * as its argument. This may result in a - * SecurityException being raised (in the current thread). - *

- * If this thread is different from the current thread (that is, the current - * thread is trying to stop a thread other than itself), the - * security manager's checkPermission method (with a - * RuntimePermission("stopThread") argument) is called in - * addition. - * Again, this may result in throwing a - * SecurityException (in the current thread). - *

- * The thread represented by this thread is forced to stop whatever - * it is doing abnormally and to throw a newly created - * ThreadDeath object as an exception. - *

- * It is permitted to stop a thread that has not yet been started. - * If the thread is eventually started, it immediately terminates. - *

- * An application should not normally try to catch - * ThreadDeath unless it must do some extraordinary - * cleanup operation (note that the throwing of - * ThreadDeath causes finally clauses of - * try statements to be executed before the thread - * officially dies). If a catch clause catches a - * ThreadDeath object, it is important to rethrow the - * object so that the thread actually dies. - *

- * The top-level error handler that reacts to otherwise uncaught - * exceptions does not print out a message or otherwise notify the - * application if the uncaught exception is an instance of - * ThreadDeath. - * - * @exception SecurityException if the current thread cannot - * modify this thread. - * @see #interrupt() - * @see #checkAccess() - * @see #run() - * @see #start() - * @see ThreadDeath - * @see ThreadGroup#uncaughtException(Thread,Throwable) - * @see SecurityManager#checkAccess(Thread) - * @see SecurityManager#checkPermission - * @deprecated This method is inherently unsafe. Stopping a thread with - * Thread.stop causes it to unlock all of the monitors that it - * has locked (as a natural consequence of the unchecked - * ThreadDeath exception propagating up the stack). If - * any of the objects previously protected by these monitors were in - * an inconsistent state, the damaged objects become visible to - * other threads, potentially resulting in arbitrary behavior. Many - * uses of stop should be replaced by code that simply - * modifies some variable to indicate that the target thread should - * stop running. The target thread should check this variable - * regularly, and return from its run method in an orderly fashion - * if the variable indicates that it is to stop running. If the - * target thread waits for long periods (on a condition variable, - * for example), the interrupt method should be used to - * interrupt the wait. - * For more information, see - * Why - * are Thread.stop, Thread.suspend and Thread.resume Deprecated?. - */ - @Deprecated - public final void stop() { - stop(new ThreadDeath()); - } - - /** - * Forces the thread to stop executing. - *

- * If there is a security manager installed, the checkAccess - * method of this thread is called, which may result in a - * SecurityException being raised (in the current thread). - *

- * If this thread is different from the current thread (that is, the current - * thread is trying to stop a thread other than itself) or - * obj is not an instance of ThreadDeath, the - * security manager's checkPermission method (with the - * RuntimePermission("stopThread") argument) is called in - * addition. - * Again, this may result in throwing a - * SecurityException (in the current thread). - *

- * If the argument obj is null, a - * NullPointerException is thrown (in the current thread). - *

- * The thread represented by this thread is forced to stop - * whatever it is doing abnormally and to throw the - * Throwable object obj as an exception. This - * is an unusual action to take; normally, the stop method - * that takes no arguments should be used. - *

- * It is permitted to stop a thread that has not yet been started. - * If the thread is eventually started, it immediately terminates. - * - * @param obj the Throwable object to be thrown. - * @exception SecurityException if the current thread cannot modify - * this thread. - * @throws NullPointerException if obj is null. - * @see #interrupt() - * @see #checkAccess() - * @see #run() - * @see #start() - * @see #stop() - * @see SecurityManager#checkAccess(Thread) - * @see SecurityManager#checkPermission - * @deprecated This method is inherently unsafe. See {@link #stop()} - * for details. An additional danger of this - * method is that it may be used to generate exceptions that the - * target thread is unprepared to handle (including checked - * exceptions that the thread could not possibly throw, were it - * not for this method). - * For more information, see - * Why - * are Thread.stop, Thread.suspend and Thread.resume Deprecated?. - */ - @Deprecated - public final synchronized void stop(Throwable obj) { - if (obj == null) - throw new NullPointerException(); - - SecurityManager security = System.getSecurityManager(); - if (security != null) { - checkAccess(); - if ((this != Thread.currentThread()) || - (!(obj instanceof ThreadDeath))) { - security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION); - } - } - // A zero status value corresponds to "NEW", it can't change to - // not-NEW because we hold the lock. - if (threadStatus != 0) { - resume(); // Wake up thread if it was suspended; no-op otherwise - } - - // The VM can handle all thread states - stop0(obj); - } - - /** - * Interrupts this thread. - * - *

Unless the current thread is interrupting itself, which is - * always permitted, the {@link #checkAccess() checkAccess} method - * of this thread is invoked, which may cause a {@link - * SecurityException} to be thrown. - * - *

If this thread is blocked in an invocation of the {@link - * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link - * Object#wait(long, int) wait(long, int)} methods of the {@link Object} - * class, or of the {@link #join()}, {@link #join(long)}, {@link - * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)}, - * methods of this class, then its interrupt status will be cleared and it - * will receive an {@link InterruptedException}. - * - *

If this thread is blocked in an I/O operation upon an {@link - * java.nio.channels.InterruptibleChannel interruptible - * channel} then the channel will be closed, the thread's interrupt - * status will be set, and the thread will receive a {@link - * java.nio.channels.ClosedByInterruptException}. - * - *

If this thread is blocked in a {@link java.nio.channels.Selector} - * then the thread's interrupt status will be set and it will return - * immediately from the selection operation, possibly with a non-zero - * value, just as if the selector's {@link - * java.nio.channels.Selector#wakeup wakeup} method were invoked. - * - *

If none of the previous conditions hold then this thread's interrupt - * status will be set.

- * - *

Interrupting a thread that is not alive need not have any effect. - * - * @throws SecurityException - * if the current thread cannot modify this thread - * - * @revised 6.0 - * @spec JSR-51 - */ - public void interrupt() { - if (this != Thread.currentThread()) - checkAccess(); - - synchronized (blockerLock) { - Interruptible b = blocker; - if (b != null) { - interrupt0(); // Just to set the interrupt flag - b.interrupt(this); - return; - } - } - interrupt0(); - } - - /** - * Tests whether the current thread has been interrupted. The - * interrupted status of the thread is cleared by this method. In - * other words, if this method were to be called twice in succession, the - * second call would return false (unless the current thread were - * interrupted again, after the first call had cleared its interrupted - * status and before the second call had examined it). - * - *

A thread interruption ignored because a thread was not alive - * at the time of the interrupt will be reflected by this method - * returning false. - * - * @return true if the current thread has been interrupted; - * false otherwise. - * @see #isInterrupted() - * @revised 6.0 - */ - public static boolean interrupted() { - Thread current = currentThread(); - if (!current.interruptPending) { - return false; - } - current.interruptPending = false; - return true; - } - - /** - * Tests whether this thread has been interrupted. The interrupted - * status of the thread is unaffected by this method. - * - *

A thread interruption ignored because a thread was not alive - * at the time of the interrupt will be reflected by this method - * returning false. - * - * @return true if this thread has been interrupted; - * false otherwise. - * @see #interrupted() - * @revised 6.0 - */ - public boolean isInterrupted() { - return interruptPending; - } - - /** - * Throws {@link NoSuchMethodError}. - * - * @deprecated This method was originally designed to destroy this - * thread without any cleanup. Any monitors it held would have - * remained locked. However, the method was never implemented. - * If if were to be implemented, it would be deadlock-prone in - * much the manner of {@link #suspend}. If the target thread held - * a lock protecting a critical system resource when it was - * destroyed, no thread could ever access this resource again. - * If another thread ever attempted to lock this resource, deadlock - * would result. Such deadlocks typically manifest themselves as - * "frozen" processes. For more information, see - * - * Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?. - * @throws NoSuchMethodError always - */ - @Deprecated - public void destroy() { - throw new NoSuchMethodError(); - } - - /** - * Tests if this thread is alive. A thread is alive if it has - * been started and has not yet died. - * - * @return true if this thread is alive; - * false otherwise. - */ - public final boolean isAlive() { - return (threadStatus & 0x0001) != 0; - } - - /** - * Suspends this thread. - *

- * First, the checkAccess method of this thread is called - * with no arguments. This may result in throwing a - * SecurityException (in the current thread). - *

- * If the thread is alive, it is suspended and makes no further - * progress unless and until it is resumed. - * - * @exception SecurityException if the current thread cannot modify - * this thread. - * @see #checkAccess - * @deprecated This method has been deprecated, as it is - * inherently deadlock-prone. If the target thread holds a lock on the - * monitor protecting a critical system resource when it is suspended, no - * thread can access this resource until the target thread is resumed. If - * the thread that would resume the target thread attempts to lock this - * monitor prior to calling resume, deadlock results. Such - * deadlocks typically manifest themselves as "frozen" processes. - * For more information, see - * Why - * are Thread.stop, Thread.suspend and Thread.resume Deprecated?. - */ - @Deprecated - public final void suspend() { - checkAccess(); - suspend0(); - } - - /** - * Resumes a suspended thread. - *

- * First, the checkAccess method of this thread is called - * with no arguments. This may result in throwing a - * SecurityException (in the current thread). - *

- * If the thread is alive but suspended, it is resumed and is - * permitted to make progress in its execution. - * - * @exception SecurityException if the current thread cannot modify this - * thread. - * @see #checkAccess - * @see #suspend() - * @deprecated This method exists solely for use with {@link #suspend}, - * which has been deprecated because it is deadlock-prone. - * For more information, see - * Why - * are Thread.stop, Thread.suspend and Thread.resume Deprecated?. - */ - @Deprecated - public final void resume() { - checkAccess(); - resume0(); - } - - /** - * Changes the priority of this thread. - *

- * First the checkAccess method of this thread is called - * with no arguments. This may result in throwing a - * SecurityException. - *

- * Otherwise, the priority of this thread is set to the smaller of - * the specified newPriority and the maximum permitted - * priority of the thread's thread group. - * - * @param newPriority priority to set this thread to - * @exception IllegalArgumentException If the priority is not in the - * range MIN_PRIORITY to - * MAX_PRIORITY. - * @exception SecurityException if the current thread cannot modify - * this thread. - * @see #getPriority - * @see #checkAccess() - * @see #getThreadGroup() - * @see #MAX_PRIORITY - * @see #MIN_PRIORITY - * @see ThreadGroup#getMaxPriority() - */ - public final void setPriority(int newPriority) { - ThreadGroup g; - checkAccess(); - if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { - throw new IllegalArgumentException(); - } - if((g = getThreadGroup()) != null) { - if (newPriority > g.getMaxPriority()) { - newPriority = g.getMaxPriority(); - } - setPriority0(priority = newPriority); - } - } - - /** - * Returns this thread's priority. - * - * @return this thread's priority. - * @see #setPriority - */ - public final int getPriority() { - return priority; - } - - /** - * Changes the name of this thread to be equal to the argument - * name. - *

- * First the checkAccess method of this thread is called - * with no arguments. This may result in throwing a - * SecurityException. - * - * @param name the new name for this thread. - * @exception SecurityException if the current thread cannot modify this - * thread. - * @see #getName - * @see #checkAccess() - */ - public final void setName(String name) { - checkAccess(); - this.name = name.toCharArray(); - } - - /** - * Returns this thread's name. - * - * @return this thread's name. - * @see #setName(String) - */ - public final String getName() { - return String.valueOf(name); - } - - /** - * Returns the thread group to which this thread belongs. - * This method returns null if this thread has died - * (been stopped). - * - * @return this thread's thread group. - */ - public final ThreadGroup getThreadGroup() { - return group; - } - - /** - * Returns an estimate of the number of active threads in the current - * thread's {@linkplain java.lang.ThreadGroup thread group} and its - * subgroups. Recursively iterates over all subgroups in the current - * thread's thread group. - * - *

The value returned is only an estimate because the number of - * threads may change dynamically while this method traverses internal - * data structures, and might be affected by the presence of certain - * system threads. This method is intended primarily for debugging - * and monitoring purposes. - * - * @return an estimate of the number of active threads in the current - * thread's thread group and in any other thread group that - * has the current thread's thread group as an ancestor - */ - public static int activeCount() { - return currentThread().getThreadGroup().activeCount(); - } - - /** - * Copies into the specified array every active thread in the current - * thread's thread group and its subgroups. This method simply - * invokes the {@link java.lang.ThreadGroup#enumerate(Thread[])} - * method of the current thread's thread group. - * - *

An application might use the {@linkplain #activeCount activeCount} - * method to get an estimate of how big the array should be, however - * if the array is too short to hold all the threads, the extra threads - * are silently ignored. If it is critical to obtain every active - * thread in the current thread's thread group and its subgroups, the - * invoker should verify that the returned int value is strictly less - * than the length of {@code tarray}. - * - *

Due to the inherent race condition in this method, it is recommended - * that the method only be used for debugging and monitoring purposes. - * - * @param tarray - * an array into which to put the list of threads - * - * @return the number of threads put into the array - * - * @throws SecurityException - * if {@link java.lang.ThreadGroup#checkAccess} determines that - * the current thread cannot access its thread group - */ - public static int enumerate(Thread tarray[]) { - return currentThread().getThreadGroup().enumerate(tarray); - } - - /** - * Counts the number of stack frames in this thread. The thread must - * be suspended. - * - * @return the number of stack frames in this thread. - * @exception IllegalThreadStateException if this thread is not - * suspended. - * @deprecated The definition of this call depends on {@link #suspend}, - * which is deprecated. Further, the results of this call - * were never well-defined. - */ - @Deprecated - public int countStackFrames() { - return 0; - } - - /** - * Waits at most {@code millis} milliseconds for this thread to - * die. A timeout of {@code 0} means to wait forever. - * - *

This implementation uses a loop of {@code this.wait} calls - * conditioned on {@code this.isAlive}. As a thread terminates the - * {@code this.notifyAll} method is invoked. It is recommended that - * applications not use {@code wait}, {@code notify}, or - * {@code notifyAll} on {@code Thread} instances. - * - * @param millis - * the time to wait in milliseconds - * - * @throws IllegalArgumentException - * if the value of {@code millis} is negative - * - * @throws InterruptedException - * if any thread has interrupted the current thread. The - * interrupted status of the current thread is - * cleared when this exception is thrown. - */ - public final synchronized void join(long millis) - throws InterruptedException { - long base = System.currentTimeMillis(); - long now = 0; - - if (millis < 0) { - throw new IllegalArgumentException("timeout value is negative"); - } - - if (millis == 0) { - while (isAlive()) { - wait(0); - } - } else { - while (isAlive()) { - long delay = millis - now; - if (delay <= 0) { - break; - } - wait(delay); - now = System.currentTimeMillis() - base; - } - } - } - - /** - * Waits at most {@code millis} milliseconds plus - * {@code nanos} nanoseconds for this thread to die. - * - *

This implementation uses a loop of {@code this.wait} calls - * conditioned on {@code this.isAlive}. As a thread terminates the - * {@code this.notifyAll} method is invoked. It is recommended that - * applications not use {@code wait}, {@code notify}, or - * {@code notifyAll} on {@code Thread} instances. - * - * @param millis - * the time to wait in milliseconds - * - * @param nanos - * {@code 0-999999} additional nanoseconds to wait - * - * @throws IllegalArgumentException - * if the value of {@code millis} is negative, or the value - * of {@code nanos} is not in the range {@code 0-999999} - * - * @throws InterruptedException - * if any thread has interrupted the current thread. The - * interrupted status of the current thread is - * cleared when this exception is thrown. - */ - public final synchronized void join(long millis, int nanos) - throws InterruptedException { - - if (millis < 0) { - throw new IllegalArgumentException("timeout value is negative"); - } - - if (nanos < 0 || nanos > 999999) { - throw new IllegalArgumentException( - "nanosecond timeout value out of range"); - } - - if (nanos >= 500000 || (nanos != 0 && millis == 0)) { - millis++; - } - - join(millis); - } - - /** - * Waits for this thread to die. - * - *

An invocation of this method behaves in exactly the same - * way as the invocation - * - *

- * {@linkplain #join(long) join}{@code (0)} - *
- * - * @throws InterruptedException - * if any thread has interrupted the current thread. The - * interrupted status of the current thread is - * cleared when this exception is thrown. - */ - public final void join() throws InterruptedException { - join(0); - } - - /** - * Prints a stack trace of the current thread to the standard error stream. - * This method is used only for debugging. - * - * @see Throwable#printStackTrace() - */ - public static void dumpStack() { - new Exception("Stack trace").printStackTrace(); - } - - /** - * Marks this thread as either a {@linkplain #isDaemon daemon} thread - * or a user thread. The Java Virtual Machine exits when the only - * threads running are all daemon threads. - * - *

This method must be invoked before the thread is started. - * - * @param on - * if {@code true}, marks this thread as a daemon thread - * - * @throws IllegalThreadStateException - * if this thread is {@linkplain #isAlive alive} - * - * @throws SecurityException - * if {@link #checkAccess} determines that the current - * thread cannot modify this thread - */ - public final void setDaemon(boolean on) { - checkAccess(); - if (isAlive()) { - throw new IllegalThreadStateException(); - } - daemon = on; - } - - /** - * Tests if this thread is a daemon thread. - * - * @return true if this thread is a daemon thread; - * false otherwise. - * @see #setDaemon(boolean) - */ - public final boolean isDaemon() { - return daemon; - } - - /** - * Determines if the currently running thread has permission to - * modify this thread. - *

- * If there is a security manager, its checkAccess method - * is called with this thread as its argument. This may result in - * throwing a SecurityException. - * - * @exception SecurityException if the current thread is not allowed to - * access this thread. - * @see SecurityManager#checkAccess(Thread) - */ - public final void checkAccess() { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkAccess(this); - } - } - - /** - * Returns a string representation of this thread, including the - * thread's name, priority, and thread group. - * - * @return a string representation of this thread. - */ - public String toString() { - ThreadGroup group = getThreadGroup(); - if (group != null) { - return "Thread[" + getName() + "," + getPriority() + "," + - group.getName() + "]"; - } else { - return "Thread[" + getName() + "," + getPriority() + "," + - "" + "]"; - } - } - - /** - * Returns the context ClassLoader for this Thread. The context - * ClassLoader is provided by the creator of the thread for use - * by code running in this thread when loading classes and resources. - * If not {@linkplain #setContextClassLoader set}, the default is the - * ClassLoader context of the parent Thread. The context ClassLoader of the - * primordial thread is typically set to the class loader used to load the - * application. - * - *

If a security manager is present, and the invoker's class loader is not - * {@code null} and is not the same as or an ancestor of the context class - * loader, then this method invokes the security manager's {@link - * SecurityManager#checkPermission(java.security.Permission) checkPermission} - * method with a {@link RuntimePermission RuntimePermission}{@code - * ("getClassLoader")} permission to verify that retrieval of the context - * class loader is permitted. - * - * @return the context ClassLoader for this Thread, or {@code null} - * indicating the system class loader (or, failing that, the - * bootstrap class loader) - * - * @throws SecurityException - * if the current thread cannot get the context ClassLoader - * - * @since 1.2 - */ - @CallerSensitive - public ClassLoader getContextClassLoader() { - if (contextClassLoader == ClassLoader.DUMMY) { - contextClassLoader = ClassLoader.getSystemClassLoader(); - } - if (contextClassLoader == null) - return null; - - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - ClassLoader.checkClassLoaderPermission(contextClassLoader, - Reflection.getCallerClass()); - } - return contextClassLoader; - } - - /** - * Sets the context ClassLoader for this Thread. The context - * ClassLoader can be set when a thread is created, and allows - * the creator of the thread to provide the appropriate class loader, - * through {@code getContextClassLoader}, to code running in the thread - * when loading classes and resources. - * - *

If a security manager is present, its {@link - * SecurityManager#checkPermission(java.security.Permission) checkPermission} - * method is invoked with a {@link RuntimePermission RuntimePermission}{@code - * ("setContextClassLoader")} permission to see if setting the context - * ClassLoader is permitted. - * - * @param cl - * the context ClassLoader for this Thread, or null indicating the - * system class loader (or, failing that, the bootstrap class loader) - * - * @throws SecurityException - * if the current thread cannot set the context ClassLoader - * - * @since 1.2 - */ - public void setContextClassLoader(ClassLoader cl) { - if (cl == ClassLoader.DUMMY) { - // we're being called by Thread. to force this method to be JIT compiled - return; - } - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("setContextClassLoader")); - } - contextClassLoader = cl; - } - - // [IKVM] called by sun.misc.Launcher (via map.xml patch) to initialize the context class loader - final void initContextClassLoader(ClassLoader cl) { - // we only set contextClassLoader if it hasn't been set (by user code) previously - java.util.concurrent.atomic.AtomicReferenceFieldUpdater - .newUpdater(Thread.class, ClassLoader.class, "contextClassLoader") - .compareAndSet(this, ClassLoader.DUMMY, cl); - } - - /** - * Returns true if and only if the current thread holds the - * monitor lock on the specified object. - * - *

This method is designed to allow a program to assert that - * the current thread already holds a specified lock: - *

-     *     assert Thread.holdsLock(obj);
-     * 
- * - * @param obj the object on which to test lock ownership - * @throws NullPointerException if obj is null - * @return true if the current thread holds the monitor lock on - * the specified object. - * @since 1.4 - */ - public static boolean holdsLock(Object obj) { - if (obj == null) { - throw new NullPointerException(); - } - try { - if (false) throw new cli.System.Threading.SynchronizationLockException(); - // The 1.5 memory model (JSR133) explicitly allows spurious wake-ups from Object.wait, - // so we abuse Pulse to check if we own the monitor. - cli.System.Threading.Monitor.Pulse(obj); - return true; - } - catch (cli.System.Threading.SynchronizationLockException _) { - return false; - } - } - - private static final StackTraceElement[] EMPTY_STACK_TRACE - = new StackTraceElement[0]; - - /** - * Returns an array of stack trace elements representing the stack dump - * of this thread. This method will return a zero-length array if - * this thread has not started, has started but has not yet been - * scheduled to run by the system, or has terminated. - * If the returned array is of non-zero length then the first element of - * the array represents the top of the stack, which is the most recent - * method invocation in the sequence. The last element of the array - * represents the bottom of the stack, which is the least recent method - * invocation in the sequence. - * - *

If there is a security manager, and this thread is not - * the current thread, then the security manager's - * checkPermission method is called with a - * RuntimePermission("getStackTrace") permission - * to see if it's ok to get the stack trace. - * - *

Some virtual machines may, under some circumstances, omit one - * or more stack frames from the stack trace. In the extreme case, - * a virtual machine that has no stack trace information concerning - * this thread is permitted to return a zero-length array from this - * method. - * - * @return an array of StackTraceElement, - * each represents one stack frame. - * - * @throws SecurityException - * if a security manager exists and its - * checkPermission method doesn't allow - * getting the stack trace of thread. - * @see SecurityManager#checkPermission - * @see RuntimePermission - * @see Throwable#getStackTrace - * - * @since 1.5 - */ - public StackTraceElement[] getStackTrace() { - if (this != Thread.currentThread()) { - // check for getStackTrace permission - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission( - SecurityConstants.GET_STACK_TRACE_PERMISSION); - } - // optimization so we do not call into the vm for threads that - // have not yet started or have terminated - if (!isAlive()) { - return EMPTY_STACK_TRACE; - } - StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this}); - StackTraceElement[] stackTrace = stackTraceArray[0]; - // a thread that was alive during the previous isAlive call may have - // since terminated, therefore not having a stacktrace. - if (stackTrace == null) { - stackTrace = EMPTY_STACK_TRACE; - } - return stackTrace; - } else { - // Don't need JVM help for current thread - return (new Exception()).getStackTrace(); - } - } - - /** - * Returns a map of stack traces for all live threads. - * The map keys are threads and each map value is an array of - * StackTraceElement that represents the stack dump - * of the corresponding Thread. - * The returned stack traces are in the format specified for - * the {@link #getStackTrace getStackTrace} method. - * - *

The threads may be executing while this method is called. - * The stack trace of each thread only represents a snapshot and - * each stack trace may be obtained at different time. A zero-length - * array will be returned in the map value if the virtual machine has - * no stack trace information about a thread. - * - *

If there is a security manager, then the security manager's - * checkPermission method is called with a - * RuntimePermission("getStackTrace") permission as well as - * RuntimePermission("modifyThreadGroup") permission - * to see if it is ok to get the stack trace of all threads. - * - * @return a Map from Thread to an array of - * StackTraceElement that represents the stack trace of - * the corresponding thread. - * - * @throws SecurityException - * if a security manager exists and its - * checkPermission method doesn't allow - * getting the stack trace of thread. - * @see #getStackTrace - * @see SecurityManager#checkPermission - * @see RuntimePermission - * @see Throwable#getStackTrace - * - * @since 1.5 - */ - public static Map getAllStackTraces() { - // check for getStackTrace permission - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission( - SecurityConstants.GET_STACK_TRACE_PERMISSION); - security.checkPermission( - SecurityConstants.MODIFY_THREADGROUP_PERMISSION); - } - - // Get a snapshot of the list of all threads - Thread[] threads = getThreads(); - StackTraceElement[][] traces = dumpThreads(threads); - Map m = new HashMap<>(threads.length); - for (int i = 0; i < threads.length; i++) { - StackTraceElement[] stackTrace = traces[i]; - if (stackTrace != null) { - m.put(threads[i], stackTrace); - } - // else terminated so we don't put it in the map - } - return m; - } - - - private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION = - new RuntimePermission("enableContextClassLoaderOverride"); - - /** cache of subclass security audit results */ - /* Replace with ConcurrentReferenceHashMap when/if it appears in a future - * release */ - private static class Caches { - /** cache of subclass security audit results */ - static final ConcurrentMap subclassAudits = - new ConcurrentHashMap<>(); - - /** queue for WeakReferences to audited subclasses */ - static final ReferenceQueue> subclassAuditsQueue = - new ReferenceQueue<>(); - } - - /** - * Verifies that this (possibly subclass) instance can be constructed - * without violating security constraints: the subclass must not override - * security-sensitive non-final methods, or else the - * "enableContextClassLoaderOverride" RuntimePermission is checked. - */ - @cli.System.Runtime.CompilerServices.MethodImplAttribute.Annotation(value = cli.System.Runtime.CompilerServices.MethodImplOptions.__Enum.NoInlining) - private static native boolean isCCLOverridden(Thread thread); // [IKVM] implemented in map.xml - - private static boolean isCCLOverridden(Class cl) { - if (cl == Thread.class) - return false; - - processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); - WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); - Boolean result = Caches.subclassAudits.get(key); - if (result == null) { - result = Boolean.valueOf(auditSubclass(cl)); - Caches.subclassAudits.putIfAbsent(key, result); - } - - return result.booleanValue(); - } - - /** - * Performs reflective checks on given subclass to verify that it doesn't - * override security-sensitive non-final methods. Returns true if the - * subclass overrides any of the methods, false otherwise. - */ - private static boolean auditSubclass(final Class subcl) { - Boolean result = AccessController.doPrivileged( - new PrivilegedAction() { - public Boolean run() { - for (Class cl = subcl; - cl != Thread.class; - cl = cl.getSuperclass()) - { - try { - cl.getDeclaredMethod("getContextClassLoader", new Class[0]); - return Boolean.TRUE; - } catch (NoSuchMethodException ex) { - } - try { - Class[] params = {ClassLoader.class}; - cl.getDeclaredMethod("setContextClassLoader", params); - return Boolean.TRUE; - } catch (NoSuchMethodException ex) { - } - } - return Boolean.FALSE; - } - } - ); - return result.booleanValue(); - } - - private static StackTraceElement[][] dumpThreads(Thread[] threads) { - StackTraceElement[][] stacks = new StackTraceElement[threads.length][]; - for (int i = 0; i < threads.length; i++) { - cli.System.Threading.Thread nativeThread = threads[i].nativeThread; - if (nativeThread == null) { - stacks[i] = new StackTraceElement[0]; - } else { - try { - if (false) throw new cli.System.Threading.ThreadStateException(); - boolean suspended = false; - if ((nativeThread.get_ThreadState().Value & cli.System.Threading.ThreadState.Suspended) == 0 && nativeThread != cli.System.Threading.Thread.get_CurrentThread()) { - suspended = true; - nativeThread.Suspend(); - } - cli.System.Diagnostics.StackTrace stack; - try { - stack = new cli.System.Diagnostics.StackTrace(nativeThread, true); - } - finally { - if (suspended) { - nativeThread.Resume(); - } - } - stacks[i] = getStackTrace(stack); - } - catch (cli.System.Threading.ThreadStateException _) { - stacks[i] = new StackTraceElement[0]; - } - } - } - return stacks; - } - - private static native StackTraceElement[] getStackTrace(cli.System.Diagnostics.StackTrace stack); - - private static native Thread[] getThreads(); - - /** - * Returns the identifier of this Thread. The thread ID is a positive - * long number generated when this thread was created. - * The thread ID is unique and remains unchanged during its lifetime. - * When a thread is terminated, this thread ID may be reused. - * - * @return this thread's ID. - * @since 1.5 - */ - public long getId() { - return tid; - } - - /** - * A thread state. A thread can be in one of the following states: - *

    - *
  • {@link #NEW}
    - * A thread that has not yet started is in this state. - *
  • - *
  • {@link #RUNNABLE}
    - * A thread executing in the Java virtual machine is in this state. - *
  • - *
  • {@link #BLOCKED}
    - * A thread that is blocked waiting for a monitor lock - * is in this state. - *
  • - *
  • {@link #WAITING}
    - * A thread that is waiting indefinitely for another thread to - * perform a particular action is in this state. - *
  • - *
  • {@link #TIMED_WAITING}
    - * A thread that is waiting for another thread to perform an action - * for up to a specified waiting time is in this state. - *
  • - *
  • {@link #TERMINATED}
    - * A thread that has exited is in this state. - *
  • - *
- * - *

- * A thread can be in only one state at a given point in time. - * These states are virtual machine states which do not reflect - * any operating system thread states. - * - * @since 1.5 - * @see #getState - */ - public enum State { - /** - * Thread state for a thread which has not yet started. - */ - NEW, - - /** - * Thread state for a runnable thread. A thread in the runnable - * state is executing in the Java virtual machine but it may - * be waiting for other resources from the operating system - * such as processor. - */ - RUNNABLE, - - /** - * Thread state for a thread blocked waiting for a monitor lock. - * A thread in the blocked state is waiting for a monitor lock - * to enter a synchronized block/method or - * reenter a synchronized block/method after calling - * {@link Object#wait() Object.wait}. - */ - BLOCKED, - - /** - * Thread state for a waiting thread. - * A thread is in the waiting state due to calling one of the - * following methods: - *

    - *
  • {@link Object#wait() Object.wait} with no timeout
  • - *
  • {@link #join() Thread.join} with no timeout
  • - *
  • {@link LockSupport#park() LockSupport.park}
  • - *
- * - *

A thread in the waiting state is waiting for another thread to - * perform a particular action. - * - * For example, a thread that has called Object.wait() - * on an object is waiting for another thread to call - * Object.notify() or Object.notifyAll() on - * that object. A thread that has called Thread.join() - * is waiting for a specified thread to terminate. - */ - WAITING, - - /** - * Thread state for a waiting thread with a specified waiting time. - * A thread is in the timed waiting state due to calling one of - * the following methods with a specified positive waiting time: - *

    - *
  • {@link #sleep Thread.sleep}
  • - *
  • {@link Object#wait(long) Object.wait} with timeout
  • - *
  • {@link #join(long) Thread.join} with timeout
  • - *
  • {@link LockSupport#parkNanos LockSupport.parkNanos}
  • - *
  • {@link LockSupport#parkUntil LockSupport.parkUntil}
  • - *
- */ - TIMED_WAITING, - - /** - * Thread state for a terminated thread. - * The thread has completed execution. - */ - TERMINATED; - } - - /** - * Returns the state of this thread. - * This method is designed for use in monitoring of the system state, - * not for synchronization control. - * - * @return this thread's state. - * @since 1.5 - */ - public State getState() { - // get current thread state - switch (threadStatus) { - case 0: - return State.NEW; - case 0x0002: - return State.TERMINATED; - } - synchronized (lock) { - if (interruptableWait) { - // NOTE if objectWait has satisfied the wait condition (or has been interrupted or has timed-out), - // it can be blocking on the re-acquire of the monitor, but we have no way of detecting that. - return timedWait ? State.TIMED_WAITING : State.WAITING; - } - } - cli.System.Threading.Thread nativeThread = this.nativeThread; - if (nativeThread == null) { - return State.TERMINATED; - } - if ((nativeThread.get_ThreadState().Value & cli.System.Threading.ThreadState.WaitSleepJoin) != 0) { - return State.BLOCKED; - } - return State.RUNNABLE; - } - - // Added in JSR-166 - - /** - * Interface for handlers invoked when a Thread abruptly - * terminates due to an uncaught exception. - *

When a thread is about to terminate due to an uncaught exception - * the Java Virtual Machine will query the thread for its - * UncaughtExceptionHandler using - * {@link #getUncaughtExceptionHandler} and will invoke the handler's - * uncaughtException method, passing the thread and the - * exception as arguments. - * If a thread has not had its UncaughtExceptionHandler - * explicitly set, then its ThreadGroup object acts as its - * UncaughtExceptionHandler. If the ThreadGroup object - * has no - * special requirements for dealing with the exception, it can forward - * the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler - * default uncaught exception handler}. - * - * @see #setDefaultUncaughtExceptionHandler - * @see #setUncaughtExceptionHandler - * @see ThreadGroup#uncaughtException - * @since 1.5 - */ - public interface UncaughtExceptionHandler { - /** - * Method invoked when the given thread terminates due to the - * given uncaught exception. - *

Any exception thrown by this method will be ignored by the - * Java Virtual Machine. - * @param t the thread - * @param e the exception - */ - void uncaughtException(Thread t, Throwable e); - } - - // null unless explicitly set - private volatile UncaughtExceptionHandler uncaughtExceptionHandler; - - // null unless explicitly set - private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler; - - /** - * Set the default handler invoked when a thread abruptly terminates - * due to an uncaught exception, and no other handler has been defined - * for that thread. - * - *

Uncaught exception handling is controlled first by the thread, then - * by the thread's {@link ThreadGroup} object and finally by the default - * uncaught exception handler. If the thread does not have an explicit - * uncaught exception handler set, and the thread's thread group - * (including parent thread groups) does not specialize its - * uncaughtException method, then the default handler's - * uncaughtException method will be invoked. - *

By setting the default uncaught exception handler, an application - * can change the way in which uncaught exceptions are handled (such as - * logging to a specific device, or file) for those threads that would - * already accept whatever "default" behavior the system - * provided. - * - *

Note that the default uncaught exception handler should not usually - * defer to the thread's ThreadGroup object, as that could cause - * infinite recursion. - * - * @param eh the object to use as the default uncaught exception handler. - * If null then there is no default handler. - * - * @throws SecurityException if a security manager is present and it - * denies {@link RuntimePermission} - * ("setDefaultUncaughtExceptionHandler") - * - * @see #setUncaughtExceptionHandler - * @see #getUncaughtExceptionHandler - * @see ThreadGroup#uncaughtException - * @since 1.5 - */ - public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission( - new RuntimePermission("setDefaultUncaughtExceptionHandler") - ); - } - - defaultUncaughtExceptionHandler = eh; - } - - /** - * Returns the default handler invoked when a thread abruptly terminates - * due to an uncaught exception. If the returned value is null, - * there is no default. - * @since 1.5 - * @see #setDefaultUncaughtExceptionHandler - */ - public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){ - return defaultUncaughtExceptionHandler; - } - - /** - * Returns the handler invoked when this thread abruptly terminates - * due to an uncaught exception. If this thread has not had an - * uncaught exception handler explicitly set then this thread's - * ThreadGroup object is returned, unless this thread - * has terminated, in which case null is returned. - * @since 1.5 - */ - public UncaughtExceptionHandler getUncaughtExceptionHandler() { - return uncaughtExceptionHandler != null ? - uncaughtExceptionHandler : group; - } - - /** - * Set the handler invoked when this thread abruptly terminates - * due to an uncaught exception. - *

A thread can take full control of how it responds to uncaught - * exceptions by having its uncaught exception handler explicitly set. - * If no such handler is set then the thread's ThreadGroup - * object acts as its handler. - * @param eh the object to use as this thread's uncaught exception - * handler. If null then this thread has no explicit handler. - * @throws SecurityException if the current thread is not allowed to - * modify this thread. - * @see #setDefaultUncaughtExceptionHandler - * @see ThreadGroup#uncaughtException - * @since 1.5 - */ - public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) { - checkAccess(); - uncaughtExceptionHandler = eh; - } - - /** - * Dispatch an uncaught exception to the handler. This method is - * intended to be called only by the JVM. - */ - private void dispatchUncaughtException(Throwable e) { - getUncaughtExceptionHandler().uncaughtException(this, e); - } - - /** - * Removes from the specified map any keys that have been enqueued - * on the specified reference queue. - */ - static void processQueue(ReferenceQueue> queue, - ConcurrentMap>, ?> map) - { - Reference> ref; - while((ref = queue.poll()) != null) { - map.remove(ref); - } - } - - /** - * Weak key for Class objects. - **/ - static class WeakClassKey extends WeakReference> { - /** - * saved value of the referent's identity hash code, to maintain - * a consistent hash code after the referent has been cleared - */ - private final int hash; - - /** - * Create a new WeakClassKey to the given object, registered - * with a queue. - */ - WeakClassKey(Class cl, ReferenceQueue> refQueue) { - super(cl, refQueue); - hash = System.identityHashCode(cl); - } - - /** - * Returns the identity hash code of the original referent. - */ - @Override - public int hashCode() { - return hash; - } - - /** - * Returns true if the given object is this identical - * WeakClassKey instance, or, if this object's referent has not - * been cleared, if the given object is another WeakClassKey - * instance with the identical non-null referent as this one. - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - - if (obj instanceof WeakClassKey) { - Object referent = get(); - return (referent != null) && - (referent == ((WeakClassKey) obj).get()); - } else { - return false; - } - } - } - - /* Some private helper methods */ - private synchronized void setPriority0(int newPriority) { - cli.System.Threading.Thread nativeThread = this.nativeThread; - if (nativeThread != null) { - try { - if (false) throw new cli.System.Threading.ThreadStateException(); - nativeThread.set_Priority(cli.System.Threading.ThreadPriority.wrap(mapJavaPriorityToClr(newPriority))); - } - catch (cli.System.Threading.ThreadStateException _) { - } - } - } - - private void stop0(Throwable x) { - synchronized (lock) { - if (!running) { - stillborn = x; - x = null; - } - } - if (x != null) { - // NOTE we allow ThreadDeath (and its subclasses) to be thrown on every thread, but any - // other exception is ignored, except if we're throwing it on the current Thread. This - // is done to allow exception handlers to be type specific, otherwise every exception - // handler would have to catch ThreadAbortException and look inside it to see if it - // contains the real exception that we wish to handle. - // I hope we can get away with this behavior, because Thread.stop() is deprecated - // anyway. Note that we do allow arbitrary exceptions to be thrown on the current - // thread, since this is harmless (because they aren't wrapped) and also because it - // provides some real value, because it is one of the ways you can throw arbitrary checked - // exceptions from Java. - if (this == current) { - sun.misc.Unsafe.getUnsafe().throwException(x); - } - else if (x instanceof ThreadDeath) { - cli.System.Threading.Thread nativeThread = this.nativeThread; - if (nativeThread == null) { - return; - } - try { - if (false) throw new cli.System.Threading.ThreadStateException(); - nativeThread.Abort(x); - } - catch (cli.System.Threading.ThreadStateException _) { - // .NET 2.0 throws a ThreadStateException if the target thread is currently suspended - // (but it does record the Abort request) - } - try { - if (false) throw new cli.System.Threading.ThreadStateException(); - int suspend = cli.System.Threading.ThreadState.Suspended | cli.System.Threading.ThreadState.SuspendRequested; - while ((nativeThread.get_ThreadState().Value & suspend) != 0) { - nativeThread.Resume(); - } - } - catch (cli.System.Threading.ThreadStateException _) { - } - } - } - } - - private void suspend0() { - try { - if (false) throw new cli.System.Threading.ThreadStateException(); - cli.System.Threading.Thread nativeThread = this.nativeThread; - if (nativeThread != null) { - nativeThread.Suspend(); - } - } - catch (cli.System.Threading.ThreadStateException _) { - } - } - - private void resume0() { - try { - if (false) throw new cli.System.Threading.ThreadStateException(); - cli.System.Threading.Thread nativeThread = this.nativeThread; - if (nativeThread != null) { - nativeThread.Resume(); - } - } - catch (cli.System.Threading.ThreadStateException _) { - } - } - - private void interrupt0() { - synchronized (lock) { - // if the thread hasn't been started yet or has been terminated, the interrupt is ignored - // (like on the reference implementation) - if (nativeThread == null) { - return; - } - if (!interruptPending) { - interruptPending = true; - if (interruptableWait) { - nativeInterruptPending = true; - nativeThread.Interrupt(); - } - } - } - } - - private void setRunningAndCheckStillborn() throws Throwable { - Throwable x; - synchronized (lock) { - running = true; - x = stillborn; - stillborn = null; - } - if (x != null) { - throw x; - } - } - - // [IKVM] this the entry point of thread started from Java - @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation - void threadProc() { - current = this; - try { - // the body of the try block is in another method to allow the (limited) try/finally optimizer - // to properly recognize the try/finally block, because we want to make sure that die() - // runs in a finally block to prevent it from being asynchronously aborted. - threadProc2(); - } - finally { - die(); - } - } - - @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation - private void threadProc2() { - try { - setRunningAndCheckStillborn(); - run(); - } - catch (Throwable x) { - try { - getUncaughtExceptionHandler().uncaughtException(this, x); - } - catch (Throwable _) { - } - } - } - - // [IKVM] this the implementation of Object.wait(long timeout, int nanos). It is hooked up in map.xml. - static void objectWait(Object o, long timeout, int nanos) throws InterruptedException { - if (o == null) { - throw new NullPointerException(); - } - if (timeout < 0) { - throw new IllegalArgumentException("timeout value is negative"); - } - if (nanos < 0 || nanos > 999999) { - throw new IllegalArgumentException("nanosecond timeout value out of range"); - } - if (nanos >= 500000 || (nanos != 0 && timeout == 0)) { - timeout++; - } - objectWait(o, timeout); - } - - // [IKVM] this the implementation of Object.wait(long timeout). It is hooked up in map.xml. - static void objectWait(Object o, long timeout) throws InterruptedException { - if (o == null) { - throw new NullPointerException(); - } - if (timeout < 0) { - throw new IllegalArgumentException("timeout value is negative"); - } - Thread t = currentThread(); - t.enterInterruptableWait(timeout != 0); - try { - if (false) throw new cli.System.Threading.ThreadInterruptedException(); - if (timeout == 0 || timeout > 922337203685476L) { - cli.System.Threading.Monitor.Wait(o); - } - else { - // We wait a maximum of Integer.MAX_VALUE milliseconds, because that is the maximum that Monitor.Wait will wait. - // Note that the Object.wait() specification allows for spurious wakeups, so this isn't a problem. Trying to - // emulate a longer wait with multiple Monitor.Wait() calls is not allowed, because that would mean that - // we acquire and release the synchronization lock multiple times during the wait. - cli.System.Threading.Monitor.Wait(o, (int)Math.min(timeout, Integer.MAX_VALUE)); - } - } - catch (cli.System.Threading.ThreadInterruptedException _) { - } - finally { - t.leaveInterruptableWait(); - } - } -} diff --git a/external/ikvm/openjdk/java/lang/Thread.java.REMOVED.git-id b/external/ikvm/openjdk/java/lang/Thread.java.REMOVED.git-id new file mode 100644 index 0000000000..3685fc66ec --- /dev/null +++ b/external/ikvm/openjdk/java/lang/Thread.java.REMOVED.git-id @@ -0,0 +1 @@ +7ab53c76bb97c702c39866643a2547962ef3ead6 \ No newline at end of file diff --git a/external/ikvm/openjdk/map.xml.REMOVED.git-id b/external/ikvm/openjdk/map.xml.REMOVED.git-id index b5b141299c..96001e9c28 100644 --- a/external/ikvm/openjdk/map.xml.REMOVED.git-id +++ b/external/ikvm/openjdk/map.xml.REMOVED.git-id @@ -1 +1 @@ -33393ac257cbddfb25bbbbef28c2d70a939dcc57 \ No newline at end of file +df6a641f2325337bd9354a4d23537dc48a60d0ee \ No newline at end of file diff --git a/external/ikvm/openjdk/openjdk.build b/external/ikvm/openjdk/openjdk.build index 37f23b2d57..41e2382e28 100644 --- a/external/ikvm/openjdk/openjdk.build +++ b/external/ikvm/openjdk/openjdk.build @@ -1,16 +1,42 @@ + - - + + + + + - + @@ -26,7 +52,7 @@ - + @@ -70,27 +96,38 @@ - + - + + + + + + + + + + + + @@ -99,20 +136,33 @@ + + + + + + + + + + + + + @@ -122,14 +172,28 @@ - + + + + + + + + + + + + + + - - - - + + + + + @@ -147,10 +211,30 @@ + + + + + + + + + + + + + + + + + + + + - + @@ -158,7 +242,7 @@ - + @@ -169,7 +253,7 @@ --> - + @@ -177,13 +261,42 @@ - + - + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + @@ -192,13 +305,35 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + @@ -217,6 +352,8 @@ + + @@ -225,11 +362,14 @@ + + + @@ -268,7 +408,7 @@ - + @@ -280,6 +420,8 @@ + + @@ -300,9 +442,14 @@ - + + + + + + diff --git a/external/ikvm/openjdk/response.txt b/external/ikvm/openjdk/response.txt deleted file mode 100644 index f7d9471db2..0000000000 --- a/external/ikvm/openjdk/response.txt +++ /dev/null @@ -1,1116 +0,0 @@ -# -# Copyright (C) 2002-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 -# - -assembly.class -{ - -out:IKVM.OpenJDK.Core.dll - -baseaddress:0x56000000 - -remap:map.xml - -exclude:exclude.lst - -resource:META-INF/MANIFEST.MF=MANIFEST.MF - -resource:java/lang/uniName.dat=@OPENJDK7@/build/linux-amd64/classes/java/lang/uniName.dat - -resource:sun/net/idn/uidna.spp=@OPENJDK7@/build/linux-amd64/classes/sun/net/idn/uidna.spp - ikvm/internal/*.class - java/io/*.class - java/lang/*.class - java/lang/invoke/*.class - java/lang/ref/*.class - java/lang/reflect/*.class - java/net/*.class - java/nio/*.class - java/security/*.class - java/util/*.class - java/util/concurrent/locks/*.class - gnu/java/util/*.class - sun/misc/*.class - sun/net/sdp/*.class - sun/net/www/protocol/file/*.class - sun/net/www/protocol/ikvmres/*.class - sun/net/www/protocol/jar/*.class - sun/nio/ch/*.class - sun/nio/cs/*.class - sun/nio/fs/*.class - sun/reflect/*.class - sun/reflect/misc/*.class - ../classpath/gnu/java/net/protocol/ikvmres/*.class - ../classpath/ikvm/extensions/*.class - ../classpath/ikvm/internal/*.class - ../classpath/ikvm/io/*.class - ../classpath/ikvm/lang/*.class - ../classpath/ikvm/runtime/*.class - ../classpath/java/util/concurrent/atomic/*.class - ../classpath/sun/misc/*.class - @OPENJDK7@/build/linux-amd64/gensrc/java/lang/*.class - @OPENJDK7@/build/linux-amd64/gensrc/java/nio/*.class - @OPENJDK7@/build/linux-amd64/gensrc/java/nio/channels/*.class - @OPENJDK7@/build/linux-amd64/gensrc/java/nio/charset/*.class - @OPENJDK7@/build/linux-amd64/gensrc/sun/nio/cs/*.class - @OPENJDK7@/build/linux-amd64/gensrc/sun/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/istack/internal/logging/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/developer/ServerSideException.class - @OPENJDK7@/jdk/src/share/classes/com/sun/nio/file/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/nio/sctp/*.class - @OPENJDK7@/jdk/src/share/classes/java/beans/ChangeListenerMap.class - @OPENJDK7@/jdk/src/share/classes/java/beans/IndexedPropertyChangeEvent.class - @OPENJDK7@/jdk/src/share/classes/java/beans/PropertyChangeEvent.class - @OPENJDK7@/jdk/src/share/classes/java/beans/PropertyChangeListener.class - @OPENJDK7@/jdk/src/share/classes/java/beans/PropertyChangeListenerProxy.class - @OPENJDK7@/jdk/src/share/classes/java/beans/PropertyChangeSupport*.class - @OPENJDK7@/jdk/src/share/classes/java/io/*.class - @OPENJDK7@/jdk/src/share/classes/java/lang/*.class - @OPENJDK7@/jdk/src/share/classes/java/lang/annotation/*.class - @OPENJDK7@/jdk/src/share/classes/java/lang/invoke/*.class - @OPENJDK7@/jdk/src/share/classes/java/lang/ref/*.class - @OPENJDK7@/jdk/src/share/classes/java/lang/reflect/*.class - @OPENJDK7@/jdk/src/share/classes/java/math/*.class - @OPENJDK7@/jdk/src/share/classes/java/net/*.class - @OPENJDK7@/jdk/src/share/classes/java/nio/*.class - @OPENJDK7@/jdk/src/share/classes/java/nio/channels/*.class - @OPENJDK7@/jdk/src/share/classes/java/nio/channels/spi/*.class - @OPENJDK7@/jdk/src/share/classes/java/nio/charset/*.class - @OPENJDK7@/jdk/src/share/classes/java/nio/charset/spi/*.class - @OPENJDK7@/jdk/src/share/classes/java/nio/file/*.class - @OPENJDK7@/jdk/src/share/classes/java/nio/file/attribute/*.class - @OPENJDK7@/jdk/src/share/classes/java/nio/file/spi/*.class - @OPENJDK7@/jdk/src/share/classes/java/security/*.class - @OPENJDK7@/jdk/src/share/classes/java/security/cert/*.class - @OPENJDK7@/jdk/src/share/classes/java/sql/Timestamp.class - @OPENJDK7@/jdk/src/share/classes/java/util/*.class - @OPENJDK7@/jdk/src/share/classes/java/util/concurrent/*.class - @OPENJDK7@/jdk/src/share/classes/java/util/concurrent/atomic/*.class - @OPENJDK7@/jdk/src/share/classes/java/util/concurrent/locks/*.class - @OPENJDK7@/jdk/src/share/classes/java/util/jar/Attributes*.class - @OPENJDK7@/jdk/src/share/classes/java/util/jar/Manifest*.class - @OPENJDK7@/jdk/src/share/classes/java/util/regex/*.class - @OPENJDK7@/jdk/src/share/classes/javax/net/*.class - @OPENJDK7@/jdk/src/share/classes/sun/invoke/*.class - @OPENJDK7@/jdk/src/share/classes/sun/invoke/anon/*.class - @OPENJDK7@/jdk/src/share/classes/sun/invoke/empty/*.class - @OPENJDK7@/jdk/src/share/classes/sun/invoke/util/*.class - @OPENJDK7@/jdk/src/share/classes/sun/misc/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/ftp/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/ftp/impl/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/idn/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/smtp/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/spi/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/spi/nameservice/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/util/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/content/text/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/http/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/protocol/ftp/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/protocol/http/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/protocol/http/logging/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/protocol/http/spnego/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/protocol/jar/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/protocol/mailto/*.class - @OPENJDK7@/jdk/src/share/classes/sun/nio/*.class - @OPENJDK7@/jdk/src/share/classes/sun/nio/ch/*.class - @OPENJDK7@/jdk/src/share/classes/sun/nio/cs/*.class - @OPENJDK7@/jdk/src/share/classes/sun/nio/fs/*.class - @OPENJDK7@/jdk/src/share/classes/sun/reflect/*.class - @OPENJDK7@/jdk/src/share/classes/sun/reflect/annotation/*.class - @OPENJDK7@/jdk/src/share/classes/sun/reflect/generics/factory/*.class - @OPENJDK7@/jdk/src/share/classes/sun/reflect/generics/parser/*.class - @OPENJDK7@/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/*.class - @OPENJDK7@/jdk/src/share/classes/sun/reflect/generics/repository/*.class - @OPENJDK7@/jdk/src/share/classes/sun/reflect/generics/scope/*.class - @OPENJDK7@/jdk/src/share/classes/sun/reflect/generics/tree/*.class - @OPENJDK7@/jdk/src/share/classes/sun/reflect/generics/visitor/*.class - @OPENJDK7@/jdk/src/share/classes/sun/reflect/misc/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/action/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/jca/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/provider/ByteArrayAccess.class - @OPENJDK7@/jdk/src/share/classes/sun/security/provider/DigestBase.class - @OPENJDK7@/jdk/src/share/classes/sun/security/provider/SHA.class - @OPENJDK7@/jdk/src/share/classes/sun/security/provider/Sun.class - @OPENJDK7@/jdk/src/share/classes/sun/security/provider/SunEntries$1.class - @OPENJDK7@/jdk/src/share/classes/sun/security/provider/SunEntries.class - @OPENJDK7@/jdk/src/share/classes/sun/security/util/Debug.class - @OPENJDK7@/jdk/src/share/classes/sun/security/util/PermissionFactory.class - @OPENJDK7@/jdk/src/share/classes/sun/security/util/PropertyExpander$ExpandException.class - @OPENJDK7@/jdk/src/share/classes/sun/security/util/PropertyExpander.class - @OPENJDK7@/jdk/src/share/classes/sun/security/util/SecurityConstants*.class - @OPENJDK7@/jdk/src/share/classes/sun/util/*.class - @OPENJDK7@/jdk/src/share/classes/sun/util/locale/*.class - @OPENJDK7@/jdk/src/share/classes/sun/util/logging/*.class - @OPENJDK7@/jdk/src/solaris/classes/java/io/*.class - @OPENJDK7@/jdk/src/solaris/classes/sun/net/www/protocol/http/ntlm/*.class - @OPENJDK7@/jdk/src/windows/classes/java/io/*.class - @OPENJDK7@/jdk/src/windows/classes/java/lang/*.class - @OPENJDK7@/jdk/src/windows/classes/java/net/DefaultInterface.class - @OPENJDK7@/jdk/src/windows/classes/sun/net/*.class - @OPENJDK7@/jdk/src/windows/classes/sun/nio/ch/*.class - @OPENJDK7@/jdk/src/windows/classes/sun/nio/fs/*.class - @OPENJDK7@/jdk/src/windows/classes/sun/security/provider/NativePRNG.class -} -{ - -out:IKVM.OpenJDK.Corba.dll - -baseaddress:0x56C60000 - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/corba/* - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/jndi/cosnaming/jndiprovider.properties - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/activation/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/copyobject/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/corba/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/dynamicany/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/encoding/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/interceptors/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/io/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/ior/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/ior/iiop/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/javax/rmi/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/javax/rmi/CORBA/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/legacy/connection/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/logging/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/monitoring/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/naming/cosnaming/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/naming/namingutil/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/naming/pcosnaming/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/oa/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/oa/poa/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/oa/toa/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/orb/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/orbutil/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/orbutil/closure/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/orbutil/concurrent/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/orbutil/fsm/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/orbutil/graph/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/orbutil/threadpool/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/presentation/rmi/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/protocol/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/protocol/giopmsgheaders/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/resolver/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/transport/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/internal/corba/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/internal/CosNaming/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/internal/iiop/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/internal/Interceptors/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/internal/POA/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/org/omg/CORBA/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/pept/broker/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/pept/encoding/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/pept/protocol/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/pept/transport/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/PortableActivationIDL/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/PortableActivationIDL/InitialNameServicePackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/PortableActivationIDL/LocatorPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/PortableActivationIDL/RepositoryPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/activation/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/activation/InitialNameServicePackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/activation/LocatorPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/activation/RepositoryPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/copyobject/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/encoding/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/extension/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/ior/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/ior/iiop/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/legacy/connection/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/legacy/interceptor/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/logging/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/monitoring/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/oa/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/orb/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/orbutil/closure/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/orbutil/fsm/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/orbutil/proxy/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/orbutil/threadpool/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/presentation/rmi/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/protocol/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/resolver/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/servicecontext/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/spi/transport/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/omg/CORBA/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/omg/CORBA/portable/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/omg/CORBA/ValueDefPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/omg/SendingContext/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/omg/SendingContext/CodeBasePackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/rmi/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/rmi/CORBA/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/CORBA/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/CORBA/DynAnyPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/CORBA/ORBPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/CORBA/portable/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/CORBA/TypeCodePackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/CORBA_2_3/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/CORBA_2_3/portable/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/CosNaming/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/CosNaming/NamingContextExtPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/CosNaming/NamingContextPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/Dynamic/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/DynamicAny/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/DynamicAny/DynAnyFactoryPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/DynamicAny/DynAnyPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/IOP/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/IOP/CodecFactoryPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/IOP/CodecPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/Messaging/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/PortableInterceptor/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/PortableInterceptor/ORBInitInfoPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/PortableServer/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/PortableServer/CurrentPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/PortableServer/POAManagerPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/PortableServer/POAPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/PortableServer/portable/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/PortableServer/ServantLocatorPackage/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/SendingContext/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/omg/stub/java/rmi/*.class - @OPENJDK7@/build/linux-amd64/impsrc/sun/corba/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/cosnaming/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/toolkit/corba/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/url/corbaname/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/url/iiop/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/url/iiopname/*.class -} -{ - -out:IKVM.OpenJDK.XML.API.dll - -baseaddress:0x572C0000 - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/datatype/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/namespace/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/parsers/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/stream/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/stream/events/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/stream/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/transform/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/transform/dom/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/transform/sax/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/transform/stax/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/transform/stream/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/validation/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/xpath/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/w3c/dom/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/w3c/dom/bootstrap/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/w3c/dom/css/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/w3c/dom/events/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/w3c/dom/html/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/w3c/dom/ls/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/w3c/dom/ranges/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/w3c/dom/stylesheets/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/w3c/dom/traversal/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/w3c/dom/views/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/w3c/dom/xpath/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/xml/sax/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/xml/sax/ext/*.class - @OPENJDK7@/build/linux-amd64/impsrc/org/xml/sax/helpers/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/java/browser/dom/*.class -} -{ - -out:IKVM.OpenJDK.XML.XPath.dll - -baseaddress:0x57380000 - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xalan/internal/res/* - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/extensions/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/res/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/dtm/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/dtm/ref/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/dtm/ref/dom2dtm/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/dtm/ref/sax2dtm/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/utils/AttList.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/utils/DOMHelper.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/utils/DOM2Helper.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/utils/TreeWalker.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xpath/internal/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xpath/internal/axes/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xpath/internal/compiler/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xpath/internal/domapi/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xpath/internal/functions/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xpath/internal/jaxp/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xpath/internal/objects/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xpath/internal/operations/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xpath/internal/patterns/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xpath/internal/res/*.class -} -{ - -out:IKVM.OpenJDK.XML.Parse.dll - -baseaddress:0x576E0000 - -resource:com/sun/org/apache/xml/internal/serialize/HTMLEntities.res=@OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/serialize/HTMLEntities.res - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xerces/* - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xml/internal/serializer/* - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/utils/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/dom/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/dom/events/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/dtd/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/dtd/models/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/dv/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/dv/dtd/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/dv/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/dv/xs/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/io/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/msg/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/validation/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/xpath/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/xpath/regex/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/xs/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/xs/identity/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/xs/models/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/xs/opti/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/xs/traversers/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/impl/xs/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/jaxp/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/jaxp/datatype/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/jaxp/validation/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/parsers/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/utils/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/xinclude/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/xni/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/xni/grammars/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/xni/parser/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/xpointer/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/xs/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xerces/internal/xs/datatypes/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/res/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/resolver/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/resolver/helpers/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/resolver/readers/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/resolver/tools/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/serialize/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/serializer/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/serializer/utils/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/utils/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/utils/res/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/org/jvnet/staxex/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/stream/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/stream/buffer/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/stream/buffer/sax/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/stream/buffer/stax/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/stream/dtd/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/stream/dtd/nonvalidating/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/stream/events/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/stream/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/stream/writers/*.class -} -{ - -out:IKVM.OpenJDK.XML.Transform.dll - -baseaddress:0x57E90000 - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/java_cup/internal/runtime/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/classfile/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/generic/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/regexp/internal/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/lib/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/templates/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/xslt/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/xsltc/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/xsltc/cmdline/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/xsltc/cmdline/getopt/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/xsltc/compiler/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/xsltc/compiler/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/xsltc/dom/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/xsltc/runtime/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/xsltc/runtime/output/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/xsltc/trax/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/xsltc/util/*.class -} -{ - -out:IKVM.OpenJDK.XML.Bind.dll - -baseaddress:0x582B0000 - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/javax/xml/bind/* - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/bind/* - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/fastinfoset/* - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/istack/internal/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/istack/internal/localization/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/annotation/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/api/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/api/impl/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/marshaller/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/unmarshaller/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/bytecode/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/model/annotation/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/model/core/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/model/impl/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/model/nav/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/model/runtime/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/runtime/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/runtime/output/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/runtime/property/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/runtime/reflect/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/runtime/reflect/opt/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/runtime/unmarshaller/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/schemagen/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/schemagen/episode/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/schemagen/xmlschema/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/bind/v2/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/algorithm/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/alphabet/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/dom/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/org/apache/xerces/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/sax/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/stax/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/stax/events/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/stax/factory/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/stax/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/tools/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/fastinfoset/vocab/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/org/jvnet/fastinfoset/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/org/jvnet/fastinfoset/sax/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/org/jvnet/fastinfoset/sax/helpers/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/org/jvnet/fastinfoset/stax/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/txw2/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/txw2/annotation/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/txw2/output/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/bind/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/bind/annotation/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/bind/annotation/adapters/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/bind/attachment/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/bind/helpers/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/bind/util/*.class -} -{ - -out:IKVM.OpenJDK.XML.WebServices.dll - -baseaddress:0x58610000 - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/messaging/* - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/ws/* - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/external/amx/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/external/arc/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/external/probe/provider/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/external/probe/provider/annotations/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/external/statistics/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/external/statistics/annotations/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/external/statistics/impl/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/gmbal/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/gmbal/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/client/p2p/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/packaging/mime/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/packaging/mime/internet/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/packaging/mime/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/soap/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/soap/dynamic/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/soap/impl/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/soap/name/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/soap/ver1_1/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/soap/ver1_2/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/util/transform/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/org/jvnet/mimepull/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/addressing/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/addressing/model/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/addressing/policy/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/addressing/v200408/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/addressing/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/client/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/config/management/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/config/management/policy/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/fastinfoset/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/ha/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/handler/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/message/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/message/stream/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/model/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/model/soap/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/model/wsdl/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/pipe/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/pipe/helper/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/policy/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/server/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/streaming/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/wsdl/parser/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/api/wsdl/writer/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/binding/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/client/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/client/dispatch/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/client/sei/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/config/management/policy/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/developer/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/encoding/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/encoding/fastinfoset/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/encoding/policy/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/encoding/soap/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/encoding/soap/streaming/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/encoding/xml/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/fault/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/handler/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/message/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/message/jaxb/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/message/saaj/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/message/source/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/message/stream/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/model/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/model/soap/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/model/wsdl/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/org/objectweb/asm/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/policy/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/policy/jaxws/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/policy/jaxws/spi/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/policy/privateutil/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/policy/sourcemodel/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/policy/sourcemodel/attach/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/policy/sourcemodel/wspolicy/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/policy/spi/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/policy/subject/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/protocol/soap/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/protocol/xml/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/resources/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/server/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/server/provider/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/server/sei/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/spi/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/streaming/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/transport/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/transport/http/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/transport/http/client/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/transport/http/server/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/util/exception/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/util/localization/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/util/pipe/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/util/xml/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/wsdl/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/wsdl/parser/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/wsdl/writer/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/wsdl/writer/document/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/wsdl/writer/document/http/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/wsdl/writer/document/soap/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/wsdl/writer/document/soap12/*.class - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/xml/internal/ws/wsdl/writer/document/xsd/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/soap/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/ws/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/ws/handler/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/ws/handler/soap/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/ws/http/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/ws/soap/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/ws/spi/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/ws/spi/http/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/ws/wsaddressing/*.class -} -{ - -out:IKVM.OpenJDK.XML.Crypto.dll - -baseaddress:0x58B80000 - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xml/internal/security/* - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/exceptions/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/signature/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/*.class - @OPENJDK7@/jdk/src/share/classes/javax/xml/crypto/*.class - @OPENJDK7@/jdk/src/share/classes/javax/xml/crypto/dom/*.class - @OPENJDK7@/jdk/src/share/classes/javax/xml/crypto/dsig/*.class - @OPENJDK7@/jdk/src/share/classes/javax/xml/crypto/dsig/dom/*.class - @OPENJDK7@/jdk/src/share/classes/javax/xml/crypto/dsig/keyinfo/*.class - @OPENJDK7@/jdk/src/share/classes/javax/xml/crypto/dsig/spec/*.class - @OPENJDK7@/jdk/src/share/classes/org/jcp/xml/dsig/internal/*.class - @OPENJDK7@/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/*.class -} -{ - -out:IKVM.OpenJDK.SwingAWT.dll - -baseaddress:0x58CD0000 - -remap:swingawt.xml - -resource:META-INF/services/sun.java2d.pipe.RenderingEngine=resources/META-INF/services/sun.java2d.pipe.RenderingEngine - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/sun.java2d.cmm.PCMM - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/java/swing/* - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/javax/swing/* - -recurse:resources.zip/com/sun/swing/internal/plaf/* - -recurse:resources.zip/com/sun/java/swing/plaf/* - -r:System.Drawing.dll - -r:IKVM.AWT.WinForms.dll - ikvm/awt/*.class - java/awt/*.class - java/awt/color/*.class - java/awt/image/*.class - gnu/java/awt/*.class - gnu/java/awt/color/*.class - sun/awt/*.class - sun/awt/image/*.class - sun/awt/shell/*.class - sun/font/*.class - sun/java2d/*.class - sun/java2d/cmm/lcms/*.class - sun/java2d/pipe/*.class - @OPENJDK7@/build/linux-amd64/gensrc/com/sun/accessibility/internal/resources/*.class - @OPENJDK7@/build/linux-amd64/gensrc/com/sun/java/swing/plaf/motif/resources/*.class - @OPENJDK7@/build/linux-amd64/gensrc/com/sun/java/swing/plaf/windows/resources/*.class - @OPENJDK7@/build/linux-amd64/gensrc/com/sun/swing/internal/plaf/basic/resources/*.class - @OPENJDK7@/build/linux-amd64/gensrc/com/sun/swing/internal/plaf/metal/resources/*.class - @OPENJDK7@/build/linux-amd64/gensrc/com/sun/swing/internal/plaf/synth/resources/*.class - @OPENJDK7@/build/linux-amd64/gensrc/javax/swing/plaf/nimbus/*.class - @OPENJDK7@/build/linux-amd64/gensrc/sun/awt/resources/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/awt/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/java/swing/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/java/swing/plaf/motif/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/java/swing/plaf/nimbus/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/java/swing/plaf/windows/*.class - @OPENJDK7@/jdk/src/share/classes/java/applet/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/color/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/datatransfer/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/dnd/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/dnd/peer/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/event/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/font/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/geom/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/im/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/im/spi/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/image/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/image/renderable/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/peer/*.class - @OPENJDK7@/jdk/src/share/classes/java/awt/print/*.class - @OPENJDK7@/jdk/src/share/classes/javax/accessibility/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/border/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/colorchooser/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/event/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/filechooser/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/plaf/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/plaf/basic/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/plaf/metal/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/plaf/multi/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/plaf/nimbus/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/plaf/synth/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/table/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/text/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/text/html/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/text/html/parser/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/text/rtf/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/tree/*.class - @OPENJDK7@/jdk/src/share/classes/javax/swing/undo/*.class - @OPENJDK7@/jdk/src/share/classes/sun/applet/*.class - @OPENJDK7@/jdk/src/share/classes/sun/awt/*.class - @OPENJDK7@/jdk/src/share/classes/sun/awt/datatransfer/*.class - @OPENJDK7@/jdk/src/share/classes/sun/awt/dnd/*.class - @OPENJDK7@/jdk/src/share/classes/sun/awt/event/*.class - @OPENJDK7@/jdk/src/share/classes/sun/awt/geom/*.class - @OPENJDK7@/jdk/src/share/classes/sun/awt/im/*.class - @OPENJDK7@/jdk/src/share/classes/sun/awt/image/*.class - @OPENJDK7@/jdk/src/share/classes/sun/awt/shell/*.class - @OPENJDK7@/jdk/src/share/classes/sun/awt/util/*.class - @OPENJDK7@/jdk/src/share/classes/sun/font/*.class - @OPENJDK7@/jdk/src/share/classes/sun/java2d/*.class - @OPENJDK7@/jdk/src/share/classes/sun/java2d/cmm/*.class - @OPENJDK7@/jdk/src/share/classes/sun/java2d/pipe/*.class - @OPENJDK7@/jdk/src/share/classes/sun/java2d/pipe/hw/*.class - @OPENJDK7@/jdk/src/share/classes/sun/java2d/pisces/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/content/image/*.class - @OPENJDK7@/jdk/src/share/classes/sun/swing/*.class - @OPENJDK7@/jdk/src/share/classes/sun/swing/icon/*.class - @OPENJDK7@/jdk/src/share/classes/sun/swing/plaf/*.class - @OPENJDK7@/jdk/src/share/classes/sun/swing/plaf/synth/*.class - @OPENJDK7@/jdk/src/share/classes/sun/swing/plaf/windows/*.class - @OPENJDK7@/jdk/src/share/classes/sun/swing/table/*.class - @OPENJDK7@/jdk/src/share/classes/sun/swing/text/*.class - @OPENJDK7@/jdk/src/share/classes/sun/swing/text/html/*.class - @OPENJDK7@/jdk/src/solaris/classes/sun/awt/windows/*.class - @OPENJDK7@/jdk/src/windows/classes/sun/awt/*.class -} -{ - -out:IKVM.OpenJDK.Charsets.dll - -baseaddress:0x59E70000 - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/charsets.jar/sun/nio/cs/ext/sjis0213.dat - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/charsets.jar/META-INF/services/java.nio.charset.spi.CharsetProvider - @OPENJDK7@/build/linux-amd64/gensrc/sun/nio/cs/ext/*.class - @OPENJDK7@/jdk/src/share/classes/sun/io/*.class - @OPENJDK7@/jdk/src/share/classes/sun/nio/cs/ext/*.class -} -{ - -out:IKVM.OpenJDK.Util.dll - -baseaddress:0x5A500000 - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/java/util/jar/pack/intrinsic.properties - -recurse:resources.zip/sun/launcher/resources/* - -resource:META-INF/services/java.nio.file.spi.FileSystemProvider=@OPENJDK7@/jdk/src/share/demo/nio/zipfs/src/META-INF/services/java.nio.file.spi.FileSystemProvider - java/util/zip/*.class - @OPENJDK7@/build/linux-amd64/gensrc/sun/util/logging/resources/*.class - @OPENJDK7@/build/linux-amd64/gensrc/sun/util/resources/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/java/browser/net/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/java/util/jar/pack/*.class - @OPENJDK7@/jdk/src/share/classes/java/util/jar/*.class - @OPENJDK7@/jdk/src/share/classes/java/util/logging/*.class - @OPENJDK7@/jdk/src/share/classes/java/util/prefs/*.class - @OPENJDK7@/jdk/src/share/classes/java/util/spi/*.class - @OPENJDK7@/jdk/src/share/classes/java/util/zip/*.class - @OPENJDK7@/jdk/src/share/classes/sun/launcher/*.class - @OPENJDK7@/jdk/src/share/classes/sun/util/calendar/*.class - @OPENJDK7@/jdk/src/share/classes/sun/util/resources/*.class - @OPENJDK7@/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/*.class - @OPENJDK7@/jdk/src/solaris/classes/java/util/prefs/*.class - @OPENJDK7@/jdk/src/windows/classes/java/util/prefs/*.class -} -{ - -out:IKVM.OpenJDK.Text.dll - -baseaddress:0x5AAD0000 - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/text/* - @OPENJDK7@/build/linux-amd64/j2re-image/lib/ext/localedata.jar - @OPENJDK7@/jdk/src/share/classes/java/text/*.class - @OPENJDK7@/jdk/src/share/classes/java/text/spi/*.class - @OPENJDK7@/jdk/src/share/classes/sun/text/*.class - @OPENJDK7@/jdk/src/share/classes/sun/text/bidi/*.class - @OPENJDK7@/jdk/src/share/classes/sun/text/normalizer/*.class - @OPENJDK7@/jdk/src/share/classes/sun/text/resources/*.class -} -{ - -out:IKVM.OpenJDK.Security.dll - -baseaddress:0x5AD40000 - -remap:security.xml - sun/security/jgss/wrapper/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/crypto/provider/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/net/ssl/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/net/ssl/internal/ssl/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/net/ssl/internal/www/protocol/https/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/auth/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/auth/callback/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/auth/login/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/auth/module/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/cert/internal/x509/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/jgss/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/ntlm/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/sasl/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/sasl/digest/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/sasl/gsskerb/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/sasl/ntlm/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/security/sasl/util/*.class - @OPENJDK7@/jdk/src/share/classes/java/security/acl/*.class - @OPENJDK7@/jdk/src/share/classes/java/security/interfaces/*.class - @OPENJDK7@/jdk/src/share/classes/java/security/spec/*.class - @OPENJDK7@/jdk/src/share/classes/javax/crypto/*.class - @OPENJDK7@/jdk/src/share/classes/javax/crypto/interfaces/*.class - @OPENJDK7@/jdk/src/share/classes/javax/crypto/spec/*.class - @OPENJDK7@/jdk/src/share/classes/javax/net/ssl/*.class - @OPENJDK7@/jdk/src/share/classes/javax/security/auth/*.class - @OPENJDK7@/jdk/src/share/classes/javax/security/auth/callback/*.class - @OPENJDK7@/jdk/src/share/classes/javax/security/auth/kerberos/*.class - @OPENJDK7@/jdk/src/share/classes/javax/security/auth/login/*.class - @OPENJDK7@/jdk/src/share/classes/javax/security/auth/spi/*.class - @OPENJDK7@/jdk/src/share/classes/javax/security/auth/x500/*.class - @OPENJDK7@/jdk/src/share/classes/javax/security/cert/*.class - @OPENJDK7@/jdk/src/share/classes/javax/security/sasl/*.class - @OPENJDK7@/jdk/src/share/classes/org/ietf/jgss/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/protocol/http/ntlm/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/protocol/https/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/acl/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/ec/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/internal/interfaces/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/internal/spec/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/jgss/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/jgss/krb5/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/jgss/spi/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/jgss/spnego/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/krb5/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/krb5/internal/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/krb5/internal/ccache/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/krb5/internal/crypto/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/krb5/internal/ktab/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/krb5/internal/rcache/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/krb5/internal/util/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/pkcs/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/pkcs12/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/provider/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/provider/certpath/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/provider/certpath/ldap/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/rsa/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/ssl/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/ssl/krb5/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/timestamp/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/tools/KeyStoreUtil.class - @OPENJDK7@/jdk/src/share/classes/sun/security/util/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/validator/*.class - @OPENJDK7@/jdk/src/share/classes/sun/security/x509/*.class - @OPENJDK7@/jdk/src/windows/classes/sun/security/krb5/internal/tools/*.class - @OPENJDK7@/jdk/src/windows/classes/sun/security/provider/*.class -} -{ - -out:IKVM.OpenJDK.Management.dll - -baseaddress:0x5B550000 - com/sun/management/*.class - java/lang/management/*.class - sun/management/*.class - @OPENJDK7@/build/linux-amd64/classes/javax/management/remote/rmi/*.class - @OPENJDK7@/build/linux-amd64/classes/org/omg/stub/javax/management/remote/rmi/*.class - @OPENJDK7@/build/linux-amd64/gensrc/sun/management/resources/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jmx/defaults/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jmx/interceptor/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jmx/mbeanserver/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jmx/remote/internal/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jmx/remote/protocol/iiop/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jmx/remote/protocol/rmi/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jmx/remote/security/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jmx/remote/util/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/management/*.class - @OPENJDK7@/jdk/src/share/classes/java/lang/management/*.class - @OPENJDK7@/jdk/src/share/classes/javax/management/*.class - @OPENJDK7@/jdk/src/share/classes/javax/management/loading/*.class - @OPENJDK7@/jdk/src/share/classes/javax/management/modelmbean/*.class - @OPENJDK7@/jdk/src/share/classes/javax/management/monitor/*.class - @OPENJDK7@/jdk/src/share/classes/javax/management/openmbean/*.class - @OPENJDK7@/jdk/src/share/classes/javax/management/relation/*.class - @OPENJDK7@/jdk/src/share/classes/javax/management/remote/*.class - @OPENJDK7@/jdk/src/share/classes/javax/management/remote/rmi/*.class - @OPENJDK7@/jdk/src/share/classes/javax/management/timer/*.class - @OPENJDK7@/jdk/src/share/classes/sun/management/*.class - @OPENJDK7@/jdk/src/share/classes/sun/management/counter/*.class - @OPENJDK7@/jdk/src/share/classes/sun/management/counter/perf/*.class - @OPENJDK7@/jdk/src/share/classes/sun/management/jmxremote/*.class - @OPENJDK7@/jdk/src/windows/classes/com/sun/management/*.class -} -{ - -out:IKVM.OpenJDK.Misc.dll - -baseaddress:0x5B8B0000 - -resource:com/sun/servicetag/resources/javase_5_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties - -resource:com/sun/servicetag/resources/javase_6_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties - -resource:com/sun/servicetag/resources/javase_7_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties - -resource:com/sun/servicetag/resources/product_registration.xsd=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/product_registration.xsd - -resource:com/sun/servicetag/resources/register.html=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/register.html - -resource:com/sun/servicetag/resources/register_ja.html=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html - -resource:com/sun/servicetag/resources/register_zh_CN.html=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html - @OPENJDK7@/build/linux-amd64/impsrc/javax/activity/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/annotation/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/annotation/processing/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/jws/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/jws/soap/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/lang/model/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/lang/model/element/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/lang/model/type/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/lang/model/util/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/tools/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/transaction/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/transaction/xa/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/net/httpserver/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/net/httpserver/spi/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/pept/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/pept/encoding/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/pept/ept/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/pept/presentation/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/pept/protocol/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/pept/transport/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/*.class - @OPENJDK7@/jdk/src/share/classes/java/lang/instrument/*.class - @OPENJDK7@/jdk/src/share/classes/javax/script/*.class - @OPENJDK7@/jdk/src/share/classes/javax/smartcardio/*.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharASCII.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharConverter.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharCp1250.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharCp1251.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharCp1252.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharCp1253.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharCp1254.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharCp1257.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharISO8859_1.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharISO8859_13.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharISO8859_15.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharISO8859_2.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharISO8859_4.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharISO8859_5.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharISO8859_7.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharISO8859_9.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharKOI8_R.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharSingleByte.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharUnicode.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharUnicodeBig.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharUnicodeBigUnmarked.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharUnicodeLittle.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharUnicodeLittleUnmarked.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharUTF16.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ByteToCharUTF8.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharacterEncoding$1.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharacterEncoding$2.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharacterEncoding.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteASCII.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteConverter.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteCp1250.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteCp1251.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteCp1252.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteCp1253.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteCp1254.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteCp1257.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteISO8859_1.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteISO8859_13.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteISO8859_15.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteISO8859_2.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteISO8859_4.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteISO8859_5.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteISO8859_7.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteISO8859_9.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteKOI8_R.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteSingleByte.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteUnicode.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteUnicodeBig.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteUnicodeBigUnmarked.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteUnicodeLittle.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteUnicodeLittleUnmarked.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteUTF16.class - @OPENJDK7@/jdk/src/share/classes/sun/io/CharToByteUTF8.class - @OPENJDK7@/jdk/src/share/classes/sun/io/ConversionBufferFullException.class - @OPENJDK7@/jdk/src/share/classes/sun/io/Converters.class - @OPENJDK7@/jdk/src/share/classes/sun/io/MalformedInputException.class - @OPENJDK7@/jdk/src/share/classes/sun/io/UnknownCharacterException.class - @OPENJDK7@/jdk/src/share/classes/sun/misc/resources/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/httpserver/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/protocol/gopher/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/www/protocol/netdoc/*.class - @OPENJDK7@/jdk/src/share/classes/sunw/io/*.class - @OPENJDK7@/jdk/src/share/classes/sunw/util/*.class - @OPENJDK7@/langtools/src/share/classes/javax/lang/model/*.class - @OPENJDK7@/langtools/src/share/classes/javax/lang/model/element/*.class - @OPENJDK7@/langtools/src/share/classes/javax/lang/model/type/*.class -} -{ - -out:IKVM.OpenJDK.Naming.dll - -baseaddress:0x5B9D0000 - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/jndi/ldap/jndiprovider.properties - -resource:META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor=@OPENJDK7@/jdk/src/share/classes/sun/net/spi/nameservice/dns/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor - sun/net/dns/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/dns/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/ldap/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/ldap/ext/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/ldap/pool/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/ldap/sasl/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/toolkit/ctx/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/toolkit/dir/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/toolkit/url/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/url/dns/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/url/ldap/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/url/ldaps/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/naming/internal/*.class - @OPENJDK7@/jdk/src/share/classes/javax/naming/*.class - @OPENJDK7@/jdk/src/share/classes/javax/naming/directory/*.class - @OPENJDK7@/jdk/src/share/classes/javax/naming/event/*.class - @OPENJDK7@/jdk/src/share/classes/javax/naming/ldap/*.class - @OPENJDK7@/jdk/src/share/classes/javax/naming/spi/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/dns/*.class - @OPENJDK7@/jdk/src/share/classes/sun/net/spi/nameservice/dns/*.class -} -{ - -out:IKVM.OpenJDK.Jdbc.dll - -baseaddress:0x5BB20000 - -resource:META-INF/services/java.sql.Driver=resources/META-INF/services/java.sql.Driver - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/rowset/* - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/javax/sql/* - -r:System.Data.dll - java/sql/*.class - sun/jdbc/odbc/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/rowset/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/rowset/internal/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/rowset/providers/*.class - @OPENJDK7@/jdk/src/share/classes/java/sql/*.class - @OPENJDK7@/jdk/src/share/classes/javax/sql/*.class - @OPENJDK7@/jdk/src/share/classes/javax/sql/rowset/*.class - @OPENJDK7@/jdk/src/share/classes/javax/sql/rowset/serial/*.class - @OPENJDK7@/jdk/src/share/classes/javax/sql/rowset/spi/*.class -} -{ - -out:IKVM.OpenJDK.Remoting.dll - -baseaddress:0x5BC70000 - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/rmi/* - @OPENJDK7@/build/linux-amd64/classes/sun/rmi/registry/*.class - @OPENJDK7@/build/linux-amd64/classes/sun/rmi/server/*.class - @OPENJDK7@/build/linux-amd64/classes/sun/rmi/transport/*.class - @OPENJDK7@/build/linux-amd64/classes/com/sun/jndi/rmi/registry/*.class - @OPENJDK7@/build/linux-amd64/classes/java/rmi/activation/*.class - @OPENJDK7@/jdk/src/share/classes/java/rmi/*.class - @OPENJDK7@/jdk/src/share/classes/java/rmi/activation/*.class - @OPENJDK7@/jdk/src/share/classes/java/rmi/dgc/*.class - @OPENJDK7@/jdk/src/share/classes/java/rmi/registry/*.class - @OPENJDK7@/jdk/src/share/classes/java/rmi/server/*.class - @OPENJDK7@/jdk/src/share/classes/javax/rmi/ssl/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/rmi/registry/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/jndi/url/rmi/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/rmi/rmid/*.class - @OPENJDK7@/jdk/src/share/classes/sun/rmi/log/*.class - @OPENJDK7@/jdk/src/share/classes/sun/rmi/registry/*.class - @OPENJDK7@/jdk/src/share/classes/sun/rmi/runtime/*.class - @OPENJDK7@/jdk/src/share/classes/sun/rmi/server/*.class - @OPENJDK7@/jdk/src/share/classes/sun/rmi/transport/*.class - @OPENJDK7@/jdk/src/share/classes/sun/rmi/transport/proxy/*.class - @OPENJDK7@/jdk/src/share/classes/sun/rmi/transport/tcp/*.class -} -{ - -out:IKVM.OpenJDK.Beans.dll - -baseaddress:0x5BD90000 - @OPENJDK7@/build/linux-amd64/impsrc/com/sun/activation/registries/*.class - @OPENJDK7@/build/linux-amd64/impsrc/javax/activation/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/beans/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/beans/decoder/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/beans/finder/*.class - @OPENJDK7@/jdk/src/share/classes/java/beans/*.class - @OPENJDK7@/jdk/src/share/classes/java/beans/beancontext/*.class - @OPENJDK7@/jdk/src/share/classes/sun/beans/editors/*.class - @OPENJDK7@/jdk/src/share/classes/sun/beans/infos/*.class -} -{ - -out:IKVM.OpenJDK.Media.dll - -baseaddress:0x5BE50000 - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.print.* - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.sound.* - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/imageio/plugins/common/iio-plugin.properties - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/print/* - -r:System.Drawing.dll - com/sun/imageio/plugins/jpeg/*.class - icedtea/rt/com/sun/media/sound/*.class - sun/print/*.class - sun/awt/windows/*.class - @OPENJDK7@/build/linux-amd64/gensrc/sun/print/resources/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/bmp/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/common/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/gif/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/png/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/spi/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/stream/*.class - @OPENJDK7@/jdk/src/share/classes/com/sun/media/sound/*.class - @OPENJDK7@/jdk/src/share/classes/javax/imageio/*.class - @OPENJDK7@/jdk/src/share/classes/javax/imageio/event/*.class - @OPENJDK7@/jdk/src/share/classes/javax/imageio/metadata/*.class - @OPENJDK7@/jdk/src/share/classes/javax/imageio/plugins/bmp/*.class - @OPENJDK7@/jdk/src/share/classes/javax/imageio/plugins/jpeg/*.class - @OPENJDK7@/jdk/src/share/classes/javax/imageio/spi/*.class - @OPENJDK7@/jdk/src/share/classes/javax/imageio/stream/*.class - @OPENJDK7@/jdk/src/share/classes/javax/print/*.class - @OPENJDK7@/jdk/src/share/classes/javax/print/attribute/*.class - @OPENJDK7@/jdk/src/share/classes/javax/print/attribute/standard/*.class - @OPENJDK7@/jdk/src/share/classes/javax/print/event/*.class - @OPENJDK7@/jdk/src/share/classes/javax/sound/midi/*.class - @OPENJDK7@/jdk/src/share/classes/javax/sound/midi/spi/*.class - @OPENJDK7@/jdk/src/share/classes/javax/sound/sampled/*.class - @OPENJDK7@/jdk/src/share/classes/javax/sound/sampled/spi/*.class - @OPENJDK7@/jdk/src/share/classes/sun/print/*.class - @OPENJDK7@/jdk/src/windows/classes/sun/print/*.class -} diff --git a/external/ikvm/openjdk/response.txt.REMOVED.git-id b/external/ikvm/openjdk/response.txt.REMOVED.git-id new file mode 100644 index 0000000000..2213d187fb --- /dev/null +++ b/external/ikvm/openjdk/response.txt.REMOVED.git-id @@ -0,0 +1 @@ +0371c2e17040377153909ef9f19d553f527c5078 \ No newline at end of file diff --git a/external/ikvm/openjdk/sun/management/FileSystemImpl.java b/external/ikvm/openjdk/sun/management/FileSystemImpl.java deleted file mode 100644 index 51ed8d77c2..0000000000 --- a/external/ikvm/openjdk/sun/management/FileSystemImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2011 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.management; - -import ikvm.internal.NotYetImplementedError; -import java.io.File; - -public class FileSystemImpl extends FileSystem -{ - public boolean supportsFileSecurity(File f) - { - throw new NotYetImplementedError(); - } - - public boolean isAccessUserOnly(File f) - { - throw new NotYetImplementedError(); - } -} diff --git a/external/ikvm/openjdk/sun/management/GcInfoBuilder.java b/external/ikvm/openjdk/sun/management/GcInfoBuilder.java deleted file mode 100644 index abe5082f5c..0000000000 --- a/external/ikvm/openjdk/sun/management/GcInfoBuilder.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2003, 2008, 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.management; - -import ikvm.internal.NotYetImplementedError; - -import java.lang.management.GarbageCollectorMXBean; -import java.lang.management.MemoryUsage; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; -import javax.management.openmbean.TabularType; -import javax.management.openmbean.TabularData; -import javax.management.openmbean.TabularDataSupport; -import javax.management.openmbean.CompositeType; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.OpenDataException; -import com.sun.management.GcInfo; - -/** - * Helper class to build composite data. - */ -public class GcInfoBuilder { - private final GarbageCollectorMXBean gc; - private final String[] poolNames; - private String[] allItemNames; - - // GC-specific composite type: - // Each GarbageCollectorMXBean may have different GC-specific attributes - // the CompositeType for the GcInfo could be different. - private CompositeType gcInfoCompositeType; - - // GC-specific items - private final int gcExtItemCount; - private final String[] gcExtItemNames; - private final String[] gcExtItemDescs; - private final char[] gcExtItemTypes; - - GcInfoBuilder(GarbageCollectorMXBean gc, String[] poolNames) { - this.gc = gc; - this.poolNames = poolNames; - this.gcExtItemCount = getNumGcExtAttributes(gc); - this.gcExtItemNames = new String[gcExtItemCount]; - this.gcExtItemDescs = new String[gcExtItemCount]; - this.gcExtItemTypes = new char[gcExtItemCount]; - - // Fill the information about extension attributes - fillGcAttributeInfo(gc, gcExtItemCount, gcExtItemNames, - gcExtItemTypes, gcExtItemDescs); - - // lazily build the CompositeType for the GcInfo - // including the GC-specific extension attributes - this.gcInfoCompositeType = null; - } - - GcInfo getLastGcInfo() { - MemoryUsage[] usageBeforeGC = new MemoryUsage[poolNames.length]; - MemoryUsage[] usageAfterGC = new MemoryUsage[poolNames.length]; - Object[] values = new Object[gcExtItemCount]; - - return getLastGcInfo0(gc, gcExtItemCount, values, gcExtItemTypes, - usageBeforeGC, usageAfterGC); - } - - public String[] getPoolNames() { - return poolNames; - } - - int getGcExtItemCount() { - return gcExtItemCount; - } - - // Returns the CompositeType for the GcInfo including - // the extension attributes - synchronized CompositeType getGcInfoCompositeType() { - if (gcInfoCompositeType != null) - return gcInfoCompositeType; - - // First, fill with the attributes in the GcInfo - String[] gcInfoItemNames = GcInfoCompositeData.getBaseGcInfoItemNames(); - OpenType[] gcInfoItemTypes = GcInfoCompositeData.getBaseGcInfoItemTypes(); - int numGcInfoItems = gcInfoItemNames.length; - - int itemCount = numGcInfoItems + gcExtItemCount; - allItemNames = new String[itemCount]; - String[] allItemDescs = new String[itemCount]; - OpenType[] allItemTypes = new OpenType[itemCount]; - - System.arraycopy(gcInfoItemNames, 0, allItemNames, 0, numGcInfoItems); - System.arraycopy(gcInfoItemNames, 0, allItemDescs, 0, numGcInfoItems); - System.arraycopy(gcInfoItemTypes, 0, allItemTypes, 0, numGcInfoItems); - - // Then fill with the extension GC-specific attributes, if any. - if (gcExtItemCount > 0) { - fillGcAttributeInfo(gc, gcExtItemCount, gcExtItemNames, - gcExtItemTypes, gcExtItemDescs); - System.arraycopy(gcExtItemNames, 0, allItemNames, - numGcInfoItems, gcExtItemCount); - System.arraycopy(gcExtItemDescs, 0, allItemDescs, - numGcInfoItems, gcExtItemCount); - for (int i = numGcInfoItems, j = 0; j < gcExtItemCount; i++, j++) { - switch (gcExtItemTypes[j]) { - case 'Z': - allItemTypes[i] = SimpleType.BOOLEAN; - break; - case 'B': - allItemTypes[i] = SimpleType.BYTE; - break; - case 'C': - allItemTypes[i] = SimpleType.CHARACTER; - break; - case 'S': - allItemTypes[i] = SimpleType.SHORT; - break; - case 'I': - allItemTypes[i] = SimpleType.INTEGER; - break; - case 'J': - allItemTypes[i] = SimpleType.LONG; - break; - case 'F': - allItemTypes[i] = SimpleType.FLOAT; - break; - case 'D': - allItemTypes[i] = SimpleType.DOUBLE; - break; - default: - throw new AssertionError( - "Unsupported type [" + gcExtItemTypes[i] + "]"); - } - } - } - - CompositeType gict = null; - try { - final String typeName = - "sun.management." + gc.getName() + ".GcInfoCompositeType"; - - gict = new CompositeType(typeName, - "CompositeType for GC info for " + - gc.getName(), - allItemNames, - allItemDescs, - allItemTypes); - } catch (OpenDataException e) { - // shouldn't reach here - throw Util.newException(e); - } - gcInfoCompositeType = gict; - - return gcInfoCompositeType; - } - - synchronized String[] getItemNames() { - if (allItemNames == null) { - // initialize when forming the composite type - getGcInfoCompositeType(); - } - return allItemNames; - } - - // Retrieve information about extension attributes - private /*native*/ int getNumGcExtAttributes(GarbageCollectorMXBean gc){ - throw new NotYetImplementedError(); - } - - private /*native*/ void fillGcAttributeInfo(GarbageCollectorMXBean gc, - int numAttributes, - String[] attributeNames, - char[] types, - String[] descriptions){ - throw new NotYetImplementedError(); - } - - /** - * Returns the last GcInfo - * - * @param gc GarbageCollectorMXBean that the gc info is associated with. - * @param numExtAtts number of extension attributes - * @param extAttValues Values of extension attributes to be filled. - * @param before Memory usage before GC to be filled. - * @param after Memory usage after GC to be filled. - */ - private /*native*/ GcInfo getLastGcInfo0(GarbageCollectorMXBean gc, - int numExtAtts, - Object[] extAttValues, - char[] extAttTypes, - MemoryUsage[] before, - MemoryUsage[] after){ - throw new NotYetImplementedError(); - } -} diff --git a/external/ikvm/openjdk/sun/nio/fs/NetFileSystemProvider.java b/external/ikvm/openjdk/sun/nio/fs/NetFileSystemProvider.java index 3c569b1e37..3a16383c53 100644 --- a/external/ikvm/openjdk/sun/nio/fs/NetFileSystemProvider.java +++ b/external/ikvm/openjdk/sun/nio/fs/NetFileSystemProvider.java @@ -338,7 +338,7 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider } } - return FileChannelImpl.open(open(npath.path, mode, rights, share, options), npath.path, read, write, append, null); + return FileChannelImpl.open(open(npath.path, mode, rights, share, options), read, write, append, null); } private static FileDescriptor open(String path, int mode, int rights, int share, int options) throws IOException @@ -1104,7 +1104,7 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider public long size() { - return info.get_Length(); + return info.get_Exists() ? info.get_Length() : 0; } public boolean isArchive() @@ -1140,7 +1140,12 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider if (false) throw new cli.System.ArgumentException(); if (false) throw new cli.System.IO.FileNotFoundException(); if (false) throw new cli.System.IO.IOException(); - return new DosFileAttributesImpl(new FileInfo(path)); + FileInfo info = new FileInfo(path); + if (!info.get_Exists()) + { + throw new NoSuchFileException(path); + } + return new DosFileAttributesImpl(info); } catch (cli.System.IO.FileNotFoundException _) { @@ -1193,6 +1198,10 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider info.set_Attributes(cli.System.IO.FileAttributes.wrap(info.get_Attributes().Value & ~attr)); } } + catch (cli.System.IO.FileNotFoundException _) + { + throw new NoSuchFileException(path); + } catch (cli.System.ArgumentException | cli.System.IO.IOException x) { diff --git a/external/ikvm/openjdk/sun/reflect/annotation/AnnotationType.java b/external/ikvm/openjdk/sun/reflect/annotation/AnnotationType.java new file mode 100644 index 0000000000..80280018a5 --- /dev/null +++ b/external/ikvm/openjdk/sun/reflect/annotation/AnnotationType.java @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2003, 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 sun.reflect.annotation; + +import sun.misc.JavaLangAccess; + +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.*; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Represents an annotation type at run time. Used to type-check annotations + * and apply member defaults. + * + * @author Josh Bloch + * @since 1.5 + */ +public class AnnotationType { + /** + * Member name -> type mapping. Note that primitive types + * are represented by the class objects for the corresponding wrapper + * types. This matches the return value that must be used for a + * dynamic proxy, allowing for a simple isInstance test. + */ + private final Map> memberTypes; + + /** + * Member name -> default value mapping. + */ + private final Map memberDefaults; + + /** + * Member name -> Method object mapping. This (and its assoicated + * accessor) are used only to generate AnnotationTypeMismatchExceptions. + */ + private final Map members; + + /** + * The retention policy for this annotation type. + */ + private final RetentionPolicy retention; + + /** + * Whether this annotation type is inherited. + */ + private final boolean inherited; + + /** + * Returns an AnnotationType instance for the specified annotation type. + * + * @throw IllegalArgumentException if the specified class object for + * does not represent a valid annotation type + */ + public static AnnotationType getInstance( + Class annotationClass) + { + JavaLangAccess jla = sun.misc.SharedSecrets.getJavaLangAccess(); + AnnotationType result = jla.getAnnotationType(annotationClass); // volatile read + if (result == null) { + result = new AnnotationType(annotationClass); + // try to CAS the AnnotationType: null -> result + if (!jla.casAnnotationType(annotationClass, null, result)) { + // somebody was quicker -> read it's result + result = jla.getAnnotationType(annotationClass); + assert result != null; + } + } + + return result; + } + + /** + * Sole constructor. + * + * @param annotationClass the class object for the annotation type + * @throw IllegalArgumentException if the specified class object for + * does not represent a valid annotation type + */ + private AnnotationType(final Class annotationClass) { + if (!annotationClass.isAnnotation()) + throw new IllegalArgumentException("Not an annotation type"); + + Method[] methods = + AccessController.doPrivileged(new PrivilegedAction() { + public Method[] run() { + // Initialize memberTypes and defaultValues + return annotationClass.getDeclaredMethods(); + } + }); + + memberTypes = new HashMap>(methods.length+1, 1.0f); + memberDefaults = new HashMap(0); + members = new HashMap(methods.length+1, 1.0f); + + for (Method method : methods) { + if (method.getParameterTypes().length != 0) + throw new IllegalArgumentException(method + " has params"); + String name = method.getName(); + Class type = method.getReturnType(); + memberTypes.put(name, invocationHandlerReturnType(type)); + members.put(name, method); + + Object defaultValue = method.getDefaultValue(); + if (defaultValue != null) + memberDefaults.put(name, defaultValue); + } + + // Initialize retention, & inherited fields. Special treatment + // of the corresponding annotation types breaks infinite recursion. + if (annotationClass != Retention.class && + annotationClass != Inherited.class) { + Retention ret = (Retention) annotationClass.getDeclaredAnnotation(Retention.class); + retention = (ret == null ? RetentionPolicy.CLASS : ret.value()); + inherited = annotationClass.isAnnotationPresent(Inherited.class); + } + else { + retention = RetentionPolicy.RUNTIME; + inherited = false; + } + } + + /** + * Returns the type that must be returned by the invocation handler + * of a dynamic proxy in order to have the dynamic proxy return + * the specified type (which is assumed to be a legal member type + * for an annotation). + */ + public static Class invocationHandlerReturnType(Class type) { + // Translate primitives to wrappers + if (type == byte.class) + return Byte.class; + if (type == char.class) + return Character.class; + if (type == double.class) + return Double.class; + if (type == float.class) + return Float.class; + if (type == int.class) + return Integer.class; + if (type == long.class) + return Long.class; + if (type == short.class) + return Short.class; + if (type == boolean.class) + return Boolean.class; + + // Otherwise, just return declared type + return type; + } + + /** + * Returns member types for this annotation type + * (member name -> type mapping). + */ + public Map> memberTypes() { + return memberTypes; + } + + /** + * Returns members of this annotation type + * (member name -> associated Method object mapping). + */ + public Map members() { + return members; + } + + /** + * Returns the default values for this annotation type + * (Member name -> default value mapping). + */ + public Map memberDefaults() { + return memberDefaults; + } + + /** + * Returns the retention policy for this annotation type. + */ + public RetentionPolicy retention() { + return retention; + } + + /** + * Returns true if this this annotation type is inherited. + */ + public boolean isInherited() { + return inherited; + } + + /** + * For debugging. + */ + public String toString() { + return "Annotation Type:\n" + + " Member types: " + memberTypes + "\n" + + " Member defaults: " + memberDefaults + "\n" + + " Retention policy: " + retention + "\n" + + " Inherited: " + inherited; + } +} diff --git a/external/ikvm/reflect/CustomAttributeData.cs b/external/ikvm/reflect/CustomAttributeData.cs index 98905af89b..70e1b1422b 100644 --- a/external/ikvm/reflect/CustomAttributeData.cs +++ b/external/ikvm/reflect/CustomAttributeData.cs @@ -157,7 +157,7 @@ namespace IKVM.Reflection throw new BadImageFormatException(); } lazyConstructorArguments = ReadConstructorArguments(module, br, constructor); - lazyNamedArguments = ReadNamedArguments(module, br, br.ReadUInt16(), constructor.DeclaringType); + lazyNamedArguments = ReadNamedArguments(module, br, br.ReadUInt16(), constructor.DeclaringType, true); } } @@ -443,13 +443,17 @@ namespace IKVM.Reflection return list.AsReadOnly(); } - private static IList ReadNamedArguments(Module context, ByteReader br, int named, Type type) + private static IList ReadNamedArguments(Module context, ByteReader br, int named, Type type, bool required) { List list = new List(named); for (int i = 0; i < named; i++) { byte fieldOrProperty = br.ReadByte(); Type fieldOrPropertyType = ReadFieldOrPropType(context, br); + if (fieldOrPropertyType.__IsMissing && !required) + { + return null; + } string name = br.ReadString(); CustomAttributeTypedArgument value = ReadFixedArg(context, br, fieldOrPropertyType); MemberInfo member; @@ -580,7 +584,7 @@ namespace IKVM.Reflection { if (lazyConstructorArguments == null) { - LazyParseArguments(); + LazyParseArguments(false); } return lazyConstructorArguments; } @@ -595,21 +599,21 @@ namespace IKVM.Reflection if (customAttributeIndex >= 0) { // 1) Unresolved Custom Attribute - LazyParseArguments(); + LazyParseArguments(true); } else { // 5) Unresolved declarative security ByteReader br = new ByteReader(declSecurityBlob, 0, declSecurityBlob.Length); // LAMESPEC the count of named arguments is a compressed integer (instead of UInt16 as NumNamed in custom attributes) - lazyNamedArguments = ReadNamedArguments(module, br, br.ReadCompressedUInt(), Constructor.DeclaringType); + lazyNamedArguments = ReadNamedArguments(module, br, br.ReadCompressedUInt(), Constructor.DeclaringType, true); } } return lazyNamedArguments; } } - private void LazyParseArguments() + private void LazyParseArguments(bool requireNameArguments) { ByteReader br = module.GetBlob(module.CustomAttribute.records[customAttributeIndex].Value); if (br.Length == 0) @@ -625,7 +629,7 @@ namespace IKVM.Reflection throw new BadImageFormatException(); } lazyConstructorArguments = ReadConstructorArguments(module, br, Constructor); - lazyNamedArguments = ReadNamedArguments(module, br, br.ReadUInt16(), Constructor.DeclaringType); + lazyNamedArguments = ReadNamedArguments(module, br, br.ReadUInt16(), Constructor.DeclaringType, requireNameArguments); } } diff --git a/external/ikvm/reflect/Emit/AssemblyBuilder.cs b/external/ikvm/reflect/Emit/AssemblyBuilder.cs index 7732c57ab3..61f7ffa03d 100644 --- a/external/ikvm/reflect/Emit/AssemblyBuilder.cs +++ b/external/ikvm/reflect/Emit/AssemblyBuilder.cs @@ -373,9 +373,9 @@ namespace IKVM.Reflection.Emit foreach (CustomAttributeBuilder cab in customAttributes) { // .NET doesn't support copying blob custom attributes into the version info - if (!cab.HasBlob) + if (!cab.HasBlob || universe.DecodeVersionInfoAttributeBlobs) { - versionInfo.SetAttribute(cab); + versionInfo.SetAttribute(this, cab); } } ByteBuffer versionInfoData = new ByteBuffer(512); diff --git a/external/ikvm/reflect/IKVM.Reflection.csproj b/external/ikvm/reflect/IKVM.Reflection.csproj index 5e117288d8..2ded215c2e 100644 --- a/external/ikvm/reflect/IKVM.Reflection.csproj +++ b/external/ikvm/reflect/IKVM.Reflection.csproj @@ -3,7 +3,7 @@ Debug AnyCPU - 9.0.30729 + 9.0.21022 2.0 {4CB170EF-DFE6-4A56-9E1B-A85449E827A7} Library @@ -22,6 +22,8 @@ + true + ..\ikvm-fork.snk true diff --git a/external/ikvm/reflect/Type.cs b/external/ikvm/reflect/Type.cs index 3b70c999c1..66606c12e2 100644 --- a/external/ikvm/reflect/Type.cs +++ b/external/ikvm/reflect/Type.cs @@ -2040,6 +2040,7 @@ namespace IKVM.Reflection { if (this.Assembly == this.Universe.Mscorlib || this.Assembly.GetName().Name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase) + || this.Assembly.GetName().Name.Equals("System.Runtime", StringComparison.OrdinalIgnoreCase) // check if mscorlib forwards the type (.NETCore profile reference mscorlib forwards System.Enum and System.ValueType to System.Runtime.dll) || this.Universe.Mscorlib.FindType(new TypeName(__Namespace, __Name)) == this) { diff --git a/external/ikvm/reflect/Universe.cs b/external/ikvm/reflect/Universe.cs index 1b4b351a9a..26fb558eb7 100644 --- a/external/ikvm/reflect/Universe.cs +++ b/external/ikvm/reflect/Universe.cs @@ -128,6 +128,7 @@ namespace IKVM.Reflection MetadataOnly = 16, ResolveMissingMembers = 32, DisableWindowsRuntimeProjection = 64, + DecodeVersionInfoAttributeBlobs = 128, } public sealed class Universe : IDisposable @@ -1216,5 +1217,10 @@ namespace IKVM.Reflection { get { return (options & UniverseOptions.DisableWindowsRuntimeProjection) == 0; } } + + internal bool DecodeVersionInfoAttributeBlobs + { + get { return (options & UniverseOptions.DecodeVersionInfoAttributeBlobs) != 0; } + } } } diff --git a/external/ikvm/reflect/Writer/VersionInfo.cs b/external/ikvm/reflect/Writer/VersionInfo.cs index 41938a108f..25eb193b4e 100644 --- a/external/ikvm/reflect/Writer/VersionInfo.cs +++ b/external/ikvm/reflect/Writer/VersionInfo.cs @@ -50,41 +50,41 @@ namespace IKVM.Reflection.Writer this.fileName = System.IO.Path.GetFileName(assemblyFileName); } - internal void SetAttribute(CustomAttributeBuilder cab) + internal void SetAttribute(AssemblyBuilder asm, CustomAttributeBuilder cab) { Universe u = cab.Constructor.Module.universe; Type type = cab.Constructor.DeclaringType; if (copyright == null && type == u.System_Reflection_AssemblyCopyrightAttribute) { - copyright = (string)cab.GetConstructorArgument(0); + copyright = (string)cab.DecodeBlob(asm).GetConstructorArgument(0); } else if (trademark == null && type == u.System_Reflection_AssemblyTrademarkAttribute) { - trademark = (string)cab.GetConstructorArgument(0); + trademark = (string)cab.DecodeBlob(asm).GetConstructorArgument(0); } else if (product == null && type == u.System_Reflection_AssemblyProductAttribute) { - product = (string)cab.GetConstructorArgument(0); + product = (string)cab.DecodeBlob(asm).GetConstructorArgument(0); } else if (company == null && type == u.System_Reflection_AssemblyCompanyAttribute) { - company = (string)cab.GetConstructorArgument(0); + company = (string)cab.DecodeBlob(asm).GetConstructorArgument(0); } else if (description == null && type == u.System_Reflection_AssemblyDescriptionAttribute) { - description = (string)cab.GetConstructorArgument(0); + description = (string)cab.DecodeBlob(asm).GetConstructorArgument(0); } else if (title == null && type == u.System_Reflection_AssemblyTitleAttribute) { - title = (string)cab.GetConstructorArgument(0); + title = (string)cab.DecodeBlob(asm).GetConstructorArgument(0); } else if (informationalVersion == null && type == u.System_Reflection_AssemblyInformationalVersionAttribute) { - informationalVersion = (string)cab.GetConstructorArgument(0); + informationalVersion = (string)cab.DecodeBlob(asm).GetConstructorArgument(0); } else if (fileVersion == null && type == u.System_Reflection_AssemblyFileVersionAttribute) { - fileVersion = (string)cab.GetConstructorArgument(0); + fileVersion = (string)cab.DecodeBlob(asm).GetConstructorArgument(0); } } diff --git a/external/ikvm/runtime/AssemblyClassLoader.cs b/external/ikvm/runtime/AssemblyClassLoader.cs index 960beead75..09653c7334 100644 --- a/external/ikvm/runtime/AssemblyClassLoader.cs +++ b/external/ikvm/runtime/AssemblyClassLoader.cs @@ -746,8 +746,16 @@ namespace IKVM.Internal using (java.io.InputStream inp = url.openStream()) { byte[] buf = new byte[inp.available()]; - inp.read(buf, 0, buf.Length); - return TypeWrapper.FromClass(IKVM.NativeCode.java.lang.ClassLoader.defineClass1(GetJavaClassLoader(), name, buf, 0, buf.Length, GetProtectionDomain(), null)); + for (int pos = 0; pos < buf.Length; ) + { + int read = inp.read(buf, pos, buf.Length - pos); + if (read <= 0) + { + break; + } + pos += read; + } + return TypeWrapper.FromClass(Java_java_lang_ClassLoader.defineClass1(GetJavaClassLoader(), name, buf, 0, buf.Length, GetProtectionDomain(), null)); } } #endif @@ -860,7 +868,7 @@ namespace IKVM.Internal if (!found && unmangledName.EndsWith(".class", StringComparison.Ordinal) && unmangledName.IndexOf('.') == unmangledName.Length - 6) { TypeWrapper tw = FindLoadedClass(unmangledName.Substring(0, unmangledName.Length - 6).Replace('/', '.')); - if (tw != null && tw.GetClassLoader() == this && !tw.IsArray && !(tw is DynamicTypeWrapper)) + if (tw != null && tw.GetClassLoader() == this && !tw.IsArray && !tw.IsDynamic) { #if !FIRST_PASS yield return new java.io.File(VirtualFileSystem.GetAssemblyClassesPath(assemblyLoader.Assembly) + unmangledName).toURI().toURL(); @@ -1103,28 +1111,23 @@ namespace IKVM.Internal LazyInitExports(); lock (this) { - Array.Resize(ref delegates, delegates.Length + 1); - delegates[delegates.Length - 1] = acl; + delegates = ArrayUtil.Concat(delegates, acl); } } #if !STATIC_COMPILER && !STUB_GENERATOR - internal string[] GetPackages() + internal List> GetPackageInfo() { - string[] packages = new string[0]; + List> list = new List>(); foreach (Module m in assemblyLoader.Assembly.GetModules(false)) { object[] attr = m.GetCustomAttributes(typeof(PackageListAttribute), false); foreach (PackageListAttribute p in attr) { - string[] mp = p.GetPackages(); - string[] tmp = new string[packages.Length + mp.Length]; - Array.Copy(packages, 0, tmp, 0, packages.Length); - Array.Copy(mp, 0, tmp, packages.Length, mp.Length); - packages = tmp; + list.Add(new KeyValuePair(p.jar, p.packages)); } } - return packages; + return list; } #endif @@ -1313,6 +1316,10 @@ namespace IKVM.Internal return base.GetWrapperFromAssemblyType(type); } + protected override void CheckProhibitedPackage(string className) + { + } + #if !FIRST_PASS && !STATIC_COMPILER && !STUB_GENERATOR internal override java.lang.ClassLoader GetJavaClassLoader() { diff --git a/external/ikvm/runtime/BigEndianBinaryReader.cs b/external/ikvm/runtime/BigEndianBinaryReader.cs index fcd5dfa5a2..5d9b286869 100644 --- a/external/ikvm/runtime/BigEndianBinaryReader.cs +++ b/external/ikvm/runtime/BigEndianBinaryReader.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2012 Jeroen Frijters + Copyright (C) 2002-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 @@ -164,7 +164,7 @@ sealed class BigEndianBinaryReader case 0: if(c == 0) { - throw new ClassFormatError("{0} (Illegal UTF8 string in constant pool)", classFile); + goto default; } break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: @@ -175,9 +175,13 @@ sealed class BigEndianBinaryReader char2 = buf[pos + ++i]; if((char2 & 0xc0) != 0x80 || i >= len) { - throw new ClassFormatError("{0} (Illegal UTF8 string in constant pool)", classFile); + goto default; } c = (((c & 0x1F) << 6) | (char2 & 0x3F)); + if(c < 0x80 && c != 0) + { + goto default; + } break; case 14: // 1110 xxxx 10xx xxxx 10xx xxxx @@ -185,12 +189,16 @@ sealed class BigEndianBinaryReader char3 = buf[pos + ++i]; if((char2 & 0xc0) != 0x80 || (char3 & 0xc0) != 0x80 || i >= len) { - throw new ClassFormatError("{0} (Illegal UTF8 string in constant pool)", classFile); + goto default; } c = (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0)); + if(c < 0x800) + { + goto default; + } break; default: - throw new ClassFormatError("{0} (Illegal UTF8 string in constant pool)", classFile); + throw new ClassFormatError("Illegal UTF8 string in constant pool in class file {0}", classFile); } ch[l++] = (char)c; } @@ -224,4 +232,11 @@ sealed class BigEndianBinaryReader pos += 4; return i; } + + internal byte[] ToArray() + { + byte[] res = new byte[end - pos]; + Buffer.BlockCopy(buf, pos, res, 0, res.Length); + return res; + } } diff --git a/external/ikvm/runtime/Boxer.cs b/external/ikvm/runtime/Boxer.cs new file mode 100644 index 0000000000..880e015e43 --- /dev/null +++ b/external/ikvm/runtime/Boxer.cs @@ -0,0 +1,212 @@ +/* + Copyright (C) 2011-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 + 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; + +namespace IKVM.Internal +{ + static class Boxer + { + private static readonly TypeWrapper javaLangByte; + private static readonly MethodWrapper byteValue; + private static readonly MethodWrapper valueOfByte; + private static readonly TypeWrapper javaLangBoolean; + private static readonly MethodWrapper booleanValue; + private static readonly MethodWrapper valueOfBoolean; + private static readonly TypeWrapper javaLangShort; + private static readonly MethodWrapper shortValue; + private static readonly MethodWrapper valueOfShort; + private static readonly TypeWrapper javaLangCharacter; + private static readonly MethodWrapper charValue; + private static readonly MethodWrapper valueOfCharacter; + private static readonly TypeWrapper javaLangInteger; + private static readonly MethodWrapper intValue; + private static readonly MethodWrapper valueOfInteger; + private static readonly TypeWrapper javaLangFloat; + private static readonly MethodWrapper floatValue; + private static readonly MethodWrapper valueOfFloat; + private static readonly TypeWrapper javaLangLong; + private static readonly MethodWrapper longValue; + private static readonly MethodWrapper valueOfLong; + private static readonly TypeWrapper javaLangDouble; + private static readonly MethodWrapper doubleValue; + private static readonly MethodWrapper valueOfDouble; + + static Boxer() + { + ClassLoaderWrapper bootClassLoader = ClassLoaderWrapper.GetBootstrapClassLoader(); + javaLangByte = bootClassLoader.LoadClassByDottedNameFast("java.lang.Byte"); + byteValue = javaLangByte.GetMethodWrapper("byteValue", "()B", false); + byteValue.Link(); + valueOfByte = javaLangByte.GetMethodWrapper("valueOf", "(B)Ljava.lang.Byte;", false); + valueOfByte.Link(); + javaLangBoolean = bootClassLoader.LoadClassByDottedNameFast("java.lang.Boolean"); + booleanValue = javaLangBoolean.GetMethodWrapper("booleanValue", "()Z", false); + booleanValue.Link(); + valueOfBoolean = javaLangBoolean.GetMethodWrapper("valueOf", "(Z)Ljava.lang.Boolean;", false); + valueOfBoolean.Link(); + javaLangShort = bootClassLoader.LoadClassByDottedNameFast("java.lang.Short"); + shortValue = javaLangShort.GetMethodWrapper("shortValue", "()S", false); + shortValue.Link(); + valueOfShort = javaLangShort.GetMethodWrapper("valueOf", "(S)Ljava.lang.Short;", false); + valueOfShort.Link(); + javaLangCharacter = bootClassLoader.LoadClassByDottedNameFast("java.lang.Character"); + charValue = javaLangCharacter.GetMethodWrapper("charValue", "()C", false); + charValue.Link(); + valueOfCharacter = javaLangCharacter.GetMethodWrapper("valueOf", "(C)Ljava.lang.Character;", false); + valueOfCharacter.Link(); + javaLangInteger = bootClassLoader.LoadClassByDottedNameFast("java.lang.Integer"); + intValue = javaLangInteger.GetMethodWrapper("intValue", "()I", false); + intValue.Link(); + valueOfInteger = javaLangInteger.GetMethodWrapper("valueOf", "(I)Ljava.lang.Integer;", false); + valueOfInteger.Link(); + javaLangFloat = bootClassLoader.LoadClassByDottedNameFast("java.lang.Float"); + floatValue = javaLangFloat.GetMethodWrapper("floatValue", "()F", false); + floatValue.Link(); + valueOfFloat = javaLangFloat.GetMethodWrapper("valueOf", "(F)Ljava.lang.Float;", false); + valueOfFloat.Link(); + javaLangLong = bootClassLoader.LoadClassByDottedNameFast("java.lang.Long"); + longValue = javaLangLong.GetMethodWrapper("longValue", "()J", false); + longValue.Link(); + valueOfLong = javaLangLong.GetMethodWrapper("valueOf", "(J)Ljava.lang.Long;", false); + valueOfLong.Link(); + javaLangDouble = bootClassLoader.LoadClassByDottedNameFast("java.lang.Double"); + doubleValue = javaLangDouble.GetMethodWrapper("doubleValue", "()D", false); + doubleValue.Link(); + valueOfDouble = javaLangDouble.GetMethodWrapper("valueOf", "(D)Ljava.lang.Double;", false); + valueOfDouble.Link(); + } + + internal static void EmitUnbox(CodeEmitter ilgen, TypeWrapper tw, bool cast) + { + if (tw == PrimitiveTypeWrapper.BYTE) + { + if (cast) + { + javaLangByte.EmitCheckcast(ilgen); + } + byteValue.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.BOOLEAN) + { + if (cast) + { + javaLangBoolean.EmitCheckcast(ilgen); + } + booleanValue.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.SHORT) + { + if (cast) + { + javaLangShort.EmitCheckcast(ilgen); + } + shortValue.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.CHAR) + { + if (cast) + { + javaLangCharacter.EmitCheckcast(ilgen); + } + charValue.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.INT) + { + if (cast) + { + javaLangInteger.EmitCheckcast(ilgen); + } + intValue.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.FLOAT) + { + if (cast) + { + javaLangFloat.EmitCheckcast(ilgen); + } + floatValue.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.LONG) + { + if (cast) + { + javaLangLong.EmitCheckcast(ilgen); + } + longValue.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.DOUBLE) + { + if (cast) + { + javaLangDouble.EmitCheckcast(ilgen); + } + doubleValue.EmitCall(ilgen); + } + else + { + throw new InvalidOperationException(); + } + } + + internal static void EmitBox(CodeEmitter ilgen, TypeWrapper tw) + { + if (tw == PrimitiveTypeWrapper.BYTE) + { + valueOfByte.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.BOOLEAN) + { + valueOfBoolean.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.SHORT) + { + valueOfShort.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.CHAR) + { + valueOfCharacter.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.INT) + { + valueOfInteger.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.FLOAT) + { + valueOfFloat.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.LONG) + { + valueOfLong.EmitCall(ilgen); + } + else if (tw == PrimitiveTypeWrapper.DOUBLE) + { + valueOfDouble.EmitCall(ilgen); + } + else + { + throw new InvalidOperationException(); + } + } + } +} diff --git a/external/ikvm/runtime/ClassFile.cs b/external/ikvm/runtime/ClassFile.cs index db684117b3..bdb51002a7 100644 --- a/external/ikvm/runtime/ClassFile.cs +++ b/external/ikvm/runtime/ClassFile.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2013 Jeroen Frijters + Copyright (C) 2002-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 @@ -39,8 +39,6 @@ namespace IKVM.Internal NoSuchMethodError, LinkageError, // "exceptions" that are wrapped in an IncompatibleClassChangeError - NoSuchFieldException, - NoSuchMethodException, IllegalAccessException, // if an error is added here, it must also be added to MethodAnalyzer.SetHardError() } @@ -52,6 +50,7 @@ namespace IKVM.Internal LocalVariableTable = 1, LineNumberTable = 2, RelaxedClassNameValidation = 4, + TrustedAnnotations = 8, } sealed class ClassFile @@ -66,6 +65,9 @@ namespace IKVM.Internal private const ushort FLAG_MASK_DEPRECATED = 0x100; private const ushort FLAG_MASK_INTERNAL = 0x200; private const ushort FLAG_CALLERSENSITIVE = 0x400; + private const ushort FLAG_LAMBDAFORM_COMPILED = 0x800; + private const ushort FLAG_LAMBDAFORM_HIDDEN = 0x1000; + private const ushort FLAG_FORCEINLINE = 0x2000; private ConstantPoolItemClass[] interfaces; private Field[] fields; private Method[] methods; @@ -79,11 +81,12 @@ namespace IKVM.Internal private string signature; private string[] enclosingMethod; private BootstrapMethod[] bootstrapMethods; + private byte[] runtimeVisibleTypeAnnotations; private static class SupportedVersions { internal static readonly int Minimum = 45; - internal static readonly int Maximum = Experimental.JDK_8 ? 52 : 51; + internal static readonly int Maximum = Experimental.JDK_9 ? 53 : 52; } #if STATIC_COMPILER @@ -160,7 +163,7 @@ namespace IKVM.Internal } #endif // STATIC_COMPILER - internal ClassFile(byte[] buf, int offset, int length, string inputClassName, ClassFileParseOptions options) + internal ClassFile(byte[] buf, int offset, int length, string inputClassName, ClassFileParseOptions options, object[] constantPoolPatches) { try { @@ -242,6 +245,10 @@ namespace IKVM.Internal throw new ClassFormatError("{0} (Illegal constant pool type 0x{1:X})", inputClassName, tag); } } + if (constantPoolPatches != null) + { + PatchConstantPool(constantPoolPatches, utf8_cp, inputClassName); + } for(int i = 1; i < constantpoolcount; i++) { if(constantpool[i] != null) @@ -283,7 +290,7 @@ namespace IKVM.Internal ValidateConstantPoolItemClass(inputClassName, this_class); super_class = br.ReadUInt16(); ValidateConstantPoolItemClass(inputClassName, super_class); - if(IsInterface && (super_class == 0 || this.SuperClass != "java.lang.Object")) + if(IsInterface && (super_class == 0 || this.SuperClass.Name != "java.lang.Object")) { throw new ClassFormatError("{0} (Interfaces must have java.lang.Object as superclass)", Name); } @@ -479,6 +486,14 @@ namespace IKVM.Internal } bootstrapMethods = ReadBootstrapMethods(br, this); break; + case "RuntimeVisibleTypeAnnotations": + if(majorVersion < 52) + { + goto default; + } + CreateUtf8ConstantPoolItems(utf8_cp); + runtimeVisibleTypeAnnotations = br.Section(br.ReadUInt32()).ToArray(); + break; case "IKVM.NET.Assembly": if(br.ReadUInt32() != 2) { @@ -528,6 +543,17 @@ namespace IKVM.Internal // } } + private void CreateUtf8ConstantPoolItems(string[] utf8_cp) + { + for (int i = 0; i < constantpool.Length; i++) + { + if (constantpool[i] == null && utf8_cp[i] != null) + { + constantpool[i] = new ConstantPoolItemUtf8(utf8_cp[i]); + } + } + } + private void CheckDuplicates(T[] members, string msg) where T : IEquatable { @@ -558,6 +584,66 @@ namespace IKVM.Internal } } + private void PatchConstantPool(object[] constantPoolPatches, string[] utf8_cp, string inputClassName) + { +#if !STATIC_COMPILER && !FIRST_PASS + for (int i = 0; i < constantPoolPatches.Length; i++) + { + if (constantPoolPatches[i] != null) + { + if (utf8_cp[i] != null) + { + if (!(constantPoolPatches[i] is string)) + { + throw new ClassFormatError("Illegal utf8 patch at {0} in class file {1}", i, inputClassName); + } + utf8_cp[i] = (string)constantPoolPatches[i]; + } + else if (constantpool[i] != null) + { + switch (constantpool[i].GetConstantType()) + { + case ConstantType.String: + constantpool[i] = new ConstantPoolItemLiveObject(constantPoolPatches[i]); + break; + case ConstantType.Class: + java.lang.Class clazz; + string name; + if ((clazz = constantPoolPatches[i] as java.lang.Class) != null) + { + TypeWrapper tw = TypeWrapper.FromClass(clazz); + constantpool[i] = new ConstantPoolItemClass(tw.Name, tw); + } + else if ((name = constantPoolPatches[i] as string) != null) + { + constantpool[i] = new ConstantPoolItemClass(String.Intern(name.Replace('/', '.')), null); + } + else + { + throw new ClassFormatError("Illegal class patch at {0} in class file {1}", i, inputClassName); + } + break; + case ConstantType.Integer: + ((ConstantPoolItemInteger)constantpool[i]).v = ((java.lang.Integer)constantPoolPatches[i]).intValue(); + break; + case ConstantType.Long: + ((ConstantPoolItemLong)constantpool[i]).l = ((java.lang.Long)constantPoolPatches[i]).longValue(); + break; + case ConstantType.Float: + ((ConstantPoolItemFloat)constantpool[i]).v = ((java.lang.Float)constantPoolPatches[i]).floatValue(); + break; + case ConstantType.Double: + ((ConstantPoolItemDouble)constantpool[i]).d = ((java.lang.Double)constantPoolPatches[i]).doubleValue(); + break; + default: + throw new NotImplementedException("ConstantPoolPatch: " + constantPoolPatches[i]); + } + } + } + } +#endif + } + private void MarkLinkRequiredConstantPoolItem(int index) { if (index > 0 && index < constantpool.Length && constantpool[index] != null) @@ -730,7 +816,7 @@ namespace IKVM.Internal } for(int i = 0; i < name.Length; i++) { - if(".;/<>".IndexOf(name[i]) != -1) + if(".;[/<>".IndexOf(name[i]) != -1) { return false; } @@ -746,7 +832,7 @@ namespace IKVM.Internal } for(int i = 0; i < name.Length; i++) { - if(".;/".IndexOf(name[i]) != -1) + if(".;[/".IndexOf(name[i]) != -1) { return false; } @@ -875,6 +961,8 @@ namespace IKVM.Internal internal void Link(TypeWrapper thisType) { + // this is not just an optimization, it's required for anonymous classes to be able to refer to themselves + ((ConstantPoolItemClass)constantpool[this_class]).LinkSelf(thisType); for(int i = 1; i < constantpool.Length; i++) { if(constantpool[i] != null) @@ -1102,6 +1190,11 @@ namespace IKVM.Internal return (ConstantPoolItemMethodType)constantpool[index]; } + internal object GetConstantPoolConstantLiveObject(int index) + { + return ((ConstantPoolItemLiveObject)constantpool[index]).Value; + } + internal string Name { get @@ -1110,11 +1203,11 @@ namespace IKVM.Internal } } - internal string SuperClass + internal ConstantPoolItemClass SuperClass { get { - return GetConstantPoolClass(super_class); + return (ConstantPoolItemClass)constantpool[super_class]; } } @@ -1184,6 +1277,27 @@ namespace IKVM.Internal } } + internal byte[] RuntimeVisibleTypeAnnotations + { + get + { + return runtimeVisibleTypeAnnotations; + } + } + + internal object[] GetConstantPool() + { + object[] cp = new object[constantpool.Length]; + for (int i = 1; i < cp.Length; i++) + { + if (constantpool[i] != null) + { + cp[i] = constantpool[i].GetRuntimeValue(); + } + } + return cp; + } + internal string IKVMAssemblyAttribute { get @@ -1301,6 +1415,7 @@ namespace IKVM.Internal Class, MethodHandle, MethodType, + LiveObject, // used by anonymous class constant pool patching } internal abstract class ConstantPoolItem @@ -1321,6 +1436,13 @@ namespace IKVM.Internal internal virtual void MarkLinkRequired() { } + + // this is used for sun.reflect.ConstantPool + // it returns a boxed System.Int32, System.Int64, System.Float, System.Double or a string + internal virtual object GetRuntimeValue() + { + return null; + } } internal sealed class ConstantPoolItemClass : ConstantPoolItem, IEquatable @@ -1328,15 +1450,26 @@ namespace IKVM.Internal private ushort name_index; private string name; private TypeWrapper typeWrapper; - private static char[] invalidJava15Characters = { '.', ';' }; + private static char[] invalidJava15Characters = { '.', ';', '[', ']' }; internal ConstantPoolItemClass(BigEndianBinaryReader br) { name_index = br.ReadUInt16(); } + internal ConstantPoolItemClass(string name, TypeWrapper typeWrapper) + { + this.name = name; + this.typeWrapper = typeWrapper; + } + internal override void Resolve(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions options) { + // if the item was patched, we already have a name + if(name != null) + { + return; + } name = classFile.GetConstantPoolUtf8String(utf8_cp, name_index); if(name.Length > 0) { @@ -1383,6 +1516,7 @@ namespace IKVM.Internal #endif { // since 1.5 the restrictions on class names have been greatly reduced + int start = 0; int end = name.Length; if(name[0] == '[') { @@ -1398,8 +1532,12 @@ namespace IKVM.Internal { end--; } + while(name[start] == '[') + { + start++; + } } - if(name.IndexOfAny(invalidJava15Characters, 0, end) >= 0) + if(name.IndexOfAny(invalidJava15Characters, start, end - start) >= 0) { goto barf; } @@ -1413,7 +1551,15 @@ namespace IKVM.Internal internal override void MarkLinkRequired() { - typeWrapper = VerifierTypeWrapper.Null; + if(typeWrapper == null) + { + typeWrapper = VerifierTypeWrapper.Null; + } + } + + internal void LinkSelf(TypeWrapper thisType) + { + this.typeWrapper = thisType; } internal override void Link(TypeWrapper thisType) @@ -1469,7 +1615,7 @@ namespace IKVM.Internal private sealed class ConstantPoolItemDouble : ConstantPoolItem { - private double d; + internal double d; internal ConstantPoolItemDouble(BigEndianBinaryReader br) { @@ -1488,6 +1634,11 @@ namespace IKVM.Internal return d; } } + + internal override object GetRuntimeValue() + { + return d; + } } internal abstract class ConstantPoolItemFMI : ConstantPoolItem @@ -1799,7 +1950,7 @@ namespace IKVM.Internal private sealed class ConstantPoolItemFloat : ConstantPoolItem { - private float v; + internal float v; internal ConstantPoolItemFloat(BigEndianBinaryReader br) { @@ -1818,11 +1969,16 @@ namespace IKVM.Internal return v; } } + + internal override object GetRuntimeValue() + { + return v; + } } private sealed class ConstantPoolItemInteger : ConstantPoolItem { - private int v; + internal int v; internal ConstantPoolItemInteger(BigEndianBinaryReader br) { @@ -1841,11 +1997,16 @@ namespace IKVM.Internal return v; } } + + internal override object GetRuntimeValue() + { + return v; + } } private sealed class ConstantPoolItemLong : ConstantPoolItem { - private long l; + internal long l; internal ConstantPoolItemLong(BigEndianBinaryReader br) { @@ -1864,6 +2025,11 @@ namespace IKVM.Internal return l; } } + + internal override object GetRuntimeValue() + { + return l; + } } private sealed class ConstantPoolItemNameAndType : ConstantPoolItem @@ -1914,7 +2080,7 @@ namespace IKVM.Internal case RefKind.invokeStatic: case RefKind.newInvokeSpecial: cpi = classFile.GetConstantPoolItem(method_index) as ConstantPoolItemMethodref; - if (cpi == null && classFile.MajorVersion >= 52 && (RefKind)ref_kind == RefKind.invokeStatic) + if (cpi == null && classFile.MajorVersion >= 52 && ((RefKind)ref_kind == RefKind.invokeStatic || (RefKind)ref_kind == RefKind.invokeSpecial)) goto case RefKind.invokeInterface; break; case RefKind.invokeInterface: @@ -2146,6 +2312,38 @@ namespace IKVM.Internal } } + // this is only used to copy strings into "constantpool" when we see a RuntimeVisibleTypeAnnotations attribute, + // because we need a consistent way of exposing constant pool items to the runtime and that case + private sealed class ConstantPoolItemUtf8 : ConstantPoolItem + { + private readonly string str; + + internal ConstantPoolItemUtf8(string str) + { + this.str = str; + } + + internal override object GetRuntimeValue() + { + return str; + } + } + + private sealed class ConstantPoolItemLiveObject : ConstantPoolItem + { + internal readonly object Value; + + internal ConstantPoolItemLiveObject(object value) + { + this.Value = value; + } + + internal override ConstantType GetConstantType() + { + return ConstantType.LiveObject; + } + } + internal enum Constant { Utf8 = 1, @@ -2173,6 +2371,7 @@ namespace IKVM.Internal private string descriptor; protected string signature; protected object[] annotations; + protected byte[] runtimeVisibleTypeAnnotations; internal FieldOrMethod(ClassFile classFile, string[] utf8_cp, BigEndianBinaryReader br) { @@ -2329,6 +2528,14 @@ namespace IKVM.Internal } } + internal byte[] RuntimeVisibleTypeAnnotations + { + get + { + return runtimeVisibleTypeAnnotations; + } + } + public sealed override int GetHashCode() { return name.GetHashCode() ^ descriptor.GetHashCode(); @@ -2463,6 +2670,14 @@ namespace IKVM.Internal #endif } break; + case "RuntimeVisibleTypeAnnotations": + if (classFile.MajorVersion < 52) + { + goto default; + } + classFile.CreateUtf8ConstantPoolItems(utf8_cp); + runtimeVisibleTypeAnnotations = br.Section(br.ReadUInt32()).ToArray(); + break; default: br.Skip(br.ReadUInt32()); break; @@ -2568,6 +2783,7 @@ namespace IKVM.Internal #if STATIC_COMPILER internal string DllExportName; internal int DllExportOrdinal; + internal string InterlockedCompareAndSetField; #endif } @@ -2655,15 +2871,29 @@ namespace IKVM.Internal goto default; } annotations = ReadAnnotations(br, classFile, utf8_cp); -#if STATIC_COMPILER - foreach(object[] annot in annotations) + if ((options & ClassFileParseOptions.TrustedAnnotations) != 0) { - if(annot[1].Equals("Lsun/reflect/CallerSensitive;")) + foreach(object[] annot in annotations) { - flags |= FLAG_CALLERSENSITIVE; + switch((string)annot[1]) + { +#if STATIC_COMPILER + case "Lsun/reflect/CallerSensitive;": + flags |= FLAG_CALLERSENSITIVE; + break; +#endif + case "Ljava/lang/invoke/LambdaForm$Compiled;": + flags |= FLAG_LAMBDAFORM_COMPILED; + break; + case "Ljava/lang/invoke/LambdaForm$Hidden;": + flags |= FLAG_LAMBDAFORM_HIDDEN; + break; + case "Ljava/lang/invoke/ForceInline;": + flags |= FLAG_FORCEINLINE; + break; + } } } -#endif break; case "RuntimeVisibleParameterAnnotations": { @@ -2763,6 +2993,25 @@ namespace IKVM.Internal } } } + if(annot[1].Equals("Likvm/internal/InterlockedCompareAndSet;")) + { + string field = null; + for (int j = 2; j < annot.Length; j += 2) + { + if (annot[j].Equals("value") && annot[j + 1] is string) + { + field = (string)annot[j + 1]; + } + } + if (field != null) + { + if (low == null) + { + low = new LowFreqData(); + } + low.InterlockedCompareAndSetField = field; + } + } } break; #endif @@ -2776,20 +3025,17 @@ namespace IKVM.Internal { throw new ClassFormatError("{0} (Duplicate MethodParameters attribute)", classFile.Name); } - BigEndianBinaryReader rdr = br.Section(br.ReadUInt32()); - byte parameters_count = rdr.ReadByte(); - parameters = new MethodParametersEntry[parameters_count]; - for(int j = 0; j < parameters_count; j++) - { - parameters[j].name = classFile.GetConstantPoolUtf8String(utf8_cp, rdr.ReadUInt16()); - parameters[j].flags = rdr.ReadUInt16(); - } - if(!rdr.IsAtEnd) - { - throw new ClassFormatError("{0} (MethodParameters attribute has wrong length)", classFile.Name); - } + parameters = ReadMethodParameters(br, utf8_cp); break; } + case "RuntimeVisibleTypeAnnotations": + if (classFile.MajorVersion < 52) + { + goto default; + } + classFile.CreateUtf8ConstantPoolItems(utf8_cp); + runtimeVisibleTypeAnnotations = br.Section(br.ReadUInt32()).ToArray(); + break; default: br.Skip(br.ReadUInt32()); break; @@ -2799,7 +3045,7 @@ namespace IKVM.Internal { if(!code.IsEmpty) { - throw new ClassFormatError("Abstract or native method cannot have a Code attribute"); + throw new ClassFormatError("Code attribute in native or abstract methods in class file " + classFile.Name); } } else @@ -2816,6 +3062,32 @@ namespace IKVM.Internal } } + private static MethodParametersEntry[] ReadMethodParameters(BigEndianBinaryReader br, string[] utf8_cp) + { + uint length = br.ReadUInt32(); + if(length > 0) + { + BigEndianBinaryReader rdr = br.Section(length); + byte parameters_count = rdr.ReadByte(); + if(length == 1 + parameters_count * 4) + { + MethodParametersEntry[] parameters = new MethodParametersEntry[parameters_count]; + for(int j = 0; j < parameters_count; j++) + { + ushort name = rdr.ReadUInt16(); + if(name >= utf8_cp.Length || (name != 0 && utf8_cp[name] == null)) + { + return MethodParametersEntry.Malformed; + } + parameters[j].name = utf8_cp[name]; + parameters[j].flags = rdr.ReadUInt16(); + } + return parameters; + } + } + throw new ClassFormatError("Invalid MethodParameters method attribute length " + length + " in class file"); + } + protected override void ValidateSig(ClassFile classFile, string descriptor) { if(!IsValidMethodSig(descriptor)) @@ -2832,6 +3104,15 @@ namespace IKVM.Internal } } + internal bool IsVirtual + { + get + { + return (access_flags & (Modifiers.Static | Modifiers.Private)) == 0 + && !IsConstructor; + } + } + // Is this the ()V method? internal bool IsClassInitializer { @@ -2859,6 +3140,30 @@ namespace IKVM.Internal } #endif + internal bool IsLambdaFormCompiled + { + get + { + return (flags & FLAG_LAMBDAFORM_COMPILED) != 0; + } + } + + internal bool IsLambdaFormHidden + { + get + { + return (flags & FLAG_LAMBDAFORM_HIDDEN) != 0; + } + } + + internal bool IsForceInline + { + get + { + return (flags & FLAG_FORCEINLINE) != 0; + } + } + internal string[] ExceptionsAttribute { get @@ -2899,6 +3204,14 @@ namespace IKVM.Internal return low == null ? -1 : low.DllExportOrdinal; } } + + internal string InterlockedCompareAndSetField + { + get + { + return low == null ? null : low.InterlockedCompareAndSetField; + } + } #endif internal string VerifyError @@ -2982,6 +3295,14 @@ namespace IKVM.Internal } } + internal bool MalformedMethodParameters + { + get + { + return parameters == MethodParametersEntry.Malformed; + } + } + internal bool HasJsr { get @@ -3007,9 +3328,9 @@ namespace IKVM.Internal max_stack = br.ReadUInt16(); max_locals = br.ReadUInt16(); uint code_length = br.ReadUInt32(); - if(code_length > 65535) + if(code_length == 0 || code_length > 65535) { - throw new ClassFormatError("{0} (Invalid Code length {1})", classFile.Name, code_length); + throw new ClassFormatError("Invalid method Code length {1} in class file {0}", classFile.Name, code_length); } Instruction[] instructions = new Instruction[code_length + 1]; int basePosition = br.Position; @@ -3563,12 +3884,6 @@ namespace IKVM.Internal internal string descriptor; internal ushort index; } - - internal struct MethodParametersEntry - { - internal string name; - internal ushort flags; - } } internal Field GetField(string name, string sig) diff --git a/external/ikvm/runtime/ClassLoaderWrapper.cs b/external/ikvm/runtime/ClassLoaderWrapper.cs index 813e41f604..9eee11a503 100644 --- a/external/ikvm/runtime/ClassLoaderWrapper.cs +++ b/external/ikvm/runtime/ClassLoaderWrapper.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2013 Jeroen Frijters + Copyright (C) 2002-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 @@ -52,16 +52,18 @@ namespace IKVM.Internal RemoveAsserts = 16, NoAutomagicSerialization = 32, DisableDynamicBinding = 64, + NoRefEmitHelpers = 128, } #if !STUB_GENERATOR abstract class TypeWrapperFactory { internal abstract ModuleBuilder ModuleBuilder { get; } - internal abstract TypeWrapper DefineClassImpl(Dictionary types, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain protectionDomain); + internal abstract TypeWrapper DefineClassImpl(Dictionary types, TypeWrapper host, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain protectionDomain); internal abstract bool ReserveName(string name); internal abstract string AllocMangledName(DynamicTypeWrapper tw); internal abstract Type DefineUnloadable(string name); + internal abstract Type DefineDelegate(int parameterCount, bool returnVoid); internal abstract bool HasInternalAccess { get; } #if CLASSGC internal abstract void AddInternalsVisibleTo(Assembly friend); @@ -293,6 +295,50 @@ namespace IKVM.Internal } } + internal bool EmitNoRefEmitHelpers + { + get + { + return (codegenoptions & CodeGenOptions.NoRefEmitHelpers) != 0; + } + } + + internal bool WorkaroundAbstractMethodWidening + { + get + { + // pre-Roslyn C# compiler doesn't like widening access to abstract methods + return true; + } + } + + internal bool WorkaroundInterfaceFields + { + get + { + // pre-Roslyn C# compiler doesn't allow access to interface fields + return true; + } + } + + internal bool WorkaroundInterfacePrivateMethods + { + get + { + // pre-Roslyn C# compiler doesn't like interfaces that have non-public methods + return true; + } + } + + internal bool WorkaroundInterfaceStaticMethods + { + get + { + // pre-Roslyn C# compiler doesn't allow access to interface static methods + return true; + } + } + #if !STATIC_COMPILER && !STUB_GENERATOR internal bool RelaxedClassNameValidation { @@ -307,6 +353,14 @@ namespace IKVM.Internal } #endif // !STATIC_COMPILER && !STUB_GENERATOR + protected virtual void CheckProhibitedPackage(string className) + { + if (className.StartsWith("java.", StringComparison.Ordinal)) + { + throw new JavaSecurityException("Prohibited package name: " + className.Substring(0, className.LastIndexOf('.'))); + } + } + #if !STUB_GENERATOR internal TypeWrapper DefineClass(ClassFile f, ProtectionDomain protectionDomain) { @@ -334,6 +388,7 @@ namespace IKVM.Internal return RegisterInitiatingLoader(tw); } #endif + CheckProhibitedPackage(f.Name); // check if the class already exists if we're an AssemblyClassLoader if(FindLoadedClassLazy(f.Name) != null) { @@ -365,7 +420,7 @@ namespace IKVM.Internal } try { - return GetTypeWrapperFactory().DefineClassImpl(types, f, this, protectionDomain); + return GetTypeWrapperFactory().DefineClassImpl(types, null, f, this, protectionDomain); } finally { @@ -775,15 +830,6 @@ namespace IKVM.Internal } #endif - internal TypeWrapper ExpressionTypeWrapper(string type) - { - Debug.Assert(!type.StartsWith("Lret;")); - Debug.Assert(type != "Lnull"); - - int index = 0; - return SigDecoderWrapper(ref index, type, false); - } - // NOTE this exposes potentially unfinished types internal Type[] ArgTypeListFromSig(string sig) { @@ -802,7 +848,7 @@ namespace IKVM.Internal private TypeWrapper SigDecoderLoadClass(string name, bool nothrow) { - return nothrow ? LoadClassNoThrow(this, name) : LoadClassByDottedName(name); + return nothrow ? LoadClassNoThrow(this, name, false) : LoadClassByDottedName(name); } // NOTE: this will ignore anything following the sig marker (so that it can be used to decode method signatures) @@ -1038,16 +1084,40 @@ namespace IKVM.Internal { Assembly asm = type.Assembly; #if CLASSGC - ClassLoaderWrapper loader; + ClassLoaderWrapper loader = null; if(dynamicAssemblies != null && dynamicAssemblies.TryGetValue(asm, out loader)) { lock(loader.typeToTypeWrapper) { - return loader.typeToTypeWrapper[type]; + TypeWrapper tw; + if(loader.typeToTypeWrapper.TryGetValue(type, out tw)) + { + return tw; + } + // it must be an anonymous type then + Debug.Assert(AnonymousTypeWrapper.IsAnonymous(type)); } } #endif #if !STATIC_COMPILER && !STUB_GENERATOR + if(AnonymousTypeWrapper.IsAnonymous(type)) + { + Dictionary typeToTypeWrapper; +#if CLASSGC + typeToTypeWrapper = loader != null ? loader.typeToTypeWrapper : globalTypeToTypeWrapper; +#else + typeToTypeWrapper = globalTypeToTypeWrapper; +#endif + TypeWrapper tw = new AnonymousTypeWrapper(type); + lock(typeToTypeWrapper) + { + if(!typeToTypeWrapper.TryGetValue(type, out wrapper)) + { + typeToTypeWrapper.Add(type, wrapper = tw); + } + } + return wrapper; + } if(ReflectUtil.IsReflectionOnly(type)) { // historically we've always returned null for types that don't have a corresponding TypeWrapper (or java.lang.Class) @@ -1340,7 +1410,7 @@ namespace IKVM.Internal } #endif - internal static TypeWrapper LoadClassNoThrow(ClassLoaderWrapper classLoader, string name) + internal static TypeWrapper LoadClassNoThrow(ClassLoaderWrapper classLoader, string name, bool issueWarning) { try { @@ -1355,7 +1425,10 @@ namespace IKVM.Internal elementTypeName = elementTypeName.Substring(skip, elementTypeName.Length - skip - 1); } #if STATIC_COMPILER - classLoader.IssueMessage(Message.ClassNotFound, elementTypeName); + if (issueWarning || classLoader.WarningLevelHigh) + { + classLoader.IssueMessage(Message.ClassNotFound, elementTypeName); + } #else Tracer.Error(Tracer.ClassLoading, "Class not found: {0}", elementTypeName); #endif @@ -1413,6 +1486,54 @@ namespace IKVM.Internal } #endif } + +#if !STUB_GENERATOR + internal ClassFileParseOptions ClassFileParseOptions + { + get + { +#if STATIC_COMPILER + ClassFileParseOptions cfp = ClassFileParseOptions.LocalVariableTable; + if (EmitStackTraceInfo) + { + cfp |= ClassFileParseOptions.LineNumberTable; + } + if (bootstrapClassLoader is CompilerClassLoader) + { + cfp |= ClassFileParseOptions.TrustedAnnotations; + } + return cfp; +#else + ClassFileParseOptions cfp = ClassFileParseOptions.LineNumberTable; + if (EmitDebugInfo) + { + cfp |= ClassFileParseOptions.LocalVariableTable; + } + if (RelaxedClassNameValidation) + { + cfp |= ClassFileParseOptions.RelaxedClassNameValidation; + } + if (this == bootstrapClassLoader) + { + cfp |= ClassFileParseOptions.TrustedAnnotations; + } + return cfp; +#endif + } + } +#endif + +#if STATIC_COMPILER + internal virtual bool WarningLevelHigh + { + get { return false; } + } + + internal virtual bool NoParameterReflection + { + get { return false; } + } +#endif } sealed class GenericClassLoaderWrapper : ClassLoaderWrapper @@ -1495,7 +1616,7 @@ namespace IKVM.Internal if (name.EndsWith(".class", StringComparison.Ordinal) && name.IndexOf('.') == name.Length - 6) { TypeWrapper tw = FindLoadedClass(name.Substring(0, name.Length - 6).Replace('/', '.')); - if (tw != null && !tw.IsArray && !(tw is DynamicTypeWrapper)) + if (tw != null && !tw.IsArray && !tw.IsDynamic) { ClassLoaderWrapper loader = tw.GetClassLoader(); if (loader is GenericClassLoaderWrapper) @@ -1521,7 +1642,7 @@ namespace IKVM.Internal if (name.EndsWith(".class", StringComparison.Ordinal) && name.IndexOf('.') == name.Length - 6) { TypeWrapper tw = FindLoadedClass(name.Substring(0, name.Length - 6).Replace('/', '.')); - if (tw != null && tw.GetClassLoader() == this && !tw.IsArray && !(tw is DynamicTypeWrapper)) + if (tw != null && tw.GetClassLoader() == this && !tw.IsArray && !tw.IsDynamic) { return new java.net.URL("ikvmres", "gen", ClassLoaderWrapper.GetGenericClassLoaderId(this), "/" + name); } diff --git a/external/ikvm/runtime/DotNetTypeWrapper.cs b/external/ikvm/runtime/DotNetTypeWrapper.cs index 94e699388d..657a1d46d5 100644 --- a/external/ikvm/runtime/DotNetTypeWrapper.cs +++ b/external/ikvm/runtime/DotNetTypeWrapper.cs @@ -272,7 +272,7 @@ namespace IKVM.Internal { return false; } - if (type.Assembly == IKVM.NativeCode.java.lang.SecurityManager.jniAssembly) + if (type.Assembly == Java_java_lang_SecurityManager.jniAssembly) { return false; } @@ -359,7 +359,7 @@ namespace IKVM.Internal this.baseWrapper = baseWrapper; } - internal override TypeWrapper BaseTypeWrapper + internal sealed override TypeWrapper BaseTypeWrapper { get { return baseWrapper; } } @@ -368,6 +368,11 @@ namespace IKVM.Internal { get { return true; } } + + internal sealed override Modifiers ReflectiveModifiers + { + get { return Modifiers | Modifiers.Static; } + } } private sealed class DelegateInnerClassTypeWrapper : FakeTypeWrapper @@ -450,16 +455,21 @@ namespace IKVM.Internal { get { return true; } } + + internal override MethodParametersEntry[] GetMethodParameters(MethodWrapper mw) + { + return DeclaringTypeWrapper.GetMethodParameters(DeclaringTypeWrapper.GetMethodWrapper(mw.Name, mw.Signature, false)); + } } - private class DynamicOnlyMethodWrapper : MethodWrapper, ICustomInvoke + private class DynamicOnlyMethodWrapper : MethodWrapper { internal DynamicOnlyMethodWrapper(TypeWrapper declaringType, string name, string sig, TypeWrapper returnType, TypeWrapper[] parameterTypes, MemberFlags flags) : base(declaringType, name, sig, null, returnType, parameterTypes, Modifiers.Public | Modifiers.Abstract, flags) { } - internal override bool IsDynamicOnly + internal sealed override bool IsDynamicOnly { get { @@ -468,7 +478,8 @@ namespace IKVM.Internal } #if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR - object ICustomInvoke.Invoke(object obj, object[] args) + [HideFromJava] + internal sealed override object Invoke(object obj, object[] args) { // a DynamicOnlyMethodWrapper is an interface method, but now that we've been called on an actual object instance, // we can resolve to a real method and call that instead @@ -482,14 +493,9 @@ namespace IKVM.Internal { throw new java.lang.IllegalAccessError(tw.Name + "." + this.Name + this.Signature); } - if (mw.HasCallerID) - { - // an interface method cannot require a CallerID - throw new InvalidOperationException(); - } - java.lang.reflect.Method m = (java.lang.reflect.Method)mw.ToMethodOrConstructor(true); - m.@override = true; - return m.invoke(obj, args, null); + mw.Link(); + mw.ResolveMethod(); + return mw.Invoke(obj, args); } #endif // !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR } @@ -508,10 +514,10 @@ namespace IKVM.Internal #endif } -#if !STATIC_COMPILER && !STUB_GENERATOR +#if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS internal object GetUnspecifiedValue() { - return ((EnumFieldWrapper)GetFieldWrapper("__unspecified", this.SigName)).GetValue(); + return GetFieldWrapper("__unspecified", this.SigName).GetValue(null); } #endif @@ -530,8 +536,8 @@ namespace IKVM.Internal #endif } -#if !STATIC_COMPILER && !STUB_GENERATOR - internal object GetValue() +#if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS + internal override object GetValue(object obj) { if (val == null) { @@ -539,9 +545,13 @@ namespace IKVM.Internal } return val; } + + internal override void SetValue(object obj, object value) + { + } #endif -#if !STUB_GENERATOR +#if EMITTERS protected override void EmitGetImpl(CodeEmitter ilgen) { #if STATIC_COMPILER @@ -556,10 +566,10 @@ namespace IKVM.Internal protected override void EmitSetImpl(CodeEmitter ilgen) { } -#endif // !STUB_GENERATOR +#endif // EMITTERS } - private sealed class EnumValuesMethodWrapper : MethodWrapper, ICustomInvoke + private sealed class EnumValuesMethodWrapper : MethodWrapper { internal EnumValuesMethodWrapper(TypeWrapper declaringType) : base(declaringType, "values", "()[" + declaringType.SigName, null, declaringType.MakeArrayType(1), TypeWrapper.EmptyArray, Modifiers.Public | Modifiers.Static, MemberFlags.None) @@ -575,20 +585,20 @@ namespace IKVM.Internal } #if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR - object ICustomInvoke.Invoke(object obj, object[] args) + internal override object Invoke(object obj, object[] args) { FieldWrapper[] values = this.DeclaringType.GetFields(); object[] array = (object[])Array.CreateInstance(this.DeclaringType.TypeAsArrayType, values.Length); for (int i = 0; i < values.Length; i++) { - array[i] = ((EnumFieldWrapper)values[i]).GetValue(); + array[i] = values[i].GetValue(null); } return array; } #endif // !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR } - private sealed class EnumValueOfMethodWrapper : MethodWrapper, ICustomInvoke + private sealed class EnumValueOfMethodWrapper : MethodWrapper { internal EnumValueOfMethodWrapper(TypeWrapper declaringType) : base(declaringType, "valueOf", "(Ljava.lang.String;)" + declaringType.SigName, null, declaringType, new TypeWrapper[] { CoreClasses.java.lang.String.Wrapper }, Modifiers.Public | Modifiers.Static, MemberFlags.None) @@ -604,14 +614,14 @@ namespace IKVM.Internal } #if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR - object ICustomInvoke.Invoke(object obj, object[] args) + internal override object Invoke(object obj, object[] args) { FieldWrapper[] values = this.DeclaringType.GetFields(); for (int i = 0; i < values.Length; i++) { if (values[i].Name.Equals(args[0])) { - return ((EnumFieldWrapper)values[i]).GetValue(); + return values[i].GetValue(null); } } throw new java.lang.IllegalArgumentException("" + args[0]); @@ -1800,7 +1810,7 @@ namespace IKVM.Internal this.iface = iface; } -#if !STUB_GENERATOR +#if EMITTERS internal override bool EmitIntrinsic(EmitIntrinsicContext context) { TypeWrapper targetType = context.GetStackTypeWrapper(0, 0); @@ -1851,7 +1861,7 @@ namespace IKVM.Internal ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicCreateDelegate); ilgen.Emit(OpCodes.Castclass, delegateConstructor.DeclaringType); } -#endif // !STUB_GENERATOR +#endif // EMITTERS } private sealed class ByRefMethodWrapper : SmartMethodWrapper @@ -1870,7 +1880,7 @@ namespace IKVM.Internal #endif } -#if !STUB_GENERATOR +#if EMITTERS protected override void CallImpl(CodeEmitter ilgen) { ConvertByRefArgs(ilgen); @@ -1912,7 +1922,7 @@ namespace IKVM.Internal } } } -#endif // !STUB_GENERATOR +#endif // EMITTERS } private sealed class EnumWrapMethodWrapper : MethodWrapper @@ -1922,14 +1932,21 @@ namespace IKVM.Internal { } -#if !STUB_GENERATOR +#if EMITTERS internal override void EmitCall(CodeEmitter ilgen) { // We don't actually need to do anything here! // The compiler will insert a boxing operation after calling us and that will // result in our argument being boxed (since that's still sitting on the stack). } -#endif // !STUB_GENERATOR +#endif // EMITTERS + +#if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS + internal override object Invoke(object obj, object[] args) + { + return Enum.ToObject(DeclaringType.TypeAsTBD, args[0]); + } +#endif } internal sealed class EnumValueFieldWrapper : FieldWrapper @@ -1942,7 +1959,7 @@ namespace IKVM.Internal underlyingType = EnumHelper.GetUnderlyingType(tw.type); } -#if !STUB_GENERATOR +#if EMITTERS protected override void EmitGetImpl(CodeEmitter ilgen) { // NOTE if the reference on the stack is null, we *want* the NullReferenceException, so we don't use TypeWrapper.EmitUnbox @@ -1960,7 +1977,19 @@ namespace IKVM.Internal ilgen.Emit(OpCodes.Stobj, underlyingType); ilgen.ReleaseTempLocal(temp); } -#endif // !STUB_GENERATOR +#endif // EMITTERS + +#if !STUB_GENERATOR && !STATIC_COMPILER && !FIRST_PASS + internal override object GetValue(object obj) + { + return obj; + } + + internal override void SetValue(object obj, object value) + { + obj.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance)[0].SetValue(obj, value); + } +#endif } private sealed class ValueTypeDefaultCtor : MethodWrapper @@ -1970,14 +1999,21 @@ namespace IKVM.Internal { } -#if !STUB_GENERATOR +#if EMITTERS internal override void EmitNewobj(CodeEmitter ilgen) { CodeEmitterLocal local = ilgen.DeclareLocal(DeclaringType.TypeAsTBD); ilgen.Emit(OpCodes.Ldloc, local); ilgen.Emit(OpCodes.Box, DeclaringType.TypeAsTBD); } -#endif // !STUB_GENERATOR +#endif // EMITTERS + +#if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS + internal override object CreateInstance(object[] args) + { + return Activator.CreateInstance(DeclaringType.TypeAsTBD); + } +#endif } private sealed class FinalizeMethodWrapper : MethodWrapper @@ -1987,7 +2023,7 @@ namespace IKVM.Internal { } -#if !STUB_GENERATOR +#if EMITTERS internal override void EmitCall(CodeEmitter ilgen) { ilgen.Emit(OpCodes.Pop); @@ -1997,7 +2033,7 @@ namespace IKVM.Internal { ilgen.Emit(OpCodes.Pop); } -#endif // !STUB_GENERATOR +#endif // EMITTERS } private sealed class CloneMethodWrapper : MethodWrapper @@ -2007,7 +2043,7 @@ namespace IKVM.Internal { } -#if !STUB_GENERATOR +#if EMITTERS internal override void EmitCall(CodeEmitter ilgen) { ilgen.Emit(OpCodes.Dup); @@ -2027,7 +2063,7 @@ namespace IKVM.Internal { EmitCall(ilgen); } -#endif // !STUB_GENERATOR +#endif // EMITTERS } protected override void LazyPublishMembers() @@ -2269,9 +2305,7 @@ namespace IKVM.Internal && !typeof(java.io.Serializable.__Interface).IsAssignableFrom(type) && !methodsList.ContainsKey("writeReplace()Ljava.lang.Object;")) { - methodsList.Add("writeReplace()Ljava.lang.Object;", new SimpleCallMethodWrapper(this, "writeReplace", "()Ljava.lang.Object;", - typeof(ikvm.@internal.Serialization).GetMethod("writeReplace"), CoreClasses.java.lang.Object.Wrapper, TypeWrapper.EmptyArray, - Modifiers.Private, MemberFlags.None, SimpleOpCode.Call, SimpleOpCode.Call)); + methodsList.Add("writeReplace()Ljava.lang.Object;", new ExceptionWriteReplaceMethodWrapper(this)); } #endif // !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS @@ -2281,6 +2315,31 @@ namespace IKVM.Internal } } +#if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS + private sealed class ExceptionWriteReplaceMethodWrapper : MethodWrapper + { + internal ExceptionWriteReplaceMethodWrapper(TypeWrapper declaringType) + : base(declaringType, "writeReplace", "()Ljava.lang.Object;", null, CoreClasses.java.lang.Object.Wrapper, TypeWrapper.EmptyArray, Modifiers.Private, MemberFlags.None) + { + } + + internal override bool IsDynamicOnly + { + get { return true; } + } + + internal override object Invoke(object obj, object[] args) + { + Exception x = (Exception)obj; + com.sun.xml.@internal.ws.developer.ServerSideException sse + = new com.sun.xml.@internal.ws.developer.ServerSideException(ikvm.extensions.ExtensionMethods.getClass(x).getName(), x.Message); + sse.initCause(x.InnerException); + sse.setStackTrace(ikvm.extensions.ExtensionMethods.getStackTrace(x)); + return sse; + } + } +#endif // !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS + private void InterfaceMethodStubHelper(Dictionary methodsList, MethodBase method, string name, string sig, TypeWrapper[] args, TypeWrapper ret) { string key = name + sig; @@ -2317,7 +2376,7 @@ namespace IKVM.Internal { } -#if !STUB_GENERATOR +#if EMITTERS internal override void EmitCall(CodeEmitter ilgen) { // we direct EmitCall to EmitCallvirt, because we always want to end up at the instancehelper method @@ -2329,7 +2388,7 @@ namespace IKVM.Internal { m.EmitCallvirt(ilgen); } -#endif // !STUB_GENERATOR +#endif // EMITTERS } internal static bool IsUnsupportedAbstractMethod(MethodBase mb) @@ -2362,7 +2421,11 @@ namespace IKVM.Internal } type = type.GetElementType(); } +#if STATIC_COMPILER || STUB_GENERATOR + return type.__IsFunctionPointer; +#else return false; +#endif } private bool MakeMethodDescriptor(MethodBase mb, out string name, out string sig, out TypeWrapper[] args, out TypeWrapper ret) @@ -2493,12 +2556,12 @@ namespace IKVM.Internal foreach (ParameterInfo p in invoke.GetParameters()) { // we don't support delegates with pointer parameters - if (p.ParameterType.IsPointer) + if (IsPointerType(p.ParameterType)) { return false; } } - return true; + return !IsPointerType(invoke.ReturnType); } } return false; @@ -2668,7 +2731,7 @@ namespace IKVM.Internal } } -#if !STUB_GENERATOR +#if EMITTERS internal override void EmitInstanceOf(CodeEmitter ilgen) { if (IsRemapped) @@ -2698,7 +2761,7 @@ namespace IKVM.Internal } ilgen.EmitCastclass(type); } -#endif // !STUB_GENERATOR +#endif // EMITTERS internal override void Finish() { @@ -2726,6 +2789,38 @@ namespace IKVM.Internal finished = true; } + internal override MethodParametersEntry[] GetMethodParameters(MethodWrapper mw) + { + MethodBase mb = mw.GetMethod(); + if (mb == null) + { + return null; + } + ParameterInfo[] parameters = mb.GetParameters(); + if (parameters.Length == 0) + { + return null; + } + MethodParametersEntry[] mp = new MethodParametersEntry[parameters.Length]; + bool hasName = false; + for (int i = 0; i < mp.Length; i++) + { + string name = parameters[i].Name; + bool empty = String.IsNullOrEmpty(name); + if (empty) + { + name = "arg" + i; + } + mp[i].name = name; + hasName |= !empty; + } + if (!hasName) + { + return null; + } + return mp; + } + #if !STATIC_COMPILER && !STUB_GENERATOR internal override object[] GetDeclaredAnnotations() { @@ -2780,6 +2875,10 @@ namespace IKVM.Internal // (i.e. injected into the assembly) internal override bool IsPackageAccessibleFrom(TypeWrapper wrapper) { + if (wrapper == DeclaringTypeWrapper) + { + return true; + } if (!base.IsPackageAccessibleFrom(wrapper)) { return false; diff --git a/external/ikvm/runtime/DynamicClassLoader.cs b/external/ikvm/runtime/DynamicClassLoader.cs index 593080584a..e31fbc768b 100644 --- a/external/ikvm/runtime/DynamicClassLoader.cs +++ b/external/ikvm/runtime/DynamicClassLoader.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2013 Jeroen Frijters + Copyright (C) 2002-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 @@ -62,6 +62,7 @@ namespace IKVM.Internal #endif // STATIC_COMPILER private Dictionary unloadables; private TypeBuilder unloadableContainer; + private Type[] delegates; #if !STATIC_COMPILER && !CLASSGC private static DynamicClassLoader instance = new DynamicClassLoader(CreateModuleBuilder(), false); #endif @@ -222,21 +223,29 @@ namespace IKVM.Internal return mangledTypeName; } - internal sealed override TypeWrapper DefineClassImpl(Dictionary types, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain protectionDomain) + internal sealed override TypeWrapper DefineClassImpl(Dictionary types, TypeWrapper host, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain protectionDomain) { #if STATIC_COMPILER AotTypeWrapper type = new AotTypeWrapper(f, (CompilerClassLoader)classLoader); type.CreateStep1(); types[f.Name] = type; return type; +#elif FIRST_PASS + return null; #else // this step can throw a retargettable exception, if the class is incorrect - DynamicTypeWrapper type = new DynamicTypeWrapper(f, classLoader, protectionDomain); + DynamicTypeWrapper type = new DynamicTypeWrapper(host, f, classLoader, protectionDomain); // This step actually creates the TypeBuilder. It is not allowed to throw any exceptions, // if an exception does occur, it is due to a programming error in the IKVM or CLR runtime // and will cause a CriticalFailure and exit the process. type.CreateStep1(); type.CreateStep2(); + if(types == null) + { + // we're defining an anonymous class, so we don't need any locking + TieClassAndWrapper(type, protectionDomain); + return type; + } lock(types) { // in very extreme conditions another thread may have beaten us to it @@ -248,16 +257,7 @@ namespace IKVM.Internal if(race == null) { types[f.Name] = type; -#if !FIRST_PASS - java.lang.Class clazz = new java.lang.Class(null); -#if __MonoCS__ - TypeWrapper.SetTypeWrapperHack(clazz, type); -#else - clazz.typeWrapper = type; -#endif - clazz.pd = protectionDomain; - type.SetClassObject(clazz); -#endif + TieClassAndWrapper(type, protectionDomain); } else { @@ -268,42 +268,37 @@ namespace IKVM.Internal #endif // STATIC_COMPILER } +#if !STATIC_COMPILER && !FIRST_PASS + private static java.lang.Class TieClassAndWrapper(TypeWrapper type, ProtectionDomain protectionDomain) + { + java.lang.Class clazz = new java.lang.Class(null); +#if __MonoCS__ + TypeWrapper.SetTypeWrapperHack(clazz, type); +#else + clazz.typeWrapper = type; +#endif + clazz.pd = protectionDomain; + type.SetClassObject(clazz); + return clazz; + } +#endif + #if STATIC_COMPILER - internal TypeBuilder DefineProxy(TypeWrapper proxyClass, TypeWrapper[] interfaces) + internal TypeBuilder DefineProxy(string name, TypeAttributes typeAttributes, Type parent, Type[] interfaces) { if (proxiesContainer == null) { - proxiesContainer = moduleBuilder.DefineType("__", TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Abstract); + proxiesContainer = moduleBuilder.DefineType(TypeNameUtil.ProxiesContainer, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Abstract); AttributeHelper.HideFromJava(proxiesContainer); AttributeHelper.SetEditorBrowsableNever(proxiesContainer); proxies = new List(); } - Type[] ifaces = new Type[interfaces.Length]; - for (int i = 0; i < ifaces.Length; i++) - { - ifaces[i] = interfaces[i].TypeAsBaseType; - } - TypeBuilder tb = proxiesContainer.DefineNestedType(GetProxyNestedName(interfaces), TypeAttributes.NestedPublic | TypeAttributes.Class | TypeAttributes.Sealed, proxyClass.TypeAsBaseType, ifaces); + TypeBuilder tb = proxiesContainer.DefineNestedType(name, typeAttributes, parent, interfaces); proxies.Add(tb); return tb; } #endif - private static string GetProxyNestedName(TypeWrapper[] interfaces) - { - System.Text.StringBuilder sb = new System.Text.StringBuilder(); - foreach (TypeWrapper tw in interfaces) - { - sb.Append(tw.Name.Length).Append('|').Append(tw.Name); - } - return TypeNameUtil.MangleNestedTypeName(sb.ToString()); - } - - internal static string GetProxyName(TypeWrapper[] interfaces) - { - return "__+" + GetProxyNestedName(interfaces); - } - internal override Type DefineUnloadable(string name) { lock(this) @@ -328,6 +323,47 @@ namespace IKVM.Internal } } + internal override Type DefineDelegate(int parameterCount, bool returnVoid) + { + lock (this) + { + if (delegates == null) + { + delegates = new Type[512]; + } + int index = parameterCount + (returnVoid ? 256 : 0); + Type type = delegates[index]; + if (type != null) + { + return type; + } + TypeBuilder tb = moduleBuilder.DefineType(returnVoid ? "__<>NVIV`" + parameterCount : "__<>NVI`" + (parameterCount + 1), TypeAttributes.NotPublic | TypeAttributes.Sealed, Types.MulticastDelegate); + string[] names = new string[parameterCount + (returnVoid ? 0 : 1)]; + for (int i = 0; i < names.Length; i++) + { + names[i] = "P" + i; + } + if (!returnVoid) + { + names[names.Length - 1] = "R"; + } + Type[] genericParameters = tb.DefineGenericParameters(names); + Type[] parameterTypes = genericParameters; + if (!returnVoid) + { + parameterTypes = new Type[genericParameters.Length - 1]; + Array.Copy(genericParameters, parameterTypes, parameterTypes.Length); + } + tb.DefineMethod(ConstructorInfo.ConstructorName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, Types.Void, new Type[] { Types.Object, Types.IntPtr }) + .SetImplementationFlags(MethodImplAttributes.Runtime); + MethodBuilder mb = tb.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.NewSlot | MethodAttributes.Virtual, returnVoid ? Types.Void : genericParameters[genericParameters.Length - 1], parameterTypes); + mb.SetImplementationFlags(MethodImplAttributes.Runtime); + type = tb.CreateType(); + delegates[index] = type; + return type; + } + } + internal override bool HasInternalAccess { get { return hasInternalAccess; } @@ -403,7 +439,7 @@ namespace IKVM.Internal { AssemblyName name = new AssemblyName(); name.Name = "jniproxy"; - jniProxyAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave, null, null, null, null, null, true); + jniProxyAssemblyBuilder = DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave, null); return jniProxyAssemblyBuilder.DefineDynamicModule("jniproxy.dll", "jniproxy.dll"); } #endif @@ -544,12 +580,7 @@ namespace IKVM.Internal attribs.Add(new CustomAttributeBuilder(typeof(System.Security.SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes), new object[0])); } #endif - AssemblyBuilder assemblyBuilder = -#if NET_4_0 - AppDomain.CurrentDomain.DefineDynamicAssembly(name, access, null, true, attribs); -#else - AppDomain.CurrentDomain.DefineDynamicAssembly(name, access, null, null, null, null, null, true, attribs); -#endif + AssemblyBuilder assemblyBuilder = DefineDynamicAssembly(name, access, attribs); AttributeHelper.SetRuntimeCompatibilityAttribute(assemblyBuilder); bool debug = JVM.EmitSymbols; CustomAttributeBuilder debugAttr = new CustomAttributeBuilder(typeof(DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new object[] { true, debug }); @@ -558,6 +589,15 @@ namespace IKVM.Internal moduleBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(IKVM.Attributes.JavaModuleAttribute).GetConstructor(Type.EmptyTypes), new object[0])); return moduleBuilder; } + + private static AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, IEnumerable assemblyAttributes) + { +#if NET_4_0 + return AppDomain.CurrentDomain.DefineDynamicAssembly(name, access, null, true, assemblyAttributes); +#else + return AppDomain.CurrentDomain.DefineDynamicAssembly(name, access, null, null, null, null, null, true, assemblyAttributes); +#endif + } #endif // !STATIC_COMPILER } } diff --git a/external/ikvm/runtime/DynamicTypeWrapper.cs.REMOVED.git-id b/external/ikvm/runtime/DynamicTypeWrapper.cs.REMOVED.git-id index 3c6b369ccb..259dba8c03 100644 --- a/external/ikvm/runtime/DynamicTypeWrapper.cs.REMOVED.git-id +++ b/external/ikvm/runtime/DynamicTypeWrapper.cs.REMOVED.git-id @@ -1 +1 @@ -ad0861972ed1ac0e9caf2cde6149145bd346f957 \ No newline at end of file +c40b0a040f514f61c3bce5ca397280b4247710bf \ No newline at end of file diff --git a/external/ikvm/runtime/ExceptionHelper.cs b/external/ikvm/runtime/ExceptionHelper.cs index e69ae970bf..ff40d16765 100644 --- a/external/ikvm/runtime/ExceptionHelper.cs +++ b/external/ikvm/runtime/ExceptionHelper.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2013 Jeroen Frijters + Copyright (C) 2002-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 @@ -197,13 +197,14 @@ namespace IKVM.Internal { StackFrame frame = st.GetFrame(i); MethodBase m = frame.GetMethod(); - if (m == null || m.DeclaringType == null) + if (m == null) { continue; } Type type = m.DeclaringType; if (cleanStackTrace && - (typeof(MethodBase).IsAssignableFrom(type) + (type == null + || typeof(MethodBase).IsAssignableFrom(type) || type == typeof(RuntimeMethodHandle) || (type == typeof(Throwable) && m.Name == "instancehelper_fillInStackTrace") || (m.Name == "ToJava" && typeof(RetargetableJavaException).IsAssignableFrom(type)) @@ -298,6 +299,14 @@ namespace IKVM.Internal { return mb.Name.Substring(NamePrefix.DefaultMethod.Length); } + else if(mb.Name.StartsWith(NamePrefix.Bridge, StringComparison.Ordinal)) + { + return mb.Name.Substring(NamePrefix.Bridge.Length); + } + else if(mb.IsSpecialName) + { + return UnicodeUtil.UnescapeInvalidSurrogates(mb.Name); + } else { return mb.Name; @@ -309,12 +318,17 @@ namespace IKVM.Internal #if FIRST_PASS return false; #else - return Java_sun_reflect_Reflection.IsHideFromJava(mb) || (mb.DeclaringType == typeof(ikvm.runtime.Util) && mb.Name == "mapException"); + return (Java_sun_reflect_Reflection.GetHideFromJavaFlags(mb) & HideFromJavaFlags.StackTrace) != 0 + || (mb.DeclaringType == typeof(ikvm.runtime.Util) && mb.Name == "mapException"); #endif } private static string getClassNameFromType(Type type) { + if(type == null) + { + return ""; + } if(ClassLoaderWrapper.IsRemappedType(type)) { return DotNetTypeWrapper.GetName(type); @@ -326,6 +340,12 @@ namespace IKVM.Internal { return DotNetTypeWrapper.GetName(type); } +#if !FIRST_PASS + if(tw.IsUnsafeAnonymous) + { + return tw.ClassObject.getName(); + } +#endif return tw.Name; } return type.FullName; @@ -337,7 +357,7 @@ namespace IKVM.Internal if(ilOffset != StackFrame.OFFSET_UNKNOWN) { MethodBase mb = frame.GetMethod(); - if(mb != null) + if(mb != null && mb.DeclaringType != null) { if(ClassLoaderWrapper.IsRemappedType(mb.DeclaringType)) { @@ -356,7 +376,7 @@ namespace IKVM.Internal private static string GetFileName(StackFrame frame) { MethodBase mb = frame.GetMethod(); - if(mb != null) + if(mb != null && mb.DeclaringType != null) { if(ClassLoaderWrapper.IsRemappedType(mb.DeclaringType)) { diff --git a/external/ikvm/runtime/IKVM.Runtime.8.csproj b/external/ikvm/runtime/IKVM.Runtime.8.csproj index 15f4814c5e..0418b8ed1e 100644 --- a/external/ikvm/runtime/IKVM.Runtime.8.csproj +++ b/external/ikvm/runtime/IKVM.Runtime.8.csproj @@ -36,7 +36,7 @@ false - TRACE;DEBUG + TRACE;DEBUG;EMITTERS true @@ -87,6 +87,7 @@ Code + Code @@ -94,6 +95,7 @@ Code + Code @@ -120,6 +122,7 @@ Code + Code @@ -141,15 +144,28 @@ Code + Code - + + + + + + + + + + + + + Code diff --git a/external/ikvm/runtime/JavaException.cs b/external/ikvm/runtime/JavaException.cs index e41fad7226..e2a1d8e3c2 100644 --- a/external/ikvm/runtime/JavaException.cs +++ b/external/ikvm/runtime/JavaException.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Jeroen Frijters + Copyright (C) 2002-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 @@ -216,3 +216,18 @@ sealed class UnsupportedClassVersionError : ClassFormatError } #endif } + +sealed class JavaSecurityException : RetargetableJavaException +{ + internal JavaSecurityException(string msg) + : base(msg) + { + } + +#if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR + internal override Exception ToJava() + { + return new java.lang.SecurityException(Message); + } +#endif +} diff --git a/external/ikvm/runtime/LambdaMetafactory.cs b/external/ikvm/runtime/LambdaMetafactory.cs new file mode 100644 index 0000000000..e3a2a31bf0 --- /dev/null +++ b/external/ikvm/runtime/LambdaMetafactory.cs @@ -0,0 +1,1024 @@ +/* + Copyright (C) 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 + 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.Collections.Generic; +using System.Diagnostics; +#if STATIC_COMPILER +using IKVM.Reflection; +using IKVM.Reflection.Emit; +using Type = IKVM.Reflection.Type; +#else +using System.Reflection; +using System.Reflection.Emit; +#endif + +namespace IKVM.Internal +{ + sealed class LambdaMetafactory + { + private MethodBuilder ctor; + + internal static bool Emit(DynamicTypeWrapper.FinishContext context, ClassFile classFile, int constantPoolIndex, ClassFile.ConstantPoolItemInvokeDynamic cpi, CodeEmitter ilgen) + { + ClassFile.BootstrapMethod bsm = classFile.GetBootstrapMethod(cpi.BootstrapMethod); + if (!IsLambdaMetafactory(classFile, bsm) && !IsLambdaAltMetafactory(classFile, bsm)) + { + return false; + } + LambdaMetafactory lmf = context.GetValue(constantPoolIndex); + if (lmf.ctor == null && !lmf.EmitImpl(context, classFile, cpi, bsm, ilgen)) + { +#if STATIC_COMPILER + if (context.TypeWrapper.GetClassLoader().DisableDynamicBinding) + { + StaticCompiler.IssueMessage(Message.UnableToCreateLambdaFactory); + } +#endif + return false; + } + ilgen.Emit(OpCodes.Newobj, lmf.ctor); + // the CLR verification rules about type merging mean we have to explicitly cast to the interface type here + ilgen.Emit(OpCodes.Castclass, cpi.GetRetType().TypeAsBaseType); + return true; + } + + private bool EmitImpl(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, ClassFile.BootstrapMethod bsm, CodeEmitter ilgen) + { + if (HasUnloadable(cpi)) + { + Fail("cpi has unloadable"); + return false; + } + bool serializable = false; + TypeWrapper[] markers = TypeWrapper.EmptyArray; + ClassFile.ConstantPoolItemMethodType[] bridges = null; + if (bsm.ArgumentCount > 3) + { + AltFlags flags = (AltFlags)classFile.GetConstantPoolConstantInteger(bsm.GetArgument(3)); + serializable = (flags & AltFlags.Serializable) != 0; + int argpos = 4; + if ((flags & AltFlags.Markers) != 0) + { + markers = new TypeWrapper[classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++))]; + for (int i = 0; i < markers.Length; i++) + { + if ((markers[i] = classFile.GetConstantPoolClassType(bsm.GetArgument(argpos++))).IsUnloadable) + { + Fail("unloadable marker"); + return false; + } + } + } + if ((flags & AltFlags.Bridges) != 0) + { + bridges = new ClassFile.ConstantPoolItemMethodType[classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++))]; + for (int i = 0; i < bridges.Length; i++) + { + bridges[i] = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(argpos++)); + if (HasUnloadable(bridges[i])) + { + Fail("unloadable bridge"); + return false; + } + } + } + } + ClassFile.ConstantPoolItemMethodType samMethodType = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(0)); + ClassFile.ConstantPoolItemMethodHandle implMethod = classFile.GetConstantPoolConstantMethodHandle(bsm.GetArgument(1)); + ClassFile.ConstantPoolItemMethodType instantiatedMethodType = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(2)); + if (HasUnloadable(samMethodType) + || HasUnloadable((ClassFile.ConstantPoolItemMI)implMethod.MemberConstantPoolItem) + || HasUnloadable(instantiatedMethodType)) + { + Fail("bsm args has unloadable"); + return false; + } + TypeWrapper interfaceType = cpi.GetRetType(); + MethodWrapper[] methodList; + if (!CheckSupportedInterfaces(context.TypeWrapper, interfaceType, markers, bridges, out methodList)) + { + Fail("unsupported interface"); + return false; + } + if (serializable && Array.Exists(methodList, delegate(MethodWrapper mw) { return mw.Name == "writeReplace" && mw.Signature == "()Ljava.lang.Object;"; })) + { + Fail("writeReplace"); + return false; + } + if (!IsSupportedImplMethod(implMethod, context.TypeWrapper, cpi.GetArgTypes(), instantiatedMethodType)) + { + Fail("implMethod " + implMethod.MemberConstantPoolItem.Class + "::" + implMethod.MemberConstantPoolItem.Name + implMethod.MemberConstantPoolItem.Signature); + return false; + } + TypeWrapper[] implParameters = GetImplParameters(implMethod); + CheckConstraints(instantiatedMethodType, samMethodType, cpi.GetArgTypes(), implParameters); + if (bridges != null) + { + foreach (ClassFile.ConstantPoolItemMethodType bridge in bridges) + { + if (bridge.Signature == samMethodType.Signature) + { + Fail("bridge signature matches sam"); + return false; + } + if (!CheckConstraints(instantiatedMethodType, bridge, cpi.GetArgTypes(), implParameters)) + { + Fail("bridge constraints"); + return false; + } + } + } + if (instantiatedMethodType.GetRetType() != PrimitiveTypeWrapper.VOID) + { + TypeWrapper Rt = instantiatedMethodType.GetRetType(); + TypeWrapper Ra = GetImplReturnType(implMethod); + if (Ra == PrimitiveTypeWrapper.VOID || !IsAdaptable(Ra, Rt, true)) + { + Fail("The return type Rt is void, or the return type Ra is not void and is adaptable to Rt"); + return false; + } + } + MethodWrapper interfaceMethod = null; + List methods = new List(); + foreach (MethodWrapper mw in methodList) + { + if (mw.Name == cpi.Name && mw.Signature == samMethodType.Signature) + { + interfaceMethod = mw; + methods.Add(mw); + } + else if (mw.IsAbstract && !IsObjectMethod(mw)) + { + methods.Add(mw); + } + } + if (interfaceMethod == null || !interfaceMethod.IsAbstract || IsObjectMethod(interfaceMethod) || !MatchSignatures(interfaceMethod, samMethodType)) + { + Fail("interfaceMethod"); + return false; + } + + TypeBuilder tb = context.DefineAnonymousClass(); + // we're not implementing the interfaces recursively (because we don't care about .NET Compact anymore), + // but should we decide to do that, we'd need to somehow communicate to AnonymousTypeWrapper what the 'real' interface is + tb.AddInterfaceImplementation(interfaceType.TypeAsBaseType); + if (serializable && Array.IndexOf(markers, CoreClasses.java.io.Serializable.Wrapper) == -1) + { + tb.AddInterfaceImplementation(CoreClasses.java.io.Serializable.Wrapper.TypeAsBaseType); + } + foreach (TypeWrapper marker in markers) + { + tb.AddInterfaceImplementation(marker.TypeAsBaseType); + } + ctor = CreateConstructorAndDispatch(context, cpi, tb, methods, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable); + AddDefaultInterfaceMethods(context, methodList, tb); + return true; + } + + [Conditional("TRACE_LAMBDA_METAFACTORY")] + private static void Fail(string msg) + { + Console.WriteLine("Fail: " + msg); + } + + private static bool CheckConstraints(ClassFile.ConstantPoolItemMethodType instantiatedMethodType, ClassFile.ConstantPoolItemMethodType methodType, TypeWrapper[] args, TypeWrapper[] implParameters) + { + if (!IsSubTypeOf(instantiatedMethodType, methodType)) + { + Fail("instantiatedMethodType <= methodType"); + return false; + } + if (args.Length + methodType.GetArgTypes().Length != implParameters.Length) + { + Fail("K + N = M"); + return false; + } + for (int i = 0, K = args.Length; i < K; i++) + { + if (!args[i].IsSubTypeOf(implParameters[i])) + { + Fail("For i=1..K, Di = Ai"); + return false; + } + } + for (int i = 0, N = methodType.GetArgTypes().Length, k = args.Length; i < N; i++) + { + if (!IsAdaptable(instantiatedMethodType.GetArgTypes()[i], implParameters[i + k], false)) + { + Fail("For i=1..N, Ti is adaptable to Aj, where j=i+k"); + return false; + } + } + return true; + } + + private static TypeWrapper[] GetImplParameters(ClassFile.ConstantPoolItemMethodHandle implMethod) + { + MethodWrapper mw = (MethodWrapper)implMethod.Member; + TypeWrapper[] parameters = mw.GetParameters(); + if (mw.IsStatic || mw.IsConstructor) + { + return parameters; + } + return ArrayUtil.Concat(mw.DeclaringType, parameters); + } + + private static TypeWrapper GetImplReturnType(ClassFile.ConstantPoolItemMethodHandle implMethod) + { + return implMethod.Kind == ClassFile.RefKind.newInvokeSpecial + ? implMethod.Member.DeclaringType + : ((MethodWrapper)implMethod.Member).ReturnType; + } + + private static bool IsAdaptable(TypeWrapper Q, TypeWrapper S, bool isReturn) + { + if (Q == S) + { + return true; + } + + if (Q.IsPrimitive) + { + if (S.IsPrimitive) + { + // Q can be converted to S via a primitive widening conversion + switch (Q.SigName[0] | S.SigName[0] << 8) + { + case 'B' | 'S' << 8: + case 'B' | 'I' << 8: + case 'B' | 'J' << 8: + case 'B' | 'F' << 8: + case 'B' | 'D' << 8: + case 'S' | 'I' << 8: + case 'S' | 'J' << 8: + case 'S' | 'F' << 8: + case 'S' | 'D' << 8: + case 'C' | 'I' << 8: + case 'C' | 'J' << 8: + case 'C' | 'F' << 8: + case 'C' | 'D' << 8: + case 'I' | 'J' << 8: + case 'I' | 'F' << 8: + case 'I' | 'D' << 8: + case 'J' | 'F' << 8: + case 'J' | 'D' << 8: + case 'F' | 'D' << 8: + return true; + default: + return false; + } + } + else + { + // S is a supertype of the Wrapper(Q) + return GetWrapper(Q).IsAssignableTo(S); + } + } + else if (isReturn) + { + return true; + } + else + { + if (S.IsPrimitive) + { + // If Q is a primitive wrapper, check that Primitive(Q) can be widened to S + TypeWrapper primitive = GetPrimitiveFromWrapper(Q); + return primitive != null && IsAdaptable(primitive, S, isReturn); + } + else + { + // for parameter types: S is a supertype of Q + return Q.IsAssignableTo(S); + } + } + } + + private static TypeWrapper GetWrapper(TypeWrapper primitive) + { + Debug.Assert(primitive.IsPrimitive); + switch (primitive.SigName[0]) + { + case 'Z': + return ClassLoaderWrapper.LoadClassCritical("java.lang.Boolean"); + case 'B': + return ClassLoaderWrapper.LoadClassCritical("java.lang.Byte"); + case 'S': + return ClassLoaderWrapper.LoadClassCritical("java.lang.Short"); + case 'C': + return ClassLoaderWrapper.LoadClassCritical("java.lang.Character"); + case 'I': + return ClassLoaderWrapper.LoadClassCritical("java.lang.Integer"); + case 'J': + return ClassLoaderWrapper.LoadClassCritical("java.lang.Long"); + case 'F': + return ClassLoaderWrapper.LoadClassCritical("java.lang.Float"); + case 'D': + return ClassLoaderWrapper.LoadClassCritical("java.lang.Double"); + default: + throw new InvalidOperationException(); + } + } + + private static TypeWrapper GetPrimitiveFromWrapper(TypeWrapper wrapper) + { + switch (wrapper.Name) + { + case "java.lang.Boolean": + return PrimitiveTypeWrapper.BOOLEAN; + case "java.lang.Byte": + return PrimitiveTypeWrapper.BYTE; + case "java.lang.Short": + return PrimitiveTypeWrapper.SHORT; + case "java.lang.Character": + return PrimitiveTypeWrapper.CHAR; + case "java.lang.Integer": + return PrimitiveTypeWrapper.INT; + case "java.lang.Long": + return PrimitiveTypeWrapper.LONG; + case "java.lang.Float": + return PrimitiveTypeWrapper.FLOAT; + case "java.lang.Double": + return PrimitiveTypeWrapper.DOUBLE; + default: + return null; + } + } + + private static bool IsSubTypeOf(ClassFile.ConstantPoolItemMethodType instantiatedMethodType, ClassFile.ConstantPoolItemMethodType samMethodType) + { + TypeWrapper[] T = instantiatedMethodType.GetArgTypes(); + TypeWrapper[] U = samMethodType.GetArgTypes(); + if (T.Length != U.Length) + { + return false; + } + for (int i = 0; i < T.Length; i++) + { + if (!T[i].IsAssignableTo(U[i])) + { + return false; + } + } + TypeWrapper Rt = instantiatedMethodType.GetRetType(); + TypeWrapper Ru = samMethodType.GetRetType(); + return Rt.IsAssignableTo(Ru); + } + + private static MethodBuilder CreateConstructorAndDispatch(DynamicTypeWrapper.FinishContext context, ClassFile.ConstantPoolItemInvokeDynamic cpi, TypeBuilder tb, + List methods, TypeWrapper[] implParameters, ClassFile.ConstantPoolItemMethodType samMethodType, ClassFile.ConstantPoolItemMethodHandle implMethod, + ClassFile.ConstantPoolItemMethodType instantiatedMethodType, bool serializable) + { + TypeWrapper[] args = cpi.GetArgTypes(); + + // captured values + Type[] capturedTypes = new Type[args.Length]; + FieldBuilder[] capturedFields = new FieldBuilder[capturedTypes.Length]; + for (int i = 0; i < capturedTypes.Length; i++) + { + capturedTypes[i] = args[i].TypeAsSignatureType; + FieldAttributes attr = FieldAttributes.Private; + if (i > 0 || !args[0].IsGhost) + { + attr |= FieldAttributes.InitOnly; + } + capturedFields[i] = tb.DefineField("arg$" + (i + 1), capturedTypes[i], attr); + } + + // constructor + MethodBuilder ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, capturedTypes); + CodeEmitter ilgen = CodeEmitter.Create(ctor); + ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(OpCodes.Call, Types.Object.GetConstructor(Type.EmptyTypes)); + for (int i = 0; i < capturedTypes.Length; i++) + { + ilgen.EmitLdarg(0); + ilgen.EmitLdarg(i + 1); + ilgen.Emit(OpCodes.Stfld, capturedFields[i]); + } + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + + // dispatch methods + foreach (MethodWrapper mw in methods) + { + EmitDispatch(context, args, tb, mw, implParameters, implMethod, instantiatedMethodType, capturedFields); + } + + // writeReplace method + if (serializable) + { + MethodBuilder writeReplace = tb.DefineMethod("writeReplace", MethodAttributes.Private, Types.Object, Type.EmptyTypes); + ilgen = CodeEmitter.Create(writeReplace); + context.TypeWrapper.EmitClassLiteral(ilgen); + ilgen.Emit(OpCodes.Ldstr, cpi.GetRetType().Name.Replace('.', '/')); + ilgen.Emit(OpCodes.Ldstr, cpi.Name); + ilgen.Emit(OpCodes.Ldstr, samMethodType.Signature.Replace('.', '/')); + ilgen.EmitLdc_I4((int)implMethod.Kind); + ilgen.Emit(OpCodes.Ldstr, implMethod.Class.Replace('.', '/')); + ilgen.Emit(OpCodes.Ldstr, implMethod.Name); + ilgen.Emit(OpCodes.Ldstr, implMethod.Signature.Replace('.', '/')); + ilgen.Emit(OpCodes.Ldstr, instantiatedMethodType.Signature.Replace('.', '/')); + ilgen.EmitLdc_I4(capturedFields.Length); + ilgen.Emit(OpCodes.Newarr, Types.Object); + for (int i = 0; i < capturedFields.Length; i++) + { + ilgen.Emit(OpCodes.Dup); + ilgen.EmitLdc_I4(i); + ilgen.EmitLdarg(0); + ilgen.Emit(OpCodes.Ldfld, capturedFields[i]); + if (args[i].IsPrimitive) + { + Boxer.EmitBox(ilgen, args[i]); + } + else if (args[i].IsGhost) + { + args[i].EmitConvSignatureTypeToStackType(ilgen); + } + ilgen.Emit(OpCodes.Stelem, Types.Object); + } + MethodWrapper ctorSerializedLambda = ClassLoaderWrapper.LoadClassCritical("java.lang.invoke.SerializedLambda").GetMethodWrapper(StringConstants.INIT, + "(Ljava.lang.Class;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;ILjava.lang.String;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;[Ljava.lang.Object;)V", false); + ctorSerializedLambda.Link(); + ctorSerializedLambda.EmitNewobj(ilgen); + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + + if (!context.TypeWrapper.GetClassLoader().NoAutomagicSerialization) + { + // add .NET serialization interop support + Serialization.MarkSerializable(tb); + Serialization.AddGetObjectData(tb); + } + } + + return ctor; + } + + private static void EmitDispatch(DynamicTypeWrapper.FinishContext context, TypeWrapper[] args, TypeBuilder tb, MethodWrapper interfaceMethod, TypeWrapper[] implParameters, + ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, FieldBuilder[] capturedFields) + { + MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); + if (interfaceMethod.Name != interfaceMethod.RealName) + { + tb.DefineMethodOverride(mb, (MethodInfo)interfaceMethod.GetMethod()); + } + CodeEmitter ilgen = CodeEmitter.Create(mb); + for (int i = 0; i < capturedFields.Length; i++) + { + ilgen.EmitLdarg(0); + OpCode opc = OpCodes.Ldfld; + if (i == 0 && args[0].IsGhost) + { + switch (implMethod.Kind) + { + case ClassFile.RefKind.invokeInterface: + case ClassFile.RefKind.invokeVirtual: + case ClassFile.RefKind.invokeSpecial: + opc = OpCodes.Ldflda; + break; + } + } + ilgen.Emit(opc, capturedFields[i]); + } + for (int i = 0, count = interfaceMethod.GetParameters().Length, k = capturedFields.Length; i < count; i++) + { + ilgen.EmitLdarg(i + 1); + TypeWrapper Ui = interfaceMethod.GetParameters()[i]; + TypeWrapper Ti = instantiatedMethodType.GetArgTypes()[i]; + TypeWrapper Aj = implParameters[i + k]; + if (Ui == PrimitiveTypeWrapper.BYTE) + { + ilgen.Emit(OpCodes.Conv_I1); + } + if (Ti != Ui) + { + if (Ti.IsGhost) + { + Ti.EmitConvStackTypeToSignatureType(ilgen, Ui); + } + else if (Ui.IsGhost) + { + Ui.EmitConvSignatureTypeToStackType(ilgen); + } + else + { + Ti.EmitCheckcast(ilgen); + } + } + if (Ti != Aj) + { + if (Ti.IsPrimitive && !Aj.IsPrimitive) + { + Boxer.EmitBox(ilgen, Ti); + } + else if (!Ti.IsPrimitive && Aj.IsPrimitive) + { + TypeWrapper primitive = GetPrimitiveFromWrapper(Ti); + Boxer.EmitUnbox(ilgen, primitive, false); + if (primitive == PrimitiveTypeWrapper.BYTE) + { + ilgen.Emit(OpCodes.Conv_I1); + } + } + else if (Aj == PrimitiveTypeWrapper.LONG) + { + ilgen.Emit(OpCodes.Conv_I8); + } + else if (Aj == PrimitiveTypeWrapper.FLOAT) + { + ilgen.Emit(OpCodes.Conv_R4); + } + else if (Aj == PrimitiveTypeWrapper.DOUBLE) + { + ilgen.Emit(OpCodes.Conv_R8); + } + } + } + switch (implMethod.Kind) + { + case ClassFile.RefKind.invokeVirtual: + case ClassFile.RefKind.invokeInterface: + ((MethodWrapper)implMethod.Member).EmitCallvirt(ilgen); + break; + case ClassFile.RefKind.newInvokeSpecial: + ((MethodWrapper)implMethod.Member).EmitNewobj(ilgen); + break; + case ClassFile.RefKind.invokeStatic: + case ClassFile.RefKind.invokeSpecial: + ((MethodWrapper)implMethod.Member).EmitCall(ilgen); + break; + default: + throw new InvalidOperationException(); + } + TypeWrapper Ru = interfaceMethod.ReturnType; + TypeWrapper Ra = GetImplReturnType(implMethod); + TypeWrapper Rt = instantiatedMethodType.GetRetType(); + if (Ra == PrimitiveTypeWrapper.BYTE) + { + ilgen.Emit(OpCodes.Conv_I1); + } + if (Ra != Ru) + { + if (Ru == PrimitiveTypeWrapper.VOID) + { + ilgen.Emit(OpCodes.Pop); + } + else if (Ra.IsGhost) + { + Ra.EmitConvSignatureTypeToStackType(ilgen); + } + else if (Ru.IsGhost) + { + Ru.EmitConvStackTypeToSignatureType(ilgen, Ra); + } + } + if (Ra != Rt) + { + if (Rt.IsPrimitive) + { + if (Rt == PrimitiveTypeWrapper.VOID) + { + // already popped + } + else if (!Ra.IsPrimitive) + { + TypeWrapper primitive = GetPrimitiveFromWrapper(Ra); + if (primitive != null) + { + Boxer.EmitUnbox(ilgen, primitive, false); + } + else + { + // If Q is not a primitive wrapper, cast Q to the base Wrapper(S); for example Number for numeric types + EmitConvertingUnbox(ilgen, Rt); + } + } + else if (Rt == PrimitiveTypeWrapper.LONG) + { + ilgen.Emit(OpCodes.Conv_I8); + } + else if (Rt == PrimitiveTypeWrapper.FLOAT) + { + ilgen.Emit(OpCodes.Conv_R4); + } + else if (Rt == PrimitiveTypeWrapper.DOUBLE) + { + ilgen.Emit(OpCodes.Conv_R8); + } + } + else if (Ra.IsPrimitive) + { + Boxer.EmitBox(ilgen, GetPrimitiveFromWrapper(Rt)); + } + else + { + Rt.EmitCheckcast(ilgen); + } + } + ilgen.EmitTailCallPrevention(); + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + } + + private static void EmitConvertingUnbox(CodeEmitter ilgen, TypeWrapper tw) + { + switch (tw.SigName[0]) + { + case 'Z': + case 'C': + Boxer.EmitUnbox(ilgen, tw, true); + break; + case 'B': + EmitUnboxNumber(ilgen, "byteValue", "()B"); + break; + case 'S': + EmitUnboxNumber(ilgen, "shortValue", "()S"); + break; + case 'I': + EmitUnboxNumber(ilgen, "intValue", "()I"); + break; + case 'J': + EmitUnboxNumber(ilgen, "longValue", "()J"); + break; + case 'F': + EmitUnboxNumber(ilgen, "floatValue", "()F"); + break; + case 'D': + EmitUnboxNumber(ilgen, "doubleValue", "()D"); + break; + default: + throw new InvalidOperationException(); + } + } + + private static void EmitUnboxNumber(CodeEmitter ilgen, string methodName, string methodSig) + { + TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical("java.lang.Number"); + tw.EmitCheckcast(ilgen); + MethodWrapper mw = tw.GetMethodWrapper(methodName, methodSig, false); + mw.Link(); + mw.EmitCallvirt(ilgen); + } + + private static void AddDefaultInterfaceMethods(DynamicTypeWrapper.FinishContext context, MethodWrapper[] methodList, TypeBuilder tb) + { + // we use special name to hide these from Java reflection + const MethodAttributes attr = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName; + TypeWrapperFactory factory = context.TypeWrapper.GetClassLoader().GetTypeWrapperFactory(); + foreach (MethodWrapper mw in methodList) + { + if (!mw.IsAbstract) + { + MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr); + if (mw.Name != mw.RealName) + { + tb.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); + } + DynamicTypeWrapper.FinishContext.EmitCallDefaultInterfaceMethod(mb, mw); + } + else if (IsObjectMethod(mw)) + { + MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr); + if (mw.Name != mw.RealName) + { + tb.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); + } + CodeEmitter ilgen = CodeEmitter.Create(mb); + for (int i = 0, count = mw.GetParameters().Length; i <= count; i++) + { + ilgen.EmitLdarg(i); + } + CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper(mw.Name, mw.Signature, false).EmitCallvirt(ilgen); + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + } + } + } + + private static bool IsSupportedImplMethod(ClassFile.ConstantPoolItemMethodHandle implMethod, TypeWrapper caller, TypeWrapper[] captured, ClassFile.ConstantPoolItemMethodType instantiatedMethodType) + { + switch (implMethod.Kind) + { + case ClassFile.RefKind.invokeVirtual: + case ClassFile.RefKind.invokeInterface: + case ClassFile.RefKind.newInvokeSpecial: + case ClassFile.RefKind.invokeStatic: + case ClassFile.RefKind.invokeSpecial: + break; + default: + return false; + } + MethodWrapper mw = (MethodWrapper)implMethod.Member; + if (mw == null || mw.HasCallerID || DynamicTypeWrapper.RequiresDynamicReflectionCallerClass(mw.DeclaringType.Name, mw.Name, mw.Signature)) + { + return false; + } + TypeWrapper instance; + if (mw.IsConstructor) + { + instance = mw.DeclaringType; + } + else if (mw.IsStatic) + { + instance = null; + } + else + { + // if implMethod is an instance method, the type of the first captured value must be subtype of implMethod.DeclaringType + instance = captured.Length == 0 ? instantiatedMethodType.GetArgTypes()[0] : captured[0]; + if (!instance.IsAssignableTo(mw.DeclaringType)) + { + return false; + } + } + if (!mw.IsAccessibleFrom(mw.DeclaringType, caller, instance)) + { + return false; + } + mw.Link(); + return true; + } + + private static bool IsSupportedInterface(TypeWrapper tw, TypeWrapper caller) + { + return tw.IsInterface + && !tw.IsGhost + && tw.IsAccessibleFrom(caller) + && !Serialization.IsISerializable(tw); + } + + private static bool CheckSupportedInterfaces(TypeWrapper caller, TypeWrapper tw, TypeWrapper[] markers, ClassFile.ConstantPoolItemMethodType[] bridges, out MethodWrapper[] methodList) + { + // we don't need to check for unloadable, because we already did that while validating the invoke signature + if (!IsSupportedInterface(tw, caller)) + { + methodList = null; + return false; + } + Dictionary methods = new Dictionary(); + int abstractMethodCount = 0; + int bridgeMethodCount = 0; + if (GatherAllInterfaceMethods(tw, bridges, methods, ref abstractMethodCount, ref bridgeMethodCount) && abstractMethodCount == 1) + { + foreach (TypeWrapper marker in markers) + { + if (!IsSupportedInterface(marker, caller)) + { + methodList = null; + return false; + } + if (!GatherAllInterfaceMethods(marker, null, methods, ref abstractMethodCount, ref bridgeMethodCount) || abstractMethodCount != 1) + { + methodList = null; + return false; + } + } + if (bridges != null && bridgeMethodCount != bridges.Length) + { + methodList = null; + return false; + } + methodList = new MethodWrapper[methods.Count]; + methods.Values.CopyTo(methodList, 0); + return true; + } + methodList = null; + return false; + } + + private static bool GatherAllInterfaceMethods(TypeWrapper tw, ClassFile.ConstantPoolItemMethodType[] bridges, Dictionary methods, + ref int abstractMethodCount, ref int bridgeMethodCount) + { + foreach (MethodWrapper mw in tw.GetMethods()) + { + if (mw.IsVirtual) + { + MirandaMethodWrapper mmw = mw as MirandaMethodWrapper; + if (mmw != null) + { + if (mmw.Error != null) + { + return false; + } + continue; + } + MethodKey key = new MethodKey("", mw.Name, mw.Signature); + MethodWrapper current; + if (methods.TryGetValue(key, out current)) + { + if (!MatchSignatures(mw, current)) + { + // linkage error (or unloadable type) + return false; + } + } + else + { + methods.Add(key, mw); + if (mw.IsAbstract && !IsObjectMethod(mw)) + { + if (bridges != null && IsBridge(mw, bridges)) + { + bridgeMethodCount++; + } + else + { + abstractMethodCount++; + } + } + } + mw.Link(); + if (mw.GetMethod() == null) + { + return false; + } + if (current != null && mw.RealName != current.RealName) + { + return false; + } + } + } + foreach (TypeWrapper tw1 in tw.Interfaces) + { + if (!GatherAllInterfaceMethods(tw1, bridges, methods, ref abstractMethodCount, ref bridgeMethodCount)) + { + return false; + } + } + return true; + } + + private static bool IsBridge(MethodWrapper mw, ClassFile.ConstantPoolItemMethodType[] bridges) + { + foreach (ClassFile.ConstantPoolItemMethodType bridge in bridges) + { + if (bridge.Signature == mw.Signature) + { + return true; + } + } + return false; + } + + private static bool IsObjectMethod(MethodWrapper mw) + { + MethodWrapper objectMethod; + return (objectMethod = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper(mw.Name, mw.Signature, false)) != null + && objectMethod.IsPublic; + } + + private static bool MatchSignatures(MethodWrapper interfaceMethod, ClassFile.ConstantPoolItemMethodType samMethodType) + { + return interfaceMethod.ReturnType == samMethodType.GetRetType() + && MatchTypes(interfaceMethod.GetParameters(), samMethodType.GetArgTypes()); + } + + private static bool MatchSignatures(MethodWrapper mw1, MethodWrapper mw2) + { + return mw1.ReturnType == mw2.ReturnType + && MatchTypes(mw1.GetParameters(), mw2.GetParameters()); + } + + private static bool MatchTypes(TypeWrapper[] ar1, TypeWrapper[] ar2) + { + if (ar1.Length != ar2.Length) + { + return false; + } + for (int i = 0; i < ar1.Length; i++) + { + if (ar1[i] != ar2[i]) + { + return false; + } + } + return true; + } + + private static bool IsLambdaMetafactory(ClassFile classFile, ClassFile.BootstrapMethod bsm) + { + ClassFile.ConstantPoolItemMethodHandle mh; + return bsm.ArgumentCount == 3 + && classFile.GetConstantPoolConstantType(bsm.GetArgument(0)) == ClassFile.ConstantType.MethodType + && classFile.GetConstantPoolConstantType(bsm.GetArgument(1)) == ClassFile.ConstantType.MethodHandle + && classFile.GetConstantPoolConstantType(bsm.GetArgument(2)) == ClassFile.ConstantType.MethodType + && (mh = classFile.GetConstantPoolConstantMethodHandle(bsm.BootstrapMethodIndex)).Kind == ClassFile.RefKind.invokeStatic + && IsLambdaMetafactory(mh.Member); + } + + private static bool IsLambdaMetafactory(MemberWrapper mw) + { + return mw.Name == "metafactory" + && mw.Signature == "(Ljava.lang.invoke.MethodHandles$Lookup;Ljava.lang.String;Ljava.lang.invoke.MethodType;Ljava.lang.invoke.MethodType;Ljava.lang.invoke.MethodHandle;Ljava.lang.invoke.MethodType;)Ljava.lang.invoke.CallSite;" + && mw.DeclaringType.Name == "java.lang.invoke.LambdaMetafactory"; + } + + [Flags] + enum AltFlags + { + Serializable = 1, + Markers = 2, + Bridges = 4, + Mask = Serializable | Markers | Bridges + } + + private static bool IsLambdaAltMetafactory(ClassFile classFile, ClassFile.BootstrapMethod bsm) + { + ClassFile.ConstantPoolItemMethodHandle mh; + AltFlags flags; + int argpos = 4; + return bsm.ArgumentCount >= 4 + && (mh = classFile.GetConstantPoolConstantMethodHandle(bsm.BootstrapMethodIndex)).Kind == ClassFile.RefKind.invokeStatic + && IsLambdaAltMetafactory(mh.Member) + && classFile.GetConstantPoolConstantType(bsm.GetArgument(0)) == ClassFile.ConstantType.MethodType + && classFile.GetConstantPoolConstantType(bsm.GetArgument(1)) == ClassFile.ConstantType.MethodHandle + && classFile.GetConstantPoolConstantType(bsm.GetArgument(2)) == ClassFile.ConstantType.MethodType + && classFile.GetConstantPoolConstantType(bsm.GetArgument(3)) == ClassFile.ConstantType.Integer + && ((flags = (AltFlags)classFile.GetConstantPoolConstantInteger(bsm.GetArgument(3))) & ~AltFlags.Mask) == 0 + && ((flags & AltFlags.Markers) == 0 || CheckOptionalArgs(classFile, bsm, ClassFile.ConstantType.Class, ref argpos)) + && ((flags & AltFlags.Bridges) == 0 || CheckOptionalArgs(classFile, bsm, ClassFile.ConstantType.MethodType, ref argpos)) + && argpos == bsm.ArgumentCount; + } + + private static bool IsLambdaAltMetafactory(MemberWrapper mw) + { + return mw.Name == "altMetafactory" + && mw.Signature == "(Ljava.lang.invoke.MethodHandles$Lookup;Ljava.lang.String;Ljava.lang.invoke.MethodType;[Ljava.lang.Object;)Ljava.lang.invoke.CallSite;" + && mw.DeclaringType.Name == "java.lang.invoke.LambdaMetafactory"; + } + + private static bool CheckOptionalArgs(ClassFile classFile, ClassFile.BootstrapMethod bsm, ClassFile.ConstantType type, ref int argpos) + { + if (bsm.ArgumentCount - argpos < 1) + { + return false; + } + if (classFile.GetConstantPoolConstantType(bsm.GetArgument(argpos)) != ClassFile.ConstantType.Integer) + { + return false; + } + int count = classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++)); + if (count < 0 || bsm.ArgumentCount - argpos < count) + { + return false; + } + for (int i = 0; i < count; i++) + { + if (classFile.GetConstantPoolConstantType(bsm.GetArgument(argpos++)) != type) + { + return false; + } + } + return true; + } + + private static bool HasUnloadable(ClassFile.ConstantPoolItemInvokeDynamic cpi) + { + return HasUnloadable(cpi.GetArgTypes()) || cpi.GetRetType().IsUnloadable; + } + + private static bool HasUnloadable(ClassFile.ConstantPoolItemMethodType cpi) + { + return HasUnloadable(cpi.GetArgTypes()) || cpi.GetRetType().IsUnloadable; + } + + private static bool HasUnloadable(ClassFile.ConstantPoolItemMI cpi) + { + return HasUnloadable(cpi.GetArgTypes()) || cpi.GetRetType().IsUnloadable; + } + + private static bool HasUnloadable(TypeWrapper[] wrappers) + { + foreach (TypeWrapper tw in wrappers) + { + if (tw.IsUnloadable) + { + return true; + } + } + return false; + } + } +} diff --git a/external/ikvm/runtime/Serialization.cs b/external/ikvm/runtime/Serialization.cs index 1145d35108..024c12d6a4 100644 --- a/external/ikvm/runtime/Serialization.cs +++ b/external/ikvm/runtime/Serialization.cs @@ -52,6 +52,11 @@ namespace IKVM.Internal psetSerializationFormatter.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter)); } + internal static bool IsISerializable(TypeWrapper wrapper) + { + return wrapper == iserializable; + } + private static bool IsSafeForAutomagicSerialization(TypeWrapper wrapper) { if (wrapper.TypeAsBaseType.IsSerializable) @@ -147,15 +152,21 @@ namespace IKVM.Internal return null; } - private static void MarkSerializable(TypeBuilder tb) + internal static void MarkSerializable(TypeBuilder tb) { tb.SetCustomAttribute(serializableAttribute); } - private static void AddGetObjectData(TypeBuilder tb) + internal static void AddGetObjectData(TypeBuilder tb) { + string name = tb.IsSealed + ? "System.Runtime.Serialization.ISerializable.GetObjectData" + : "GetObjectData"; + MethodAttributes attr = tb.IsSealed + ? MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final + : MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride; tb.AddInterfaceImplementation(JVM.Import(typeof(ISerializable))); - MethodBuilder getObjectData = tb.DefineMethod("GetObjectData", MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot, null, + MethodBuilder getObjectData = tb.DefineMethod(name, attr, null, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) }); getObjectData.SetCustomAttribute(securityCriticalAttribute); AttributeHelper.HideFromJava(getObjectData); diff --git a/external/ikvm/runtime/TypeWrapper.cs.REMOVED.git-id b/external/ikvm/runtime/TypeWrapper.cs.REMOVED.git-id index 4afe4adc42..326fea284f 100644 --- a/external/ikvm/runtime/TypeWrapper.cs.REMOVED.git-id +++ b/external/ikvm/runtime/TypeWrapper.cs.REMOVED.git-id @@ -1 +1 @@ -3ed1d9cc7e683c9f379f858859a155d3b4c778a1 \ No newline at end of file +fabd1aa5c712bc82971cd56b6f8a9d6cf648740c \ No newline at end of file diff --git a/external/ikvm/runtime/attributes.cs b/external/ikvm/runtime/attributes.cs index 1605837d57..78ab40b019 100644 --- a/external/ikvm/runtime/attributes.cs +++ b/external/ikvm/runtime/attributes.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2011 Jeroen Frijters + Copyright (C) 2002-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 @@ -22,6 +22,8 @@ */ using System; +using System.Collections.Generic; +using IKVM.Internal; #if STATIC_COMPILER || STUB_GENERATOR using IKVM.Reflection; using Type = IKVM.Reflection.Type; @@ -388,7 +390,7 @@ namespace IKVM.Attributes public JavaModuleAttribute(string[] classMap) { - this.classMap = classMap; + this.classMap = UnicodeUtil.UnescapeInvalidSurrogates(classMap); } public string[] GetClassMap() @@ -418,11 +420,33 @@ namespace IKVM.Attributes [AttributeUsage(AttributeTargets.All)] public sealed class HideFromJavaAttribute : Attribute { + private readonly HideFromJavaFlags flags; + + public HideFromJavaAttribute() + { + flags = HideFromJavaFlags.All; + } + + public HideFromJavaAttribute(HideFromJavaFlags flags) + { + this.flags = flags; + } + + public HideFromJavaFlags Flags + { + get { return flags; } + } } - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] - public sealed class HideFromReflectionAttribute : Attribute + [Flags] + public enum HideFromJavaFlags : byte { + All = Code | Reflection | StackWalk | StackTrace, + None = 0, + Code = 1, + Reflection = 2, + StackWalk = 4, // used for LambdaForm$Compiled + StackTrace = 8, // used for LambdaForm$Hidden } [Flags] @@ -493,8 +517,8 @@ namespace IKVM.Attributes public NameSigAttribute(string name, string sig) { - this.name = name; - this.sig = sig; + this.name = UnicodeUtil.UnescapeInvalidSurrogates(name); + this.sig = UnicodeUtil.UnescapeInvalidSurrogates(sig); } public string Name @@ -523,7 +547,7 @@ namespace IKVM.Attributes // this constructor is used by ikvmc, the other constructors are for use in other .NET languages public ThrowsAttribute(string[] classes) { - this.classes = classes; + this.classes = UnicodeUtil.UnescapeInvalidSurrogates(classes); } public ThrowsAttribute(Type type) @@ -555,7 +579,7 @@ namespace IKVM.Attributes // NOTE this is not CLS compliant, so maybe we should have a couple of overloads public ImplementsAttribute(string[] interfaces) { - this.interfaces = interfaces; + this.interfaces = UnicodeUtil.UnescapeInvalidSurrogates(interfaces); } public string[] Interfaces @@ -577,7 +601,7 @@ namespace IKVM.Attributes public InnerClassAttribute(string innerClassName, Modifiers modifiers) { - this.innerClassName = innerClassName; + this.innerClassName = UnicodeUtil.UnescapeInvalidSurrogates(innerClassName); this.modifiers = modifiers; } @@ -605,7 +629,7 @@ namespace IKVM.Attributes public NonNestedInnerClassAttribute(string innerClassName) { - this.innerClassName = innerClassName; + this.innerClassName = UnicodeUtil.UnescapeInvalidSurrogates(innerClassName); } public string InnerClassName @@ -624,7 +648,7 @@ namespace IKVM.Attributes public NonNestedOuterClassAttribute(string outerClassName) { - this.outerClassName = outerClassName; + this.outerClassName = UnicodeUtil.UnescapeInvalidSurrogates(outerClassName); } public string OuterClassName @@ -662,7 +686,7 @@ namespace IKVM.Attributes public SignatureAttribute(string signature) { - this.signature = signature; + this.signature = UnicodeUtil.UnescapeInvalidSurrogates(signature); } public string Signature @@ -683,9 +707,9 @@ namespace IKVM.Attributes public EnclosingMethodAttribute(string className, string methodName, string methodSig) { - this.className = className; - this.methodName = methodName; - this.methodSig = methodSig; + this.className = UnicodeUtil.UnescapeInvalidSurrogates(className); + this.methodName = UnicodeUtil.UnescapeInvalidSurrogates(methodName); + this.methodSig = UnicodeUtil.UnescapeInvalidSurrogates(methodSig); } internal EnclosingMethodAttribute SetClassName(Type type) @@ -749,7 +773,7 @@ namespace IKVM.Attributes // new object[] { (byte)'?', "", "" } public AnnotationDefaultAttribute(object defaultValue) { - this.defaultValue = defaultValue; + this.defaultValue = Unescape(defaultValue); } public object Value @@ -759,6 +783,36 @@ namespace IKVM.Attributes return defaultValue; } } + + internal static object Escape(object obj) + { + return EscapeOrUnescape(obj, true); + } + + internal static object Unescape(object obj) + { + return EscapeOrUnescape(obj, false); + } + + private static object EscapeOrUnescape(object obj, bool escape) + { + string str = obj as string; + if (str != null) + { + return escape + ? UnicodeUtil.EscapeInvalidSurrogates(str) + : UnicodeUtil.UnescapeInvalidSurrogates(str); + } + object[] arr = obj as object[]; + if (arr != null) + { + for (int i = 0; i < arr.Length; i++) + { + arr[i] = EscapeOrUnescape(arr[i], escape); + } + } + return obj; + } } [AttributeUsage(AttributeTargets.Interface)] @@ -768,7 +822,7 @@ namespace IKVM.Attributes public AnnotationAttributeAttribute(string attributeType) { - this.attributeType = attributeType; + this.attributeType = UnicodeUtil.UnescapeInvalidSurrogates(attributeType); } public string AttributeType @@ -780,14 +834,16 @@ namespace IKVM.Attributes } } - [AttributeUsage(AttributeTargets.Module)] + [AttributeUsage(AttributeTargets.Module, AllowMultiple = true)] public sealed class PackageListAttribute : Attribute { - private string[] packages; + internal string jar; + internal string[] packages; - public PackageListAttribute(string[] packages) + public PackageListAttribute(string jar, string[] packages) { - this.packages = packages; + this.jar = jar; + this.packages = UnicodeUtil.UnescapeInvalidSurrogates(packages); } public string[] GetPackages() @@ -826,7 +882,7 @@ namespace IKVM.Attributes public DynamicAnnotationAttribute(object[] definition) { - this.definition = definition; + this.definition = (object[])AnnotationDefaultAttribute.Unescape(definition); } public object[] Definition @@ -835,6 +891,120 @@ namespace IKVM.Attributes } } + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor)] + public sealed class MethodParametersAttribute : Attribute + { + private readonly Modifiers[] modifiers; + + public MethodParametersAttribute(Modifiers[] modifiers) + { + this.modifiers = modifiers; + } + + public Modifiers[] Modifiers + { + get { return modifiers; } + } + + public bool IsMalformed + { + get { return modifiers == null; } + } + } + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] + public sealed class ConstantPoolAttribute : Attribute + { + internal readonly object[] constantPool; + + public ConstantPoolAttribute(object[] constantPool) + { + this.constantPool = Decompress(constantPool); + } + + internal static object[] Decompress(object[] constantPool) + { + List list = new List(); + foreach (object obj in constantPool) + { + int emptySlots = obj as byte? ?? obj as ushort? ?? 0; + if (emptySlots == 0) + { + list.Add(Unescape(obj)); + } + else + { + for (int i = 0; i < emptySlots; i++) + { + list.Add(null); + } + } + } + return list.ToArray(); + } + + private static object Unescape(object obj) + { + string str = obj as string; + if (str != null) + { + obj = UnicodeUtil.UnescapeInvalidSurrogates(str); + } + return obj; + } + + internal static object[] Compress(object[] constantPool, bool[] inUse) + { + int length = constantPool.Length; + while (!inUse[length - 1]) + { + length--; + } + int write = 0; + for (int read = 0; read < length; read++) + { + int start = read; + while (!inUse[read]) + { + read++; + } + int emptySlots = read - start; + if (emptySlots > 255) + { + constantPool[write++] = (ushort)emptySlots; + } + else if (emptySlots > 0) + { + constantPool[write++] = (byte)emptySlots; + } + constantPool[write++] = Escape(constantPool[read]); + } + Array.Resize(ref constantPool, write); + return constantPool; + } + + private static object Escape(object obj) + { + string str = obj as string; + if (str != null) + { + obj = UnicodeUtil.EscapeInvalidSurrogates(str); + } + return obj; + } + } + + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Field)] + public sealed class RuntimeVisibleTypeAnnotationsAttribute : Attribute + { + internal readonly byte[] data; + + public RuntimeVisibleTypeAnnotationsAttribute(byte[] data) + { + this.data = data; + } + } + // used in custom modifier for access stubs public static class AccessStub { } } diff --git a/external/ikvm/runtime/common.cs b/external/ikvm/runtime/common.cs index 27698b64c1..94cad5878c 100644 --- a/external/ikvm/runtime/common.cs +++ b/external/ikvm/runtime/common.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2007, 2010 Jeroen Frijters + Copyright (C) 2002-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 @@ -25,6 +25,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Runtime.InteropServices; using IKVM.Attributes; using IKVM.Runtime; using IKVM.Internal; @@ -49,7 +50,7 @@ namespace IKVM.NativeCode.gnu.java.net.protocol.ikvmres MemoryStream mem = new MemoryStream(); #if !FIRST_PASS bool includeNonPublicInterfaces = !"true".Equals(global::java.lang.Props.props.getProperty("ikvm.stubgen.skipNonPublicInterfaces"), StringComparison.OrdinalIgnoreCase); - IKVM.StubGen.StubGenerator.WriteClass(mem, TypeWrapper.FromClass(c), includeNonPublicInterfaces, false, false, false); + IKVM.StubGen.StubGenerator.WriteClass(mem, TypeWrapper.FromClass(c), includeNonPublicInterfaces, false, false, true); #endif return mem.ToArray(); } @@ -119,6 +120,53 @@ namespace IKVM.NativeCode.java.lang { return VirtualFileSystem.GetAssemblyClassesPath(JVM.CoreAssembly); } + + public static string getStdoutEncoding() + { + return IsWindowsConsole(true) ? GetConsoleEncoding() : null; + } + + public static string getStderrEncoding() + { + return IsWindowsConsole(false) ? GetConsoleEncoding() : null; + } + + private static bool IsWindowsConsole(bool stdout) + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + { + return false; + } + // these properties are available starting with .NET 4.5 + PropertyInfo pi = typeof(Console).GetProperty(stdout ? "IsOutputRedirected" : "IsErrorRedirected"); + if (pi != null) + { + return !(bool)pi.GetValue(null, null); + } + const int STD_OUTPUT_HANDLE = -11; + const int STD_ERROR_HANDLE = -12; + IntPtr handle = GetStdHandle(stdout ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE); + if (handle == IntPtr.Zero) + { + return false; + } + const int FILE_TYPE_CHAR = 2; + return GetFileType(handle) == FILE_TYPE_CHAR; + } + + private static string GetConsoleEncoding() + { + int codepage = Console.InputEncoding.CodePage; + return codepage >= 847 && codepage <= 950 + ? "ms" + codepage + : "cp" + codepage; + } + + [DllImport("kernel32")] + private static extern int GetFileType(IntPtr hFile); + + [DllImport("kernel32")] + private static extern IntPtr GetStdHandle(int nStdHandle); } } @@ -144,6 +192,11 @@ namespace IKVM.NativeCode.ikvm.@internal static class AnnotationAttributeBase { + public static object[] unescapeInvalidSurrogates(object[] def) + { + return (object[])AnnotationDefaultAttribute.Unescape(def); + } + public static object newAnnotationInvocationHandler(jlClass type, object memberValues) { #if FIRST_PASS @@ -271,25 +324,6 @@ namespace IKVM.NativeCode.ikvm.runtime return null; } - private static global::java.util.jar.Manifest GetManifest(global::java.lang.ClassLoader _this) - { - try - { - global::java.net.URL url = findResource(_this, "META-INF/MANIFEST.MF"); - if (url != null) - { - return new global::java.util.jar.Manifest(url.openStream()); - } - } - catch (global::java.net.MalformedURLException) - { - } - catch (global::java.io.IOException) - { - } - return null; - } - private static string GetAttributeValue(global::java.util.jar.Attributes.Name name, global::java.util.jar.Attributes first, global::java.util.jar.Attributes second) { string result = null; @@ -310,31 +344,37 @@ namespace IKVM.NativeCode.ikvm.runtime #if !FIRST_PASS AssemblyClassLoader_ wrapper = (AssemblyClassLoader_)ClassLoaderWrapper.GetClassLoaderWrapper(_this); global::java.net.URL sealBase = GetCodeBase(wrapper.MainAssembly); - global::java.util.jar.Manifest manifest = GetManifest(_this); - global::java.util.jar.Attributes attr = null; - if (manifest != null) + foreach (KeyValuePair packages in wrapper.GetPackageInfo()) { - attr = manifest.getMainAttributes(); - } - string[] packages = wrapper.GetPackages(); - for (int i = 0; i < packages.Length; i++) - { - string name = packages[i]; - if (_this.getPackage(name) == null) + global::java.util.jar.Manifest manifest = null; + global::java.util.jar.Attributes attr = null; + if (packages.Key != null) { - global::java.util.jar.Attributes entryAttr = null; - if (manifest != null) + global::java.util.jar.JarFile jarFile = new global::java.util.jar.JarFile(VirtualFileSystem.GetAssemblyResourcesPath(wrapper.MainAssembly) + packages.Key); + manifest = jarFile.getManifest(); + } + if (manifest != null) + { + attr = manifest.getMainAttributes(); + } + foreach (string name in packages.Value) + { + if (_this.getPackage(name) == null) { - entryAttr = manifest.getAttributes(name.Replace('.', '/') + '/'); + global::java.util.jar.Attributes entryAttr = null; + if (manifest != null) + { + entryAttr = manifest.getAttributes(name.Replace('.', '/') + '/'); + } + _this.definePackage(name, + GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_TITLE, entryAttr, attr), + GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_VERSION, entryAttr, attr), + GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_VENDOR, entryAttr, attr), + GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_TITLE, entryAttr, attr), + GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_VERSION, entryAttr, attr), + GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_VENDOR, entryAttr, attr), + "true".Equals(GetAttributeValue(global::java.util.jar.Attributes.Name.SEALED, entryAttr, attr), StringComparison.OrdinalIgnoreCase) ? sealBase : null); } - _this.definePackage(name, - GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_TITLE, entryAttr, attr), - GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_VERSION, entryAttr, attr), - GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_VENDOR, entryAttr, attr), - GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_TITLE, entryAttr, attr), - GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_VERSION, entryAttr, attr), - GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_VENDOR, entryAttr, attr), - "true".Equals(GetAttributeValue(global::java.util.jar.Attributes.Name.SEALED, entryAttr, attr), StringComparison.OrdinalIgnoreCase) ? sealBase : null); } } #endif diff --git a/external/ikvm/runtime/compiler.cs.REMOVED.git-id b/external/ikvm/runtime/compiler.cs.REMOVED.git-id index 87ec1ead6f..51fb6709e6 100644 --- a/external/ikvm/runtime/compiler.cs.REMOVED.git-id +++ b/external/ikvm/runtime/compiler.cs.REMOVED.git-id @@ -1 +1 @@ -8b8a30e4b47038b6fae92d434aa386871005e4fb \ No newline at end of file +e38729f8e1419779787415d4fd6aa39532dbfcf7 \ No newline at end of file diff --git a/external/ikvm/runtime/openjdk/java.io.cs b/external/ikvm/runtime/openjdk/java.io.cs new file mode 100644 index 0000000000..f161fa7b37 --- /dev/null +++ b/external/ikvm/runtime/openjdk/java.io.cs @@ -0,0 +1,1371 @@ +/* + Copyright (C) 2007-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 + 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.Diagnostics; +using System.IO; +using System.Reflection; +using System.Text; +#if !NO_REF_EMIT +using System.Reflection.Emit; +#endif +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; +using Microsoft.Win32.SafeHandles; +using IKVM.Internal; + +static class Java_java_io_Console +{ + public static string encoding() + { + int cp = 437; + try + { + cp = Console.InputEncoding.CodePage; + } + catch + { + } + if (cp >= 874 && cp <= 950) + { + return "ms" + cp; + } + return "cp" + cp; + } + + private const int STD_INPUT_HANDLE = -10; + private const int ENABLE_ECHO_INPUT = 0x0004; + + [DllImport("kernel32")] + private static extern IntPtr GetStdHandle(int nStdHandle); + + [DllImport("kernel32")] + private static extern int GetConsoleMode(IntPtr hConsoleHandle, out int lpMode); + + [DllImport("kernel32")] + private static extern int SetConsoleMode(IntPtr hConsoleHandle, int dwMode); + + public static bool echo(bool on) + { +#if !FIRST_PASS + // HACK the only way to get this to work is by p/invoking the Win32 APIs + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + { + IntPtr hStdIn = GetStdHandle(STD_INPUT_HANDLE); + if (hStdIn.ToInt64() == 0 || hStdIn.ToInt64() == -1) + { + throw new java.io.IOException("The handle is invalid"); + } + int fdwMode; + if (GetConsoleMode(hStdIn, out fdwMode) == 0) + { + throw new java.io.IOException("GetConsoleMode failed"); + } + bool old = (fdwMode & ENABLE_ECHO_INPUT) != 0; + if (on) + { + fdwMode |= ENABLE_ECHO_INPUT; + } + else + { + fdwMode &= ~ENABLE_ECHO_INPUT; + } + if (SetConsoleMode(hStdIn, fdwMode) == 0) + { + throw new java.io.IOException("SetConsoleMode failed"); + } + return old; + } +#endif + return true; + } + + public static bool istty() + { + // The JDK returns false here if stdin or stdout (not stderr) is redirected to a file + // or if there is no console associated with the current process. + // The best we can do is to look at the KeyAvailable property, which + // will throw an InvalidOperationException if stdin is redirected or not available + try + { + return Console.KeyAvailable || true; + } + catch (InvalidOperationException) + { + return false; + } + } +} + +static class Java_java_io_FileDescriptor +{ + private static Converter fsync; + + public static Stream open(string name, FileMode fileMode, FileAccess fileAccess) + { + if (VirtualFileSystem.IsVirtualFS(name)) + { + return VirtualFileSystem.Open(name, fileMode, fileAccess); + } + else if (fileMode == FileMode.Append) + { + // this is the way to get atomic append behavior for all writes + return new FileStream(name, fileMode, FileSystemRights.AppendData, FileShare.ReadWrite, 1, FileOptions.None); + } + else + { + return new FileStream(name, fileMode, fileAccess, FileShare.ReadWrite, 1, false); + } + } + + [SecuritySafeCritical] + public static bool flushPosix(FileStream fs) + { + if (fsync == null) + { + ResolveFSync(); + } + bool success = false; + SafeFileHandle handle = fs.SafeFileHandle; + RuntimeHelpers.PrepareConstrainedRegions(); + try + { + handle.DangerousAddRef(ref success); + return fsync(handle.DangerousGetHandle().ToInt32()) == 0; + } + finally + { + if (success) + { + handle.DangerousRelease(); + } + } + } + + [SecurityCritical] + private static void ResolveFSync() + { + // we don't want a build time dependency on this Mono assembly, so we use reflection + Type type = Type.GetType("Mono.Unix.Native.Syscall, Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"); + if (type != null) + { + fsync = (Converter)Delegate.CreateDelegate(typeof(Converter), type, "fsync", false, false); + } + if (fsync == null) + { + fsync = DummyFSync; + } + } + + private static int DummyFSync(int fd) + { + return 0; + } +} + +static class Java_java_io_ObjectInputStream +{ + public static void bytesToFloats(byte[] src, int srcpos, float[] dst, int dstpos, int nfloats) + { + IKVM.Runtime.FloatConverter converter = new IKVM.Runtime.FloatConverter(); + for (int i = 0; i < nfloats; i++) + { + int v = src[srcpos++]; + v = (v << 8) | src[srcpos++]; + v = (v << 8) | src[srcpos++]; + v = (v << 8) | src[srcpos++]; + dst[dstpos++] = IKVM.Runtime.FloatConverter.ToFloat(v, ref converter); + } + } + + public static void bytesToDoubles(byte[] src, int srcpos, double[] dst, int dstpos, int ndoubles) + { + IKVM.Runtime.DoubleConverter converter = new IKVM.Runtime.DoubleConverter(); + for (int i = 0; i < ndoubles; i++) + { + long v = src[srcpos++]; + v = (v << 8) | src[srcpos++]; + v = (v << 8) | src[srcpos++]; + v = (v << 8) | src[srcpos++]; + v = (v << 8) | src[srcpos++]; + v = (v << 8) | src[srcpos++]; + v = (v << 8) | src[srcpos++]; + v = (v << 8) | src[srcpos++]; + dst[dstpos++] = IKVM.Runtime.DoubleConverter.ToDouble(v, ref converter); + } + } +} + +static class Java_java_io_ObjectOutputStream +{ + public static void floatsToBytes(float[] src, int srcpos, byte[] dst, int dstpos, int nfloats) + { + IKVM.Runtime.FloatConverter converter = new IKVM.Runtime.FloatConverter(); + for (int i = 0; i < nfloats; i++) + { + int v = IKVM.Runtime.FloatConverter.ToInt(src[srcpos++], ref converter); + dst[dstpos++] = (byte)(v >> 24); + dst[dstpos++] = (byte)(v >> 16); + dst[dstpos++] = (byte)(v >> 8); + dst[dstpos++] = (byte)(v >> 0); + } + } + + public static void doublesToBytes(double[] src, int srcpos, byte[] dst, int dstpos, int ndoubles) + { + IKVM.Runtime.DoubleConverter converter = new IKVM.Runtime.DoubleConverter(); + for (int i = 0; i < ndoubles; i++) + { + long v = IKVM.Runtime.DoubleConverter.ToLong(src[srcpos++], ref converter); + dst[dstpos++] = (byte)(v >> 56); + dst[dstpos++] = (byte)(v >> 48); + dst[dstpos++] = (byte)(v >> 40); + dst[dstpos++] = (byte)(v >> 32); + dst[dstpos++] = (byte)(v >> 24); + dst[dstpos++] = (byte)(v >> 16); + dst[dstpos++] = (byte)(v >> 8); + dst[dstpos++] = (byte)(v >> 0); + } + } +} + +namespace IKVM.Internal +{ + public static class IOHelpers + { + public static void WriteByte(byte[] buf, int offset, byte value) + { + buf[offset] = value; + } + + public static void WriteBoolean(byte[] buf, int offset, bool value) + { + buf[offset] = value ? (byte)1 : (byte)0; + } + + public static void WriteChar(byte[] buf, int offset, char value) + { + buf[offset + 0] = (byte)(value >> 8); + buf[offset + 1] = (byte)(value >> 0); + } + + public static void WriteShort(byte[] buf, int offset, short value) + { + buf[offset + 0] = (byte)(value >> 8); + buf[offset + 1] = (byte)(value >> 0); + } + + public static void WriteInt(byte[] buf, int offset, int value) + { + buf[offset + 0] = (byte)(value >> 24); + buf[offset + 1] = (byte)(value >> 16); + buf[offset + 2] = (byte)(value >> 8); + buf[offset + 3] = (byte)(value >> 0); + } + + public static void WriteFloat(byte[] buf, int offset, float value) + { +#if !FIRST_PASS + java.io.Bits.putFloat(buf, offset, value); +#endif + } + + public static void WriteLong(byte[] buf, int offset, long value) + { + WriteInt(buf, offset, (int)(value >> 32)); + WriteInt(buf, offset + 4, (int)value); + } + + public static void WriteDouble(byte[] buf, int offset, double value) + { +#if !FIRST_PASS + java.io.Bits.putDouble(buf, offset, value); +#endif + } + + public static byte ReadByte(byte[] buf, int offset) + { + return buf[offset]; + } + + public static bool ReadBoolean(byte[] buf, int offset) + { + return buf[offset] != 0; + } + + public static char ReadChar(byte[] buf, int offset) + { + return (char)((buf[offset] << 8) + buf[offset + 1]); + } + + public static short ReadShort(byte[] buf, int offset) + { + return (short)((buf[offset] << 8) + buf[offset + 1]); + } + + public static int ReadInt(byte[] buf, int offset) + { + return (buf[offset + 0] << 24) + + (buf[offset + 1] << 16) + + (buf[offset + 2] << 8) + + (buf[offset + 3] << 0); + } + + public static float ReadFloat(byte[] buf, int offset) + { +#if FIRST_PASS + return 0; +#else + return java.lang.Float.intBitsToFloat(ReadInt(buf, offset)); +#endif + } + + public static long ReadLong(byte[] buf, int offset) + { + long hi = (uint)ReadInt(buf, offset); + long lo = (uint)ReadInt(buf, offset + 4); + return lo + (hi << 32); + } + + public static double ReadDouble(byte[] buf, int offset) + { +#if FIRST_PASS + return 0; +#else + return java.lang.Double.longBitsToDouble(ReadLong(buf, offset)); +#endif + } + } +} + +static class Java_java_io_ObjectStreamClass +{ + public static void initNative() + { + } + + public static bool isDynamicTypeWrapper(java.lang.Class cl) + { + TypeWrapper wrapper = TypeWrapper.FromClass(cl); + return !wrapper.IsFastClassLiteralSafe; + } + + public static bool hasStaticInitializer(java.lang.Class cl) + { + TypeWrapper wrapper = TypeWrapper.FromClass(cl); + try + { + wrapper.Finish(); + } + catch (RetargetableJavaException x) + { + throw x.ToJava(); + } + Type type = wrapper.TypeAsTBD; + if (!type.IsArray && type.TypeInitializer != null) + { + wrapper.RunClassInit(); + return !AttributeHelper.IsHideFromJava(type.TypeInitializer); + } + return false; + } + +#if !FIRST_PASS && !NO_REF_EMIT + private sealed class FastFieldReflector : ikvm.@internal.FieldReflectorBase + { + private static readonly MethodInfo ReadByteMethod = typeof(IOHelpers).GetMethod("ReadByte"); + private static readonly MethodInfo ReadBooleanMethod = typeof(IOHelpers).GetMethod("ReadBoolean"); + private static readonly MethodInfo ReadCharMethod = typeof(IOHelpers).GetMethod("ReadChar"); + private static readonly MethodInfo ReadShortMethod = typeof(IOHelpers).GetMethod("ReadShort"); + private static readonly MethodInfo ReadIntMethod = typeof(IOHelpers).GetMethod("ReadInt"); + private static readonly MethodInfo ReadFloatMethod = typeof(IOHelpers).GetMethod("ReadFloat"); + private static readonly MethodInfo ReadLongMethod = typeof(IOHelpers).GetMethod("ReadLong"); + private static readonly MethodInfo ReadDoubleMethod = typeof(IOHelpers).GetMethod("ReadDouble"); + private static readonly MethodInfo WriteByteMethod = typeof(IOHelpers).GetMethod("WriteByte"); + private static readonly MethodInfo WriteBooleanMethod = typeof(IOHelpers).GetMethod("WriteBoolean"); + private static readonly MethodInfo WriteCharMethod = typeof(IOHelpers).GetMethod("WriteChar"); + private static readonly MethodInfo WriteShortMethod = typeof(IOHelpers).GetMethod("WriteShort"); + private static readonly MethodInfo WriteIntMethod = typeof(IOHelpers).GetMethod("WriteInt"); + private static readonly MethodInfo WriteFloatMethod = typeof(IOHelpers).GetMethod("WriteFloat"); + private static readonly MethodInfo WriteLongMethod = typeof(IOHelpers).GetMethod("WriteLong"); + private static readonly MethodInfo WriteDoubleMethod = typeof(IOHelpers).GetMethod("WriteDouble"); + private delegate void ObjFieldGetterSetter(object obj, object[] objarr); + private delegate void PrimFieldGetterSetter(object obj, byte[] objarr); + private static readonly ObjFieldGetterSetter objDummy = new ObjFieldGetterSetter(Dummy); + private static readonly PrimFieldGetterSetter primDummy = new PrimFieldGetterSetter(Dummy); + private java.io.ObjectStreamField[] fields; + private ObjFieldGetterSetter objFieldGetter; + private PrimFieldGetterSetter primFieldGetter; + private ObjFieldGetterSetter objFieldSetter; + private PrimFieldGetterSetter primFieldSetter; + + private static void Dummy(object obj, object[] objarr) + { + } + + private static void Dummy(object obj, byte[] barr) + { + } + + internal FastFieldReflector(java.io.ObjectStreamField[] fields) + { + this.fields = fields; + TypeWrapper tw = null; + foreach (java.io.ObjectStreamField field in fields) + { + FieldWrapper fw = GetFieldWrapper(field); + if (fw != null) + { + if (tw == null) + { + tw = fw.DeclaringType; + } + else if (tw != fw.DeclaringType) + { + // pre-condition is that all fields are from the same Type! + throw new java.lang.InternalError(); + } + } + } + if (tw == null) + { + objFieldGetter = objFieldSetter = objDummy; + primFieldGetter = primFieldSetter = primDummy; + } + else + { + try + { + tw.Finish(); + } + catch (RetargetableJavaException x) + { + throw x.ToJava(); + } + DynamicMethod dmObjGetter = DynamicMethodUtils.Create("__", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(object[]) }); + DynamicMethod dmPrimGetter = DynamicMethodUtils.Create("__", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(byte[]) }); + DynamicMethod dmObjSetter = DynamicMethodUtils.Create("__", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(object[]) }); + DynamicMethod dmPrimSetter = DynamicMethodUtils.Create("__", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(byte[]) }); + CodeEmitter ilgenObjGetter = CodeEmitter.Create(dmObjGetter); + CodeEmitter ilgenPrimGetter = CodeEmitter.Create(dmPrimGetter); + CodeEmitter ilgenObjSetter = CodeEmitter.Create(dmObjSetter); + CodeEmitter ilgenPrimSetter = CodeEmitter.Create(dmPrimSetter); + + // we want the getters to be verifiable (because writeObject can be used from partial trust), + // so we create a local to hold the properly typed object reference + CodeEmitterLocal objGetterThis = ilgenObjGetter.DeclareLocal(tw.TypeAsBaseType); + CodeEmitterLocal primGetterThis = ilgenPrimGetter.DeclareLocal(tw.TypeAsBaseType); + ilgenObjGetter.Emit(OpCodes.Ldarg_0); + ilgenObjGetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType); + ilgenObjGetter.Emit(OpCodes.Stloc, objGetterThis); + ilgenPrimGetter.Emit(OpCodes.Ldarg_0); + ilgenPrimGetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType); + ilgenPrimGetter.Emit(OpCodes.Stloc, primGetterThis); + + foreach (java.io.ObjectStreamField field in fields) + { + FieldWrapper fw = GetFieldWrapper(field); + if (fw == null) + { + continue; + } + fw.ResolveField(); + TypeWrapper fieldType = fw.FieldTypeWrapper; + try + { + fieldType = fieldType.EnsureLoadable(tw.GetClassLoader()); + fieldType.Finish(); + } + catch (RetargetableJavaException x) + { + throw x.ToJava(); + } + if (fieldType.IsPrimitive) + { + // Getter + ilgenPrimGetter.Emit(OpCodes.Ldarg_1); + ilgenPrimGetter.EmitLdc_I4(field.getOffset()); + ilgenPrimGetter.Emit(OpCodes.Ldloc, primGetterThis); + fw.EmitGet(ilgenPrimGetter); + if (fieldType == PrimitiveTypeWrapper.BYTE) + { + ilgenPrimGetter.Emit(OpCodes.Call, WriteByteMethod); + } + else if (fieldType == PrimitiveTypeWrapper.BOOLEAN) + { + ilgenPrimGetter.Emit(OpCodes.Call, WriteBooleanMethod); + } + else if (fieldType == PrimitiveTypeWrapper.CHAR) + { + ilgenPrimGetter.Emit(OpCodes.Call, WriteCharMethod); + } + else if (fieldType == PrimitiveTypeWrapper.SHORT) + { + ilgenPrimGetter.Emit(OpCodes.Call, WriteShortMethod); + } + else if (fieldType == PrimitiveTypeWrapper.INT) + { + ilgenPrimGetter.Emit(OpCodes.Call, WriteIntMethod); + } + else if (fieldType == PrimitiveTypeWrapper.FLOAT) + { + ilgenPrimGetter.Emit(OpCodes.Call, WriteFloatMethod); + } + else if (fieldType == PrimitiveTypeWrapper.LONG) + { + ilgenPrimGetter.Emit(OpCodes.Call, WriteLongMethod); + } + else if (fieldType == PrimitiveTypeWrapper.DOUBLE) + { + ilgenPrimGetter.Emit(OpCodes.Call, WriteDoubleMethod); + } + else + { + throw new java.lang.InternalError(); + } + + // Setter + ilgenPrimSetter.Emit(OpCodes.Ldarg_0); + ilgenPrimSetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType); + ilgenPrimSetter.Emit(OpCodes.Ldarg_1); + ilgenPrimSetter.EmitLdc_I4(field.getOffset()); + if (fieldType == PrimitiveTypeWrapper.BYTE) + { + ilgenPrimSetter.Emit(OpCodes.Call, ReadByteMethod); + } + else if (fieldType == PrimitiveTypeWrapper.BOOLEAN) + { + ilgenPrimSetter.Emit(OpCodes.Call, ReadBooleanMethod); + } + else if (fieldType == PrimitiveTypeWrapper.CHAR) + { + ilgenPrimSetter.Emit(OpCodes.Call, ReadCharMethod); + } + else if (fieldType == PrimitiveTypeWrapper.SHORT) + { + ilgenPrimSetter.Emit(OpCodes.Call, ReadShortMethod); + } + else if (fieldType == PrimitiveTypeWrapper.INT) + { + ilgenPrimSetter.Emit(OpCodes.Call, ReadIntMethod); + } + else if (fieldType == PrimitiveTypeWrapper.FLOAT) + { + ilgenPrimSetter.Emit(OpCodes.Call, ReadFloatMethod); + } + else if (fieldType == PrimitiveTypeWrapper.LONG) + { + ilgenPrimSetter.Emit(OpCodes.Call, ReadLongMethod); + } + else if (fieldType == PrimitiveTypeWrapper.DOUBLE) + { + ilgenPrimSetter.Emit(OpCodes.Call, ReadDoubleMethod); + } + else + { + throw new java.lang.InternalError(); + } + fw.EmitSet(ilgenPrimSetter); + } + else + { + // Getter + ilgenObjGetter.Emit(OpCodes.Ldarg_1); + ilgenObjGetter.EmitLdc_I4(field.getOffset()); + ilgenObjGetter.Emit(OpCodes.Ldloc, objGetterThis); + fw.EmitGet(ilgenObjGetter); + fieldType.EmitConvSignatureTypeToStackType(ilgenObjGetter); + ilgenObjGetter.Emit(OpCodes.Stelem_Ref); + + // Setter + ilgenObjSetter.Emit(OpCodes.Ldarg_0); + ilgenObjSetter.Emit(OpCodes.Ldarg_1); + ilgenObjSetter.EmitLdc_I4(field.getOffset()); + ilgenObjSetter.Emit(OpCodes.Ldelem_Ref); + fieldType.EmitCheckcast(ilgenObjSetter); + fieldType.EmitConvStackTypeToSignatureType(ilgenObjSetter, null); + fw.EmitSet(ilgenObjSetter); + } + } + ilgenObjGetter.Emit(OpCodes.Ret); + ilgenPrimGetter.Emit(OpCodes.Ret); + ilgenObjSetter.Emit(OpCodes.Ret); + ilgenPrimSetter.Emit(OpCodes.Ret); + ilgenObjGetter.DoEmit(); + ilgenPrimGetter.DoEmit(); + ilgenObjSetter.DoEmit(); + ilgenPrimSetter.DoEmit(); + objFieldGetter = (ObjFieldGetterSetter)dmObjGetter.CreateDelegate(typeof(ObjFieldGetterSetter)); + primFieldGetter = (PrimFieldGetterSetter)dmPrimGetter.CreateDelegate(typeof(PrimFieldGetterSetter)); + objFieldSetter = (ObjFieldGetterSetter)dmObjSetter.CreateDelegate(typeof(ObjFieldGetterSetter)); + primFieldSetter = (PrimFieldGetterSetter)dmPrimSetter.CreateDelegate(typeof(PrimFieldGetterSetter)); + } + } + + private static FieldWrapper GetFieldWrapper(java.io.ObjectStreamField field) + { + java.lang.reflect.Field f = field.getField(); + return f == null ? null : FieldWrapper.FromField(f); + } + + public override java.io.ObjectStreamField[] getFields() + { + return fields; + } + + public override void getObjFieldValues(object obj, object[] objarr) + { + objFieldGetter(obj, objarr); + } + + public override void setObjFieldValues(object obj, object[] objarr) + { + objFieldSetter(obj, objarr); + } + + public override void getPrimFieldValues(object obj, byte[] barr) + { + primFieldGetter(obj, barr); + } + + public override void setPrimFieldValues(object obj, byte[] barr) + { + primFieldSetter(obj, barr); + } + } +#endif // !FIRST_PASS && !NO_REF_EMIT + + public static object getFastFieldReflector(java.io.ObjectStreamField[] fieldsObj) + { +#if FIRST_PASS || NO_REF_EMIT + return null; +#else + return new FastFieldReflector(fieldsObj); +#endif + } +} + +static class Java_java_io_WinNTFileSystem +{ + internal const int ACCESS_READ = 0x04; + const int ACCESS_WRITE = 0x02; + const int ACCESS_EXECUTE = 0x01; + + public static string getDriveDirectory(object _this, int drive) + { + try + { + string path = ((char)('A' + (drive - 1))) + ":"; + return Path.GetFullPath(path).Substring(2); + } + catch (ArgumentException) + { + } + catch (SecurityException) + { + } + catch (PathTooLongException) + { + } + return "\\"; + } + + private static string CanonicalizePath(string path) + { + try + { + FileInfo fi = new FileInfo(path); + if (fi.DirectoryName == null) + { + return path.Length > 1 && path[1] == ':' + ? (Char.ToUpper(path[0]) + ":" + Path.DirectorySeparatorChar) + : path; + } + string dir = CanonicalizePath(fi.DirectoryName); + string name = fi.Name; + try + { + if (!VirtualFileSystem.IsVirtualFS(path)) + { + string[] arr = Directory.GetFileSystemEntries(dir, name); + if (arr.Length == 1) + { + name = arr[0]; + } + } + } + catch (UnauthorizedAccessException) + { + } + catch (IOException) + { + } + return Path.Combine(dir, name); + } + catch (UnauthorizedAccessException) + { + } + catch (IOException) + { + } + catch (SecurityException) + { + } + catch (NotSupportedException) + { + } + return path; + } + + public static string canonicalize0(object _this, string path) + { +#if FIRST_PASS + return null; +#else + try + { + // TODO there is still a known bug here. A dotted path component right after the root component + // are not removed as they should be. E.g. "c:\..." => "C:\..." or "\\server\..." => IOException + // Another know issue is that when running under Mono on Windows, the case names aren't converted + // to the correct (on file system) casing. + // + // FXBUG we're appending the directory separator to work around an apparent .NET bug. + // If we don't do this, "c:\j\." would be canonicalized to "C:\" + int colon = path.IndexOf(':', 2); + if (colon != -1) + { + return CanonicalizePath(path.Substring(0, colon) + Path.DirectorySeparatorChar) + path.Substring(colon); + } + return CanonicalizePath(path + Path.DirectorySeparatorChar); + } + catch (ArgumentException x) + { + throw new java.io.IOException(x.Message); + } +#endif + } + + public static string canonicalizeWithPrefix0(object _this, string canonicalPrefix, string pathWithCanonicalPrefix) + { + return canonicalize0(_this, pathWithCanonicalPrefix); + } + + private static string GetPathFromFile(java.io.File file) + { +#if FIRST_PASS + return null; +#else + return file.getPath(); +#endif + } + + public static int getBooleanAttributes(object _this, java.io.File f) + { + try + { + string path = GetPathFromFile(f); + if (VirtualFileSystem.IsVirtualFS(path)) + { + return VirtualFileSystem.GetBooleanAttributes(path); + } + FileAttributes attr = File.GetAttributes(path); + const int BA_EXISTS = 0x01; + const int BA_REGULAR = 0x02; + const int BA_DIRECTORY = 0x04; + const int BA_HIDDEN = 0x08; + int rv = BA_EXISTS; + if ((attr & FileAttributes.Directory) != 0) + { + rv |= BA_DIRECTORY; + } + else + { + rv |= BA_REGULAR; + } + if ((attr & FileAttributes.Hidden) != 0) + { + rv |= BA_HIDDEN; + } + return rv; + } + catch (ArgumentException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (SecurityException) + { + } + catch (NotSupportedException) + { + } + catch (IOException) + { + } + return 0; + } + + public static bool checkAccess(object _this, java.io.File f, int access) + { + string path = GetPathFromFile(f); + if (VirtualFileSystem.IsVirtualFS(path)) + { + return VirtualFileSystem.CheckAccess(path, access); + } + bool ok = true; + if ((access & (ACCESS_READ | ACCESS_EXECUTE)) != 0) + { + ok = false; + try + { + // HACK if path refers to a directory, we always return true + if (!Directory.Exists(path)) + { + new FileInfo(path).Open( + FileMode.Open, + FileAccess.Read, + FileShare.ReadWrite).Close(); + } + ok = true; + } + catch (SecurityException) + { + } + catch (ArgumentException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (IOException) + { + } + catch (NotSupportedException) + { + } + } + if (ok && ((access & ACCESS_WRITE) != 0)) + { + ok = false; + try + { + // HACK if path refers to a directory, we always return true + if (Directory.Exists(path)) + { + ok = true; + } + else + { + FileInfo fileInfo = new FileInfo(path); + // Like the JDK we'll only look at the read-only attribute and not + // the security permissions associated with the file or directory. + ok = (fileInfo.Attributes & FileAttributes.ReadOnly) == 0; + } + } + catch (SecurityException) + { + } + catch (ArgumentException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (IOException) + { + } + catch (NotSupportedException) + { + } + } + return ok; + } + + private static long DateTimeToJavaLongTime(DateTime datetime) + { + return (TimeZone.CurrentTimeZone.ToUniversalTime(datetime) - new DateTime(1970, 1, 1)).Ticks / 10000L; + } + + private static DateTime JavaLongTimeToDateTime(long datetime) + { + return TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(new DateTime(1970, 1, 1).Ticks + datetime * 10000L)); + } + + public static long getLastModifiedTime(object _this, java.io.File f) + { + try + { + DateTime dt = File.GetLastWriteTime(GetPathFromFile(f)); + if (dt.ToFileTime() == 0) + { + return 0; + } + else + { + return DateTimeToJavaLongTime(dt); + } + } + catch (UnauthorizedAccessException) + { + } + catch (ArgumentException) + { + } + catch (IOException) + { + } + catch (NotSupportedException) + { + } + return 0; + } + + public static long getLength(object _this, java.io.File f) + { + try + { + string path = GetPathFromFile(f); + if (VirtualFileSystem.IsVirtualFS(path)) + { + return VirtualFileSystem.GetLength(path); + } + return new FileInfo(path).Length; + } + catch (SecurityException) + { + } + catch (ArgumentException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (IOException) + { + } + catch (NotSupportedException) + { + } + return 0; + } + + public static bool setPermission(object _this, java.io.File f, int access, bool enable, bool owneronly) + { + if ((access & ACCESS_WRITE) != 0) + { + try + { + FileInfo file = new FileInfo(GetPathFromFile(f)); + if (enable) + { + file.Attributes &= ~FileAttributes.ReadOnly; + } + else + { + file.Attributes |= FileAttributes.ReadOnly; + } + return true; + } + catch (SecurityException) + { + } + catch (ArgumentException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (IOException) + { + } + catch (NotSupportedException) + { + } + return false; + } + return enable; + } + + public static bool createFileExclusively(object _this, string path) + { +#if !FIRST_PASS + try + { + File.Open(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None).Close(); + return true; + } + catch (ArgumentException x) + { + throw new java.io.IOException(x.Message); + } + catch (IOException x) + { + if (!File.Exists(path) && !Directory.Exists(path)) + { + throw new java.io.IOException(x.Message); + } + } + catch (UnauthorizedAccessException x) + { + if (!File.Exists(path) && !Directory.Exists(path)) + { + throw new java.io.IOException(x.Message); + } + } + catch (NotSupportedException x) + { + throw new java.io.IOException(x.Message); + } +#endif + return false; + } + + public static bool delete0(object _this, java.io.File f) + { + FileSystemInfo fileInfo = null; + try + { + string path = GetPathFromFile(f); + if (Directory.Exists(path)) + { + fileInfo = new DirectoryInfo(path); + } + else if (File.Exists(path)) + { + fileInfo = new FileInfo(path); + } + else + { + return false; + } + // We need to be able to delete read-only files/dirs too, so we clear + // the read-only attribute, if set. + if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0) + { + fileInfo.Attributes &= ~FileAttributes.ReadOnly; + } + fileInfo.Delete(); + return true; + } + catch (SecurityException) + { + } + catch (ArgumentException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (IOException) + { + } + catch (NotSupportedException) + { + } + return false; + } + + public static string[] list(object _this, java.io.File f) + { + try + { + string path = GetPathFromFile(f); + if (VirtualFileSystem.IsVirtualFS(path)) + { + return VirtualFileSystem.List(path); + } + string[] l = Directory.GetFileSystemEntries(path); + for (int i = 0; i < l.Length; i++) + { + int pos = l[i].LastIndexOf(Path.DirectorySeparatorChar); + if (pos >= 0) + { + l[i] = l[i].Substring(pos + 1); + } + } + return l; + } + catch (ArgumentException) + { + } + catch (IOException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (NotSupportedException) + { + } + return null; + } + + public static bool createDirectory(object _this, java.io.File f) + { + try + { + string path = GetPathFromFile(f); + DirectoryInfo parent = Directory.GetParent(path); + if (parent == null || + !Directory.Exists(parent.FullName) || + Directory.Exists(path)) + { + return false; + } + return Directory.CreateDirectory(path) != null; + } + catch (SecurityException) + { + } + catch (ArgumentException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (IOException) + { + } + catch (NotSupportedException) + { + } + return false; + } + + public static bool rename0(object _this, java.io.File f1, java.io.File f2) + { + try + { + new FileInfo(GetPathFromFile(f1)).MoveTo(GetPathFromFile(f2)); + return true; + } + catch (SecurityException) + { + } + catch (ArgumentException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (IOException) + { + } + catch (NotSupportedException) + { + } + return false; + } + + public static bool setLastModifiedTime(object _this, java.io.File f, long time) + { + try + { + new FileInfo(GetPathFromFile(f)).LastWriteTime = JavaLongTimeToDateTime(time); + return true; + } + catch (SecurityException) + { + } + catch (ArgumentException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (IOException) + { + } + catch (NotSupportedException) + { + } + return false; + } + + public static bool setReadOnly(object _this, java.io.File f) + { + try + { + FileInfo fileInfo = new FileInfo(GetPathFromFile(f)); + fileInfo.Attributes |= FileAttributes.ReadOnly; + return true; + } + catch (SecurityException) + { + } + catch (ArgumentException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (IOException) + { + } + catch (NotSupportedException) + { + } + return false; + } + + public static int listRoots0() + { + try + { + int drives = 0; + foreach (string drive in Environment.GetLogicalDrives()) + { + char c = Char.ToUpper(drive[0]); + drives |= 1 << (c - 'A'); + } + return drives; + } + catch (IOException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (SecurityException) + { + } + return 0; + } + + [SecuritySafeCritical] + public static long getSpace0(object _this, java.io.File f, int t) + { +#if !FIRST_PASS + long freeAvailable; + long total; + long totalFree; + StringBuilder volname = new StringBuilder(256); + if (GetVolumePathName(GetPathFromFile(f), volname, volname.Capacity) != 0 + && GetDiskFreeSpaceEx(volname.ToString(), out freeAvailable, out total, out totalFree) != 0) + { + switch (t) + { + case java.io.FileSystem.SPACE_TOTAL: + return total; + case java.io.FileSystem.SPACE_FREE: + return totalFree; + case java.io.FileSystem.SPACE_USABLE: + return freeAvailable; + } + } +#endif + return 0; + } + + [DllImport("kernel32")] + private static extern int GetDiskFreeSpaceEx(string directory, out long freeAvailable, out long total, out long totalFree); + + [DllImport("kernel32")] + private static extern int GetVolumePathName(string lpszFileName, [In, Out] StringBuilder lpszVolumePathName, int cchBufferLength); + + public static void initIDs() + { + } +} + +static class Java_java_io_UnixFileSystem +{ + public static int getBooleanAttributes0(object _this, java.io.File f) + { + return Java_java_io_WinNTFileSystem.getBooleanAttributes(_this, f); + } + + public static long getSpace(object _this, java.io.File f, int t) + { + // TODO + return 0; + } + + public static string canonicalize0(object _this, string path) + { + return Java_java_io_WinNTFileSystem.canonicalize0(_this, path); + } + + public static bool checkAccess(object _this, java.io.File f, int access) + { + return Java_java_io_WinNTFileSystem.checkAccess(_this, f, access); + } + + public static long getLastModifiedTime(object _this, java.io.File f) + { + return Java_java_io_WinNTFileSystem.getLastModifiedTime(_this, f); + } + + public static long getLength(object _this, java.io.File f) + { + return Java_java_io_WinNTFileSystem.getLength(_this, f); + } + + public static bool setPermission(object _this, java.io.File f, int access, bool enable, bool owneronly) + { + // TODO consider using Mono.Posix + return Java_java_io_WinNTFileSystem.setPermission(_this, f, access, enable, owneronly); + } + + public static bool createFileExclusively(object _this, string path) + { + return Java_java_io_WinNTFileSystem.createFileExclusively(_this, path); + } + + public static bool delete0(object _this, java.io.File f) + { + return Java_java_io_WinNTFileSystem.delete0(_this, f); + } + + public static string[] list(object _this, java.io.File f) + { + return Java_java_io_WinNTFileSystem.list(_this, f); + } + + public static bool createDirectory(object _this, java.io.File f) + { + return Java_java_io_WinNTFileSystem.createDirectory(_this, f); + } + + public static bool rename0(object _this, java.io.File f1, java.io.File f2) + { + return Java_java_io_WinNTFileSystem.rename0(_this, f1, f2); + } + + public static bool setLastModifiedTime(object _this, java.io.File f, long time) + { + return Java_java_io_WinNTFileSystem.setLastModifiedTime(_this, f, time); + } + + public static bool setReadOnly(object _this, java.io.File f) + { + return Java_java_io_WinNTFileSystem.setReadOnly(_this, f); + } + + public static void initIDs() + { + } +} diff --git a/external/ikvm/runtime/openjdk/java.lang.cs b/external/ikvm/runtime/openjdk/java.lang.cs index 7def9892ef..948bd25b50 100644 --- a/external/ikvm/runtime/openjdk/java.lang.cs +++ b/external/ikvm/runtime/openjdk/java.lang.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2007-2013 Jeroen Frijters + Copyright (C) 2007-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 @@ -96,6 +96,57 @@ static class Java_java_lang_Class #endif } + public static byte[] getRawTypeAnnotations(java.lang.Class thisClass) + { + return TypeWrapper.FromClass(thisClass).GetRawTypeAnnotations(); + } + +#if !FIRST_PASS + private sealed class ConstantPoolImpl : sun.reflect.ConstantPool + { + private readonly object[] constantPool; + + internal ConstantPoolImpl(object[] constantPool) + { + this.constantPool = constantPool; + } + + public override string getUTF8At(int index) + { + return (string)constantPool[index]; + } + + public override int getIntAt(int index) + { + return (int)constantPool[index]; + } + + public override long getLongAt(int index) + { + return (long)constantPool[index]; + } + + public override float getFloatAt(int index) + { + return (float)constantPool[index]; + } + + public override double getDoubleAt(int index) + { + return (double)constantPool[index]; + } + } +#endif + + public static object getConstantPool(java.lang.Class thisClass) + { +#if FIRST_PASS + return null; +#else + return new ConstantPoolImpl(TypeWrapper.FromClass(thisClass).GetConstantPool()); +#endif + } + public static bool isInstance(java.lang.Class thisClass, object obj) { return TypeWrapper.FromClass(thisClass).IsInstance(obj); @@ -169,6 +220,14 @@ static class Java_java_lang_Class return "void"; } } + if (tw.IsUnsafeAnonymous) + { +#if !FIRST_PASS + // for OpenJDK compatibility and debugging convenience we modify the class name to + // include the identity hashcode of the class object + return tw.Name + "/" + java.lang.System.identityHashCode(thisClass); +#endif + } return tw.Name; } @@ -188,7 +247,7 @@ static class Java_java_lang_Class return super != null ? super.ClassObject : null; } - public static java.lang.Class[] getInterfaces(java.lang.Class thisClass) + public static java.lang.Class[] getInterfaces0(java.lang.Class thisClass) { #if FIRST_PASS return null; @@ -252,7 +311,7 @@ static class Java_java_lang_Class } } - public static java.lang.Class getDeclaringClass(java.lang.Class thisClass) + public static java.lang.Class getDeclaringClass0(java.lang.Class thisClass) { try { @@ -286,9 +345,9 @@ static class Java_java_lang_Class return null; #else TypeWrapper wrapper = TypeWrapper.FromClass(thisClass); - while (wrapper.IsArray) + if (wrapper.IsArray) { - wrapper = wrapper.ElementTypeWrapper; + return null; } java.security.ProtectionDomain pd = wrapper.ClassObject.pd; if (pd == null) @@ -300,18 +359,17 @@ static class Java_java_lang_Class { pd = acl.GetProtectionDomain(); } + else if (wrapper is AnonymousTypeWrapper) + { + // dynamically compiled intrinsified lamdba anonymous types end up here and should get their + // protection domain from the host class + pd = ClassLoaderWrapper.GetWrapperFromType(wrapper.TypeAsTBD.DeclaringType).ClassObject.pd; + } } return pd; #endif } - public static void setProtectionDomain0(java.lang.Class thisClass, java.security.ProtectionDomain pd) - { -#if !FIRST_PASS - thisClass.pd = pd; -#endif - } - public static java.lang.Class getPrimitiveClass(string name) { // note that this method isn't used anymore (because it is an intrinsic (during core class library compilation)) @@ -341,7 +399,7 @@ static class Java_java_lang_Class } } - public static string getGenericSignature(java.lang.Class thisClass) + public static string getGenericSignature0(java.lang.Class thisClass) { TypeWrapper tw = TypeWrapper.FromClass(thisClass); tw.Finish(); @@ -620,16 +678,7 @@ static class Java_java_lang_ClassLoader try { ClassLoaderWrapper classLoaderWrapper = ClassLoaderWrapper.GetClassLoaderWrapper(thisClassLoader); - ClassFileParseOptions cfp = ClassFileParseOptions.LineNumberTable; - if (classLoaderWrapper.EmitDebugInfo) - { - cfp |= ClassFileParseOptions.LocalVariableTable; - } - if (classLoaderWrapper.RelaxedClassNameValidation) - { - cfp |= ClassFileParseOptions.RelaxedClassNameValidation; - } - ClassFile classFile = new ClassFile(b, off, len, name, cfp); + ClassFile classFile = new ClassFile(b, off, len, name, classLoaderWrapper.ClassFileParseOptions, null); if (name != null && classFile.Name != name) { #if !FIRST_PASS @@ -703,13 +752,13 @@ static class Java_java_lang_ClassLoader static class Java_java_lang_ClassLoader_00024NativeLibrary { - public static void load(object thisNativeLibrary, string name) + public static void load(object thisNativeLibrary, string name, bool isBuiltin) { #if !FIRST_PASS if (VirtualFileSystem.IsVirtualFS(name)) { // we fake success for native libraries loaded from VFS - ((java.lang.ClassLoader.NativeLibrary)thisNativeLibrary).handle = -1; + ((java.lang.ClassLoader.NativeLibrary)thisNativeLibrary).loaded = true; } else { @@ -725,7 +774,8 @@ static class Java_java_lang_ClassLoader_00024NativeLibrary private static void doLoad(object thisNativeLibrary, string name) { java.lang.ClassLoader.NativeLibrary lib = (java.lang.ClassLoader.NativeLibrary)thisNativeLibrary; - lib.handle = IKVM.Runtime.JniHelper.LoadLibrary(name, TypeWrapper.FromClass(lib.fromClass).GetClassLoader()); + lib.handle = IKVM.Runtime.JniHelper.LoadLibrary(name, TypeWrapper.FromClass(java.lang.ClassLoader.NativeLibrary.getFromClass()).GetClassLoader()); + lib.loaded = true; } #endif @@ -736,17 +786,22 @@ static class Java_java_lang_ClassLoader_00024NativeLibrary } [SecuritySafeCritical] - public static void unload(object thisNativeLibrary) + public static void unload(object thisNativeLibrary, string name, bool isBuiltin) { #if !FIRST_PASS java.lang.ClassLoader.NativeLibrary lib = (java.lang.ClassLoader.NativeLibrary)thisNativeLibrary; long handle = Interlocked.Exchange(ref lib.handle, 0); if (handle != 0) { - IKVM.Runtime.JniHelper.UnloadLibrary(handle, TypeWrapper.FromClass(lib.fromClass).GetClassLoader()); + IKVM.Runtime.JniHelper.UnloadLibrary(handle, TypeWrapper.FromClass(java.lang.ClassLoader.NativeLibrary.getFromClass()).GetClassLoader()); } #endif } + + public static string findBuiltinLib(string name) + { + return null; + } } static class Java_java_lang_Compiler @@ -823,9 +878,12 @@ static class Java_java_lang_Package { Dictionary dict = new Dictionary(); string path = VirtualFileSystem.GetAssemblyResourcesPath(JVM.CoreAssembly) + "resources.jar"; - foreach (string pkg in ClassLoaderWrapper.GetBootstrapClassLoader().GetPackages()) + foreach (KeyValuePair pkgs in ClassLoaderWrapper.GetBootstrapClassLoader().GetPackageInfo()) { - dict[pkg.Replace('.', '/') + "/"] = path; + foreach (string pkg in pkgs.Value) + { + dict[pkg.Replace('.', '/') + "/"] = path; + } } Interlocked.CompareExchange(ref systemPackages, dict, null); } @@ -927,18 +985,11 @@ static class Java_java_lang_SecurityManager { StackFrame frame = trace.GetFrame(i); MethodBase method = frame.GetMethod(); - Type type = method.DeclaringType; - // NOTE these checks should be the same as the ones in Reflection.getCallerClass - if (Java_sun_reflect_Reflection.IsHideFromJava(method) - || type == null - || type.Assembly == typeof(object).Assembly - || type.Assembly == typeof(Java_java_lang_SecurityManager).Assembly - || type.Assembly == jniAssembly - || type == typeof(java.lang.reflect.Constructor) - || type == typeof(java.lang.reflect.Method)) + if (Java_sun_reflect_Reflection.IsHideFromStackWalk(method)) { continue; } + Type type = method.DeclaringType; if (type == typeof(java.lang.SecurityManager)) { continue; @@ -1068,20 +1119,6 @@ static class Java_java_lang_StrictMath #endif } - public static double ceil(double d) - { -#if FIRST_PASS - return 0; -#else - return ikvm.@internal.JMath.ceil(d); -#endif - } - - public static double floor(double d) - { - return fdlibm.floor(d); - } - public static double atan2(double y, double x) { #if FIRST_PASS @@ -1111,15 +1148,6 @@ static class Java_java_lang_StrictMath return Math.Tanh(d); } - public static double rint(double d) - { -#if FIRST_PASS - return 0; -#else - return ikvm.@internal.JMath.rint(d); -#endif - } - public static double hypot(double a, double b) { return fdlibm.__ieee754_hypot(a, b); @@ -1223,9 +1251,14 @@ static class Java_java_lang_ProcessImpl { public static string mapVfsExecutable(string path) { - if (VirtualFileSystem.IsVirtualFS(path)) + string unquoted = path; + if (unquoted.Length > 2 && unquoted[0] == '"' && unquoted[unquoted.Length - 1] == '"') { - return VirtualFileSystem.MapExecutable(path); + unquoted = unquoted.Substring(1, unquoted.Length - 2); + } + if (VirtualFileSystem.IsVirtualFS(unquoted)) + { + return VirtualFileSystem.MapExecutable(unquoted); } return path; } @@ -1250,7 +1283,7 @@ static class Java_java_lang_ProcessImpl for (; ; ) { string str = cmdstr.Substring(0, pos); - if (Path.IsPathRooted(str)) + if (IsPathRooted(str)) { if (Exists(str)) { @@ -1303,6 +1336,18 @@ static class Java_java_lang_ProcessImpl return list; } + private static bool IsPathRooted(string path) + { + try + { + return Path.IsPathRooted(path); + } + catch (ArgumentException) + { + return false; + } + } + private static bool Exists(string file) { try @@ -1319,6 +1364,10 @@ static class Java_java_lang_ProcessImpl { return true; } + else if (mapVfsExecutable(file) != file) + { + return true; + } else { return false; diff --git a/external/ikvm/runtime/openjdk/java.lang.reflect.cs b/external/ikvm/runtime/openjdk/java.lang.reflect.cs index 994ef6074c..d663c5357e 100644 --- a/external/ikvm/runtime/openjdk/java.lang.reflect.cs +++ b/external/ikvm/runtime/openjdk/java.lang.reflect.cs @@ -689,6 +689,8 @@ static class Java_java_lang_reflect_Proxy { return null; } + // we need to explicitly register the type, because the type isn't visible by normal means + tw.GetClassLoader().SetWrapperForType(type, tw); TypeWrapper[] wrappers2 = tw.Interfaces; if (wrappers.Length != wrappers.Length) { @@ -705,29 +707,50 @@ static class Java_java_lang_reflect_Proxy } } -static class Java_java_lang_reflect_Field +static class Java_java_lang_reflect_Executable { - public static object getDeclaredAnnotationsImpl(java.lang.reflect.Field thisField) - { - FieldWrapper fw = FieldWrapper.FromField(thisField); - return Java_java_lang_Class.AnnotationsToMap(fw.DeclaringType.GetClassLoader(), fw.DeclaringType.GetFieldAnnotations(fw)); - } -} - -static class Java_java_lang_reflect_Method -{ - public static object getDeclaredAnnotationsImpl(object methodOrConstructor) - { - MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(methodOrConstructor); - return Java_java_lang_Class.AnnotationsToMap(mw.DeclaringType.GetClassLoader(), mw.DeclaringType.GetMethodAnnotations(mw)); - } - - public static object[][] getParameterAnnotationsImpl(object methodOrConstructor) + public static object[] getParameters0(java.lang.reflect.Executable _this) { #if FIRST_PASS return null; #else - MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(methodOrConstructor); + MethodWrapper mw = MethodWrapper.FromExecutable(_this); + MethodParametersEntry[] methodParameters = mw.DeclaringType.GetMethodParameters(mw); + if (methodParameters == null) + { + return null; + } + if (methodParameters == MethodParametersEntry.Malformed) + { + throw new java.lang.reflect.MalformedParametersException("Invalid constant pool index"); + } + java.lang.reflect.Parameter[] parameters = new java.lang.reflect.Parameter[methodParameters.Length]; + for (int i = 0; i < parameters.Length; i++) + { + parameters[i] = new java.lang.reflect.Parameter(methodParameters[i].name ?? "", methodParameters[i].flags, _this, i); + } + return parameters; +#endif + } + + public static byte[] getTypeAnnotationBytes0(java.lang.reflect.Executable _this) + { + MethodWrapper mw = MethodWrapper.FromExecutable(_this); + return mw.DeclaringType.GetMethodRawTypeAnnotations(mw); + } + + public static object declaredAnnotationsImpl(java.lang.reflect.Executable executable) + { + MethodWrapper mw = MethodWrapper.FromExecutable(executable); + return Java_java_lang_Class.AnnotationsToMap(mw.DeclaringType.GetClassLoader(), mw.DeclaringType.GetMethodAnnotations(mw)); + } + + public static object[][] sharedGetParameterAnnotationsImpl(java.lang.reflect.Executable executable) + { +#if FIRST_PASS + return null; +#else + MethodWrapper mw = MethodWrapper.FromExecutable(executable); object[][] objAnn = mw.DeclaringType.GetParameterAnnotations(mw); if (objAnn == null) { @@ -758,10 +781,28 @@ static class Java_java_lang_reflect_Method return ann; #endif } +} +static class Java_java_lang_reflect_Field +{ + public static object getDeclaredAnnotationsImpl(java.lang.reflect.Field thisField) + { + FieldWrapper fw = FieldWrapper.FromField(thisField); + return Java_java_lang_Class.AnnotationsToMap(fw.DeclaringType.GetClassLoader(), fw.DeclaringType.GetFieldAnnotations(fw)); + } + + public static byte[] getTypeAnnotationBytes0(java.lang.reflect.Field thisField) + { + FieldWrapper fw = FieldWrapper.FromField(thisField); + return fw.DeclaringType.GetFieldRawTypeAnnotations(fw); + } +} + +static class Java_java_lang_reflect_Method +{ public static object getDefaultValue(java.lang.reflect.Method thisMethod) { - MethodWrapper mw = MethodWrapper.FromMethod(thisMethod); + MethodWrapper mw = MethodWrapper.FromExecutable(thisMethod); return mw.DeclaringType.GetAnnotationDefault(mw); } } diff --git a/external/ikvm/runtime/openjdk/java.net.cs b/external/ikvm/runtime/openjdk/java.net.cs new file mode 100644 index 0000000000..f84cbf8127 --- /dev/null +++ b/external/ikvm/runtime/openjdk/java.net.cs @@ -0,0 +1,702 @@ +/* + 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; +using System.Collections.Generic; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Security; + +static class Java_java_net_DatagramPacket +{ + public static void init() + { + } +} + +static class Java_java_net_InetAddress +{ + public static void init() + { + } + +#if !FIRST_PASS + internal static java.net.InetAddress ConvertIPAddress(IPAddress address, string hostname) + { + if (address.IsIPv6LinkLocal || address.IsIPv6SiteLocal) + { + return java.net.Inet6Address.getByAddress(hostname, address.GetAddressBytes(), (int)address.ScopeId); + } + else + { + return java.net.InetAddress.getByAddress(hostname, address.GetAddressBytes()); + } + } +#endif +} + +static class Java_java_net_InetAddressImplFactory +{ + private static readonly bool ipv6supported = Init(); + + private static bool Init() + { + string env = IKVM.Internal.JVM.SafeGetEnvironmentVariable("IKVM_IPV6"); + int val; + if (env != null && Int32.TryParse(env, out val)) + { + return (val & 1) != 0; + } + // On Linux we can't bind both an IPv4 and IPv6 to the same port, so we have to disable IPv6 until we have a dual-stack implementation. + // Mono on Windows doesn't appear to support IPv6 either (Mono on Linux does). + return Type.GetType("Mono.Runtime") == null + && Environment.OSVersion.Platform == PlatformID.Win32NT + && Socket.OSSupportsIPv6; + } + + public static bool isIPv6Supported() + { + return ipv6supported; + } +} + +static class Java_java_net_Inet4Address +{ + public static void init() + { + } +} + +static class Java_java_net_Inet4AddressImpl +{ + public static string getLocalHostName(object thisInet4AddressImpl) + { +#if FIRST_PASS + return null; +#else + try + { + return Dns.GetHostName(); + } + catch (SocketException) + { + } + catch (SecurityException) + { + } + return "localhost"; +#endif + } + + public static object lookupAllHostAddr(object thisInet4AddressImpl, string hostname) + { +#if FIRST_PASS + return null; +#else + try + { + IPAddress[] addr = Dns.GetHostAddresses(hostname); + List addresses = new List(); + for (int i = 0; i < addr.Length; i++) + { + byte[] b = addr[i].GetAddressBytes(); + if (b.Length == 4) + { + addresses.Add(java.net.InetAddress.getByAddress(hostname, b)); + } + } + if (addresses.Count == 0) + { + throw new java.net.UnknownHostException(hostname); + } + return addresses.ToArray(); + } + catch (ArgumentException x) + { + throw new java.net.UnknownHostException(x.Message); + } + catch (SocketException x) + { + throw new java.net.UnknownHostException(x.Message); + } +#endif + } + + public static string getHostByAddr(object thisInet4AddressImpl, byte[] addr) + { +#if FIRST_PASS + return null; +#else + try + { + return Dns.GetHostEntry(new IPAddress(addr)).HostName; + } + catch (ArgumentException x) + { + throw new java.net.UnknownHostException(x.Message); + } + catch (SocketException x) + { + throw new java.net.UnknownHostException(x.Message); + } +#endif + } + + public static bool isReachable0(object thisInet4AddressImpl, byte[] addr, int timeout, byte[] ifaddr, int ttl) + { + // like the JDK, we don't use Ping, but we try a TCP connection to the echo port + // (.NET 2.0 has a System.Net.NetworkInformation.Ping class, but that doesn't provide the option of binding to a specific interface) + try + { + using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + if (ifaddr != null) + { + sock.Bind(new IPEndPoint(((ifaddr[3] << 24) + (ifaddr[2] << 16) + (ifaddr[1] << 8) + ifaddr[0]) & 0xFFFFFFFFL, 0)); + } + if (ttl > 0) + { + sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, ttl); + } + IPEndPoint ep = new IPEndPoint(((addr[3] << 24) + (addr[2] << 16) + (addr[1] << 8) + addr[0]) & 0xFFFFFFFFL, 7); + IAsyncResult res = sock.BeginConnect(ep, null, null); + if (res.AsyncWaitHandle.WaitOne(timeout, false)) + { + try + { + sock.EndConnect(res); + return true; + } + catch (SocketException x) + { + const int WSAECONNREFUSED = 10061; + if (x.ErrorCode == WSAECONNREFUSED) + { + // we got back an explicit "connection refused", that means the host was reachable. + return true; + } + } + } + } + } + catch (SocketException) + { + } + return false; + } +} + +static class Java_java_net_Inet6Address +{ + public static void init() + { + } +} + +static class Java_java_net_Inet6AddressImpl +{ + public static string getLocalHostName(object thisInet6AddressImpl) + { +#if FIRST_PASS + return null; +#else + try + { + return Dns.GetHostName(); + } + catch (SocketException x) + { + throw new java.net.UnknownHostException(x.Message); + } +#endif + } + + public static object lookupAllHostAddr(object thisInet6AddressImpl, string hostname) + { +#if FIRST_PASS + return null; +#else + try + { + IPAddress[] addr = Dns.GetHostAddresses(hostname); + java.net.InetAddress[] addresses = new java.net.InetAddress[addr.Length]; + int pos = 0; + for (int i = 0; i < addr.Length; i++) + { + if (addr[i].AddressFamily == AddressFamily.InterNetworkV6 == java.net.InetAddress.preferIPv6Address) + { + addresses[pos++] = Java_java_net_InetAddress.ConvertIPAddress(addr[i], hostname); + } + } + for (int i = 0; i < addr.Length; i++) + { + if (addr[i].AddressFamily == AddressFamily.InterNetworkV6 != java.net.InetAddress.preferIPv6Address) + { + addresses[pos++] = Java_java_net_InetAddress.ConvertIPAddress(addr[i], hostname); + } + } + if (addresses.Length == 0) + { + throw new java.net.UnknownHostException(hostname); + } + return addresses; + } + catch (ArgumentException x) + { + throw new java.net.UnknownHostException(x.Message); + } + catch (SocketException x) + { + throw new java.net.UnknownHostException(x.Message); + } +#endif + } + + public static string getHostByAddr(object thisInet6AddressImpl, byte[] addr) + { +#if FIRST_PASS + return null; +#else + try + { + return Dns.GetHostEntry(new IPAddress(addr)).HostName; + } + catch (ArgumentException x) + { + throw new java.net.UnknownHostException(x.Message); + } + catch (SocketException x) + { + throw new java.net.UnknownHostException(x.Message); + } +#endif + } + + public static bool isReachable0(object thisInet6AddressImpl, byte[] addr, int scope, int timeout, byte[] inf, int ttl, int if_scope) + { + if (addr.Length == 4) + { + return Java_java_net_Inet4AddressImpl.isReachable0(null, addr, timeout, inf, ttl); + } + // like the JDK, we don't use Ping, but we try a TCP connection to the echo port + // (.NET 2.0 has a System.Net.NetworkInformation.Ping class, but that doesn't provide the option of binding to a specific interface) + try + { + using (Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) + { + if (inf != null) + { + sock.Bind(new IPEndPoint(new IPAddress(inf, (uint)if_scope), 0)); + } + if (ttl > 0) + { + sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.HopLimit, ttl); + } + IPEndPoint ep = new IPEndPoint(new IPAddress(addr, (uint)scope), 7); + IAsyncResult res = sock.BeginConnect(ep, null, null); + if (res.AsyncWaitHandle.WaitOne(timeout, false)) + { + try + { + sock.EndConnect(res); + return true; + } + catch (SocketException x) + { + const int WSAECONNREFUSED = 10061; + if (x.ErrorCode == WSAECONNREFUSED) + { + // we got back an explicit "connection refused", that means the host was reachable. + return true; + } + } + } + } + } + catch (ArgumentException) + { + } + catch (SocketException) + { + } + return false; + } +} + +static class Java_java_net_NetworkInterface +{ +#if !FIRST_PASS + private static NetworkInterfaceInfo cache; + private static DateTime cachedSince; +#endif + + public static void init() + { + } + +#if !FIRST_PASS + private sealed class NetworkInterfaceInfo + { + internal NetworkInterface[] dotnetInterfaces; + internal java.net.NetworkInterface[] javaInterfaces; + } + + private static int Compare(NetworkInterface ni1, NetworkInterface ni2) + { + int index1 = GetIndex(ni1); + int index2 = GetIndex(ni2); + return index1.CompareTo(index2); + } + + private static IPv4InterfaceProperties GetIPv4Properties(IPInterfaceProperties props) + { + try + { + return props.GetIPv4Properties(); + } + catch (NetworkInformationException) + { + return null; + } + } + + private static IPv6InterfaceProperties GetIPv6Properties(IPInterfaceProperties props) + { + try + { + return props.GetIPv6Properties(); + } + catch (NetworkInformationException) + { + return null; + } + } + + private static int GetIndex(NetworkInterface ni) + { + IPInterfaceProperties ipprops = ni.GetIPProperties(); + IPv4InterfaceProperties ipv4props = GetIPv4Properties(ipprops); + if (ipv4props != null) + { + return ipv4props.Index; + } + else if (Java_java_net_InetAddressImplFactory.isIPv6Supported()) + { + IPv6InterfaceProperties ipv6props = GetIPv6Properties(ipprops); + if (ipv6props != null) + { + return ipv6props.Index; + } + } + return -1; + } + + private static bool IsValid(NetworkInterface ni) + { + return GetIndex(ni) != -1; + } + + private static NetworkInterfaceInfo GetInterfaces() + { + // Since many of the methods in java.net.NetworkInterface end up calling this method and the underlying stuff this is + // based on isn't very quick either, we cache the array for a couple of seconds. + if (cache != null && DateTime.UtcNow - cachedSince < new TimeSpan(0, 0, 5)) + { + return cache; + } + NetworkInterface[] ifaces = NetworkInterface.GetAllNetworkInterfaces(); + // on Mono (on Windows) we need to filter out the network interfaces that don't have any IP properties + ifaces = Array.FindAll(ifaces, IsValid); + Array.Sort(ifaces, Compare); + java.net.NetworkInterface[] ret = new java.net.NetworkInterface[ifaces.Length]; + int eth = 0; + int tr = 0; + int fddi = 0; + int lo = 0; + int ppp = 0; + int sl = 0; + int net = 0; + for (int i = 0; i < ifaces.Length; i++) + { + string name; + switch (ifaces[i].NetworkInterfaceType) + { + case NetworkInterfaceType.Ethernet: + name = "eth" + eth++; + break; + case NetworkInterfaceType.TokenRing: + name = "tr" + tr++; + break; + case NetworkInterfaceType.Fddi: + name = "fddi" + fddi++; + break; + case NetworkInterfaceType.Loopback: + if (lo > 0) + { + continue; + } + name = "lo"; + lo++; + break; + case NetworkInterfaceType.Ppp: + name = "ppp" + ppp++; + break; + case NetworkInterfaceType.Slip: + name = "sl" + sl++; + break; + default: + name = "net" + net++; + break; + } + java.net.NetworkInterface netif = new java.net.NetworkInterface(); + ret[i] = netif; + netif._set1(name, ifaces[i].Description, GetIndex(ifaces[i])); + UnicastIPAddressInformationCollection uipaic = ifaces[i].GetIPProperties().UnicastAddresses; + List addresses = new List(); + List bindings = new List(); + for (int j = 0; j < uipaic.Count; j++) + { + IPAddress addr = uipaic[j].Address; + if (addr.AddressFamily == AddressFamily.InterNetwork) + { + java.net.Inet4Address address = new java.net.Inet4Address(null, addr.GetAddressBytes()); + java.net.InterfaceAddress binding = new java.net.InterfaceAddress(); + short mask = 32; + java.net.Inet4Address broadcast = null; + IPAddress v4mask; + try + { + v4mask = uipaic[j].IPv4Mask; + } + catch (NotImplementedException) + { + // Mono (as of 2.6.7) doesn't implement the IPv4Mask property + v4mask = null; + } + if (v4mask != null && !v4mask.Equals(IPAddress.Any)) + { + broadcast = new java.net.Inet4Address(null, -1); + mask = 0; + foreach (byte b in v4mask.GetAddressBytes()) + { + mask += (short)java.lang.Integer.bitCount(b); + } + } + else if (address.isLoopbackAddress()) + { + mask = 8; + broadcast = new java.net.Inet4Address(null, 0xffffff); + } + binding._set(address, broadcast, mask); + addresses.Add(address); + bindings.Add(binding); + } + else if (Java_java_net_InetAddressImplFactory.isIPv6Supported()) + { + int scope = 0; + if (addr.IsIPv6LinkLocal || addr.IsIPv6SiteLocal) + { + scope = (int)addr.ScopeId; + } + java.net.Inet6Address ia6 = new java.net.Inet6Address(); + ia6._holder().ipaddress = addr.GetAddressBytes(); + if (scope != 0) + { + ia6._holder().scope_id = scope; + ia6._holder().scope_id_set = true; + ia6._holder().scope_ifname = netif; + ia6._holder().scope_ifname_set = true; + } + java.net.InterfaceAddress binding = new java.net.InterfaceAddress(); + // TODO where do we get the IPv6 subnet prefix length? + short mask = 128; + binding._set(ia6, null, mask); + addresses.Add(ia6); + bindings.Add(binding); + } + } + netif._set2(addresses.ToArray(), bindings.ToArray(), new java.net.NetworkInterface[0]); + } + NetworkInterfaceInfo nii = new NetworkInterfaceInfo(); + nii.dotnetInterfaces = ifaces; + nii.javaInterfaces = ret; + cache = nii; + cachedSince = DateTime.UtcNow; + return nii; + } +#endif + + private static NetworkInterface GetDotNetNetworkInterfaceByIndex(int index) + { +#if FIRST_PASS + return null; +#else + NetworkInterfaceInfo nii = GetInterfaces(); + for (int i = 0; i < nii.javaInterfaces.Length; i++) + { + if (nii.javaInterfaces[i].getIndex() == index) + { + return nii.dotnetInterfaces[i]; + } + } + throw new java.net.SocketException("interface index not found"); +#endif + } + + public static object getAll() + { +#if FIRST_PASS + return null; +#else + return GetInterfaces().javaInterfaces; +#endif + } + + public static object getByName0(string name) + { +#if FIRST_PASS + return null; +#else + foreach (java.net.NetworkInterface iface in GetInterfaces().javaInterfaces) + { + if (iface.getName() == name) + { + return iface; + } + } + return null; +#endif + } + + public static object getByIndex0(int index) + { +#if FIRST_PASS + return null; +#else + foreach (java.net.NetworkInterface iface in GetInterfaces().javaInterfaces) + { + if (iface.getIndex() == index) + { + return iface; + } + } + return null; +#endif + } + + public static object getByInetAddress0(object addr) + { +#if FIRST_PASS + return null; +#else + foreach (java.net.NetworkInterface iface in GetInterfaces().javaInterfaces) + { + java.util.Enumeration addresses = iface.getInetAddresses(); + while (addresses.hasMoreElements()) + { + if (addresses.nextElement().Equals(addr)) + { + return iface; + } + } + } + return null; +#endif + } + + public static bool isUp0(string name, int ind) + { +#if FIRST_PASS + return false; +#else + return GetDotNetNetworkInterfaceByIndex(ind).OperationalStatus == OperationalStatus.Up; +#endif + } + + public static bool isLoopback0(string name, int ind) + { +#if FIRST_PASS + return false; +#else + return GetDotNetNetworkInterfaceByIndex(ind).NetworkInterfaceType == NetworkInterfaceType.Loopback; +#endif + } + + public static bool supportsMulticast0(string name, int ind) + { +#if FIRST_PASS + return false; +#else + return GetDotNetNetworkInterfaceByIndex(ind).SupportsMulticast; +#endif + } + + public static bool isP2P0(string name, int ind) + { +#if FIRST_PASS + return false; +#else + switch (GetDotNetNetworkInterfaceByIndex(ind).NetworkInterfaceType) + { + case NetworkInterfaceType.Ppp: + case NetworkInterfaceType.Slip: + return true; + default: + return false; + } +#endif + } + + public static byte[] getMacAddr0(byte[] inAddr, string name, int ind) + { +#if FIRST_PASS + return null; +#else + return GetDotNetNetworkInterfaceByIndex(ind).GetPhysicalAddress().GetAddressBytes(); +#endif + } + + public static int getMTU0(string name, int ind) + { +#if FIRST_PASS + return 0; +#else + IPInterfaceProperties ipprops = GetDotNetNetworkInterfaceByIndex(ind).GetIPProperties(); + IPv4InterfaceProperties v4props = GetIPv4Properties(ipprops); + if (v4props != null) + { + return v4props.Mtu; + } + if (Java_java_net_InetAddressImplFactory.isIPv6Supported()) + { + IPv6InterfaceProperties v6props = GetIPv6Properties(ipprops); + if (v6props != null) + { + return v6props.Mtu; + } + } + return -1; +#endif + } +} diff --git a/external/ikvm/runtime/openjdk/java.nio.cs b/external/ikvm/runtime/openjdk/java.nio.cs new file mode 100644 index 0000000000..2d0ce9ce8b --- /dev/null +++ b/external/ikvm/runtime/openjdk/java.nio.cs @@ -0,0 +1,277 @@ +/* + 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; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.Permissions; +using IKVM.Internal; + +[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] +[SecurityCritical] +static class Java_java_nio_Bits +{ + public static void copyFromShortArray(object src, long srcPos, long dstAddr, long length) + { +#if !FIRST_PASS + short[] shortArray = src as short[]; + if (shortArray != null) + { + int index = ((int)srcPos) >> 1; + while (length > 0) + { + short v = java.lang.Short.reverseBytes(shortArray[index++]); + Marshal.WriteInt16((IntPtr)dstAddr, v); + dstAddr += 2; + length -= 2; + } + } + else + { + char[] charArray = (char[])src; + int index = ((int)srcPos) >> 1; + while (length > 0) + { + short v = java.lang.Short.reverseBytes((short)charArray[index++]); + Marshal.WriteInt16((IntPtr)dstAddr, v); + dstAddr += 2; + length -= 2; + } + } +#endif + } + + public static void copyToShortArray(long srcAddr, object dst, long dstPos, long length) + { +#if !FIRST_PASS + short[] shortArray = dst as short[]; + if (shortArray != null) + { + int index = ((int)dstPos) >> 1; + while (length > 0) + { + short v = Marshal.ReadInt16((IntPtr)srcAddr); + shortArray[index++] = java.lang.Short.reverseBytes(v); + srcAddr += 2; + length -= 2; + } + } + else + { + char[] charArray = (char[])dst; + int index = ((int)dstPos) >> 1; + while (length > 0) + { + short v = Marshal.ReadInt16((IntPtr)srcAddr); + charArray[index++] = (char)java.lang.Short.reverseBytes(v); + srcAddr += 2; + length -= 2; + } + } +#endif + } + + public static void copyFromIntArray(object src, long srcPos, long dstAddr, long length) + { +#if !FIRST_PASS + int[] intArray = src as int[]; + if (intArray != null) + { + int index = ((int)srcPos) >> 2; + while (length > 0) + { + int v = java.lang.Integer.reverseBytes(intArray[index++]); + Marshal.WriteInt32((IntPtr)dstAddr, v); + dstAddr += 4; + length -= 4; + } + } + else + { + float[] floatArray = (float[])src; + int index = ((int)srcPos) >> 2; + while (length > 0) + { + int v = java.lang.Integer.reverseBytes(java.lang.Float.floatToRawIntBits(floatArray[index++])); + Marshal.WriteInt32((IntPtr)dstAddr, v); + dstAddr += 4; + length -= 4; + } + } +#endif + } + + public static void copyToIntArray(long srcAddr, object dst, long dstPos, long length) + { +#if !FIRST_PASS + int[] intArray = dst as int[]; + if (intArray != null) + { + int index = ((int)dstPos) >> 2; + while (length > 0) + { + int v = Marshal.ReadInt32((IntPtr)srcAddr); + intArray[index++] = java.lang.Integer.reverseBytes(v); + srcAddr += 4; + length -= 4; + } + } + else + { + float[] floatArray = (float[])dst; + int index = ((int)dstPos) >> 2; + while (length > 0) + { + int v = Marshal.ReadInt32((IntPtr)srcAddr); + floatArray[index++] = java.lang.Float.intBitsToFloat(java.lang.Integer.reverseBytes(v)); + srcAddr += 4; + length -= 4; + } + } +#endif + } + + public static void copyFromLongArray(object src, long srcPos, long dstAddr, long length) + { +#if !FIRST_PASS + long[] longArray = src as long[]; + if (longArray != null) + { + int index = ((int)srcPos) >> 3; + while (length > 0) + { + long v = java.lang.Long.reverseBytes(longArray[index++]); + Marshal.WriteInt64((IntPtr)dstAddr, v); + dstAddr += 8; + length -= 8; + } + } + else + { + double[] doubleArray = (double[])src; + int index = ((int)srcPos) >> 3; + while (length > 0) + { + long v = java.lang.Long.reverseBytes(BitConverter.DoubleToInt64Bits(doubleArray[index++])); + Marshal.WriteInt64((IntPtr)dstAddr, v); + dstAddr += 8; + length -= 8; + } + } +#endif + } + + public static void copyToLongArray(long srcAddr, object dst, long dstPos, long length) + { +#if !FIRST_PASS + long[] longArray = dst as long[]; + if (longArray != null) + { + int index = ((int)dstPos) >> 3; + while (length > 0) + { + long v = Marshal.ReadInt64((IntPtr)srcAddr); + longArray[index++] = java.lang.Long.reverseBytes(v); + srcAddr += 8; + length -= 8; + } + } + else + { + double[] doubleArray = (double[])dst; + int index = ((int)dstPos) >> 3; + while (length > 0) + { + long v = Marshal.ReadInt64((IntPtr)srcAddr); + doubleArray[index++] = BitConverter.Int64BitsToDouble(java.lang.Long.reverseBytes(v)); + srcAddr += 8; + length -= 8; + } + } +#endif + } +} + +static class Java_java_nio_MappedByteBuffer +{ + private static volatile int bogusField; + + public static bool isLoaded0(object thisMappedByteBuffer, long address, long length, int pageCount) + { + // on Windows, JDK simply returns false, so we can get away with that too. + return false; + } + + [SecuritySafeCritical] + public static void load0(object thisMappedByteBuffer, long address, long length) + { + int bogus = bogusField; + while (length > 0) + { + // touch a byte in every page + bogus += Marshal.ReadByte((IntPtr)address); + length -= 4096; + address += 4096; + } + // do a volatile store of the sum of the bytes to make sure the reads don't get optimized out + bogusField = bogus; + GC.KeepAlive(thisMappedByteBuffer); + } + + [SecuritySafeCritical] + public static void force0(object thisMappedByteBuffer, object fd, long address, long length) + { + if (JVM.IsUnix) + { + ikvm_msync((IntPtr)address, (int)length); + GC.KeepAlive(thisMappedByteBuffer); + } + else + { + // according to the JDK sources, FlushViewOfFile can fail with an ERROR_LOCK_VIOLATION error, + // so like the JDK, we retry up to three times if that happens. + for (int i = 0; i < 3; i++) + { + if (FlushViewOfFile((IntPtr)address, (IntPtr)length) != 0) + { + GC.KeepAlive(thisMappedByteBuffer); + return; + } + const int ERROR_LOCK_VIOLATION = 33; + if (Marshal.GetLastWin32Error() != ERROR_LOCK_VIOLATION) + { + break; + } + } +#if !FIRST_PASS + throw new java.io.IOException("Flush failed"); +#endif + } + } + + [DllImport("kernel32", SetLastError = true)] + private static extern int FlushViewOfFile(IntPtr lpBaseAddress, IntPtr dwNumberOfBytesToFlush); + + [DllImport("ikvm-native")] + private static extern int ikvm_msync(IntPtr address, int size); +} diff --git a/external/ikvm/runtime/openjdk/java.security.cs b/external/ikvm/runtime/openjdk/java.security.cs new file mode 100644 index 0000000000..4e794d881c --- /dev/null +++ b/external/ikvm/runtime/openjdk/java.security.cs @@ -0,0 +1,154 @@ +/* + 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; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; +using IKVM.Internal; + +static class Java_java_security_AccessController +{ + public static object getStackAccessControlContext(java.security.AccessControlContext context, ikvm.@internal.CallerID callerID) + { +#if FIRST_PASS + return null; +#else + List array = new List(); + bool is_privileged = GetProtectionDomains(array, callerID, new StackTrace(1)); + if (array.Count == 0) + { + if (is_privileged && context == null) + { + return null; + } + } + return CreateAccessControlContext(array, is_privileged, context); +#endif + } + +#if !FIRST_PASS + private static bool GetProtectionDomains(List array, ikvm.@internal.CallerID callerID, StackTrace stack) + { + // first we have to skip all AccessController related frames, because we can be called from a doPrivileged implementation (not the privileged action) + // in which case we should ignore the doPrivileged frame + int skip = 0; + for (; skip < stack.FrameCount; skip++) + { + Type type = stack.GetFrame(skip).GetMethod().DeclaringType; + if (type != typeof(Java_java_security_AccessController) && type != typeof(java.security.AccessController)) + { + break; + } + } + java.security.ProtectionDomain previous_protection_domain = null; + for (int i = skip; i < stack.FrameCount; i++) + { + bool is_privileged = false; + java.security.ProtectionDomain protection_domain; + MethodBase method = stack.GetFrame(i).GetMethod(); + if (method.DeclaringType == typeof(java.security.AccessController) + && method.Name == "doPrivileged") + { + is_privileged = true; + java.lang.Class caller = callerID.getCallerClass(); + protection_domain = caller == null ? null : Java_java_lang_Class.getProtectionDomain0(caller); + } + else if (Java_sun_reflect_Reflection.IsHideFromStackWalk(method)) + { + continue; + } + else + { + protection_domain = GetProtectionDomainFromType(method.DeclaringType); + } + + if (previous_protection_domain != protection_domain && protection_domain != null) + { + previous_protection_domain = protection_domain; + array.Add(protection_domain); + } + + if (is_privileged) + { + return true; + } + } + return false; + } + + private static object CreateAccessControlContext(List context, bool is_privileged, java.security.AccessControlContext privileged_context) + { + java.security.AccessControlContext acc = new java.security.AccessControlContext(context == null || context.Count == 0 ? null : context.ToArray(), is_privileged); + acc._privilegedContext(privileged_context); + return acc; + } + + private static java.security.ProtectionDomain GetProtectionDomainFromType(Type type) + { + if (type == null + || type.Assembly == typeof(object).Assembly + || type.Assembly == typeof(Java_java_security_AccessController).Assembly + || type.Assembly == Java_java_lang_SecurityManager.jniAssembly + || type.Assembly == typeof(java.lang.Thread).Assembly) + { + return null; + } + TypeWrapper tw = ClassLoaderWrapper.GetWrapperFromType(type); + if (tw != null) + { + return Java_java_lang_Class.getProtectionDomain0(tw.ClassObject); + } + return null; + } +#endif + + public static object getInheritedAccessControlContext() + { +#if FIRST_PASS + return null; +#else + object inheritedAccessControlContext = java.lang.Thread.currentThread().inheritedAccessControlContext; + java.security.AccessControlContext acc = inheritedAccessControlContext as java.security.AccessControlContext; + if (acc != null) + { + return acc; + } + java.security.AccessController.LazyContext lc = inheritedAccessControlContext as java.security.AccessController.LazyContext; + if (lc == null) + { + return null; + } + List list = new List(); + while (lc != null) + { + if (GetProtectionDomains(list, lc.callerID, lc.stackTrace)) + { + return CreateAccessControlContext(list, true, lc.context); + } + lc = lc.parent; + } + return CreateAccessControlContext(list, false, null); +#endif + } +} diff --git a/external/ikvm/runtime/openjdk/sun.management.cs b/external/ikvm/runtime/openjdk/sun.management.cs index b8bfbc887a..de71a26b7a 100644 --- a/external/ikvm/runtime/openjdk/sun.management.cs +++ b/external/ikvm/runtime/openjdk/sun.management.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Jeroen Frijters + Copyright (C) 2011-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 @@ -21,6 +21,7 @@ jeroen@frijters.net */ +using System; #if !FIRST_PASS using java.lang.management; #endif @@ -32,6 +33,41 @@ static class Java_sun_management_ClassLoadingImpl } } +static class Java_sun_management_FileSystemImpl +{ + public static void init0() + { + } + + public static bool isSecuritySupported0(string path) + { + throw new NotSupportedException(); + } + + public static bool isAccessUserOnly0(string path) + { + throw new NotSupportedException(); + } +} + +static class Java_sun_management_GcInfoBuilder +{ + public static int getNumGcExtAttributes(object _this, object gc) + { + throw new NotSupportedException(); + } + + public static void fillGcAttributeInfo(object _this, object gc, int numAttributes, string[] attributeNames, char[] types, string[] descriptions) + { + throw new NotSupportedException(); + } + + public static object getLastGcInfo0(object _this, object gc, int numExtAtts, object[] extAttValues, char[] extAttTypes, object[] before, object[] after) + { + throw new NotSupportedException(); + } +} + static class Java_sun_management_MemoryImpl { public static object getMemoryPools0() @@ -67,11 +103,58 @@ static class Java_sun_management_MemoryImpl } } +static class Java_sun_management_OperatingSystemImpl +{ + public static long getCommittedVirtualMemorySize0(object _this) + { + throw new System.NotImplementedException(); + } + + public static long getTotalSwapSpaceSize(object _this) + { + throw new System.NotImplementedException(); + } + + public static long getFreeSwapSpaceSize(object _this) + { + throw new System.NotImplementedException(); + } + + public static long getProcessCpuTime(object _this) + { + throw new System.NotImplementedException(); + } + + public static long getFreePhysicalMemorySize(object _this) + { + throw new System.NotImplementedException(); + } + + public static long getTotalPhysicalMemorySize(object _this) + { + throw new System.NotImplementedException(); + } + + public static double getSystemCpuLoad(object _this) + { + throw new System.NotImplementedException(); + } + + public static double getProcessCpuLoad(object _this) + { + throw new System.NotImplementedException(); + } + + public static void initialize() + { + } +} + static class Java_sun_management_ThreadImpl { public static object getThreads() { - return IKVM.NativeCode.java.lang.Thread.getThreads(); + return Java_java_lang_Thread.getThreads(); } private const int JVMTI_THREAD_STATE_ALIVE = 0x0001; @@ -161,9 +244,28 @@ static class Java_sun_management_ThreadImpl #endif } + private static int GetCurrentThreadId() + { +#pragma warning disable 618 + // On the CLR and Mono on Windows this is the (obsolete) equivalent of kernel32!GetCurrentThreadId + return System.AppDomain.GetCurrentThreadId(); +#pragma warning restore 618 + } + public static long getThreadTotalCpuTime0(long id) { - throw new System.NotImplementedException(); + if (id == 0) { + int currentId = GetCurrentThreadId(); + System.Diagnostics.ProcessThreadCollection threads = System.Diagnostics.Process.GetCurrentProcess().Threads; + foreach (System.Diagnostics.ProcessThread t in threads) { + if (t.Id == currentId) { + return (long)(t.TotalProcessorTime.Ticks * 100); + } + } + return 0; + } else { + throw new System.NotImplementedException("Only current Thread is supported."); + } } public static void getThreadTotalCpuTime1(long[] ids, long[] result) @@ -188,7 +290,7 @@ static class Java_sun_management_ThreadImpl public static void setThreadCpuTimeEnabled0(bool enable) { - throw new System.NotImplementedException(); + //ignoring, we need nothing to enable } public static void setThreadAllocatedMemoryEnabled0(bool enable) diff --git a/external/ikvm/runtime/runtime.build b/external/ikvm/runtime/runtime.build index 96e1bb2a10..808f06f16a 100644 --- a/external/ikvm/runtime/runtime.build +++ b/external/ikvm/runtime/runtime.build @@ -1,4 +1,27 @@ + @@ -20,7 +43,11 @@ - + + + + + @@ -60,7 +87,7 @@ - + @@ -70,6 +97,9 @@ + + + @@ -107,9 +137,11 @@ + + @@ -120,14 +152,16 @@ + + - + @@ -151,10 +185,22 @@ + + + + + + + + + + + + diff --git a/external/ikvm/runtime/stubgen/ClassFileWriter.cs b/external/ikvm/runtime/stubgen/ClassFileWriter.cs index ded626741b..9438a5f8c3 100644 --- a/external/ikvm/runtime/stubgen/ClassFileWriter.cs +++ b/external/ikvm/runtime/stubgen/ClassFileWriter.cs @@ -72,6 +72,11 @@ namespace IKVM.StubGen stream.WriteByte(b); } + public void WriteBytes(byte[] data) + { + stream.Write(data, 0, data.Length); + } + public void WriteUtf8(string str) { byte[] buf = new byte[str.Length * 3 + 1]; @@ -728,6 +733,24 @@ namespace IKVM.StubGen } } + sealed class RuntimeVisibleTypeAnnotationsAttribute : ClassFileAttribute + { + private readonly byte[] data; + + internal RuntimeVisibleTypeAnnotationsAttribute(ClassFileWriter classFile, byte[] data) + : base(classFile.AddUtf8("RuntimeVisibleTypeAnnotations")) + { + this.data = data; + } + + public override void Write(BigEndianStream bes) + { + base.Write(bes); + bes.WriteUInt32((uint)data.Length); + bes.WriteBytes(data); + } + } + sealed class AnnotationDefaultClassFileAttribute : ClassFileAttribute { private ClassFileWriter classFile; @@ -834,23 +857,31 @@ namespace IKVM.StubGen { private readonly ClassFileWriter classFile; private readonly ushort[] names; + private readonly ushort[] flags; - internal MethodParametersAttribute(ClassFileWriter classFile, ushort[] names) + internal MethodParametersAttribute(ClassFileWriter classFile, ushort[] names, ushort[] flags) : base(classFile.AddUtf8("MethodParameters")) { this.classFile = classFile; this.names = names; + this.flags = flags; } public override void Write(BigEndianStream bes) { base.Write(bes); + if (flags == null || names == null || flags.Length != names.Length) + { + // write a malformed MethodParameters attribute + bes.WriteUInt32(0); + return; + } bes.WriteUInt32((uint)(1 + names.Length * 4)); bes.WriteByte((byte)names.Length); - foreach (ushort idx in names) + for (int i = 0; i < names.Length; i++) { - bes.WriteUInt16(idx); - bes.WriteUInt16(0); + bes.WriteUInt16(names[i]); + bes.WriteUInt16(flags[i]); } } } diff --git a/external/ikvm/runtime/stubgen/StubGenerator.cs b/external/ikvm/runtime/stubgen/StubGenerator.cs index 1aa6f9373a..2f6938428f 100644 --- a/external/ikvm/runtime/stubgen/StubGenerator.cs +++ b/external/ikvm/runtime/stubgen/StubGenerator.cs @@ -93,6 +93,7 @@ namespace IKVM.StubGen writer.AddStringAttribute("Signature", genericTypeSignature); } AddAnnotations(writer, writer, tw.TypeAsBaseType); + AddTypeAnnotations(writer, writer, tw, tw.GetRawTypeAnnotations()); writer.AddStringAttribute("IKVM.NET.Assembly", GetAssemblyName(tw)); if (tw.TypeAsBaseType.IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false)) { @@ -103,7 +104,11 @@ namespace IKVM.StubGen if (!mw.IsHideFromReflection && (mw.IsPublic || mw.IsProtected || includeNonPublicMembers)) { FieldOrMethod m; - if (mw.Name == "") + // HACK javac has a bug in com.sun.tools.javac.code.Types.isSignaturePolymorphic() where it assumes that + // MethodHandle doesn't have any native methods with an empty argument list + // (or at least it throws a NPE when it examines the signature of a method without any parameters when it + // accesses argtypes.tail.tail) + if (mw.Name == "" || (tw == CoreClasses.java.lang.invoke.MethodHandle.Wrapper && (mw.Modifiers & Modifiers.Native) == 0)) { m = writer.AddMethod(mw.Modifiers, mw.Name, mw.Signature.Replace('.', '/')); CodeAttribute code = new CodeAttribute(writer); @@ -187,18 +192,24 @@ namespace IKVM.StubGen } if (includeParameterNames) { - ParameterInfo[] parameters = mb.GetParameters(); - if (parameters.Length != 0) + MethodParametersEntry[] mp = tw.GetMethodParameters(mw); + if (mp == MethodParametersEntry.Malformed) { - ushort[] names = new ushort[parameters.Length]; + m.AddAttribute(new MethodParametersAttribute(writer, null, null)); + } + else if (mp != null) + { + ushort[] names = new ushort[mp.Length]; + ushort[] flags = new ushort[mp.Length]; for (int i = 0; i < names.Length; i++) { - if (parameters[i].Name != null) + if (mp[i].name != null) { - names[i] = writer.AddUtf8(parameters[i].Name); + names[i] = writer.AddUtf8(mp[i].name); } + flags[i] = mp[i].flags; } - m.AddAttribute(new MethodParametersAttribute(writer, names)); + m.AddAttribute(new MethodParametersAttribute(writer, names, flags)); } } } @@ -209,6 +220,7 @@ namespace IKVM.StubGen } AddAnnotations(writer, m, mw.GetMethod()); AddParameterAnnotations(writer, m, mw.GetMethod()); + AddTypeAnnotations(writer, m, tw, tw.GetMethodRawTypeAnnotations(mw)); } } bool hasSerialVersionUID = false; @@ -240,6 +252,7 @@ namespace IKVM.StubGen f.AddAttribute(new DeprecatedAttribute(writer)); } AddAnnotations(writer, f, fw.GetField()); + AddTypeAnnotations(writer, f, tw, tw.GetFieldRawTypeAnnotations(fw)); } } } @@ -322,6 +335,143 @@ namespace IKVM.StubGen #endif } + private static void AddTypeAnnotations(ClassFileWriter writer, IAttributeOwner target, TypeWrapper tw, byte[] typeAnnotations) + { +#if !FIRST_PASS && !STUB_GENERATOR + if (typeAnnotations != null) + { + typeAnnotations = (byte[])typeAnnotations.Clone(); + object[] constantPool = tw.GetConstantPool(); + try + { + int pos = 0; + ushort num_annotations = ReadUInt16BE(typeAnnotations, ref pos); + for (int i = 0; i < num_annotations; i++) + { + FixupTypeAnnotationConstantPoolIndexes(writer, typeAnnotations, constantPool, ref pos); + } + } + catch (IndexOutOfRangeException) + { + // if the attribute is malformed, we add it anyway and hope the Java parser will agree and throw the right error + } + target.AddAttribute(new RuntimeVisibleTypeAnnotationsAttribute(writer, typeAnnotations)); + } +#endif + } + + private static void FixupTypeAnnotationConstantPoolIndexes(ClassFileWriter writer, byte[] typeAnnotations, object[] constantPool, ref int pos) + { + switch (typeAnnotations[pos++]) // target_type + { + case 0x00: + case 0x01: + case 0x16: + pos++; + break; + case 0x10: + case 0x11: + case 0x12: + case 0x17: + pos += 2; + break; + case 0x13: + case 0x14: + case 0x15: + break; + default: + throw new IndexOutOfRangeException(); + } + byte path_length = typeAnnotations[pos++]; + pos += path_length * 2; + FixupAnnotationConstantPoolIndexes(writer, typeAnnotations, constantPool, ref pos); + } + + private static void FixupAnnotationConstantPoolIndexes(ClassFileWriter writer, byte[] typeAnnotations, object[] constantPool, ref int pos) + { + FixupConstantPoolIndex(writer, typeAnnotations, constantPool, ref pos); + ushort num_components = ReadUInt16BE(typeAnnotations, ref pos); + for (int i = 0; i < num_components; i++) + { + FixupConstantPoolIndex(writer, typeAnnotations, constantPool, ref pos); + FixupAnnotationComponentValueConstantPoolIndexes(writer, typeAnnotations, constantPool, ref pos); + } + } + + private static void FixupConstantPoolIndex(ClassFileWriter writer, byte[] typeAnnotations, object[] constantPool, ref int pos) + { + ushort index = ReadUInt16BE(typeAnnotations, ref pos); + object item = constantPool[index]; + if (item is int) + { + index = writer.AddInt((int)item); + } + else if (item is long) + { + index = writer.AddLong((long)item); + } + else if (item is float) + { + index = writer.AddFloat((float)item); + } + else if (item is double) + { + index = writer.AddDouble((double)item); + } + else if (item is string) + { + index = writer.AddUtf8((string)item); + } + else + { + throw new IndexOutOfRangeException(); + } + typeAnnotations[pos - 2] = (byte)(index >> 8); + typeAnnotations[pos - 1] = (byte)(index >> 0); + } + + private static void FixupAnnotationComponentValueConstantPoolIndexes(ClassFileWriter writer, byte[] typeAnnotations, object[] constantPool, ref int pos) + { + switch ((char)typeAnnotations[pos++]) // tag + { + case 'B': + case 'C': + case 'D': + case 'F': + case 'I': + case 'J': + case 'S': + case 'Z': + case 's': + case 'c': + FixupConstantPoolIndex(writer, typeAnnotations, constantPool, ref pos); + break; + case 'e': + FixupConstantPoolIndex(writer, typeAnnotations, constantPool, ref pos); + FixupConstantPoolIndex(writer, typeAnnotations, constantPool, ref pos); + break; + case '@': + FixupAnnotationConstantPoolIndexes(writer, typeAnnotations, constantPool, ref pos); + break; + case '[': + ushort num_values = ReadUInt16BE(typeAnnotations, ref pos); + for (int i = 0; i < num_values; i++) + { + FixupAnnotationComponentValueConstantPoolIndexes(writer, typeAnnotations, constantPool, ref pos); + } + break; + default: + throw new IndexOutOfRangeException(); + } + } + + private static ushort ReadUInt16BE(byte[] buf, ref int pos) + { + ushort s = (ushort)((buf[pos] << 8) + buf[pos + 1]); + pos += 2; + return s; + } + #if !FIRST_PASS && !STUB_GENERATOR private static object[] GetAnnotation(CustomAttributeData cad) { @@ -525,7 +675,7 @@ namespace IKVM.StubGen "value", targets.ToArray() }); - if (Experimental.JDK_8 && IsRepeatableAnnotation(tw)) + if (IsRepeatableAnnotation(tw)) { annot.Add(new object[] { AnnotationDefaultAttribute.TAG_ANNOTATION, diff --git a/external/ikvm/runtime/verifier.cs.REMOVED.git-id b/external/ikvm/runtime/verifier.cs.REMOVED.git-id index 873c71d443..934c0f60c0 100644 --- a/external/ikvm/runtime/verifier.cs.REMOVED.git-id +++ b/external/ikvm/runtime/verifier.cs.REMOVED.git-id @@ -1 +1 @@ -81b479291c9b3c8f98f03a54e464caea811df044 \ No newline at end of file +c0168e79b1441480a125c7c6db72132875a3f366 \ No newline at end of file diff --git a/external/ikvm/runtime/vfs.cs b/external/ikvm/runtime/vfs.cs index 3ff13c3ecf..4439af8fe2 100644 --- a/external/ikvm/runtime/vfs.cs +++ b/external/ikvm/runtime/vfs.cs @@ -577,7 +577,7 @@ namespace IKVM.Internal { System.IO.MemoryStream mem = new System.IO.MemoryStream(); bool includeNonPublicInterfaces = !"true".Equals(java.lang.Props.props.getProperty("ikvm.stubgen.skipNonPublicInterfaces"), StringComparison.OrdinalIgnoreCase); - IKVM.StubGen.StubGenerator.WriteClass(mem, tw, includeNonPublicInterfaces, false, false, false); + IKVM.StubGen.StubGenerator.WriteClass(mem, tw, includeNonPublicInterfaces, false, false, true); buf = mem.ToArray(); } #endif @@ -756,6 +756,7 @@ namespace IKVM.Internal AddDummyLibrary(bin, "net"); AddDummyLibrary(bin, "splashscreen"); AddDummyLibrary(bin, "osx"); + AddDummyLibrary(bin, "management"); bin.Add("java", new VfsJavaExe()); bin.Add("javaw", new VfsJavaExe()); bin.Add("java.exe", new VfsJavaExe()); @@ -985,7 +986,7 @@ namespace IKVM.Internal #if FIRST_PASS return false; #else - return access == Java_java_io_Win32FileSystem.ACCESS_READ && GetVfsEntry(path) != null; + return access == Java_java_io_WinNTFileSystem.ACCESS_READ && GetVfsEntry(path) != null; #endif } diff --git a/external/ikvm/website/build/site/devguide/concepts.html b/external/ikvm/website/build/site/devguide/concepts.html index ad38a807e1..504de3b001 100644 --- a/external/ikvm/website/build/site/devguide/concepts.html +++ b/external/ikvm/website/build/site/devguide/concepts.html @@ -90,11 +90,11 @@
  • -FAQ +FAQ
  • -License +License
  • @@ -108,19 +108,19 @@ @@ -228,7 +228,7 @@

    Class Loading in Dynamically Interpreted Java Applications

    When you run a Java application using ikvm, ikvm finds and loads Java .class files much like - other Java VM's. See the ikvm notes for details.

    + other Java VM's. See the ikvm notes for details.

    Class Loading in ikvmc-compiled Java Applications

    diff --git a/external/ikvm/website/build/site/devguide/intro.html b/external/ikvm/website/build/site/devguide/intro.html index 139206c597..272699be25 100644 --- a/external/ikvm/website/build/site/devguide/intro.html +++ b/external/ikvm/website/build/site/devguide/intro.html @@ -90,11 +90,11 @@
  • -FAQ +FAQ
  • -License +License
  • @@ -108,19 +108,19 @@ diff --git a/external/ikvm/website/build/site/devguide/java2net.html b/external/ikvm/website/build/site/devguide/java2net.html index e2cd9b0ee3..6763d5c53b 100644 --- a/external/ikvm/website/build/site/devguide/java2net.html +++ b/external/ikvm/website/build/site/devguide/java2net.html @@ -90,11 +90,11 @@
  • -FAQ +FAQ
  • -License +License
  • @@ -108,19 +108,19 @@ @@ -246,7 +246,7 @@
  • -
  • Use the ikvmstub application to generate a Java jar file for each dll you identified in step 2. +
  • Use the ikvmstub application to generate a Java jar file for each dll you identified in step 2.

    The ikvmstub tool analyzes the .NET classes in the designated dll and generates a jar file containing Java interfaces and stub classes. This information is needed by the Java source compiler, which knows nothing about .NET assemblies.

    @@ -259,7 +259,7 @@ .NET classes you used; do not include the ikvmstub-generated jar files on the compiler classpath.
  • -

    For an example of this, see the tutorial.

    +

    For an example of this, see the tutorial.

    diff --git a/external/ikvm/website/build/site/devguide/net2java.html b/external/ikvm/website/build/site/devguide/net2java.html index 22846f8db1..c784686017 100644 --- a/external/ikvm/website/build/site/devguide/net2java.html +++ b/external/ikvm/website/build/site/devguide/net2java.html @@ -90,11 +90,11 @@
  • -FAQ +FAQ
  • -License +License
  • @@ -108,19 +108,19 @@ @@ -234,7 +234,7 @@
  • To use other Java API's, you can take one of the following approaches: