Imported Upstream version 3.10.0

Former-commit-id: 172c8e3c300b39d5785c7a3e8dfb08ebdbc1a99b
This commit is contained in:
Jo Shields 2014-10-04 11:27:48 +01:00
parent fe777c5c82
commit 8b9b85e7f5
970 changed files with 20242 additions and 31308 deletions

View File

@ -85,7 +85,7 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(srcdir)/config.h.in mkinstalldirs \ $(srcdir)/config.h.in mkinstalldirs \
$(srcdir)/mono-core.spec.in $(srcdir)/mono-uninstalled.pc.in \ $(srcdir)/mono-core.spec.in $(srcdir)/mono-uninstalled.pc.in \
AUTHORS COPYING.LIB ChangeLog NEWS compile config.guess \ 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 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/iconv.m4 \ am__aclocal_m4_deps = $(top_srcdir)/m4/iconv.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \

View File

@ -1,7 +1,7 @@
Mono is a software platform designed to allow developers to easily create cross platform applications. 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. 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) 1. [Installation](#compilation-and-installation)
2. [Using Mono](#using-mono) 2. [Using Mono](#using-mono)

View File

@ -123,7 +123,6 @@ if test x$has_ext_mod = xtrue; then
popd popd
else else
cat mono/mini/Makefile.am.in > mono/mini/Makefile.am cat mono/mini/Makefile.am.in > mono/mini/Makefile.am
cat mono/metadata/Makefile.am.in > mono/metadata/Makefile.am
fi fi

View File

@ -1 +1 @@
e2d46ae5f394ada396886d241225ad895d4fa194 f98bd1e8bf7b203688329a408624ecaaf8192c9a

View File

@ -1 +1 @@
9ad91a3e3e9b4a437dedfc1a32a3c9092d967f5e 6792b0c1cb1e40049a4610645db04eb603741561

View File

@ -377,7 +377,7 @@ mono_class_get_method_from_name (MonoClass *klass, const char *name, int param_c
</div> </div>
<p /> <p />
<b>Parameters</b> <b>Parameters</b>
<blockquote><dt><i>klass:</i></dt><dd> where to look for the method</dd><dt><i>name_space:</i></dt><dd> name of the method</dd><dt><i>param_count:</i></dt><dd> number of parameters. -1 for any number.</dd></blockquote> <blockquote><dt><i>klass:</i></dt><dd> where to look for the method</dd><dt><i>name:</i></dt><dd> name of the method</dd><dt><i>param_count:</i></dt><dd> number of parameters. -1 for any number.</dd></blockquote>
<b>Remarks</b> <b>Remarks</b>
<p /> <p />
Obtains a MonoMethod with a given name and number of parameters. Obtains a MonoMethod with a given name and number of parameters.

View File

@ -283,15 +283,8 @@
<div class="api"> <div class="api">
<div class="api-entry">DeleteCriticalSection</div> <div class="api-entry">DeleteCriticalSection</div>
<div class="prototype">void DeleteCriticalSection(WapiCriticalSection *section) <div class="prototype">Prototype: DeleteCriticalSection</div>
</div>
<p /> <p />
<b>Parameters</b>
<blockquote><dt><i>section:</i></dt><dd> The critical section to delete.</dd></blockquote>
<b>Remarks</b>
<p />
Releases all resources owned by critical section <i>section</i>.
</div> <a name="api:DeleteFile"></a> </div> <a name="api:DeleteFile"></a>
<div class="api"> <div class="api">
@ -764,35 +757,15 @@ gpointer GetStdHandle(WapiStdHandle stdhandle)
<div class="api"> <div class="api">
<div class="api-entry">InitializeCriticalSectionAndSpinCount</div> <div class="api-entry">InitializeCriticalSectionAndSpinCount</div>
<div class="prototype">gboolean InitializeCriticalSectionAndSpinCount(WapiCriticalSection *section, <div class="prototype">Prototype: InitializeCriticalSectionAndSpinCount</div>
guint32 spincount G_GNUC_UNUSED)
</div>
<p /> <p />
<b>Parameters</b>
<blockquote><dt><i>section:</i></dt><dd> The critical section to initialise.</dd><dt><i>spincount:</i></dt><dd> The spin count for this critical section. Not</dd></blockquote>
<b>Remarks</b>
<p /> 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).
</div> <a name="api:InitializeCriticalSection"></a> </div> <a name="api:InitializeCriticalSection"></a>
<div class="api"> <div class="api">
<div class="api-entry">InitializeCriticalSection</div> <div class="api-entry">InitializeCriticalSection</div>
<div class="prototype">void InitializeCriticalSection(WapiCriticalSection *section) <div class="prototype">Prototype: InitializeCriticalSection</div>
</div>
<p /> <p />
<b>Parameters</b>
<blockquote><dt><i>section:</i></dt><dd> The critical section to initialise</dd></blockquote>
<b>Remarks</b>
<p />
Initialises a critical section.
</div> <a name="api:ioctlsocket"></a> </div> <a name="api:ioctlsocket"></a>
<div class="api"> <div class="api">
@ -1046,19 +1019,8 @@ gpointer GetStdHandle(WapiStdHandle stdhandle)
<div class="api"> <div class="api">
<div class="api-entry">SetCriticalSectionSpinCount</div> <div class="api-entry">SetCriticalSectionSpinCount</div>
<div class="prototype">guint32 SetCriticalSectionSpinCount(WapiCriticalSection *section G_GNUC_UNUSED, guint32 spincount G_GNUC_UNUSED) <div class="prototype">Prototype: SetCriticalSectionSpinCount</div>
</div>
<p /> <p />
<b>Parameters</b>
<blockquote><dt><i>section:</i></dt><dd> The critical section to set</dd><dt><i>spincount:</i></dt><dd> The new spin count for this critical section. Not</dd></blockquote>
<b>Remarks</b>
<p /> currently used.
Sets the spin count for the critical section <i>section</i>. The spin
count is currently ignored, and set to zero.
Return value: The previous spin count. (Currently always zero).
</div> <a name="api:SetCurrentDirectory"></a> </div> <a name="api:SetCurrentDirectory"></a>
<div class="api"> <div class="api">
@ -1356,24 +1318,8 @@ SleepEx (guint32 ms, gboolean alertable)
<div class="api"> <div class="api">
<div class="api-entry">TryEnterCriticalSection</div> <div class="api-entry">TryEnterCriticalSection</div>
<div class="prototype">gboolean TryEnterCriticalSection(WapiCriticalSection *section) <div class="prototype">Prototype: TryEnterCriticalSection</div>
</div>
<p /> <p />
<b>Parameters</b>
<blockquote><dt><i>section:</i></dt><dd> The critical section to try and enter</dd></blockquote>
<b>Remarks</b>
<p />
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.
</div> <a name="api:UnlockFile"></a> </div> <a name="api:UnlockFile"></a>
<div class="api"> <div class="api">

View File

@ -273,3 +273,9 @@
#define g_utf8_get_char_validated monoeg_utf8_get_char_validated #define g_utf8_get_char_validated monoeg_utf8_get_char_validated
#define g_utf8_prev_char monoeg_utf8_prev_char #define g_utf8_prev_char monoeg_utf8_prev_char
#define g_utf8_to_ucs4 monoeg_utf8_to_ucs4 #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

View File

@ -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_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__) #define g_debug(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, __VA_ARGS__)
#endif /* ndef HAVE_C99_SUPPORT */ #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 * Conversions
*/ */

View File

@ -35,85 +35,47 @@
/* The current fatal levels, error is always fatal */ /* The current fatal levels, error is always fatal */
static GLogLevelFlags fatal = G_LOG_LEVEL_ERROR; 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 static void default_stdout_handler (const gchar *string);
#include <android/log.h> static void default_stderr_handler (const gchar *string);
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 <asl.h>
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
void void
g_print (const gchar *format, ...) g_print (const gchar *format, ...)
{ {
char *msg;
va_list args; va_list args;
va_start (args, format); va_start (args, format);
if (vasprintf (&msg, format, args) < 0)
out_vfprintf (stdout, format, args); return;
va_end (args); va_end (args);
if (!stdout_handler)
stdout_handler = default_stdout_handler;
stdout_handler (msg);
free (msg);
} }
void void
g_printerr (const gchar *format, ...) g_printerr (const gchar *format, ...)
{ {
char *msg;
va_list args; va_list args;
va_start (args, format); va_start (args, format);
if (vasprintf (&msg, format, args) < 0)
out_vfprintf (stderr, format, args); return;
va_end (args); va_end (args);
if (!stderr_handler)
stderr_handler = default_stderr_handler;
stderr_handler (msg);
free (msg);
} }
GLogLevelFlags GLogLevelFlags
@ -140,42 +102,16 @@ g_log_set_fatal_mask (const gchar *log_domain, GLogLevelFlags fatal_mask)
void void
g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args) 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; char *msg;
if (!default_log_func)
default_log_func = g_log_default_handler;
if (vasprintf (&msg, format, args) < 0) if (vasprintf (&msg, format, args) < 0)
return; return;
#ifdef G_OS_WIN32 default_log_func (log_domain, log_level, msg, default_log_func_user_data);
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
free (msg); free (msg);
if (log_level & fatal){
fflush (stdout);
fflush (stderr);
}
#endif
if (log_level & fatal){
abort ();
}
} }
void void
@ -196,6 +132,143 @@ g_assertion_message (const gchar *format, ...)
va_start (args, format); va_start (args, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args); g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args);
va_end (args); va_end (args);
abort (); }
#if PLATFORM_ANDROID
#include <android/log.h>
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 <asl.h>
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;
} }

View File

@ -150,6 +150,11 @@ namespace Mono.Cecil.PE {
PointerToRawData = buffer.ReadInt32 (), PointerToRawData = buffer.ReadInt32 (),
}; };
if (directory.SizeOfData == 0 || directory.PointerToRawData == 0) {
header = Empty<byte>.Array;
return directory;
}
buffer.position = (int) (directory.PointerToRawData - section.PointerToRawData); buffer.position = (int) (directory.PointerToRawData - section.PointerToRawData);
header = new byte [directory.SizeOfData]; header = new byte [directory.SizeOfData];

View File

@ -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 () 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) object ReadCustomAttributeEnum (TypeReference enum_type)

View File

@ -1164,9 +1164,14 @@ namespace Mono.Cecil {
MetadataToken GetTypeRefToken (TypeReference type) MetadataToken GetTypeRefToken (TypeReference type)
{ {
MetadataToken token;
if (module.CustomMetadataWriter != null) {
if (module.CustomMetadataWriter.CreateTypeRefToken (ref type, out token))
return token;
}
var row = CreateTypeRefRow (type); var row = CreateTypeRefRow (type);
MetadataToken token;
if (type_ref_map.TryGetValue (row, out token)) if (type_ref_map.TryGetValue (row, out token))
return token; return token;

View File

@ -437,7 +437,7 @@ namespace Mono.Cecil {
} }
#endif #endif
public TypeReference ImportType (TypeReference type, ImportGenericContext context) public virtual TypeReference ImportType (TypeReference type, ImportGenericContext context)
{ {
if (type.IsTypeSpecification ()) if (type.IsTypeSpecification ())
return ImportTypeSpecification (type, context); return ImportTypeSpecification (type, context);
@ -466,6 +466,7 @@ namespace Mono.Cecil {
case MetadataScopeType.AssemblyNameReference: case MetadataScopeType.AssemblyNameReference:
return ImportAssemblyName ((AssemblyNameReference) scope); return ImportAssemblyName ((AssemblyNameReference) scope);
case MetadataScopeType.ModuleDefinition: case MetadataScopeType.ModuleDefinition:
if (scope == module) return scope;
return ImportAssemblyName (((ModuleDefinition) scope).Assembly.Name); return ImportAssemblyName (((ModuleDefinition) scope).Assembly.Name);
case MetadataScopeType.ModuleReference: case MetadataScopeType.ModuleReference:
throw new NotImplementedException (); throw new NotImplementedException ();
@ -474,7 +475,7 @@ namespace Mono.Cecil {
throw new NotSupportedException (); throw new NotSupportedException ();
} }
AssemblyNameReference ImportAssemblyName (AssemblyNameReference name) protected virtual AssemblyNameReference ImportAssemblyName (AssemblyNameReference name)
{ {
AssemblyNameReference reference; AssemblyNameReference reference;
if (TryGetAssemblyNameReference (name, out reference)) if (TryGetAssemblyNameReference (name, out reference))

View File

@ -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 { public sealed class WriterParameters {
Stream symbol_stream; Stream symbol_stream;
@ -216,6 +232,7 @@ namespace Mono.Cecil {
#if !READ_ONLY #if !READ_ONLY
MetadataImporter importer; MetadataImporter importer;
ICustomMetadataWriter custom_writer;
#endif #endif
Collection<CustomAttribute> custom_attributes; Collection<CustomAttribute> custom_attributes;
Collection<AssemblyNameReference> references; Collection<AssemblyNameReference> references;
@ -286,6 +303,18 @@ namespace Mono.Cecil {
internal MetadataImporter MetadataImporter { internal MetadataImporter MetadataImporter {
get { return importer ?? (importer = new MetadataImporter (this)); } 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 #endif
public IAssemblyResolver AssemblyResolver { public IAssemblyResolver AssemblyResolver {

View File

@ -1,7 +1,7 @@
/* /*
Copyright (C) 2002, 2004, 2005, 2006, 2007 Jeroen Frijters Copyright (C) 2002, 2004, 2005, 2006, 2007 Jeroen Frijters
Copyright (C) 2006 Active Endpoints, Inc. 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) Copyright (C) 2011 Karsten Heinrich (i-net software)
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
@ -40,17 +40,29 @@ namespace ikvm.awt
internal class BitmapGraphics : NetGraphics internal class BitmapGraphics : NetGraphics
{ {
private readonly Bitmap bitmap; private readonly Bitmap bitmap;
private readonly BufferedImage image;
internal BitmapGraphics(Bitmap bitmap, java.awt.Font font, Color fgcolor, Color bgcolor) internal BitmapGraphics(Bitmap bitmap, Object destination, java.awt.Font font, Color fgcolor, Color bgcolor)
: base(createGraphics(bitmap), font, fgcolor, bgcolor) : base(createGraphics(bitmap), destination, font, fgcolor, bgcolor)
{ {
this.bitmap = bitmap; this.bitmap = bitmap;
image = destination as BufferedImage;
} }
internal BitmapGraphics(Bitmap bitmap) internal BitmapGraphics(Bitmap bitmap, Object destination)
: base(createGraphics(bitmap), null, Color.White, Color.Black) : 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() { protected override SizeF GetSize() {
@ -89,8 +101,8 @@ namespace ikvm.awt
{ {
private readonly Control control; private readonly Control control;
internal ComponentGraphics(Control control, java.awt.Color fgColor, java.awt.Color bgColor, java.awt.Font font) internal ComponentGraphics(Control control, java.awt.Component target, java.awt.Color fgColor, java.awt.Color bgColor, java.awt.Font font)
: base(control.CreateGraphics(), font, J2C.ConvertColor(fgColor), J2C.ConvertColor(bgColor)) : base(control.CreateGraphics(), target, font, J2C.ConvertColor(fgColor), J2C.ConvertColor(bgColor))
{ {
this.control = control; this.control = control;
} }
@ -116,12 +128,17 @@ namespace ikvm.awt
return (Point)this.control.Invoke(new Converter<Point,Point>(getPointToScreenImpl),point); return (Point)this.control.Invoke(new Converter<Point,Point>(getPointToScreenImpl),point);
} }
public override void copyArea(int x, int y, int width, int height, int dx, int dy) 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)); Matrix t = g.Transform;
Point dest = new Point(x + (int)this.g.Transform.OffsetX + dx, y + (int)this.g.Transform.OffsetY + dy); Point src = getPointToScreen(new Point(x + (int)t.OffsetX, y + (int)t.OffsetY));
this.g.CopyFromScreen(src, dest, new Size(width, height)); 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) public override void clip(java.awt.Shape shape)
{ {
@ -150,7 +167,7 @@ namespace ikvm.awt
private bool isBase = true; private bool isBase = true;
internal PrintGraphics(Graphics g) internal PrintGraphics(Graphics g)
: base(g, null, Color.White, Color.Black) : base(g, null, null, Color.White, Color.Black)
{ {
baseContext = new PrintGraphicsContext(); baseContext = new PrintGraphicsContext();
baseContext.Current = this; baseContext.Current = this;
@ -744,7 +761,7 @@ namespace ikvm.awt
netG.g.Clip = Clip; netG.g.Clip = Clip;
netG.g.SmoothingMode = SmoothingMode; netG.g.SmoothingMode = SmoothingMode;
netG.g.PixelOffsetMode = PixelOffsetMode; netG.g.PixelOffsetMode = PixelOffsetMode;
netG.g.TextRenderingHint = TextRenderingHint; netG.setTextRenderingHint(TextRenderingHint);
netG.g.InterpolationMode = InterpolationMode; netG.g.InterpolationMode = InterpolationMode;
netG.g.CompositingMode = CompositingMode; 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; private Graphics graphics;
internal Graphics JGraphics { get { return g; } }
private java.awt.Color javaColor; private java.awt.Color javaColor;
private java.awt.Paint javaPaint; private java.awt.Paint javaPaint;
internal Color color; internal Color color;
@ -780,6 +796,7 @@ namespace ikvm.awt
private java.awt.Stroke stroke; private java.awt.Stroke stroke;
private static java.awt.BasicStroke defaultStroke = new java.awt.BasicStroke(); private static java.awt.BasicStroke defaultStroke = new java.awt.BasicStroke();
private Font netfont; private Font netfont;
private int baseline;
internal Brush brush; internal Brush brush;
internal Pen pen; internal Pen pen;
private CompositeHelper composite; private CompositeHelper composite;
@ -787,7 +804,16 @@ namespace ikvm.awt
private Object textAntialiasHint; private Object textAntialiasHint;
private Object fractionalHint = java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT; 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<String, Int32> baselines = new System.Collections.Generic.Dictionary<String, Int32>();
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) if (font == null)
{ {
@ -801,12 +827,21 @@ namespace ikvm.awt
init(g); init(g);
} }
/// <summary>
/// The current C# Graphics
/// </summary>
internal virtual Graphics g
{
get { return graphics; }
set { graphics = value; }
}
protected void init(Graphics graphics) protected void init(Graphics graphics)
{ {
NetGraphicsState state = new NetGraphicsState(); NetGraphicsState state = new NetGraphicsState();
state.saveGraphics(this); state.saveGraphics(this);
g = graphics; g = graphics;
state.restoreGraphics(this); state.restoreGraphics(this);
} }
/// <summary> /// <summary>
@ -850,7 +885,7 @@ namespace ikvm.awt
{ {
if (pen!=null) pen.Dispose(); if (pen!=null) pen.Dispose();
if (brush!=null) brush.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) 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(); netfont = f.getNetFont();
font = f; font = f;
baseline = getBaseline( netfont, g.TextRenderingHint );
} }
} }
@ -1278,30 +1314,33 @@ namespace ikvm.awt
drawString(str, (float)x, (float)y); drawString(str, (float)x, (float)y);
} }
public override void drawString(String text, float x, float y) public override void drawString(String text, float x, float y) {
{ if (text.Length == 0) {
if (text.Length == 0)
{
return; return;
} }
bool fractional = isFractionalMetrics(); CompositingMode origCM = g.CompositingMode;
StringFormat format = new StringFormat(StringFormat.GenericTypographic); try {
format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox; if (origCM != CompositingMode.SourceOver) {
format.Trimming = StringTrimming.None; // Java has a different behaviar for AlphaComposite and Text Antialiasing
if (fractional || !sun.font.StandardGlyphVector.isSimpleString(font, text)) g.CompositingMode = CompositingMode.SourceOver;
{ }
g.DrawString(text, netfont, brush, x, y - font.getSize(), format);
} bool fractional = isFractionalMetrics();
else if (fractional || !sun.font.StandardGlyphVector.isSimpleString(font, text)) {
{ g.DrawString(text, netfont, brush, x, y - baseline, FORMAT);
// fixed metric for simple text, we position every character to simulate the Java behaviour } else {
java.awt.font.FontRenderContext frc = new java.awt.font.FontRenderContext(null, isAntiAlias(), fractional); // fixed metric for simple text, we position every character to simulate the Java behaviour
sun.font.FontDesignMetrics metrics = sun.font.FontDesignMetrics.getMetrics(font, frc); java.awt.font.FontRenderContext frc = new java.awt.font.FontRenderContext(null, isAntiAlias(), fractional);
y -= font.getSize(); sun.font.FontDesignMetrics metrics = sun.font.FontDesignMetrics.getMetrics(font, frc);
for (int i = 0; i < text.Length; i++) y -= baseline;
{ for (int i = 0; i < text.Length; i++) {
g.DrawString(text.Substring(i, 1), netfont, brush, x, y, format); g.DrawString(text.Substring(i, 1), netfont, brush, x, y, FORMAT);
x += metrics.charWidth(text[i]); 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) public override void setComposite(java.awt.Composite comp)
{ {
if (javaComposite == comp) {
return;
}
if (comp == null) if (comp == null)
{ {
throw new java.lang.IllegalArgumentException("null Composite"); throw new java.lang.IllegalArgumentException("null Composite");
@ -1750,13 +1792,13 @@ namespace ikvm.awt
if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT || if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT ||
hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF) hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)
{ {
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; setTextRenderingHint(TextRenderingHint.SingleBitPerPixelGridFit);
textAntialiasHint = hintValue; textAntialiasHint = hintValue;
return; return;
} }
if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON) if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON)
{ {
g.TextRenderingHint = TextRenderingHint.AntiAlias; setTextRenderingHint(TextRenderingHint.AntiAlias);
textAntialiasHint = hintValue; textAntialiasHint = hintValue;
return; return;
} }
@ -1933,6 +1975,71 @@ namespace ikvm.awt
return stroke; return stroke;
} }
internal void setTextRenderingHint(TextRenderingHint hint)
{
g.TextRenderingHint = hint;
baseline = getBaseline(netfont, hint);
}
/// <summary>
/// Caclulate the baseline from a font and a TextRenderingHint
/// </summary>
/// <param name="font">the font</param>
/// <param name="hint">the used TextRenderingHint</param>
/// <returns></returns>
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() private bool isAntiAlias()
{ {
switch (g.TextRenderingHint) switch (g.TextRenderingHint)
@ -1962,6 +2069,7 @@ namespace ikvm.awt
Matrix currentMatrix = null; Matrix currentMatrix = null;
Font currentFont = netfont; Font currentFont = netfont;
TextRenderingHint currentHint = g.TextRenderingHint; TextRenderingHint currentHint = g.TextRenderingHint;
int currentBaseline = baseline;
try try
{ {
java.awt.Font javaFont = gv.getFont(); java.awt.Font javaFont = gv.getFont();
@ -1969,19 +2077,22 @@ namespace ikvm.awt
{ {
netfont = javaFont.getNetFont(); netfont = javaFont.getNetFont();
} }
TextRenderingHint hint;
if (frc.isAntiAliased()) { if (frc.isAntiAliased()) {
if( frc.usesFractionalMetrics() ){ if( frc.usesFractionalMetrics() ){
g.TextRenderingHint = TextRenderingHint.AntiAlias; hint = TextRenderingHint.AntiAlias;
} else { } else {
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; hint = TextRenderingHint.AntiAliasGridFit;
} }
} else { } else {
if (frc.usesFractionalMetrics()) { if (frc.usesFractionalMetrics()) {
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel; hint = TextRenderingHint.SingleBitPerPixel;
} else { } else {
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; hint = TextRenderingHint.SingleBitPerPixelGridFit;
} }
} }
g.TextRenderingHint = hint;
baseline = getBaseline(netfont, hint);
if (!frc.getTransform().equals(getTransform())) if (!frc.getTransform().equals(getTransform()))
{ {
// save the old context and use the transformation from the renderContext // save the old context and use the transformation from the renderContext
@ -1994,6 +2105,7 @@ namespace ikvm.awt
{ {
// Restore the old context if needed // Restore the old context if needed
g.TextRenderingHint = currentHint; g.TextRenderingHint = currentHint;
baseline = currentBaseline;
netfont = currentFont; netfont = currentFont;
if (currentMatrix != null) 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 bitmap with the dimensions of the argument image. Then
// create a graphics objects from the bitmap. All paint operations will // create a graphics objects from the bitmap. All paint operations will
// then paint the bitmap. // then paint the bitmap.
public override java.awt.Graphics2D createGraphics(BufferedImage bi) 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() public override java.awt.Font[] getAllFonts()

View File

@ -1 +1 @@
4341b9c30b528a9c448533ed715fc437369b3561 474cfafc92a8fad74e36e71fb612ebd44209bce8

15
external/ikvm/bin/ikvm.exe.manifest vendored Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!--The ID below indicates application support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--The ID below indicates application support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
</assembly>

View File

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

View File

@ -35,7 +35,7 @@
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow> <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile> <ConfigurationOverrideFile>
</ConfigurationOverrideFile> </ConfigurationOverrideFile>
<DefineConstants>TRACE;DEBUG;STATIC_COMPILER;IKVM_REF_EMIT</DefineConstants> <DefineConstants>TRACE;DEBUG;STATIC_COMPILER;EMITTERS</DefineConstants>
<DocumentationFile> <DocumentationFile>
</DocumentationFile> </DocumentationFile>
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@ -91,6 +91,7 @@
<Compile Include="runtime\BigEndianBinaryReader.cs"> <Compile Include="runtime\BigEndianBinaryReader.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="runtime\Boxer.cs" />
<Compile Include="runtime\ByteCode.cs"> <Compile Include="runtime\ByteCode.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
@ -119,10 +120,12 @@
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="runtime\JsrInliner.cs" /> <Compile Include="runtime\JsrInliner.cs" />
<Compile Include="runtime\LambdaMetafactory.cs" />
<Compile Include="runtime\LocalVars.cs" /> <Compile Include="runtime\LocalVars.cs" />
<Compile Include="runtime\MemberWrapper.cs"> <Compile Include="runtime\MemberWrapper.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="runtime\MethodHandleUtil.cs" />
<Compile Include="runtime\profiler.cs"> <Compile Include="runtime\profiler.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -48,14 +48,14 @@ namespace IKVM.Internal
private WorkaroundBaseClass workaroundBaseClass; private WorkaroundBaseClass workaroundBaseClass;
internal AotTypeWrapper(ClassFile f, CompilerClassLoader loader) internal AotTypeWrapper(ClassFile f, CompilerClassLoader loader)
: base(f, loader, null) : base(null, f, loader, null)
{ {
} }
protected override Type GetBaseTypeForDefineType() protected override Type GetBaseTypeForDefineType()
{ {
TypeWrapper baseTypeWrapper = BaseTypeWrapper; TypeWrapper baseTypeWrapper = BaseTypeWrapper;
if (this.IsPublic && this.IsAbstract && baseTypeWrapper.IsPublic && baseTypeWrapper.IsAbstract) if (this.IsPublic && this.IsAbstract && baseTypeWrapper.IsPublic && baseTypeWrapper.IsAbstract && classLoader.WorkaroundAbstractMethodWidening)
{ {
// FXBUG // FXBUG
// if the current class widens access on an abstract base class method, // if the current class widens access on an abstract base class method,
@ -78,7 +78,7 @@ namespace IKVM.Internal
} }
if (methods != null) if (methods != null)
{ {
string name = "__WorkaroundBaseClass__." + Name; string name = "__WorkaroundBaseClass__." + UnicodeUtil.EscapeInvalidSurrogates(Name);
while (!classLoader.ReserveName(name)) while (!classLoader.ReserveName(name))
{ {
name = "_" + name; name = "_" + name;
@ -297,10 +297,7 @@ namespace IKVM.Internal
} }
if(!found) if(!found)
{ {
FieldWrapper[] newFields = new FieldWrapper[fields.Length + 1]; fields = ArrayUtil.Concat(fields, FieldWrapper.Create(this, null, null, field.Name, field.Sig, new ExModifiers((Modifiers)field.Modifiers, false)));
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));
} }
} }
} }
@ -471,9 +468,7 @@ namespace IKVM.Internal
if(setter != null) if(setter != null)
{ {
MethodWrapper mw = setter; MethodWrapper mw = setter;
Type[] args = new Type[indexer.Length + 1]; Type[] args = ArrayUtil.Concat(indexer, typeWrapper.TypeAsSignatureType);
indexer.CopyTo(args, 0);
args[args.Length - 1] = typeWrapper.TypeAsSignatureType;
if(!CheckPropertyArgs(args, mw.GetParametersForDefineMethod())) if(!CheckPropertyArgs(args, mw.GetParametersForDefineMethod()))
{ {
Console.Error.WriteLine("Warning: ignoring invalid property setter for {0}::{1}", clazz.Name, prop.Name); 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<string, IKVM.Internal.MapXml.Class> 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) private static void MapModifiers(MapXml.MapModifiers mapmods, bool isConstructor, out bool setmodifiers, ref MethodAttributes attribs)
{ {
setmodifiers = false; setmodifiers = false;
@ -716,14 +681,14 @@ namespace IKVM.Internal
// are we adding a new method? // are we adding a new method?
if(GetMethodWrapper(method.Name, method.Sig, false) == null) 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); Console.Error.WriteLine("Error: Method {0}.{1}{2} in xml remap file doesn't have a body.", clazz.Name, method.Name, method.Sig);
continue; continue;
} }
bool setmodifiers = false;
MethodAttributes attribs = method.MethodAttributes;
MapModifiers(method.Modifiers, false, out setmodifiers, ref attribs);
Type returnType; Type returnType;
Type[] parameterTypes; Type[] parameterTypes;
MapSignature(method.Sig, out returnType, out parameterTypes); MapSignature(method.Sig, out returnType, out parameterTypes);
@ -739,9 +704,12 @@ namespace IKVM.Internal
typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod());
} }
CompilerClassLoader.AddDeclaredExceptions(mb, method.throws); CompilerClassLoader.AddDeclaredExceptions(mb, method.throws);
CodeEmitter ilgen = CodeEmitter.Create(mb); if(method.body != null)
method.Emit(classLoader, ilgen); {
ilgen.DoEmit(); CodeEmitter ilgen = CodeEmitter.Create(mb);
method.Emit(classLoader, ilgen);
ilgen.DoEmit();
}
if(method.Attributes != null) if(method.Attributes != null)
{ {
foreach(IKVM.Internal.MapXml.Attribute attr in method.Attributes) 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; return null;
} }
@ -820,11 +791,12 @@ namespace IKVM.Internal
// TODO consider adding methods from base interface and java.lang.Object as well // TODO consider adding methods from base interface and java.lang.Object as well
for(int i = 0; i < methods.Length; i++) for(int i = 0; i < methods.Length; i++)
{ {
// skip <clinit> // skip <clinit> and non-virtual interface methods introduced in Java 8
if(!methods[i].IsStatic) GhostMethodWrapper gmw = methods[i] as GhostMethodWrapper;
if(gmw != null)
{ {
TypeWrapper[] args = methods[i].GetParameters(); 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]); AddParameterMetadata(stub, methods[i]);
AttributeHelper.SetModifiers(stub, methods[i].Modifiers, methods[i].IsInternal); AttributeHelper.SetModifiers(stub, methods[i].Modifiers, methods[i].IsInternal);
CodeEmitter ilgen = CodeEmitter.Create(stub); CodeEmitter ilgen = CodeEmitter.Create(stub);
@ -850,13 +822,32 @@ namespace IKVM.Internal
ilgen.Emit(OpCodes.Isinst, implementers[j].TypeAsTBD); ilgen.Emit(OpCodes.Isinst, implementers[j].TypeAsTBD);
label = ilgen.DefineLabel(); label = ilgen.DefineLabel();
ilgen.EmitBrfalse(label); 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); 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.EmitBr(end);
ilgen.MarkLabel(label); ilgen.MarkLabel(label);
} }

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages 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}'"; 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: case IKVM.Internal.Message.FileNotFound:
return "File not found: {0}"; 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: default:
return "Missing Error Message. Please file a bug."; return "Missing Error Message. Please file a bug.";
} }
@ -167,7 +174,6 @@ sealed class IkvmcCompiler
private bool nonleaf; private bool nonleaf;
private string manifestMainClass; private string manifestMainClass;
private string defaultAssemblyName; private string defaultAssemblyName;
private List<string> classesToExclude = new List<string>();
private static bool time; private static bool time;
private static string runtimeAssembly; private static string runtimeAssembly;
private static bool nostdlib; private static bool nostdlib;
@ -515,6 +521,8 @@ sealed class IkvmcCompiler
Console.Error.WriteLine("-lib:<dir> Additional directories to search for references"); Console.Error.WriteLine("-lib:<dir> Additional directories to search for references");
Console.Error.WriteLine("-highentropyva Enable high entropy ASLR"); Console.Error.WriteLine("-highentropyva Enable high entropy ASLR");
Console.Error.WriteLine("-static Disable dynamic binding"); Console.Error.WriteLine("-static Disable dynamic binding");
Console.Error.WriteLine("-assemblyattributes:<file> Read assembly custom attributes from specified");
Console.Error.WriteLine(" class file.");
} }
void ParseCommandLine(IEnumerator<string> arglist, List<CompilerOptions> targets, CompilerOptions options) void ParseCommandLine(IEnumerator<string> arglist, List<CompilerOptions> targets, CompilerOptions options)
@ -543,7 +551,6 @@ sealed class IkvmcCompiler
IkvmcCompiler nestedLevel = new IkvmcCompiler(); IkvmcCompiler nestedLevel = new IkvmcCompiler();
nestedLevel.manifestMainClass = manifestMainClass; nestedLevel.manifestMainClass = manifestMainClass;
nestedLevel.defaultAssemblyName = defaultAssemblyName; nestedLevel.defaultAssemblyName = defaultAssemblyName;
nestedLevel.classesToExclude = new List<string>(classesToExclude);
nestedLevel.ContinueParseCommandLine(arglist, targets, options.Copy()); nestedLevel.ContinueParseCommandLine(arglist, targets, options.Copy());
} }
else if(s == "}") else if(s == "}")
@ -775,7 +782,7 @@ sealed class IkvmcCompiler
} }
else if(s.StartsWith("-exclude:")) else if(s.StartsWith("-exclude:"))
{ {
ProcessExclusionFile(classesToExclude, s.Substring(9)); ProcessExclusionFile(ref options.classesToExclude, s.Substring(9));
} }
else if(s.StartsWith("-version:")) else if(s.StartsWith("-version:"))
{ {
@ -977,12 +984,25 @@ sealed class IkvmcCompiler
} }
else if(s == "-static") 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 else if(s == "-nojarstubs") // undocumented temporary option to mitigate risk
{ {
options.nojarstubs = true; 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 else
{ {
throw new FatalCompilerErrorException(Message.UnrecognizedOption, s); throw new FatalCompilerErrorException(Message.UnrecognizedOption, s);
@ -1032,7 +1052,6 @@ sealed class IkvmcCompiler
StaticCompiler.IssueMessage(options, Message.MainMethodFromManifest, manifestMainClass); StaticCompiler.IssueMessage(options, Message.MainMethodFromManifest, manifestMainClass);
options.mainClass = manifestMainClass; options.mainClass = manifestMainClass;
} }
options.classesToExclude = classesToExclude.ToArray();
targets.Add(options); targets.Add(options);
} }
@ -1180,7 +1199,7 @@ sealed class IkvmcCompiler
{ {
foreach (CompilerOptions peer in targets) 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); ArrayAppend(ref target.peerReferences, peer.assembly);
goto next_reference; goto next_reference;
@ -1238,10 +1257,22 @@ sealed class IkvmcCompiler
} }
else else
{ {
T[] temp = new T[array.Length + 1]; array = ArrayUtil.Concat(array, element);
Array.Copy(array, 0, temp, 0, array.Length); }
temp[temp.Length - 1] = element; }
array = temp;
private static void ArrayAppend<T>(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; ClassFile cf;
try try
{ {
cf = new ClassFile(buf, 0, buf.Length, "<unknown>", ClassFileParseOptions.None); cf = new ClassFile(buf, 0, buf.Length, "<unknown>", ClassFileParseOptions.None, null);
} }
catch (ClassFormatError) catch (ClassFormatError)
{ {
@ -1290,7 +1321,7 @@ sealed class IkvmcCompiler
return true; 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)) if (ze.Name.EndsWith(".class", StringComparison.OrdinalIgnoreCase))
{ {
@ -1298,7 +1329,7 @@ sealed class IkvmcCompiler
{ {
bool stub; bool stub;
string name = ClassFile.GetClassName(data, 0, data.Length, out 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 // we use stubs to add references, but otherwise ignore them
return true; return true;
@ -1356,7 +1387,7 @@ sealed class IkvmcCompiler
{ {
found = true; found = true;
byte[] data = ReadFromZip(zf, ze); byte[] data = ReadFromZip(zf, ze);
if (IsStubLegacy(options, ze, data)) if (IsExcludedOrStubLegacy(options, ze, data))
{ {
continue; continue;
} }
@ -1405,6 +1436,10 @@ sealed class IkvmcCompiler
{ {
bool stub; bool stub;
string name = ClassFile.GetClassName(data, 0, data.Length, out stub); string name = ClassFile.GetClassName(data, 0, data.Length, out stub);
if (options.IsExcludedClass(name))
{
return;
}
if (stub && EmitStubWarning(options, data)) if (stub && EmitStubWarning(options, data))
{ {
// we use stubs to add references, but otherwise ignore them // 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 //This processes an exclusion file with a single regular expression per line
private static void ProcessExclusionFile(List<string> classesToExclude, String filename) private static void ProcessExclusionFile(ref string[] classesToExclude, string filename)
{ {
try try
{ {
List<string> list = classesToExclude == null ? new List<string>() : new List<string>(classesToExclude);
using(StreamReader file = new StreamReader(filename)) using(StreamReader file = new StreamReader(filename))
{ {
String line; String line;
@ -1486,14 +1522,29 @@ sealed class IkvmcCompiler
line = line.Trim(); line = line.Trim();
if(!line.StartsWith("//") && line.Length != 0) if(!line.StartsWith("//") && line.Length != 0)
{ {
classesToExclude.Add(line); list.Add(line);
} }
} }
} }
classesToExclude = list.ToArray();
} }
catch(Exception x) catch(Exception x)
{ {
throw new FatalCompilerErrorException(Message.ErrorReadingFile, filename, x.Message); 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);
}
}
} }

View File

@ -1 +1 @@
e7247c17ca6a6a7139699d9fdb9ddf15796f40b4 b71e0f94bba2f37126b0c66cbd774ef9d76cd588

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -23,6 +23,7 @@
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using IKVM.Attributes;
using IKVM.Reflection; using IKVM.Reflection;
using IKVM.Reflection.Emit; using IKVM.Reflection.Emit;
using Type = IKVM.Reflection.Type; using Type = IKVM.Reflection.Type;
@ -143,6 +144,7 @@ namespace IKVM.Internal
// Check for duplicates // Check for duplicates
if (!MethodExists(methods, mw)) if (!MethodExists(methods, mw))
{ {
mw.Link();
methods.Add(mw); methods.Add(mw);
} }
} }
@ -220,9 +222,20 @@ namespace IKVM.Internal
private static void CreateNoFail(CompilerClassLoader loader, TypeWrapper[] interfaces, List<ProxyMethod> methods) private static void CreateNoFail(CompilerClassLoader loader, TypeWrapper[] interfaces, List<ProxyMethod> 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(); 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); 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); CreateConstructor(tb);
for (int i = 0; i < methods.Count; i++) for (int i = 0; i < methods.Count; i++)
{ {
@ -232,7 +245,7 @@ namespace IKVM.Internal
{ {
CreateMethod(loader, tb, method); CreateMethod(loader, tb, method);
} }
CreateStaticInitializer(tb, methods); CreateStaticInitializer(tb, methods, loader);
} }
private static void CreateConstructor(TypeBuilder tb) private static void CreateConstructor(TypeBuilder tb)
@ -297,7 +310,7 @@ namespace IKVM.Internal
} }
else if (returnType.IsPrimitive) else if (returnType.IsPrimitive)
{ {
Boxer.EmitUnbox(ilgen, returnType); Boxer.EmitUnbox(ilgen, returnType, true);
} }
else if (returnType != CoreClasses.java.lang.Object.Wrapper) else if (returnType != CoreClasses.java.lang.Object.Wrapper)
{ {
@ -341,9 +354,9 @@ namespace IKVM.Internal
ilgen.DoEmit(); ilgen.DoEmit();
} }
private static void CreateStaticInitializer(TypeBuilder tb, List<ProxyMethod> methods) private static void CreateStaticInitializer(TypeBuilder tb, List<ProxyMethod> 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); CodeEmitterLocal callerID = ilgen.DeclareLocal(CoreClasses.ikvm.@internal.CallerID.Wrapper.TypeAsSignatureType);
TypeBuilder tbCallerID = DynamicTypeWrapper.FinishContext.EmitCreateCallerID(tb, ilgen); TypeBuilder tbCallerID = DynamicTypeWrapper.FinishContext.EmitCreateCallerID(tb, ilgen);
ilgen.Emit(OpCodes.Stloc, callerID); ilgen.Emit(OpCodes.Stloc, callerID);
@ -401,7 +414,10 @@ namespace IKVM.Internal
Dictionary<string, MethodWrapper> methods = new Dictionary<string, MethodWrapper>(); Dictionary<string, MethodWrapper> methods = new Dictionary<string, MethodWrapper>();
foreach (MethodWrapper mw in tw.GetMethods()) 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) 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();
}
}
}
} }

View File

@ -1,9 +1,32 @@
<?xml version="1.0"?> <?xml version="1.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
-->
<project name="ikvmc" default="ikvmc"> <project name="ikvmc" default="ikvmc">
<include buildfile="../ikvm.include" /> <include buildfile="../ikvm.include" />
<target name="ikvmc"> <target name="ikvmc">
<property name="defs" value="TRACE;STATIC_COMPILER" /> <property name="defs" value="TRACE;STATIC_COMPILER;EMITTERS" />
<if test="${property::exists('signed')}"> <if test="${property::exists('signed')}">
<property name="defs" value="${defs};${signed}" /> <property name="defs" value="${defs};${signed}" />
</if> </if>
@ -25,6 +48,7 @@
<include name="../runtime/atomic.cs" /> <include name="../runtime/atomic.cs" />
<include name="../runtime/attributes.cs" /> <include name="../runtime/attributes.cs" />
<include name="../runtime/BigEndianBinaryReader.cs" /> <include name="../runtime/BigEndianBinaryReader.cs" />
<include name="../runtime/Boxer.cs" />
<include name="../runtime/ByteCode.cs" /> <include name="../runtime/ByteCode.cs" />
<include name="../runtime/ClassFile.cs" /> <include name="../runtime/ClassFile.cs" />
<include name="../runtime/ClassLoaderWrapper.cs" /> <include name="../runtime/ClassLoaderWrapper.cs" />
@ -37,8 +61,10 @@
<include name="../runtime/intrinsics.cs" /> <include name="../runtime/intrinsics.cs" />
<include name="../runtime/JavaException.cs" /> <include name="../runtime/JavaException.cs" />
<include name="../runtime/JsrInliner.cs" /> <include name="../runtime/JsrInliner.cs" />
<include name="../runtime/LambdaMetafactory.cs" />
<include name="../runtime/LocalVars.cs" /> <include name="../runtime/LocalVars.cs" />
<include name="../runtime/MemberWrapper.cs" /> <include name="../runtime/MemberWrapper.cs" />
<include name="../runtime/MethodHandleUtil.cs" />
<include name="../runtime/profiler.cs" /> <include name="../runtime/profiler.cs" />
<include name="../runtime/ReflectUtil.cs" /> <include name="../runtime/ReflectUtil.cs" />
<include name="../runtime/RuntimeHelperTypes.cs" /> <include name="../runtime/RuntimeHelperTypes.cs" />

View File

@ -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/Class.java=java/lang/Class.java
jdk/src/share/classes/java/lang/ClassLoader.java=java/lang/ClassLoader.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/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/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/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/Constructor.java=java/lang/reflect/Constructor.java
jdk/src/share/classes/java/lang/reflect/Field.java=java/lang/reflect/Field.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/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/AccessController.java=java/security/AccessController.java
jdk/src/share/classes/java/security/ProtectionDomain.java=java/security/ProtectionDomain.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/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/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 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/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/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/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/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/ByteInterleavedRaster.java=sun/awt/image/ByteInterleavedRaster.java
jdk/src/share/classes/sun/awt/image/ImagingLib.java=sun/awt/image/ImagingLib.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/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/FontManager.java=sun/font/FontManager.java
jdk/src/share/classes/sun/font/StrikeCache.java=sun/font/StrikeCache.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/ManagementFactoryHelper.java=sun/management/ManagementFactoryHelper.java
jdk/src/share/classes/sun/management/VMManagementImpl.java=sun/management/VMManagementImpl.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/SharedSecrets.java=sun/misc/SharedSecrets.java
jdk/src/share/classes/sun/misc/VM.java=sun/misc/VM.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 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/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/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/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/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/Reflection.java=sun/reflect/Reflection.java
jdk/src/share/classes/sun/reflect/ReflectionFactory.java=sun/reflect/ReflectionFactory.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 jdk/src/solaris/classes/sun/nio/fs/UnixUriUtils.java=sun/nio/fs/UnixUriUtils.java

View File

@ -1 +1 @@
533d7645e2bb496cbbac8996759c133993dcc1bb 4911d54d998b7a044246f97683fb62901e9dc052

View File

@ -236,12 +236,14 @@ public abstract class AnnotationAttributeBase
{ {
// TODO consider checking that the type matches // TODO consider checking that the type matches
// (or better yet (?), remove the first two redundant elements from the array) // (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; definition = null;
} }
} }
} }
private static native Object[] unescapeInvalidSurrogates(Object[] definition);
private static void decodeValues(HashMap map, Class annotationClass, ClassLoader loader, Object[] array) private static void decodeValues(HashMap map, Class annotationClass, ClassLoader loader, Object[] array)
{ {
for (int i = 2; i < array.length; i += 2) for (int i = 2; i < array.length; i += 2)

View File

@ -1 +1 @@
bbc1d241f632078e8ecf146e9398406c5719dd2f 07fd7bd567e5b0ae8b3ae9c32741b56f6f363b0a

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -24,80 +24,40 @@
package java.lang; package java.lang;
import ikvm.runtime.AssemblyClassLoader; import java.lang.annotation.Annotation;
import java.io.IOException; import java.lang.reflect.Executable;
import java.net.MalformedURLException; import java.security.AccessControlContext;
import java.net.URL;
import java.security.AccessController;
import java.util.Enumeration;
import java.util.Map; import java.util.Map;
import sun.nio.ch.Interruptible; import sun.nio.ch.Interruptible;
import sun.reflect.annotation.AnnotationType; import sun.reflect.annotation.AnnotationType;
import sun.security.action.GetPropertyAction;
@ikvm.lang.Internal @ikvm.lang.Internal
public class LangHelper 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() public static sun.misc.JavaLangAccess getJavaLangAccess()
{ {
return new sun.misc.JavaLangAccess() { return new sun.misc.JavaLangAccess() {
public sun.reflect.ConstantPool getConstantPool(Class klass) { public sun.reflect.ConstantPool getConstantPool(Class klass) {
return null; return klass.getConstantPool();
} }
public void setAnnotationType(Class klass, AnnotationType type) { public boolean casAnnotationType(Class<?> klass, AnnotationType oldType, AnnotationType newType) {
klass.setAnnotationType(type); return klass.casAnnotationType(oldType, newType);
} }
public AnnotationType getAnnotationType(Class klass) { public AnnotationType getAnnotationType(Class klass) {
return klass.getAnnotationType(); return klass.getAnnotationType();
} }
public Map<Class<? extends Annotation>, 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 extends Enum<E>> public <E extends Enum<E>>
E[] getEnumConstantsShared(Class<E> klass) { E[] getEnumConstantsShared(Class<E> klass) {
return klass.getEnumConstantsShared(); return klass.getEnumConstantsShared();
@ -114,8 +74,14 @@ public class LangHelper
public StackTraceElement getStackTraceElement(Throwable t, int i) { public StackTraceElement getStackTraceElement(Throwable t, int i) {
return t.getStackTraceElement(i); return t.getStackTraceElement(i);
} }
public int getStringHash32(String string) { public String newStringUnsafe(char[] chars) {
return StringHelper.hash32(string); 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
} }
}; };
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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.lang.ProcessBuilder.Redirect;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; 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.AsyncCallback;
import cli.System.IAsyncResult; import cli.System.IAsyncResult;
import cli.System.Diagnostics.ProcessStartInfo; import cli.System.Diagnostics.ProcessStartInfo;
import cli.System.EventArgs;
import cli.System.EventHandler;
import cli.System.IO.FileAccess; import cli.System.IO.FileAccess;
import cli.System.IO.FileShare; import cli.System.IO.FileShare;
import cli.System.IO.FileMode; import cli.System.IO.FileMode;
@ -146,8 +152,17 @@ final class ProcessImpl extends Process {
return new ProcessImpl(cmdarray, environment, dir, return new ProcessImpl(cmdarray, environment, dir,
stdHandles, redirectErrorStream); stdHandles, redirectErrorStream);
} catch (Throwable t) {
if (f0 != null)
f0.close();
if (f1 != null)
f1.close();
if (f2 != null)
f2.close();
throw t;
} finally { } finally {
// HACK prevent the File[In|Out]putStream objects from closing the streams // 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) if (f0 != null)
cli.System.GC.SuppressFinalize(f0); cli.System.GC.SuppressFinalize(f0);
if (f1 != null) 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<String> 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 cli.System.Diagnostics.Process handle;
private OutputStream stdin_stream; private OutputStream stdin_stream;
private InputStream stdout_stream; private InputStream stdout_stream;
private InputStream stderr_stream; private InputStream stderr_stream;
private ProcessImpl(final String cmd[], private ProcessImpl(String cmd[],
final java.util.Map<String,String> envblock, final java.util.Map<String,String> envblock,
final String path, final String path,
final Stream[] stdHandles, final Stream[] stdHandles,
final boolean redirectErrorStream) final boolean redirectErrorStream)
throws IOException throws IOException
{ {
// Win32 CreateProcess requires cmd[0] to be normalized String cmdstr;
cmd[0] = new File(cmd[0]).getPath(); SecurityManager security = System.getSecurityManager();
boolean allowAmbiguousCommands = false;
// give the runtime an opportunity to map executables from VFS to a real executable if (security == null) {
cmd[0] = mapVfsExecutable(cmd[0]); allowAmbiguousCommands = true;
String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
StringBuilder cmdbuf = new StringBuilder(80); if (value != null)
for (int i = 0; i < cmd.length; i++) { allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
if (i > 0) { }
cmdbuf.append(' '); if (allowAmbiguousCommands) {
} // Legacy mode.
String s = cmd[i];
if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) { // Normalize path if possible.
if (s.charAt(0) != '"') { String executablePath = new File(cmd[0]).getPath();
cmdbuf.append('"');
cmdbuf.append(s); // No worry about internal, unpaired ["], and redirection/piping.
if (s.endsWith("\\")) { if (needsEscaping(VERIFICATION_LEGACY, executablePath) )
cmdbuf.append("\\"); executablePath = quoteString(executablePath);
}
cmdbuf.append('"'); cmdstr = createCommandLine(
} else if (s.endsWith("\"")) { //legacy mode doesn't worry about extended verification
/* The argument has already been quoted. */ VERIFICATION_LEGACY,
cmdbuf.append(s); executablePath,
} else { cmd);
/* Unmatched quote for the argument. */ } else {
throw new IllegalArgumentException(); String executablePath;
} try {
} else { executablePath = getExecutablePath(cmd[0]);
cmdbuf.append(s); } 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, handle = create(cmdstr, envblock, path,
stdHandles, redirectErrorStream); stdHandles, redirectErrorStream);
@ -261,6 +466,7 @@ final class ProcessImpl extends Process {
throw new InterruptedException(); throw new InterruptedException();
return exitValue(); return exitValue();
} }
private static void waitForInterruptibly(cli.System.Diagnostics.Process handle) throws InterruptedException { private static void waitForInterruptibly(cli.System.Diagnostics.Process handle) throws InterruptedException {
// to be interruptable we have to use polling // to be interruptable we have to use polling
// (on .NET 2.0 WaitForExit is actually interruptible, but this isn't documented) // (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); } public void destroy() { terminateProcess(handle); }
@Override
public Process destroyForcibly() {
destroy();
return this;
}
private static void terminateProcess(cli.System.Diagnostics.Process handle) { private static void terminateProcess(cli.System.Diagnostics.Process handle) {
try { try {
if (false) throw new cli.System.ComponentModel.Win32Exception(); 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. * 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 * @param envblock NUL-separated, double-NUL-terminated list of
* environment strings in VAR=VALUE form * environment strings in VAR=VALUE form
* @param dir the working directory of the process, or null if * @param dir the working directory of the process, or null if
@ -312,7 +575,8 @@ final class ProcessImpl extends Process {
argumentsStart++; 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_UseShellExecute(false);
si.set_RedirectStandardError(true); si.set_RedirectStandardError(true);
si.set_RedirectStandardOutput(true); si.set_RedirectStandardOutput(true);
@ -338,6 +602,27 @@ final class ProcessImpl extends Process {
} catch (cli.System.InvalidOperationException x2) { } catch (cli.System.InvalidOperationException x2) {
throw new IOException(x2.getMessage()); 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 stdin = proc.get_StandardInput().get_BaseStream();
Stream stdout = proc.get_StandardOutput().get_BaseStream(); Stream stdout = proc.get_StandardOutput().get_BaseStream();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
7ab53c76bb97c702c39866643a2547962ef3ead6

View File

@ -1 +1 @@
33393ac257cbddfb25bbbbef28c2d70a939dcc57 df6a641f2325337bd9354a4d23537dc48a60d0ee

View File

@ -1,16 +1,42 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!--
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
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
-->
<project name="ClassLibrary" default="all"> <project name="ClassLibrary" default="all">
<include buildfile="../ikvm.include" /> <include buildfile="../ikvm.include" />
<property name="pathsep" value=":" /> <property name="pathsep" value=":" />
<property overwrite="false" name="signoption" value="" /> <property overwrite="false" name="signoption" value="" />
<property overwrite="false" name="SkipSystemCoreDependency" value="false" /> <property overwrite="false" name="SkipSystemCoreDependency" value="false" />
<property name="OPENJDK_VERSION" value="OpenJDK 7u6 b24" /> <property name="OPENJDK_VERSION" value="OpenJDK 8 b132" />
<property name="OpenJDK7.dir" value="${project::get-base-directory()}/../../openjdk-7u6-b24" /> <property name="IMPLEMENTATION_VERSION" value="1.8.0" />
<property name="SPECIFICATION_VERSION" value="1.8" />
<property name="FULL_VERSION" value="1.8.0-b132" />
<property name="OpenJDK.dir" value="${project::get-base-directory()}/../../openjdk-8-b132" />
<if test="${platform::is-win32()}"> <if test="${platform::is-win32()}">
<property name="pathsep" value=";" /> <property name="pathsep" value=";" />
</if> </if>
<target name="all" depends="classes rmi vfs resources core"> <target name="all" depends="classes rmi run-nasgen vfs resources core">
</target> </target>
<target name="version"> <target name="version">
@ -26,7 +52,7 @@
<copy file="allsources.lst" tofile="allsources.gen.lst" outputencoding="ascii" overwrite="true"> <copy file="allsources.lst" tofile="allsources.gen.lst" outputencoding="ascii" overwrite="true">
<filterchain> <filterchain>
<replacetokens> <replacetokens>
<token key="OPENJDK7" value="${OpenJDK7.dir}" /> <token key="OPENJDK" value="${OpenJDK.dir}" />
</replacetokens> </replacetokens>
</filterchain> </filterchain>
</copy> </copy>
@ -70,27 +96,38 @@
</delete> </delete>
</target> </target>
<target name="classes" depends="version copyright allsources.gen.lst System.Core"> <target name="clean-classes">
<delete> <delete>
<fileset basedir="../classpath"> <fileset basedir="../classpath">
<include name="**.class"/> <include name="**.class"/>
</fileset> </fileset>
</delete> </delete>
<delete> <delete>
<fileset basedir="${OpenJDK7.dir}"> <fileset basedir="${OpenJDK.dir}">
<include name="**.class"/> <include name="**.class"/>
</fileset> </fileset>
</delete> </delete>
<delete> <delete>
<fileset basedir="."> <fileset basedir=".">
<include name="**.class"/> <include name="**.class"/>
</fileset>
</delete>
</target>
<target name="clean-stubjars">
<delete>
<fileset basedir=".">
<include name="mscorlib.jar" /> <include name="mscorlib.jar" />
<include name="System.jar" /> <include name="System.jar" />
<include name="System.Core.jar" /> <include name="System.Core.jar" />
<include name="System.Data.jar" /> <include name="System.Data.jar" />
<include name="System.Drawing.jar" /> <include name="System.Drawing.jar" />
<include name="System.XML.jar" />
</fileset> </fileset>
</delete> </delete>
</target>
<target name="stubjars" depends="clean-stubjars System.Core">
<exec program="${project::get-base-directory()}/../bin/ikvmstub.exe" commandline="-bootstrap mscorlib" useruntimeengine="true" /> <exec program="${project::get-base-directory()}/../bin/ikvmstub.exe" commandline="-bootstrap mscorlib" useruntimeengine="true" />
<exec program="${project::get-base-directory()}/../bin/ikvmstub.exe" commandline="-bootstrap System" useruntimeengine="true" /> <exec program="${project::get-base-directory()}/../bin/ikvmstub.exe" commandline="-bootstrap System" useruntimeengine="true" />
<exec program="${project::get-base-directory()}/../bin/ikvmstub.exe" commandline="-bootstrap System.Core" useruntimeengine="true" unless="${SkipSystemCoreDependency}" /> <exec program="${project::get-base-directory()}/../bin/ikvmstub.exe" commandline="-bootstrap System.Core" useruntimeengine="true" unless="${SkipSystemCoreDependency}" />
@ -99,20 +136,33 @@
</if> </if>
<exec program="${project::get-base-directory()}/../bin/ikvmstub.exe" commandline="-bootstrap System.Data" useruntimeengine="true" /> <exec program="${project::get-base-directory()}/../bin/ikvmstub.exe" commandline="-bootstrap System.Data" useruntimeengine="true" />
<exec program="${project::get-base-directory()}/../bin/ikvmstub.exe" commandline="-bootstrap System.Drawing" useruntimeengine="true" /> <exec program="${project::get-base-directory()}/../bin/ikvmstub.exe" commandline="-bootstrap System.Drawing" useruntimeengine="true" />
<exec program="${project::get-base-directory()}/../bin/ikvmstub.exe" commandline="-bootstrap System.XML" useruntimeengine="true" />
</target>
<target name="runtime-identity">
<property name="IKVM.Runtime" value="IKVM.Runtime" /> <property name="IKVM.Runtime" value="IKVM.Runtime" />
<property name="IKVM.AWT.WinForms" value="IKVM.AWT.WinForms" />
<if test="${signoption != ''}"> <if test="${signoption != ''}">
<loadfile file="../tools/pubkey.txt" property="publickey" /> <loadfile file="../tools/pubkey.txt" property="publickey" />
<property name="IKVM.Runtime" value="IKVM.Runtime, PublicKey=${publickey}" /> <property name="IKVM.Runtime" value="IKVM.Runtime, PublicKey=${publickey}" />
<property name="IKVM.AWT.WinForms" value="IKVM.AWT.WinForms, PublicKey=${publickey}" />
</if> </if>
</target>
<target name="AssemblyInfo.java" depends="runtime-identity version copyright">
<copy file="AssemblyInfo.java.in" tofile="AssemblyInfo.java" outputencoding="ascii" overwrite="true"> <copy file="AssemblyInfo.java.in" tofile="AssemblyInfo.java" outputencoding="ascii" overwrite="true">
<filterchain> <filterchain>
<replacetokens> <replacetokens>
<token key="RUNTIME" value="${IKVM.Runtime}" /> <token key="RUNTIME" value="${IKVM.Runtime}" />
<token key="AWTWINFORMS" value="${IKVM.AWT.WinForms}" />
<token key="VERSION" value="${VERSION}" /> <token key="VERSION" value="${VERSION}" />
<token key="COPYRIGHT" value="${COPYRIGHT}" /> <token key="COPYRIGHT" value="${COPYRIGHT}" />
</replacetokens> </replacetokens>
</filterchain> </filterchain>
</copy> </copy>
</target>
<target name="PropertyConstants.java" depends="version">
<copy file="java/lang/PropertyConstants.java.in" tofile="java/lang/PropertyConstants.java" outputencoding="ascii" overwrite="true"> <copy file="java/lang/PropertyConstants.java.in" tofile="java/lang/PropertyConstants.java" outputencoding="ascii" overwrite="true">
<filterchain> <filterchain>
<replacetokens> <replacetokens>
@ -122,14 +172,28 @@
</replacetokens> </replacetokens>
</filterchain> </filterchain>
</copy> </copy>
<exec program="javac" commandline="-J-Xmx1536M -implicit:none -g -nowarn -cp dummy -bootclasspath mscorlib.jar${pathsep}System.jar${pathsep}System.Core.jar${pathsep}System.Data.jar${pathsep}System.Drawing.jar${pathsep}../runtime/IKVM.Runtime.jar @allsources.gen.lst" useruntimeengine="false" /> </target>
<target name="classes" depends="clean-classes stubjars allsources.gen.lst AssemblyInfo.java PropertyConstants.java">
<exec program="javac" useruntimeengine="false">
<arg value="-J-Xmx1536M" />
<arg value="-g" />
<arg value="-nowarn" />
<arg value="-implicit:none" />
<arg value="-parameters" />
<arg line="-cp dummy" />
<arg value="-bootclasspath" />
<arg path="mscorlib.jar;System.jar;System.Core.jar;System.Data.jar;System.Drawing.jar;System.XML.jar;../runtime/IKVM.Runtime.jar" />
<arg value="@allsources.gen.lst" />
</exec>
</target> </target>
<target name="rmi"> <target name="rmi">
<property name="VMARGS" value="-J-client -J-Xmx896m -J-Xms128m -J-XX:PermSize=32m -J-XX:MaxPermSize=160m" /> <mkdir dir="rmistubs" />
<property name="CLASSPATH" value="${OpenJDK7.dir}/jdk/src/share/classes/${pathsep}${OpenJDK7.dir}/build/linux-amd64/impsrc/${pathsep}." /> <property name="VMARGS" value="-J-client -J-Xmx896m -J-Xms128m" />
<property name="OUTPUT" value="${OpenJDK7.dir}/build/linux-amd64/classes/" /> <property name="CLASSPATH" value="mscorlib.jar${pathsep}System.Xml.jar${pathsep}${OpenJDK.dir}/jdk/src/share/classes/${pathsep}${OpenJDK.dir}/corba/src/share/classes" />
<property name="ARGS" value="${VMARGS} -bootclasspath ${CLASSPATH} -d ${OUTPUT}" /> <property name="OUTPUT" value="rmistubs" />
<property name="ARGS" value="${VMARGS} -nowarn -bootclasspath ${CLASSPATH} -d ${OUTPUT}" />
<exec program="rmic" commandline="${ARGS} -v1.1 sun.rmi.registry.RegistryImpl" /> <exec program="rmic" commandline="${ARGS} -v1.1 sun.rmi.registry.RegistryImpl" />
<exec program="rmic" commandline="${ARGS} -v1.1 sun.rmi.transport.DGCImpl" /> <exec program="rmic" commandline="${ARGS} -v1.1 sun.rmi.transport.DGCImpl" />
<exec program="rmic" commandline="${ARGS} -v1.2 sun.rmi.server.Activation$ActivationSystemImpl" /> <exec program="rmic" commandline="${ARGS} -v1.2 sun.rmi.server.Activation$ActivationSystemImpl" />
@ -147,10 +211,30 @@
<exec program="rmic" commandline="${ARGS} -iiop -standardPackage javax.management.remote.rmi.RMIServer" /> <exec program="rmic" commandline="${ARGS} -iiop -standardPackage javax.management.remote.rmi.RMIServer" />
</target> </target>
<target name="run-nasgen">
<!-- nasgen doesn't understand the MethodParameters attribute, so we have to recompile the classes it processes without parameters -->
<exec program="javac" useruntimeengine="false">
<arg value="-XDignore.symbol.file" />
<arg value="-g" />
<arg value="-nowarn" />
<arg value="-implicit:none" />
<arg value="-cp" />
<arg path="mscorlib.jar;../runtime/IKVM.Runtime.jar" />
<arg value="${OpenJDK.dir}/nashorn/src/jdk/nashorn/internal/objects/*.java" />
</exec>
<exec program="java" useruntimeengine="false">
<arg line="-cp ${OpenJDK.dir}/nashorn/buildtools/nasgen/src" />
<arg value="jdk.nashorn.internal.tools.nasgen.Main" />
<arg value="${OpenJDK.dir}/nashorn/src" />
<arg value="jdk.nashorn.internal.objects" />
<arg value="${OpenJDK.dir}/nashorn/src" />
</exec>
</target>
<target name="vfs"> <target name="vfs">
<!-- This file is generated here, but it is added as a resource to IKVM.Runtime.dll, because Ref.Emit on .NET 1.1 doesn't support adding a raw resource. --> <!-- This file is generated here, but it is added as a resource to IKVM.Runtime.dll, because Ref.Emit on .NET 1.1 doesn't support adding a raw resource. -->
<zip zipfile="vfs.zip"> <zip zipfile="vfs.zip">
<fileset basedir="${OpenJDK7.dir}/build/linux-amd64/j2re-image"> <fileset basedir="${OpenJDK.dir}/build/linux-x86_64-normal-server-release/jdk">
<include name="lib/calendars.properties" /> <include name="lib/calendars.properties" />
<include name="lib/logging.properties" /> <include name="lib/logging.properties" />
<include name="lib/management/management.properties" /> <include name="lib/management/management.properties" />
@ -158,7 +242,7 @@
<include name="lib/psfontj2d.properties" /> <include name="lib/psfontj2d.properties" />
<include name="lib/sound.properties" /> <include name="lib/sound.properties" />
<include name="lib/cmm/*" /> <include name="lib/cmm/*" />
<include name="lib/zi/**/*" /> <include name="lib/tzdb.dat" />
<include name="lib/currency.data" /> <include name="lib/currency.data" />
<include name="lib/security/java.policy" /> <include name="lib/security/java.policy" />
<include name="lib/security/java.security" /> <include name="lib/security/java.security" />
@ -169,7 +253,7 @@
--> -->
<include name="lib/security/US_export_policy.jar" /> <include name="lib/security/US_export_policy.jar" />
</fileset> </fileset>
<fileset basedir="${OpenJDK7.dir}/jdk/src/windows"> <fileset basedir="${OpenJDK.dir}/jdk/src/windows">
<include name="lib/flavormap.properties" /> <include name="lib/flavormap.properties" />
<include name="lib/content-types.properties" /> <include name="lib/content-types.properties" />
</fileset> </fileset>
@ -177,13 +261,42 @@
</target> </target>
<target name="resources"> <target name="resources">
<!-- resources that are not in @OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar --> <!-- collect the resources in a zip to make it easier to include them in the right assemblies -->
<zip zipfile="resources.zip"> <zip zipfile="resources.zip">
<fileset basedir="${OpenJDK7.dir}/jdk/src/share/classes"> <fileset basedir="${OpenJDK.dir}/build/linux-x86_64-normal-server-release/jdk/classes">
<include name="com/sun/corba/se/impl/orbutil/resources/*.properties" />
<include name="com/sun/rowset/*.properties" />
<include name="javax/swing/text/html/parser/html32.bdtd" />
<include name="sun/rmi/registry/resources/*.properties" />
<include name="sun/rmi/server/resources/*.properties" />
<include name="sun/text/resources/*IteratorData" />
<include name="sun/text/resources/th/*IteratorData_th" />
<include name="sun/text/resources/th/thai_dict" />
</fileset>
<fileset basedir="${OpenJDK.dir}/corba/src/share/classes">
<include name="**/*.properties" />
</fileset>
<fileset basedir="${OpenJDK.dir}/jdk/src/share/classes">
<include name="**/*.properties" />
<include name="**/*.gif" />
<include name="**/*.png" />
<include name="**/*.wav" />
<include name="com/sun/org/apache/xml/internal/security/resource/config.*" />
<include name="com/sun/swing/internal/plaf/**/*" /> <include name="com/sun/swing/internal/plaf/**/*" />
<include name="com/sun/java/swing/plaf/**/*.properties" /> <include name="javax/swing/text/html/default.css" />
<include name="com/sun/java/swing/plaf/**/*.gif" /> <include name="javax/swing/text/rtf/charsets/*.txt" />
<include name="sun/launcher/resources/*.properties" /> <include name="sun/text/resources/**/*.icu" />
</fileset>
<fileset basedir="${OpenJDK.dir}/jaxp/src">
<include name="**/*.properties" />
<include name="**/*.res" />
</fileset>
<fileset basedir="${OpenJDK.dir}/jaxws/src/share/jaf_classes">
<include name="**/*.properties" />
</fileset>
<fileset basedir="${OpenJDK.dir}/jaxws/src/share/jaxws_classes">
<include name="**/*.properties" />
<include name="**/*.xml" />
</fileset> </fileset>
</zip> </zip>
</target> </target>
@ -192,13 +305,35 @@
<copy file="response.txt" tofile="response.gen.txt" outputencoding="ascii" overwrite="true"> <copy file="response.txt" tofile="response.gen.txt" outputencoding="ascii" overwrite="true">
<filterchain> <filterchain>
<replacetokens> <replacetokens>
<token key="OPENJDK7" value="${OpenJDK7.dir}" /> <token key="OPENJDK" value="${OpenJDK.dir}" />
</replacetokens> </replacetokens>
</filterchain> </filterchain>
</copy> </copy>
</target> </target>
<target name="core" depends="version response.gen.txt"> <target name="MANIFEST.MF">
<copy file="MANIFEST.MF.in" tofile="MANIFEST.MF" outputencoding="ascii" overwrite="true">
<filterchain>
<replacetokens>
<token key="IMPLEMENTATION_VERSION" value="${IMPLEMENTATION_VERSION}" />
<token key="SPECIFICATION_VERSION" value="${SPECIFICATION_VERSION}" />
</replacetokens>
</filterchain>
</copy>
</target>
<target name="nashorn-version">
<copy file="resources/nashorn/version.properties.in" tofile="resources/nashorn/version.properties" outputencoding="ascii" overwrite="true">
<filterchain>
<replacetokens>
<token key="FULL_VERSION" value="${FULL_VERSION}" />
<token key="IMPLEMENTATION_VERSION" value="${IMPLEMENTATION_VERSION}" />
</replacetokens>
</filterchain>
</copy>
</target>
<target name="core" depends="version response.gen.txt MANIFEST.MF nashorn-version">
<copy file="../bin/IKVM.Runtime.dll" todir="." /> <copy file="../bin/IKVM.Runtime.dll" todir="." />
<copy file="../bin/IKVM.AWT.WinForms.dll" todir="." /> <copy file="../bin/IKVM.AWT.WinForms.dll" todir="." />
<exec program="${project::get-base-directory()}/../bin/ikvmc.exe" useruntimeengine="true"> <exec program="${project::get-base-directory()}/../bin/ikvmc.exe" useruntimeengine="true">
@ -217,6 +352,8 @@
<arg value="-r:IKVM.Runtime.dll" /> <arg value="-r:IKVM.Runtime.dll" />
<!-- we already know that the JNI assembly is not available, so suppress the warning --> <!-- we already know that the JNI assembly is not available, so suppress the warning -->
<arg value="-nowarn:110" /> <arg value="-nowarn:110" />
<arg value="-w4" />
<arg value="-noparameterreflection" />
<arg value="-warnaserror" /> <arg value="-warnaserror" />
<arg value="@response.gen.txt" /> <arg value="@response.gen.txt" />
</exec> </exec>
@ -225,11 +362,14 @@
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Charsets.dll" /> <exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Charsets.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Corba.dll" /> <exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Corba.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Core.dll" /> <exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Core.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Cldrdata.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Jdbc.dll" /> <exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Jdbc.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Localedata.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Management.dll" /> <exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Management.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Media.dll" /> <exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Media.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Misc.dll" /> <exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Misc.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Naming.dll" /> <exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Naming.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Nashorn.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Remoting.dll" /> <exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Remoting.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Security.dll" /> <exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.Security.dll" />
<exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.SwingAWT.dll" /> <exec program="${peverify}" commandline="-nologo IKVM.OpenJDK.SwingAWT.dll" />
@ -268,7 +408,7 @@
<copy file="tools.rsp" tofile="tools.gen.rsp" outputencoding="ascii" overwrite="true"> <copy file="tools.rsp" tofile="tools.gen.rsp" outputencoding="ascii" overwrite="true">
<filterchain> <filterchain>
<replacetokens> <replacetokens>
<token key="OPENJDK7" value="${OpenJDK7.dir}" /> <token key="OPENJDK" value="${OpenJDK.dir}" />
</replacetokens> </replacetokens>
</filterchain> </filterchain>
</copy> </copy>
@ -280,6 +420,8 @@
<arg value="-version:${VERSION}" /> <arg value="-version:${VERSION}" />
<arg value="${signoption}" /> <arg value="${signoption}" />
<arg value="-warnaserror" /> <arg value="-warnaserror" />
<arg value="-w4" />
<arg value="-noparameterreflection" />
<arg value="@tools.gen.rsp" /> <arg value="@tools.gen.rsp" />
</exec> </exec>
</target> </target>
@ -300,9 +442,14 @@
<exec program="${project::get-base-directory()}/../bin/ikvmc.exe" useruntimeengine="true"> <exec program="${project::get-base-directory()}/../bin/ikvmc.exe" useruntimeengine="true">
<arg value="-version:${VERSION}" /> <arg value="-version:${VERSION}" />
<arg value="-out:../bin/javap.exe" /> <arg value="-out:../bin/javap.exe" />
<arg value="-main:sun.tools.javap.Main" /> <arg value="-main:com.sun.tools.javap.Main" />
<arg value="-r:../bin/IKVM.OpenJDK.Tools.dll" /> <arg value="-r:../bin/IKVM.OpenJDK.Tools.dll" />
</exec> </exec>
<exec program="${project::get-base-directory()}/../bin/ikvmc.exe" useruntimeengine="true">
<arg value="-version:${VERSION}" />
<arg value="-out:../bin/jjs.exe" />
<arg value="-main:jdk.nashorn.tools.Shell" />
</exec>
</target> </target>
</project> </project>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
0371c2e17040377153909ef9f19d553f527c5078

View File

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

View File

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

View File

@ -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 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() public long size()
{ {
return info.get_Length(); return info.get_Exists() ? info.get_Length() : 0;
} }
public boolean isArchive() 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.ArgumentException();
if (false) throw new cli.System.IO.FileNotFoundException(); if (false) throw new cli.System.IO.FileNotFoundException();
if (false) throw new cli.System.IO.IOException(); 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 _) 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)); 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 catch (cli.System.ArgumentException
| cli.System.IO.IOException x) | cli.System.IO.IOException x)
{ {

View File

@ -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<String, Class<?>> memberTypes;
/**
* Member name -> default value mapping.
*/
private final Map<String, Object> memberDefaults;
/**
* Member name -> Method object mapping. This (and its assoicated
* accessor) are used only to generate AnnotationTypeMismatchExceptions.
*/
private final Map<String, Method> 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<? extends Annotation> 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<? extends Annotation> annotationClass) {
if (!annotationClass.isAnnotation())
throw new IllegalArgumentException("Not an annotation type");
Method[] methods =
AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
public Method[] run() {
// Initialize memberTypes and defaultValues
return annotationClass.getDeclaredMethods();
}
});
memberTypes = new HashMap<String,Class<?>>(methods.length+1, 1.0f);
memberDefaults = new HashMap<String, Object>(0);
members = new HashMap<String, Method>(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<String, Class<?>> memberTypes() {
return memberTypes;
}
/**
* Returns members of this annotation type
* (member name -> associated Method object mapping).
*/
public Map<String, Method> members() {
return members;
}
/**
* Returns the default values for this annotation type
* (Member name -> default value mapping).
*/
public Map<String, Object> 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;
}
}

View File

@ -157,7 +157,7 @@ namespace IKVM.Reflection
throw new BadImageFormatException(); throw new BadImageFormatException();
} }
lazyConstructorArguments = ReadConstructorArguments(module, br, constructor); 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(); return list.AsReadOnly();
} }
private static IList<CustomAttributeNamedArgument> ReadNamedArguments(Module context, ByteReader br, int named, Type type) private static IList<CustomAttributeNamedArgument> ReadNamedArguments(Module context, ByteReader br, int named, Type type, bool required)
{ {
List<CustomAttributeNamedArgument> list = new List<CustomAttributeNamedArgument>(named); List<CustomAttributeNamedArgument> list = new List<CustomAttributeNamedArgument>(named);
for (int i = 0; i < named; i++) for (int i = 0; i < named; i++)
{ {
byte fieldOrProperty = br.ReadByte(); byte fieldOrProperty = br.ReadByte();
Type fieldOrPropertyType = ReadFieldOrPropType(context, br); Type fieldOrPropertyType = ReadFieldOrPropType(context, br);
if (fieldOrPropertyType.__IsMissing && !required)
{
return null;
}
string name = br.ReadString(); string name = br.ReadString();
CustomAttributeTypedArgument value = ReadFixedArg(context, br, fieldOrPropertyType); CustomAttributeTypedArgument value = ReadFixedArg(context, br, fieldOrPropertyType);
MemberInfo member; MemberInfo member;
@ -580,7 +584,7 @@ namespace IKVM.Reflection
{ {
if (lazyConstructorArguments == null) if (lazyConstructorArguments == null)
{ {
LazyParseArguments(); LazyParseArguments(false);
} }
return lazyConstructorArguments; return lazyConstructorArguments;
} }
@ -595,21 +599,21 @@ namespace IKVM.Reflection
if (customAttributeIndex >= 0) if (customAttributeIndex >= 0)
{ {
// 1) Unresolved Custom Attribute // 1) Unresolved Custom Attribute
LazyParseArguments(); LazyParseArguments(true);
} }
else else
{ {
// 5) Unresolved declarative security // 5) Unresolved declarative security
ByteReader br = new ByteReader(declSecurityBlob, 0, declSecurityBlob.Length); 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) // 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; return lazyNamedArguments;
} }
} }
private void LazyParseArguments() private void LazyParseArguments(bool requireNameArguments)
{ {
ByteReader br = module.GetBlob(module.CustomAttribute.records[customAttributeIndex].Value); ByteReader br = module.GetBlob(module.CustomAttribute.records[customAttributeIndex].Value);
if (br.Length == 0) if (br.Length == 0)
@ -625,7 +629,7 @@ namespace IKVM.Reflection
throw new BadImageFormatException(); throw new BadImageFormatException();
} }
lazyConstructorArguments = ReadConstructorArguments(module, br, Constructor); lazyConstructorArguments = ReadConstructorArguments(module, br, Constructor);
lazyNamedArguments = ReadNamedArguments(module, br, br.ReadUInt16(), Constructor.DeclaringType); lazyNamedArguments = ReadNamedArguments(module, br, br.ReadUInt16(), Constructor.DeclaringType, requireNameArguments);
} }
} }

View File

@ -373,9 +373,9 @@ namespace IKVM.Reflection.Emit
foreach (CustomAttributeBuilder cab in customAttributes) foreach (CustomAttributeBuilder cab in customAttributes)
{ {
// .NET doesn't support copying blob custom attributes into the version info // .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); ByteBuffer versionInfoData = new ByteBuffer(512);

View File

@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion> <ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{4CB170EF-DFE6-4A56-9E1B-A85449E827A7}</ProjectGuid> <ProjectGuid>{4CB170EF-DFE6-4A56-9E1B-A85449E827A7}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
@ -22,6 +22,8 @@
</SccAuxPath> </SccAuxPath>
<SccProvider> <SccProvider>
</SccProvider> </SccProvider>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\ikvm-fork.snk</AssemblyOriginatorKeyFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>

View File

@ -2040,6 +2040,7 @@ namespace IKVM.Reflection
{ {
if (this.Assembly == this.Universe.Mscorlib if (this.Assembly == this.Universe.Mscorlib
|| this.Assembly.GetName().Name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase) || 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) // 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) || this.Universe.Mscorlib.FindType(new TypeName(__Namespace, __Name)) == this)
{ {

View File

@ -128,6 +128,7 @@ namespace IKVM.Reflection
MetadataOnly = 16, MetadataOnly = 16,
ResolveMissingMembers = 32, ResolveMissingMembers = 32,
DisableWindowsRuntimeProjection = 64, DisableWindowsRuntimeProjection = 64,
DecodeVersionInfoAttributeBlobs = 128,
} }
public sealed class Universe : IDisposable public sealed class Universe : IDisposable
@ -1216,5 +1217,10 @@ namespace IKVM.Reflection
{ {
get { return (options & UniverseOptions.DisableWindowsRuntimeProjection) == 0; } get { return (options & UniverseOptions.DisableWindowsRuntimeProjection) == 0; }
} }
internal bool DecodeVersionInfoAttributeBlobs
{
get { return (options & UniverseOptions.DecodeVersionInfoAttributeBlobs) != 0; }
}
} }
} }

View File

@ -50,41 +50,41 @@ namespace IKVM.Reflection.Writer
this.fileName = System.IO.Path.GetFileName(assemblyFileName); 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; Universe u = cab.Constructor.Module.universe;
Type type = cab.Constructor.DeclaringType; Type type = cab.Constructor.DeclaringType;
if (copyright == null && type == u.System_Reflection_AssemblyCopyrightAttribute) 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) 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) 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) 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) 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) 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) 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) else if (fileVersion == null && type == u.System_Reflection_AssemblyFileVersionAttribute)
{ {
fileVersion = (string)cab.GetConstructorArgument(0); fileVersion = (string)cab.DecodeBlob(asm).GetConstructorArgument(0);
} }
} }

View File

@ -746,8 +746,16 @@ namespace IKVM.Internal
using (java.io.InputStream inp = url.openStream()) using (java.io.InputStream inp = url.openStream())
{ {
byte[] buf = new byte[inp.available()]; byte[] buf = new byte[inp.available()];
inp.read(buf, 0, buf.Length); for (int pos = 0; pos < buf.Length; )
return TypeWrapper.FromClass(IKVM.NativeCode.java.lang.ClassLoader.defineClass1(GetJavaClassLoader(), name, buf, 0, buf.Length, GetProtectionDomain(), null)); {
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 #endif
@ -860,7 +868,7 @@ namespace IKVM.Internal
if (!found && unmangledName.EndsWith(".class", StringComparison.Ordinal) && unmangledName.IndexOf('.') == unmangledName.Length - 6) if (!found && unmangledName.EndsWith(".class", StringComparison.Ordinal) && unmangledName.IndexOf('.') == unmangledName.Length - 6)
{ {
TypeWrapper tw = FindLoadedClass(unmangledName.Substring(0, unmangledName.Length - 6).Replace('/', '.')); 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 #if !FIRST_PASS
yield return new java.io.File(VirtualFileSystem.GetAssemblyClassesPath(assemblyLoader.Assembly) + unmangledName).toURI().toURL(); yield return new java.io.File(VirtualFileSystem.GetAssemblyClassesPath(assemblyLoader.Assembly) + unmangledName).toURI().toURL();
@ -1103,28 +1111,23 @@ namespace IKVM.Internal
LazyInitExports(); LazyInitExports();
lock (this) lock (this)
{ {
Array.Resize(ref delegates, delegates.Length + 1); delegates = ArrayUtil.Concat(delegates, acl);
delegates[delegates.Length - 1] = acl;
} }
} }
#if !STATIC_COMPILER && !STUB_GENERATOR #if !STATIC_COMPILER && !STUB_GENERATOR
internal string[] GetPackages() internal List<KeyValuePair<string, string[]>> GetPackageInfo()
{ {
string[] packages = new string[0]; List<KeyValuePair<string, string[]>> list = new List<KeyValuePair<string, string[]>>();
foreach (Module m in assemblyLoader.Assembly.GetModules(false)) foreach (Module m in assemblyLoader.Assembly.GetModules(false))
{ {
object[] attr = m.GetCustomAttributes(typeof(PackageListAttribute), false); object[] attr = m.GetCustomAttributes(typeof(PackageListAttribute), false);
foreach (PackageListAttribute p in attr) foreach (PackageListAttribute p in attr)
{ {
string[] mp = p.GetPackages(); list.Add(new KeyValuePair<string, string[]>(p.jar, p.packages));
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;
} }
} }
return packages; return list;
} }
#endif #endif
@ -1313,6 +1316,10 @@ namespace IKVM.Internal
return base.GetWrapperFromAssemblyType(type); return base.GetWrapperFromAssemblyType(type);
} }
protected override void CheckProhibitedPackage(string className)
{
}
#if !FIRST_PASS && !STATIC_COMPILER && !STUB_GENERATOR #if !FIRST_PASS && !STATIC_COMPILER && !STUB_GENERATOR
internal override java.lang.ClassLoader GetJavaClassLoader() internal override java.lang.ClassLoader GetJavaClassLoader()
{ {

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -164,7 +164,7 @@ sealed class BigEndianBinaryReader
case 0: case 0:
if(c == 0) if(c == 0)
{ {
throw new ClassFormatError("{0} (Illegal UTF8 string in constant pool)", classFile); goto default;
} }
break; break;
case 1: case 2: case 3: case 4: case 5: case 6: case 7: 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]; char2 = buf[pos + ++i];
if((char2 & 0xc0) != 0x80 || i >= len) 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)); c = (((c & 0x1F) << 6) | (char2 & 0x3F));
if(c < 0x80 && c != 0)
{
goto default;
}
break; break;
case 14: case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx // 1110 xxxx 10xx xxxx 10xx xxxx
@ -185,12 +189,16 @@ sealed class BigEndianBinaryReader
char3 = buf[pos + ++i]; char3 = buf[pos + ++i];
if((char2 & 0xc0) != 0x80 || (char3 & 0xc0) != 0x80 || i >= len) 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)); c = (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
if(c < 0x800)
{
goto default;
}
break; break;
default: 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; ch[l++] = (char)c;
} }
@ -224,4 +232,11 @@ sealed class BigEndianBinaryReader
pos += 4; pos += 4;
return i; return i;
} }
internal byte[] ToArray()
{
byte[] res = new byte[end - pos];
Buffer.BlockCopy(buf, pos, res, 0, res.Length);
return res;
}
} }

212
external/ikvm/runtime/Boxer.cs vendored Normal file
View File

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

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -39,8 +39,6 @@ namespace IKVM.Internal
NoSuchMethodError, NoSuchMethodError,
LinkageError, LinkageError,
// "exceptions" that are wrapped in an IncompatibleClassChangeError // "exceptions" that are wrapped in an IncompatibleClassChangeError
NoSuchFieldException,
NoSuchMethodException,
IllegalAccessException, IllegalAccessException,
// if an error is added here, it must also be added to MethodAnalyzer.SetHardError() // if an error is added here, it must also be added to MethodAnalyzer.SetHardError()
} }
@ -52,6 +50,7 @@ namespace IKVM.Internal
LocalVariableTable = 1, LocalVariableTable = 1,
LineNumberTable = 2, LineNumberTable = 2,
RelaxedClassNameValidation = 4, RelaxedClassNameValidation = 4,
TrustedAnnotations = 8,
} }
sealed class ClassFile sealed class ClassFile
@ -66,6 +65,9 @@ namespace IKVM.Internal
private const ushort FLAG_MASK_DEPRECATED = 0x100; private const ushort FLAG_MASK_DEPRECATED = 0x100;
private const ushort FLAG_MASK_INTERNAL = 0x200; private const ushort FLAG_MASK_INTERNAL = 0x200;
private const ushort FLAG_CALLERSENSITIVE = 0x400; 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 ConstantPoolItemClass[] interfaces;
private Field[] fields; private Field[] fields;
private Method[] methods; private Method[] methods;
@ -79,11 +81,12 @@ namespace IKVM.Internal
private string signature; private string signature;
private string[] enclosingMethod; private string[] enclosingMethod;
private BootstrapMethod[] bootstrapMethods; private BootstrapMethod[] bootstrapMethods;
private byte[] runtimeVisibleTypeAnnotations;
private static class SupportedVersions private static class SupportedVersions
{ {
internal static readonly int Minimum = 45; 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 #if STATIC_COMPILER
@ -160,7 +163,7 @@ namespace IKVM.Internal
} }
#endif // STATIC_COMPILER #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 try
{ {
@ -242,6 +245,10 @@ namespace IKVM.Internal
throw new ClassFormatError("{0} (Illegal constant pool type 0x{1:X})", inputClassName, tag); 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++) for(int i = 1; i < constantpoolcount; i++)
{ {
if(constantpool[i] != null) if(constantpool[i] != null)
@ -283,7 +290,7 @@ namespace IKVM.Internal
ValidateConstantPoolItemClass(inputClassName, this_class); ValidateConstantPoolItemClass(inputClassName, this_class);
super_class = br.ReadUInt16(); super_class = br.ReadUInt16();
ValidateConstantPoolItemClass(inputClassName, super_class); 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); throw new ClassFormatError("{0} (Interfaces must have java.lang.Object as superclass)", Name);
} }
@ -479,6 +486,14 @@ namespace IKVM.Internal
} }
bootstrapMethods = ReadBootstrapMethods(br, this); bootstrapMethods = ReadBootstrapMethods(br, this);
break; break;
case "RuntimeVisibleTypeAnnotations":
if(majorVersion < 52)
{
goto default;
}
CreateUtf8ConstantPoolItems(utf8_cp);
runtimeVisibleTypeAnnotations = br.Section(br.ReadUInt32()).ToArray();
break;
case "IKVM.NET.Assembly": case "IKVM.NET.Assembly":
if(br.ReadUInt32() != 2) 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>(T[] members, string msg) private void CheckDuplicates<T>(T[] members, string msg)
where T : IEquatable<T> where T : IEquatable<T>
{ {
@ -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) private void MarkLinkRequiredConstantPoolItem(int index)
{ {
if (index > 0 && index < constantpool.Length && constantpool[index] != null) if (index > 0 && index < constantpool.Length && constantpool[index] != null)
@ -730,7 +816,7 @@ namespace IKVM.Internal
} }
for(int i = 0; i < name.Length; i++) for(int i = 0; i < name.Length; i++)
{ {
if(".;/<>".IndexOf(name[i]) != -1) if(".;[/<>".IndexOf(name[i]) != -1)
{ {
return false; return false;
} }
@ -746,7 +832,7 @@ namespace IKVM.Internal
} }
for(int i = 0; i < name.Length; i++) for(int i = 0; i < name.Length; i++)
{ {
if(".;/".IndexOf(name[i]) != -1) if(".;[/".IndexOf(name[i]) != -1)
{ {
return false; return false;
} }
@ -875,6 +961,8 @@ namespace IKVM.Internal
internal void Link(TypeWrapper thisType) 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++) for(int i = 1; i < constantpool.Length; i++)
{ {
if(constantpool[i] != null) if(constantpool[i] != null)
@ -1102,6 +1190,11 @@ namespace IKVM.Internal
return (ConstantPoolItemMethodType)constantpool[index]; return (ConstantPoolItemMethodType)constantpool[index];
} }
internal object GetConstantPoolConstantLiveObject(int index)
{
return ((ConstantPoolItemLiveObject)constantpool[index]).Value;
}
internal string Name internal string Name
{ {
get get
@ -1110,11 +1203,11 @@ namespace IKVM.Internal
} }
} }
internal string SuperClass internal ConstantPoolItemClass SuperClass
{ {
get 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 internal string IKVMAssemblyAttribute
{ {
get get
@ -1301,6 +1415,7 @@ namespace IKVM.Internal
Class, Class,
MethodHandle, MethodHandle,
MethodType, MethodType,
LiveObject, // used by anonymous class constant pool patching
} }
internal abstract class ConstantPoolItem internal abstract class ConstantPoolItem
@ -1321,6 +1436,13 @@ namespace IKVM.Internal
internal virtual void MarkLinkRequired() 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<ConstantPoolItemClass> internal sealed class ConstantPoolItemClass : ConstantPoolItem, IEquatable<ConstantPoolItemClass>
@ -1328,15 +1450,26 @@ namespace IKVM.Internal
private ushort name_index; private ushort name_index;
private string name; private string name;
private TypeWrapper typeWrapper; private TypeWrapper typeWrapper;
private static char[] invalidJava15Characters = { '.', ';' }; private static char[] invalidJava15Characters = { '.', ';', '[', ']' };
internal ConstantPoolItemClass(BigEndianBinaryReader br) internal ConstantPoolItemClass(BigEndianBinaryReader br)
{ {
name_index = br.ReadUInt16(); 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) 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); name = classFile.GetConstantPoolUtf8String(utf8_cp, name_index);
if(name.Length > 0) if(name.Length > 0)
{ {
@ -1383,6 +1516,7 @@ namespace IKVM.Internal
#endif #endif
{ {
// since 1.5 the restrictions on class names have been greatly reduced // since 1.5 the restrictions on class names have been greatly reduced
int start = 0;
int end = name.Length; int end = name.Length;
if(name[0] == '[') if(name[0] == '[')
{ {
@ -1398,8 +1532,12 @@ namespace IKVM.Internal
{ {
end--; end--;
} }
while(name[start] == '[')
{
start++;
}
} }
if(name.IndexOfAny(invalidJava15Characters, 0, end) >= 0) if(name.IndexOfAny(invalidJava15Characters, start, end - start) >= 0)
{ {
goto barf; goto barf;
} }
@ -1413,7 +1551,15 @@ namespace IKVM.Internal
internal override void MarkLinkRequired() 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) internal override void Link(TypeWrapper thisType)
@ -1469,7 +1615,7 @@ namespace IKVM.Internal
private sealed class ConstantPoolItemDouble : ConstantPoolItem private sealed class ConstantPoolItemDouble : ConstantPoolItem
{ {
private double d; internal double d;
internal ConstantPoolItemDouble(BigEndianBinaryReader br) internal ConstantPoolItemDouble(BigEndianBinaryReader br)
{ {
@ -1488,6 +1634,11 @@ namespace IKVM.Internal
return d; return d;
} }
} }
internal override object GetRuntimeValue()
{
return d;
}
} }
internal abstract class ConstantPoolItemFMI : ConstantPoolItem internal abstract class ConstantPoolItemFMI : ConstantPoolItem
@ -1799,7 +1950,7 @@ namespace IKVM.Internal
private sealed class ConstantPoolItemFloat : ConstantPoolItem private sealed class ConstantPoolItemFloat : ConstantPoolItem
{ {
private float v; internal float v;
internal ConstantPoolItemFloat(BigEndianBinaryReader br) internal ConstantPoolItemFloat(BigEndianBinaryReader br)
{ {
@ -1818,11 +1969,16 @@ namespace IKVM.Internal
return v; return v;
} }
} }
internal override object GetRuntimeValue()
{
return v;
}
} }
private sealed class ConstantPoolItemInteger : ConstantPoolItem private sealed class ConstantPoolItemInteger : ConstantPoolItem
{ {
private int v; internal int v;
internal ConstantPoolItemInteger(BigEndianBinaryReader br) internal ConstantPoolItemInteger(BigEndianBinaryReader br)
{ {
@ -1841,11 +1997,16 @@ namespace IKVM.Internal
return v; return v;
} }
} }
internal override object GetRuntimeValue()
{
return v;
}
} }
private sealed class ConstantPoolItemLong : ConstantPoolItem private sealed class ConstantPoolItemLong : ConstantPoolItem
{ {
private long l; internal long l;
internal ConstantPoolItemLong(BigEndianBinaryReader br) internal ConstantPoolItemLong(BigEndianBinaryReader br)
{ {
@ -1864,6 +2025,11 @@ namespace IKVM.Internal
return l; return l;
} }
} }
internal override object GetRuntimeValue()
{
return l;
}
} }
private sealed class ConstantPoolItemNameAndType : ConstantPoolItem private sealed class ConstantPoolItemNameAndType : ConstantPoolItem
@ -1914,7 +2080,7 @@ namespace IKVM.Internal
case RefKind.invokeStatic: case RefKind.invokeStatic:
case RefKind.newInvokeSpecial: case RefKind.newInvokeSpecial:
cpi = classFile.GetConstantPoolItem(method_index) as ConstantPoolItemMethodref; 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; goto case RefKind.invokeInterface;
break; break;
case RefKind.invokeInterface: 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 internal enum Constant
{ {
Utf8 = 1, Utf8 = 1,
@ -2173,6 +2371,7 @@ namespace IKVM.Internal
private string descriptor; private string descriptor;
protected string signature; protected string signature;
protected object[] annotations; protected object[] annotations;
protected byte[] runtimeVisibleTypeAnnotations;
internal FieldOrMethod(ClassFile classFile, string[] utf8_cp, BigEndianBinaryReader br) 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() public sealed override int GetHashCode()
{ {
return name.GetHashCode() ^ descriptor.GetHashCode(); return name.GetHashCode() ^ descriptor.GetHashCode();
@ -2463,6 +2670,14 @@ namespace IKVM.Internal
#endif #endif
} }
break; break;
case "RuntimeVisibleTypeAnnotations":
if (classFile.MajorVersion < 52)
{
goto default;
}
classFile.CreateUtf8ConstantPoolItems(utf8_cp);
runtimeVisibleTypeAnnotations = br.Section(br.ReadUInt32()).ToArray();
break;
default: default:
br.Skip(br.ReadUInt32()); br.Skip(br.ReadUInt32());
break; break;
@ -2568,6 +2783,7 @@ namespace IKVM.Internal
#if STATIC_COMPILER #if STATIC_COMPILER
internal string DllExportName; internal string DllExportName;
internal int DllExportOrdinal; internal int DllExportOrdinal;
internal string InterlockedCompareAndSetField;
#endif #endif
} }
@ -2655,15 +2871,29 @@ namespace IKVM.Internal
goto default; goto default;
} }
annotations = ReadAnnotations(br, classFile, utf8_cp); annotations = ReadAnnotations(br, classFile, utf8_cp);
#if STATIC_COMPILER if ((options & ClassFileParseOptions.TrustedAnnotations) != 0)
foreach(object[] annot in annotations)
{ {
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; break;
case "RuntimeVisibleParameterAnnotations": 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; break;
#endif #endif
@ -2776,20 +3025,17 @@ namespace IKVM.Internal
{ {
throw new ClassFormatError("{0} (Duplicate MethodParameters attribute)", classFile.Name); throw new ClassFormatError("{0} (Duplicate MethodParameters attribute)", classFile.Name);
} }
BigEndianBinaryReader rdr = br.Section(br.ReadUInt32()); parameters = ReadMethodParameters(br, utf8_cp);
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);
}
break; break;
} }
case "RuntimeVisibleTypeAnnotations":
if (classFile.MajorVersion < 52)
{
goto default;
}
classFile.CreateUtf8ConstantPoolItems(utf8_cp);
runtimeVisibleTypeAnnotations = br.Section(br.ReadUInt32()).ToArray();
break;
default: default:
br.Skip(br.ReadUInt32()); br.Skip(br.ReadUInt32());
break; break;
@ -2799,7 +3045,7 @@ namespace IKVM.Internal
{ {
if(!code.IsEmpty) 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 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) protected override void ValidateSig(ClassFile classFile, string descriptor)
{ {
if(!IsValidMethodSig(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 <clinit>()V method? // Is this the <clinit>()V method?
internal bool IsClassInitializer internal bool IsClassInitializer
{ {
@ -2859,6 +3140,30 @@ namespace IKVM.Internal
} }
#endif #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 internal string[] ExceptionsAttribute
{ {
get get
@ -2899,6 +3204,14 @@ namespace IKVM.Internal
return low == null ? -1 : low.DllExportOrdinal; return low == null ? -1 : low.DllExportOrdinal;
} }
} }
internal string InterlockedCompareAndSetField
{
get
{
return low == null ? null : low.InterlockedCompareAndSetField;
}
}
#endif #endif
internal string VerifyError internal string VerifyError
@ -2982,6 +3295,14 @@ namespace IKVM.Internal
} }
} }
internal bool MalformedMethodParameters
{
get
{
return parameters == MethodParametersEntry.Malformed;
}
}
internal bool HasJsr internal bool HasJsr
{ {
get get
@ -3007,9 +3328,9 @@ namespace IKVM.Internal
max_stack = br.ReadUInt16(); max_stack = br.ReadUInt16();
max_locals = br.ReadUInt16(); max_locals = br.ReadUInt16();
uint code_length = br.ReadUInt32(); 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]; Instruction[] instructions = new Instruction[code_length + 1];
int basePosition = br.Position; int basePosition = br.Position;
@ -3563,12 +3884,6 @@ namespace IKVM.Internal
internal string descriptor; internal string descriptor;
internal ushort index; internal ushort index;
} }
internal struct MethodParametersEntry
{
internal string name;
internal ushort flags;
}
} }
internal Field GetField(string name, string sig) internal Field GetField(string name, string sig)

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -52,16 +52,18 @@ namespace IKVM.Internal
RemoveAsserts = 16, RemoveAsserts = 16,
NoAutomagicSerialization = 32, NoAutomagicSerialization = 32,
DisableDynamicBinding = 64, DisableDynamicBinding = 64,
NoRefEmitHelpers = 128,
} }
#if !STUB_GENERATOR #if !STUB_GENERATOR
abstract class TypeWrapperFactory abstract class TypeWrapperFactory
{ {
internal abstract ModuleBuilder ModuleBuilder { get; } internal abstract ModuleBuilder ModuleBuilder { get; }
internal abstract TypeWrapper DefineClassImpl(Dictionary<string, TypeWrapper> types, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain protectionDomain); internal abstract TypeWrapper DefineClassImpl(Dictionary<string, TypeWrapper> types, TypeWrapper host, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain protectionDomain);
internal abstract bool ReserveName(string name); internal abstract bool ReserveName(string name);
internal abstract string AllocMangledName(DynamicTypeWrapper tw); internal abstract string AllocMangledName(DynamicTypeWrapper tw);
internal abstract Type DefineUnloadable(string name); internal abstract Type DefineUnloadable(string name);
internal abstract Type DefineDelegate(int parameterCount, bool returnVoid);
internal abstract bool HasInternalAccess { get; } internal abstract bool HasInternalAccess { get; }
#if CLASSGC #if CLASSGC
internal abstract void AddInternalsVisibleTo(Assembly friend); 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 #if !STATIC_COMPILER && !STUB_GENERATOR
internal bool RelaxedClassNameValidation internal bool RelaxedClassNameValidation
{ {
@ -307,6 +353,14 @@ namespace IKVM.Internal
} }
#endif // !STATIC_COMPILER && !STUB_GENERATOR #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 #if !STUB_GENERATOR
internal TypeWrapper DefineClass(ClassFile f, ProtectionDomain protectionDomain) internal TypeWrapper DefineClass(ClassFile f, ProtectionDomain protectionDomain)
{ {
@ -334,6 +388,7 @@ namespace IKVM.Internal
return RegisterInitiatingLoader(tw); return RegisterInitiatingLoader(tw);
} }
#endif #endif
CheckProhibitedPackage(f.Name);
// check if the class already exists if we're an AssemblyClassLoader // check if the class already exists if we're an AssemblyClassLoader
if(FindLoadedClassLazy(f.Name) != null) if(FindLoadedClassLazy(f.Name) != null)
{ {
@ -365,7 +420,7 @@ namespace IKVM.Internal
} }
try try
{ {
return GetTypeWrapperFactory().DefineClassImpl(types, f, this, protectionDomain); return GetTypeWrapperFactory().DefineClassImpl(types, null, f, this, protectionDomain);
} }
finally finally
{ {
@ -775,15 +830,6 @@ namespace IKVM.Internal
} }
#endif #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 // NOTE this exposes potentially unfinished types
internal Type[] ArgTypeListFromSig(string sig) internal Type[] ArgTypeListFromSig(string sig)
{ {
@ -802,7 +848,7 @@ namespace IKVM.Internal
private TypeWrapper SigDecoderLoadClass(string name, bool nothrow) 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) // 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; Assembly asm = type.Assembly;
#if CLASSGC #if CLASSGC
ClassLoaderWrapper loader; ClassLoaderWrapper loader = null;
if(dynamicAssemblies != null && dynamicAssemblies.TryGetValue(asm, out loader)) if(dynamicAssemblies != null && dynamicAssemblies.TryGetValue(asm, out loader))
{ {
lock(loader.typeToTypeWrapper) 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 #endif
#if !STATIC_COMPILER && !STUB_GENERATOR #if !STATIC_COMPILER && !STUB_GENERATOR
if(AnonymousTypeWrapper.IsAnonymous(type))
{
Dictionary<Type, TypeWrapper> 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)) if(ReflectUtil.IsReflectionOnly(type))
{ {
// historically we've always returned null for types that don't have a corresponding TypeWrapper (or java.lang.Class) // 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 #endif
internal static TypeWrapper LoadClassNoThrow(ClassLoaderWrapper classLoader, string name) internal static TypeWrapper LoadClassNoThrow(ClassLoaderWrapper classLoader, string name, bool issueWarning)
{ {
try try
{ {
@ -1355,7 +1425,10 @@ namespace IKVM.Internal
elementTypeName = elementTypeName.Substring(skip, elementTypeName.Length - skip - 1); elementTypeName = elementTypeName.Substring(skip, elementTypeName.Length - skip - 1);
} }
#if STATIC_COMPILER #if STATIC_COMPILER
classLoader.IssueMessage(Message.ClassNotFound, elementTypeName); if (issueWarning || classLoader.WarningLevelHigh)
{
classLoader.IssueMessage(Message.ClassNotFound, elementTypeName);
}
#else #else
Tracer.Error(Tracer.ClassLoading, "Class not found: {0}", elementTypeName); Tracer.Error(Tracer.ClassLoading, "Class not found: {0}", elementTypeName);
#endif #endif
@ -1413,6 +1486,54 @@ namespace IKVM.Internal
} }
#endif #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 sealed class GenericClassLoaderWrapper : ClassLoaderWrapper
@ -1495,7 +1616,7 @@ namespace IKVM.Internal
if (name.EndsWith(".class", StringComparison.Ordinal) && name.IndexOf('.') == name.Length - 6) if (name.EndsWith(".class", StringComparison.Ordinal) && name.IndexOf('.') == name.Length - 6)
{ {
TypeWrapper tw = FindLoadedClass(name.Substring(0, name.Length - 6).Replace('/', '.')); 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(); ClassLoaderWrapper loader = tw.GetClassLoader();
if (loader is GenericClassLoaderWrapper) if (loader is GenericClassLoaderWrapper)
@ -1521,7 +1642,7 @@ namespace IKVM.Internal
if (name.EndsWith(".class", StringComparison.Ordinal) && name.IndexOf('.') == name.Length - 6) if (name.EndsWith(".class", StringComparison.Ordinal) && name.IndexOf('.') == name.Length - 6)
{ {
TypeWrapper tw = FindLoadedClass(name.Substring(0, name.Length - 6).Replace('/', '.')); 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); return new java.net.URL("ikvmres", "gen", ClassLoaderWrapper.GetGenericClassLoaderId(this), "/" + name);
} }

View File

@ -272,7 +272,7 @@ namespace IKVM.Internal
{ {
return false; return false;
} }
if (type.Assembly == IKVM.NativeCode.java.lang.SecurityManager.jniAssembly) if (type.Assembly == Java_java_lang_SecurityManager.jniAssembly)
{ {
return false; return false;
} }
@ -359,7 +359,7 @@ namespace IKVM.Internal
this.baseWrapper = baseWrapper; this.baseWrapper = baseWrapper;
} }
internal override TypeWrapper BaseTypeWrapper internal sealed override TypeWrapper BaseTypeWrapper
{ {
get { return baseWrapper; } get { return baseWrapper; }
} }
@ -368,6 +368,11 @@ namespace IKVM.Internal
{ {
get { return true; } get { return true; }
} }
internal sealed override Modifiers ReflectiveModifiers
{
get { return Modifiers | Modifiers.Static; }
}
} }
private sealed class DelegateInnerClassTypeWrapper : FakeTypeWrapper private sealed class DelegateInnerClassTypeWrapper : FakeTypeWrapper
@ -450,16 +455,21 @@ namespace IKVM.Internal
{ {
get { return true; } 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) 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) : base(declaringType, name, sig, null, returnType, parameterTypes, Modifiers.Public | Modifiers.Abstract, flags)
{ {
} }
internal override bool IsDynamicOnly internal sealed override bool IsDynamicOnly
{ {
get get
{ {
@ -468,7 +478,8 @@ namespace IKVM.Internal
} }
#if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR #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, // 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 // 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); throw new java.lang.IllegalAccessError(tw.Name + "." + this.Name + this.Signature);
} }
if (mw.HasCallerID) mw.Link();
{ mw.ResolveMethod();
// an interface method cannot require a CallerID return mw.Invoke(obj, args);
throw new InvalidOperationException();
}
java.lang.reflect.Method m = (java.lang.reflect.Method)mw.ToMethodOrConstructor(true);
m.@override = true;
return m.invoke(obj, args, null);
} }
#endif // !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR #endif // !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR
} }
@ -508,10 +514,10 @@ namespace IKVM.Internal
#endif #endif
} }
#if !STATIC_COMPILER && !STUB_GENERATOR #if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS
internal object GetUnspecifiedValue() internal object GetUnspecifiedValue()
{ {
return ((EnumFieldWrapper)GetFieldWrapper("__unspecified", this.SigName)).GetValue(); return GetFieldWrapper("__unspecified", this.SigName).GetValue(null);
} }
#endif #endif
@ -530,8 +536,8 @@ namespace IKVM.Internal
#endif #endif
} }
#if !STATIC_COMPILER && !STUB_GENERATOR #if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS
internal object GetValue() internal override object GetValue(object obj)
{ {
if (val == null) if (val == null)
{ {
@ -539,9 +545,13 @@ namespace IKVM.Internal
} }
return val; return val;
} }
internal override void SetValue(object obj, object value)
{
}
#endif #endif
#if !STUB_GENERATOR #if EMITTERS
protected override void EmitGetImpl(CodeEmitter ilgen) protected override void EmitGetImpl(CodeEmitter ilgen)
{ {
#if STATIC_COMPILER #if STATIC_COMPILER
@ -556,10 +566,10 @@ namespace IKVM.Internal
protected override void EmitSetImpl(CodeEmitter ilgen) 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) internal EnumValuesMethodWrapper(TypeWrapper declaringType)
: base(declaringType, "values", "()[" + declaringType.SigName, null, declaringType.MakeArrayType(1), TypeWrapper.EmptyArray, Modifiers.Public | Modifiers.Static, MemberFlags.None) : 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 #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(); FieldWrapper[] values = this.DeclaringType.GetFields();
object[] array = (object[])Array.CreateInstance(this.DeclaringType.TypeAsArrayType, values.Length); object[] array = (object[])Array.CreateInstance(this.DeclaringType.TypeAsArrayType, values.Length);
for (int i = 0; i < values.Length; i++) for (int i = 0; i < values.Length; i++)
{ {
array[i] = ((EnumFieldWrapper)values[i]).GetValue(); array[i] = values[i].GetValue(null);
} }
return array; return array;
} }
#endif // !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR #endif // !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR
} }
private sealed class EnumValueOfMethodWrapper : MethodWrapper, ICustomInvoke private sealed class EnumValueOfMethodWrapper : MethodWrapper
{ {
internal EnumValueOfMethodWrapper(TypeWrapper declaringType) 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) : 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 #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(); FieldWrapper[] values = this.DeclaringType.GetFields();
for (int i = 0; i < values.Length; i++) for (int i = 0; i < values.Length; i++)
{ {
if (values[i].Name.Equals(args[0])) if (values[i].Name.Equals(args[0]))
{ {
return ((EnumFieldWrapper)values[i]).GetValue(); return values[i].GetValue(null);
} }
} }
throw new java.lang.IllegalArgumentException("" + args[0]); throw new java.lang.IllegalArgumentException("" + args[0]);
@ -1800,7 +1810,7 @@ namespace IKVM.Internal
this.iface = iface; this.iface = iface;
} }
#if !STUB_GENERATOR #if EMITTERS
internal override bool EmitIntrinsic(EmitIntrinsicContext context) internal override bool EmitIntrinsic(EmitIntrinsicContext context)
{ {
TypeWrapper targetType = context.GetStackTypeWrapper(0, 0); TypeWrapper targetType = context.GetStackTypeWrapper(0, 0);
@ -1851,7 +1861,7 @@ namespace IKVM.Internal
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicCreateDelegate); ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicCreateDelegate);
ilgen.Emit(OpCodes.Castclass, delegateConstructor.DeclaringType); ilgen.Emit(OpCodes.Castclass, delegateConstructor.DeclaringType);
} }
#endif // !STUB_GENERATOR #endif // EMITTERS
} }
private sealed class ByRefMethodWrapper : SmartMethodWrapper private sealed class ByRefMethodWrapper : SmartMethodWrapper
@ -1870,7 +1880,7 @@ namespace IKVM.Internal
#endif #endif
} }
#if !STUB_GENERATOR #if EMITTERS
protected override void CallImpl(CodeEmitter ilgen) protected override void CallImpl(CodeEmitter ilgen)
{ {
ConvertByRefArgs(ilgen); ConvertByRefArgs(ilgen);
@ -1912,7 +1922,7 @@ namespace IKVM.Internal
} }
} }
} }
#endif // !STUB_GENERATOR #endif // EMITTERS
} }
private sealed class EnumWrapMethodWrapper : MethodWrapper private sealed class EnumWrapMethodWrapper : MethodWrapper
@ -1922,14 +1932,21 @@ namespace IKVM.Internal
{ {
} }
#if !STUB_GENERATOR #if EMITTERS
internal override void EmitCall(CodeEmitter ilgen) internal override void EmitCall(CodeEmitter ilgen)
{ {
// We don't actually need to do anything here! // We don't actually need to do anything here!
// The compiler will insert a boxing operation after calling us and that will // 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). // 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 internal sealed class EnumValueFieldWrapper : FieldWrapper
@ -1942,7 +1959,7 @@ namespace IKVM.Internal
underlyingType = EnumHelper.GetUnderlyingType(tw.type); underlyingType = EnumHelper.GetUnderlyingType(tw.type);
} }
#if !STUB_GENERATOR #if EMITTERS
protected override void EmitGetImpl(CodeEmitter ilgen) 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 // 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.Emit(OpCodes.Stobj, underlyingType);
ilgen.ReleaseTempLocal(temp); 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 private sealed class ValueTypeDefaultCtor : MethodWrapper
@ -1970,14 +1999,21 @@ namespace IKVM.Internal
{ {
} }
#if !STUB_GENERATOR #if EMITTERS
internal override void EmitNewobj(CodeEmitter ilgen) internal override void EmitNewobj(CodeEmitter ilgen)
{ {
CodeEmitterLocal local = ilgen.DeclareLocal(DeclaringType.TypeAsTBD); CodeEmitterLocal local = ilgen.DeclareLocal(DeclaringType.TypeAsTBD);
ilgen.Emit(OpCodes.Ldloc, local); ilgen.Emit(OpCodes.Ldloc, local);
ilgen.Emit(OpCodes.Box, DeclaringType.TypeAsTBD); 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 private sealed class FinalizeMethodWrapper : MethodWrapper
@ -1987,7 +2023,7 @@ namespace IKVM.Internal
{ {
} }
#if !STUB_GENERATOR #if EMITTERS
internal override void EmitCall(CodeEmitter ilgen) internal override void EmitCall(CodeEmitter ilgen)
{ {
ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Pop);
@ -1997,7 +2033,7 @@ namespace IKVM.Internal
{ {
ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Pop);
} }
#endif // !STUB_GENERATOR #endif // EMITTERS
} }
private sealed class CloneMethodWrapper : MethodWrapper private sealed class CloneMethodWrapper : MethodWrapper
@ -2007,7 +2043,7 @@ namespace IKVM.Internal
{ {
} }
#if !STUB_GENERATOR #if EMITTERS
internal override void EmitCall(CodeEmitter ilgen) internal override void EmitCall(CodeEmitter ilgen)
{ {
ilgen.Emit(OpCodes.Dup); ilgen.Emit(OpCodes.Dup);
@ -2027,7 +2063,7 @@ namespace IKVM.Internal
{ {
EmitCall(ilgen); EmitCall(ilgen);
} }
#endif // !STUB_GENERATOR #endif // EMITTERS
} }
protected override void LazyPublishMembers() protected override void LazyPublishMembers()
@ -2269,9 +2305,7 @@ namespace IKVM.Internal
&& !typeof(java.io.Serializable.__Interface).IsAssignableFrom(type) && !typeof(java.io.Serializable.__Interface).IsAssignableFrom(type)
&& !methodsList.ContainsKey("writeReplace()Ljava.lang.Object;")) && !methodsList.ContainsKey("writeReplace()Ljava.lang.Object;"))
{ {
methodsList.Add("writeReplace()Ljava.lang.Object;", new SimpleCallMethodWrapper(this, "writeReplace", "()Ljava.lang.Object;", methodsList.Add("writeReplace()Ljava.lang.Object;", new ExceptionWriteReplaceMethodWrapper(this));
typeof(ikvm.@internal.Serialization).GetMethod("writeReplace"), CoreClasses.java.lang.Object.Wrapper, TypeWrapper.EmptyArray,
Modifiers.Private, MemberFlags.None, SimpleOpCode.Call, SimpleOpCode.Call));
} }
#endif // !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS #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<string, MethodWrapper> methodsList, MethodBase method, string name, string sig, TypeWrapper[] args, TypeWrapper ret) private void InterfaceMethodStubHelper(Dictionary<string, MethodWrapper> methodsList, MethodBase method, string name, string sig, TypeWrapper[] args, TypeWrapper ret)
{ {
string key = name + sig; string key = name + sig;
@ -2317,7 +2376,7 @@ namespace IKVM.Internal
{ {
} }
#if !STUB_GENERATOR #if EMITTERS
internal override void EmitCall(CodeEmitter ilgen) internal override void EmitCall(CodeEmitter ilgen)
{ {
// we direct EmitCall to EmitCallvirt, because we always want to end up at the instancehelper method // 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); m.EmitCallvirt(ilgen);
} }
#endif // !STUB_GENERATOR #endif // EMITTERS
} }
internal static bool IsUnsupportedAbstractMethod(MethodBase mb) internal static bool IsUnsupportedAbstractMethod(MethodBase mb)
@ -2362,7 +2421,11 @@ namespace IKVM.Internal
} }
type = type.GetElementType(); type = type.GetElementType();
} }
#if STATIC_COMPILER || STUB_GENERATOR
return type.__IsFunctionPointer;
#else
return false; return false;
#endif
} }
private bool MakeMethodDescriptor(MethodBase mb, out string name, out string sig, out TypeWrapper[] args, out TypeWrapper ret) 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()) foreach (ParameterInfo p in invoke.GetParameters())
{ {
// we don't support delegates with pointer parameters // we don't support delegates with pointer parameters
if (p.ParameterType.IsPointer) if (IsPointerType(p.ParameterType))
{ {
return false; return false;
} }
} }
return true; return !IsPointerType(invoke.ReturnType);
} }
} }
return false; return false;
@ -2668,7 +2731,7 @@ namespace IKVM.Internal
} }
} }
#if !STUB_GENERATOR #if EMITTERS
internal override void EmitInstanceOf(CodeEmitter ilgen) internal override void EmitInstanceOf(CodeEmitter ilgen)
{ {
if (IsRemapped) if (IsRemapped)
@ -2698,7 +2761,7 @@ namespace IKVM.Internal
} }
ilgen.EmitCastclass(type); ilgen.EmitCastclass(type);
} }
#endif // !STUB_GENERATOR #endif // EMITTERS
internal override void Finish() internal override void Finish()
{ {
@ -2726,6 +2789,38 @@ namespace IKVM.Internal
finished = true; 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 #if !STATIC_COMPILER && !STUB_GENERATOR
internal override object[] GetDeclaredAnnotations() internal override object[] GetDeclaredAnnotations()
{ {
@ -2780,6 +2875,10 @@ namespace IKVM.Internal
// (i.e. injected into the assembly) // (i.e. injected into the assembly)
internal override bool IsPackageAccessibleFrom(TypeWrapper wrapper) internal override bool IsPackageAccessibleFrom(TypeWrapper wrapper)
{ {
if (wrapper == DeclaringTypeWrapper)
{
return true;
}
if (!base.IsPackageAccessibleFrom(wrapper)) if (!base.IsPackageAccessibleFrom(wrapper))
{ {
return false; return false;

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -62,6 +62,7 @@ namespace IKVM.Internal
#endif // STATIC_COMPILER #endif // STATIC_COMPILER
private Dictionary<string, TypeBuilder> unloadables; private Dictionary<string, TypeBuilder> unloadables;
private TypeBuilder unloadableContainer; private TypeBuilder unloadableContainer;
private Type[] delegates;
#if !STATIC_COMPILER && !CLASSGC #if !STATIC_COMPILER && !CLASSGC
private static DynamicClassLoader instance = new DynamicClassLoader(CreateModuleBuilder(), false); private static DynamicClassLoader instance = new DynamicClassLoader(CreateModuleBuilder(), false);
#endif #endif
@ -222,21 +223,29 @@ namespace IKVM.Internal
return mangledTypeName; return mangledTypeName;
} }
internal sealed override TypeWrapper DefineClassImpl(Dictionary<string, TypeWrapper> types, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain protectionDomain) internal sealed override TypeWrapper DefineClassImpl(Dictionary<string, TypeWrapper> types, TypeWrapper host, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain protectionDomain)
{ {
#if STATIC_COMPILER #if STATIC_COMPILER
AotTypeWrapper type = new AotTypeWrapper(f, (CompilerClassLoader)classLoader); AotTypeWrapper type = new AotTypeWrapper(f, (CompilerClassLoader)classLoader);
type.CreateStep1(); type.CreateStep1();
types[f.Name] = type; types[f.Name] = type;
return type; return type;
#elif FIRST_PASS
return null;
#else #else
// this step can throw a retargettable exception, if the class is incorrect // 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, // 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 // 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. // and will cause a CriticalFailure and exit the process.
type.CreateStep1(); type.CreateStep1();
type.CreateStep2(); 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) lock(types)
{ {
// in very extreme conditions another thread may have beaten us to it // in very extreme conditions another thread may have beaten us to it
@ -248,16 +257,7 @@ namespace IKVM.Internal
if(race == null) if(race == null)
{ {
types[f.Name] = type; types[f.Name] = type;
#if !FIRST_PASS TieClassAndWrapper(type, 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);
#endif
} }
else else
{ {
@ -268,42 +268,37 @@ namespace IKVM.Internal
#endif // STATIC_COMPILER #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 #if STATIC_COMPILER
internal TypeBuilder DefineProxy(TypeWrapper proxyClass, TypeWrapper[] interfaces) internal TypeBuilder DefineProxy(string name, TypeAttributes typeAttributes, Type parent, Type[] interfaces)
{ {
if (proxiesContainer == null) if (proxiesContainer == null)
{ {
proxiesContainer = moduleBuilder.DefineType("__<Proxies>", 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.HideFromJava(proxiesContainer);
AttributeHelper.SetEditorBrowsableNever(proxiesContainer); AttributeHelper.SetEditorBrowsableNever(proxiesContainer);
proxies = new List<TypeBuilder>(); proxies = new List<TypeBuilder>();
} }
Type[] ifaces = new Type[interfaces.Length]; TypeBuilder tb = proxiesContainer.DefineNestedType(name, typeAttributes, parent, interfaces);
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);
proxies.Add(tb); proxies.Add(tb);
return tb; return tb;
} }
#endif #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 "__<Proxies>+" + GetProxyNestedName(interfaces);
}
internal override Type DefineUnloadable(string name) internal override Type DefineUnloadable(string name)
{ {
lock(this) 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 internal override bool HasInternalAccess
{ {
get { return hasInternalAccess; } get { return hasInternalAccess; }
@ -403,7 +439,7 @@ namespace IKVM.Internal
{ {
AssemblyName name = new AssemblyName(); AssemblyName name = new AssemblyName();
name.Name = "jniproxy"; 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"); return jniProxyAssemblyBuilder.DefineDynamicModule("jniproxy.dll", "jniproxy.dll");
} }
#endif #endif
@ -544,12 +580,7 @@ namespace IKVM.Internal
attribs.Add(new CustomAttributeBuilder(typeof(System.Security.SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes), new object[0])); attribs.Add(new CustomAttributeBuilder(typeof(System.Security.SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes), new object[0]));
} }
#endif #endif
AssemblyBuilder assemblyBuilder = AssemblyBuilder assemblyBuilder = DefineDynamicAssembly(name, access, attribs);
#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
AttributeHelper.SetRuntimeCompatibilityAttribute(assemblyBuilder); AttributeHelper.SetRuntimeCompatibilityAttribute(assemblyBuilder);
bool debug = JVM.EmitSymbols; bool debug = JVM.EmitSymbols;
CustomAttributeBuilder debugAttr = new CustomAttributeBuilder(typeof(DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new object[] { true, debug }); 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])); moduleBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(IKVM.Attributes.JavaModuleAttribute).GetConstructor(Type.EmptyTypes), new object[0]));
return moduleBuilder; return moduleBuilder;
} }
private static AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, IEnumerable<CustomAttributeBuilder> 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 #endif // !STATIC_COMPILER
} }
} }

View File

@ -1 +1 @@
ad0861972ed1ac0e9caf2cde6149145bd346f957 c40b0a040f514f61c3bce5ca397280b4247710bf

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages 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); StackFrame frame = st.GetFrame(i);
MethodBase m = frame.GetMethod(); MethodBase m = frame.GetMethod();
if (m == null || m.DeclaringType == null) if (m == null)
{ {
continue; continue;
} }
Type type = m.DeclaringType; Type type = m.DeclaringType;
if (cleanStackTrace && if (cleanStackTrace &&
(typeof(MethodBase).IsAssignableFrom(type) (type == null
|| typeof(MethodBase).IsAssignableFrom(type)
|| type == typeof(RuntimeMethodHandle) || type == typeof(RuntimeMethodHandle)
|| (type == typeof(Throwable) && m.Name == "instancehelper_fillInStackTrace") || (type == typeof(Throwable) && m.Name == "instancehelper_fillInStackTrace")
|| (m.Name == "ToJava" && typeof(RetargetableJavaException).IsAssignableFrom(type)) || (m.Name == "ToJava" && typeof(RetargetableJavaException).IsAssignableFrom(type))
@ -298,6 +299,14 @@ namespace IKVM.Internal
{ {
return mb.Name.Substring(NamePrefix.DefaultMethod.Length); 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 else
{ {
return mb.Name; return mb.Name;
@ -309,12 +318,17 @@ namespace IKVM.Internal
#if FIRST_PASS #if FIRST_PASS
return false; return false;
#else #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 #endif
} }
private static string getClassNameFromType(Type type) private static string getClassNameFromType(Type type)
{ {
if(type == null)
{
return "<Module>";
}
if(ClassLoaderWrapper.IsRemappedType(type)) if(ClassLoaderWrapper.IsRemappedType(type))
{ {
return DotNetTypeWrapper.GetName(type); return DotNetTypeWrapper.GetName(type);
@ -326,6 +340,12 @@ namespace IKVM.Internal
{ {
return DotNetTypeWrapper.GetName(type); return DotNetTypeWrapper.GetName(type);
} }
#if !FIRST_PASS
if(tw.IsUnsafeAnonymous)
{
return tw.ClassObject.getName();
}
#endif
return tw.Name; return tw.Name;
} }
return type.FullName; return type.FullName;
@ -337,7 +357,7 @@ namespace IKVM.Internal
if(ilOffset != StackFrame.OFFSET_UNKNOWN) if(ilOffset != StackFrame.OFFSET_UNKNOWN)
{ {
MethodBase mb = frame.GetMethod(); MethodBase mb = frame.GetMethod();
if(mb != null) if(mb != null && mb.DeclaringType != null)
{ {
if(ClassLoaderWrapper.IsRemappedType(mb.DeclaringType)) if(ClassLoaderWrapper.IsRemappedType(mb.DeclaringType))
{ {
@ -356,7 +376,7 @@ namespace IKVM.Internal
private static string GetFileName(StackFrame frame) private static string GetFileName(StackFrame frame)
{ {
MethodBase mb = frame.GetMethod(); MethodBase mb = frame.GetMethod();
if(mb != null) if(mb != null && mb.DeclaringType != null)
{ {
if(ClassLoaderWrapper.IsRemappedType(mb.DeclaringType)) if(ClassLoaderWrapper.IsRemappedType(mb.DeclaringType))
{ {

View File

@ -36,7 +36,7 @@
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow> <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile> <ConfigurationOverrideFile>
</ConfigurationOverrideFile> </ConfigurationOverrideFile>
<DefineConstants>TRACE;DEBUG</DefineConstants> <DefineConstants>TRACE;DEBUG;EMITTERS</DefineConstants>
<DocumentationFile> <DocumentationFile>
</DocumentationFile> </DocumentationFile>
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@ -87,6 +87,7 @@
<Compile Include="AssemblyInfo.cs"> <Compile Include="AssemblyInfo.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Assertions.cs" />
<Compile Include="atomic.cs" /> <Compile Include="atomic.cs" />
<Compile Include="attributes.cs"> <Compile Include="attributes.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
@ -94,6 +95,7 @@
<Compile Include="BigEndianBinaryReader.cs"> <Compile Include="BigEndianBinaryReader.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Boxer.cs" />
<Compile Include="ByteCode.cs"> <Compile Include="ByteCode.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
@ -120,6 +122,7 @@
<Compile Include="DynamicClassLoader.cs"> <Compile Include="DynamicClassLoader.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="DynamicMethodUtils.cs" />
<Compile Include="DynamicTypeWrapper.cs" /> <Compile Include="DynamicTypeWrapper.cs" />
<Compile Include="ExceptionHelper.cs"> <Compile Include="ExceptionHelper.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
@ -141,15 +144,28 @@
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="JsrInliner.cs" /> <Compile Include="JsrInliner.cs" />
<Compile Include="LambdaMetafactory.cs" />
<Compile Include="LocalVars.cs" /> <Compile Include="LocalVars.cs" />
<Compile Include="MemberWrapper.cs"> <Compile Include="MemberWrapper.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="openjdk.cs" /> <Compile Include="MethodHandleUtil.cs" />
<Compile Include="openjdk\java.io.cs" />
<Compile Include="openjdk\java.lang.cs" />
<Compile Include="openjdk\java.lang.invoke.cs" /> <Compile Include="openjdk\java.lang.invoke.cs" />
<Compile Include="openjdk\java.lang.reflect.cs" />
<Compile Include="openjdk\java.net.cs" />
<Compile Include="openjdk\java.nio.cs" />
<Compile Include="openjdk\java.security.cs" />
<Compile Include="openjdk\java.util.cs" />
<Compile Include="openjdk\java.util.prefs.cs" />
<Compile Include="openjdk\misc.cs" />
<Compile Include="openjdk\sun.management.cs" /> <Compile Include="openjdk\sun.management.cs" />
<Compile Include="openjdk\sun.misc.cs" />
<Compile Include="openjdk\sun.nio.ch.cs" /> <Compile Include="openjdk\sun.nio.ch.cs" />
<Compile Include="openjdk\sun.reflect.cs" />
<Compile Include="openjdk\sun.security.krb5.cs" /> <Compile Include="openjdk\sun.security.krb5.cs" />
<Compile Include="openjdk\sun.util.locale.provider.cs" />
<Compile Include="PassiveWeakDictionary.cs" /> <Compile Include="PassiveWeakDictionary.cs" />
<Compile Include="profiler.cs"> <Compile Include="profiler.cs">
<SubType>Code</SubType> <SubType>Code</SubType>

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -216,3 +216,18 @@ sealed class UnsupportedClassVersionError : ClassFormatError
} }
#endif #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
}

1024
external/ikvm/runtime/LambdaMetafactory.cs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -52,6 +52,11 @@ namespace IKVM.Internal
psetSerializationFormatter.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter)); psetSerializationFormatter.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));
} }
internal static bool IsISerializable(TypeWrapper wrapper)
{
return wrapper == iserializable;
}
private static bool IsSafeForAutomagicSerialization(TypeWrapper wrapper) private static bool IsSafeForAutomagicSerialization(TypeWrapper wrapper)
{ {
if (wrapper.TypeAsBaseType.IsSerializable) if (wrapper.TypeAsBaseType.IsSerializable)
@ -147,15 +152,21 @@ namespace IKVM.Internal
return null; return null;
} }
private static void MarkSerializable(TypeBuilder tb) internal static void MarkSerializable(TypeBuilder tb)
{ {
tb.SetCustomAttribute(serializableAttribute); 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))); 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)) }); new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) });
getObjectData.SetCustomAttribute(securityCriticalAttribute); getObjectData.SetCustomAttribute(securityCriticalAttribute);
AttributeHelper.HideFromJava(getObjectData); AttributeHelper.HideFromJava(getObjectData);

View File

@ -1 +1 @@
3ed1d9cc7e683c9f379f858859a155d3b4c778a1 fabd1aa5c712bc82971cd56b6f8a9d6cf648740c

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -22,6 +22,8 @@
*/ */
using System; using System;
using System.Collections.Generic;
using IKVM.Internal;
#if STATIC_COMPILER || STUB_GENERATOR #if STATIC_COMPILER || STUB_GENERATOR
using IKVM.Reflection; using IKVM.Reflection;
using Type = IKVM.Reflection.Type; using Type = IKVM.Reflection.Type;
@ -388,7 +390,7 @@ namespace IKVM.Attributes
public JavaModuleAttribute(string[] classMap) public JavaModuleAttribute(string[] classMap)
{ {
this.classMap = classMap; this.classMap = UnicodeUtil.UnescapeInvalidSurrogates(classMap);
} }
public string[] GetClassMap() public string[] GetClassMap()
@ -418,11 +420,33 @@ namespace IKVM.Attributes
[AttributeUsage(AttributeTargets.All)] [AttributeUsage(AttributeTargets.All)]
public sealed class HideFromJavaAttribute : Attribute 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)] [Flags]
public sealed class HideFromReflectionAttribute : Attribute 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] [Flags]
@ -493,8 +517,8 @@ namespace IKVM.Attributes
public NameSigAttribute(string name, string sig) public NameSigAttribute(string name, string sig)
{ {
this.name = name; this.name = UnicodeUtil.UnescapeInvalidSurrogates(name);
this.sig = sig; this.sig = UnicodeUtil.UnescapeInvalidSurrogates(sig);
} }
public string Name 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 // this constructor is used by ikvmc, the other constructors are for use in other .NET languages
public ThrowsAttribute(string[] classes) public ThrowsAttribute(string[] classes)
{ {
this.classes = classes; this.classes = UnicodeUtil.UnescapeInvalidSurrogates(classes);
} }
public ThrowsAttribute(Type type) 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 // NOTE this is not CLS compliant, so maybe we should have a couple of overloads
public ImplementsAttribute(string[] interfaces) public ImplementsAttribute(string[] interfaces)
{ {
this.interfaces = interfaces; this.interfaces = UnicodeUtil.UnescapeInvalidSurrogates(interfaces);
} }
public string[] Interfaces public string[] Interfaces
@ -577,7 +601,7 @@ namespace IKVM.Attributes
public InnerClassAttribute(string innerClassName, Modifiers modifiers) public InnerClassAttribute(string innerClassName, Modifiers modifiers)
{ {
this.innerClassName = innerClassName; this.innerClassName = UnicodeUtil.UnescapeInvalidSurrogates(innerClassName);
this.modifiers = modifiers; this.modifiers = modifiers;
} }
@ -605,7 +629,7 @@ namespace IKVM.Attributes
public NonNestedInnerClassAttribute(string innerClassName) public NonNestedInnerClassAttribute(string innerClassName)
{ {
this.innerClassName = innerClassName; this.innerClassName = UnicodeUtil.UnescapeInvalidSurrogates(innerClassName);
} }
public string InnerClassName public string InnerClassName
@ -624,7 +648,7 @@ namespace IKVM.Attributes
public NonNestedOuterClassAttribute(string outerClassName) public NonNestedOuterClassAttribute(string outerClassName)
{ {
this.outerClassName = outerClassName; this.outerClassName = UnicodeUtil.UnescapeInvalidSurrogates(outerClassName);
} }
public string OuterClassName public string OuterClassName
@ -662,7 +686,7 @@ namespace IKVM.Attributes
public SignatureAttribute(string signature) public SignatureAttribute(string signature)
{ {
this.signature = signature; this.signature = UnicodeUtil.UnescapeInvalidSurrogates(signature);
} }
public string Signature public string Signature
@ -683,9 +707,9 @@ namespace IKVM.Attributes
public EnclosingMethodAttribute(string className, string methodName, string methodSig) public EnclosingMethodAttribute(string className, string methodName, string methodSig)
{ {
this.className = className; this.className = UnicodeUtil.UnescapeInvalidSurrogates(className);
this.methodName = methodName; this.methodName = UnicodeUtil.UnescapeInvalidSurrogates(methodName);
this.methodSig = methodSig; this.methodSig = UnicodeUtil.UnescapeInvalidSurrogates(methodSig);
} }
internal EnclosingMethodAttribute SetClassName(Type type) internal EnclosingMethodAttribute SetClassName(Type type)
@ -749,7 +773,7 @@ namespace IKVM.Attributes
// new object[] { (byte)'?', "<exceptionClass>", "<exceptionMessage>" } // new object[] { (byte)'?', "<exceptionClass>", "<exceptionMessage>" }
public AnnotationDefaultAttribute(object defaultValue) public AnnotationDefaultAttribute(object defaultValue)
{ {
this.defaultValue = defaultValue; this.defaultValue = Unescape(defaultValue);
} }
public object Value public object Value
@ -759,6 +783,36 @@ namespace IKVM.Attributes
return defaultValue; 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)] [AttributeUsage(AttributeTargets.Interface)]
@ -768,7 +822,7 @@ namespace IKVM.Attributes
public AnnotationAttributeAttribute(string attributeType) public AnnotationAttributeAttribute(string attributeType)
{ {
this.attributeType = attributeType; this.attributeType = UnicodeUtil.UnescapeInvalidSurrogates(attributeType);
} }
public string AttributeType public string AttributeType
@ -780,14 +834,16 @@ namespace IKVM.Attributes
} }
} }
[AttributeUsage(AttributeTargets.Module)] [AttributeUsage(AttributeTargets.Module, AllowMultiple = true)]
public sealed class PackageListAttribute : Attribute 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() public string[] GetPackages()
@ -826,7 +882,7 @@ namespace IKVM.Attributes
public DynamicAnnotationAttribute(object[] definition) public DynamicAnnotationAttribute(object[] definition)
{ {
this.definition = definition; this.definition = (object[])AnnotationDefaultAttribute.Unescape(definition);
} }
public object[] 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<object> list = new List<object>();
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 // used in custom modifier for access stubs
public static class AccessStub { } public static class AccessStub { }
} }

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages 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.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices;
using IKVM.Attributes; using IKVM.Attributes;
using IKVM.Runtime; using IKVM.Runtime;
using IKVM.Internal; using IKVM.Internal;
@ -49,7 +50,7 @@ namespace IKVM.NativeCode.gnu.java.net.protocol.ikvmres
MemoryStream mem = new MemoryStream(); MemoryStream mem = new MemoryStream();
#if !FIRST_PASS #if !FIRST_PASS
bool includeNonPublicInterfaces = !"true".Equals(global::java.lang.Props.props.getProperty("ikvm.stubgen.skipNonPublicInterfaces"), StringComparison.OrdinalIgnoreCase); 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 #endif
return mem.ToArray(); return mem.ToArray();
} }
@ -119,6 +120,53 @@ namespace IKVM.NativeCode.java.lang
{ {
return VirtualFileSystem.GetAssemblyClassesPath(JVM.CoreAssembly); 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 static class AnnotationAttributeBase
{ {
public static object[] unescapeInvalidSurrogates(object[] def)
{
return (object[])AnnotationDefaultAttribute.Unescape(def);
}
public static object newAnnotationInvocationHandler(jlClass type, object memberValues) public static object newAnnotationInvocationHandler(jlClass type, object memberValues)
{ {
#if FIRST_PASS #if FIRST_PASS
@ -271,25 +324,6 @@ namespace IKVM.NativeCode.ikvm.runtime
return null; 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) 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; string result = null;
@ -310,31 +344,37 @@ namespace IKVM.NativeCode.ikvm.runtime
#if !FIRST_PASS #if !FIRST_PASS
AssemblyClassLoader_ wrapper = (AssemblyClassLoader_)ClassLoaderWrapper.GetClassLoaderWrapper(_this); AssemblyClassLoader_ wrapper = (AssemblyClassLoader_)ClassLoaderWrapper.GetClassLoaderWrapper(_this);
global::java.net.URL sealBase = GetCodeBase(wrapper.MainAssembly); global::java.net.URL sealBase = GetCodeBase(wrapper.MainAssembly);
global::java.util.jar.Manifest manifest = GetManifest(_this); foreach (KeyValuePair<string, string[]> packages in wrapper.GetPackageInfo())
global::java.util.jar.Attributes attr = null;
if (manifest != null)
{ {
attr = manifest.getMainAttributes(); global::java.util.jar.Manifest manifest = null;
} global::java.util.jar.Attributes attr = null;
string[] packages = wrapper.GetPackages(); if (packages.Key != null)
for (int i = 0; i < packages.Length; i++)
{
string name = packages[i];
if (_this.getPackage(name) == null)
{ {
global::java.util.jar.Attributes entryAttr = null; global::java.util.jar.JarFile jarFile = new global::java.util.jar.JarFile(VirtualFileSystem.GetAssemblyResourcesPath(wrapper.MainAssembly) + packages.Key);
if (manifest != null) 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 #endif

View File

@ -1 +1 @@
8b8a30e4b47038b6fae92d434aa386871005e4fb e38729f8e1419779787415d4fd6aa39532dbfcf7

1371
external/ikvm/runtime/openjdk/java.io.cs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -96,6 +96,57 @@ static class Java_java_lang_Class
#endif #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) public static bool isInstance(java.lang.Class thisClass, object obj)
{ {
return TypeWrapper.FromClass(thisClass).IsInstance(obj); return TypeWrapper.FromClass(thisClass).IsInstance(obj);
@ -169,6 +220,14 @@ static class Java_java_lang_Class
return "void"; 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; return tw.Name;
} }
@ -188,7 +247,7 @@ static class Java_java_lang_Class
return super != null ? super.ClassObject : null; 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 #if FIRST_PASS
return null; 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 try
{ {
@ -286,9 +345,9 @@ static class Java_java_lang_Class
return null; return null;
#else #else
TypeWrapper wrapper = TypeWrapper.FromClass(thisClass); TypeWrapper wrapper = TypeWrapper.FromClass(thisClass);
while (wrapper.IsArray) if (wrapper.IsArray)
{ {
wrapper = wrapper.ElementTypeWrapper; return null;
} }
java.security.ProtectionDomain pd = wrapper.ClassObject.pd; java.security.ProtectionDomain pd = wrapper.ClassObject.pd;
if (pd == null) if (pd == null)
@ -300,18 +359,17 @@ static class Java_java_lang_Class
{ {
pd = acl.GetProtectionDomain(); 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; return pd;
#endif #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) 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)) // 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); TypeWrapper tw = TypeWrapper.FromClass(thisClass);
tw.Finish(); tw.Finish();
@ -620,16 +678,7 @@ static class Java_java_lang_ClassLoader
try try
{ {
ClassLoaderWrapper classLoaderWrapper = ClassLoaderWrapper.GetClassLoaderWrapper(thisClassLoader); ClassLoaderWrapper classLoaderWrapper = ClassLoaderWrapper.GetClassLoaderWrapper(thisClassLoader);
ClassFileParseOptions cfp = ClassFileParseOptions.LineNumberTable; ClassFile classFile = new ClassFile(b, off, len, name, classLoaderWrapper.ClassFileParseOptions, null);
if (classLoaderWrapper.EmitDebugInfo)
{
cfp |= ClassFileParseOptions.LocalVariableTable;
}
if (classLoaderWrapper.RelaxedClassNameValidation)
{
cfp |= ClassFileParseOptions.RelaxedClassNameValidation;
}
ClassFile classFile = new ClassFile(b, off, len, name, cfp);
if (name != null && classFile.Name != name) if (name != null && classFile.Name != name)
{ {
#if !FIRST_PASS #if !FIRST_PASS
@ -703,13 +752,13 @@ static class Java_java_lang_ClassLoader
static class Java_java_lang_ClassLoader_00024NativeLibrary 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 !FIRST_PASS
if (VirtualFileSystem.IsVirtualFS(name)) if (VirtualFileSystem.IsVirtualFS(name))
{ {
// we fake success for native libraries loaded from VFS // we fake success for native libraries loaded from VFS
((java.lang.ClassLoader.NativeLibrary)thisNativeLibrary).handle = -1; ((java.lang.ClassLoader.NativeLibrary)thisNativeLibrary).loaded = true;
} }
else else
{ {
@ -725,7 +774,8 @@ static class Java_java_lang_ClassLoader_00024NativeLibrary
private static void doLoad(object thisNativeLibrary, string name) private static void doLoad(object thisNativeLibrary, string name)
{ {
java.lang.ClassLoader.NativeLibrary lib = (java.lang.ClassLoader.NativeLibrary)thisNativeLibrary; 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 #endif
@ -736,17 +786,22 @@ static class Java_java_lang_ClassLoader_00024NativeLibrary
} }
[SecuritySafeCritical] [SecuritySafeCritical]
public static void unload(object thisNativeLibrary) public static void unload(object thisNativeLibrary, string name, bool isBuiltin)
{ {
#if !FIRST_PASS #if !FIRST_PASS
java.lang.ClassLoader.NativeLibrary lib = (java.lang.ClassLoader.NativeLibrary)thisNativeLibrary; java.lang.ClassLoader.NativeLibrary lib = (java.lang.ClassLoader.NativeLibrary)thisNativeLibrary;
long handle = Interlocked.Exchange(ref lib.handle, 0); long handle = Interlocked.Exchange(ref lib.handle, 0);
if (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 #endif
} }
public static string findBuiltinLib(string name)
{
return null;
}
} }
static class Java_java_lang_Compiler static class Java_java_lang_Compiler
@ -823,9 +878,12 @@ static class Java_java_lang_Package
{ {
Dictionary<string, string> dict = new Dictionary<string, string>(); Dictionary<string, string> dict = new Dictionary<string, string>();
string path = VirtualFileSystem.GetAssemblyResourcesPath(JVM.CoreAssembly) + "resources.jar"; string path = VirtualFileSystem.GetAssemblyResourcesPath(JVM.CoreAssembly) + "resources.jar";
foreach (string pkg in ClassLoaderWrapper.GetBootstrapClassLoader().GetPackages()) foreach (KeyValuePair<string, string[]> 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); Interlocked.CompareExchange(ref systemPackages, dict, null);
} }
@ -927,18 +985,11 @@ static class Java_java_lang_SecurityManager
{ {
StackFrame frame = trace.GetFrame(i); StackFrame frame = trace.GetFrame(i);
MethodBase method = frame.GetMethod(); MethodBase method = frame.GetMethod();
Type type = method.DeclaringType; if (Java_sun_reflect_Reflection.IsHideFromStackWalk(method))
// 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))
{ {
continue; continue;
} }
Type type = method.DeclaringType;
if (type == typeof(java.lang.SecurityManager)) if (type == typeof(java.lang.SecurityManager))
{ {
continue; continue;
@ -1068,20 +1119,6 @@ static class Java_java_lang_StrictMath
#endif #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) public static double atan2(double y, double x)
{ {
#if FIRST_PASS #if FIRST_PASS
@ -1111,15 +1148,6 @@ static class Java_java_lang_StrictMath
return Math.Tanh(d); 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) public static double hypot(double a, double b)
{ {
return fdlibm.__ieee754_hypot(a, b); return fdlibm.__ieee754_hypot(a, b);
@ -1223,9 +1251,14 @@ static class Java_java_lang_ProcessImpl
{ {
public static string mapVfsExecutable(string path) 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; return path;
} }
@ -1250,7 +1283,7 @@ static class Java_java_lang_ProcessImpl
for (; ; ) for (; ; )
{ {
string str = cmdstr.Substring(0, pos); string str = cmdstr.Substring(0, pos);
if (Path.IsPathRooted(str)) if (IsPathRooted(str))
{ {
if (Exists(str)) if (Exists(str))
{ {
@ -1303,6 +1336,18 @@ static class Java_java_lang_ProcessImpl
return list; return list;
} }
private static bool IsPathRooted(string path)
{
try
{
return Path.IsPathRooted(path);
}
catch (ArgumentException)
{
return false;
}
}
private static bool Exists(string file) private static bool Exists(string file)
{ {
try try
@ -1319,6 +1364,10 @@ static class Java_java_lang_ProcessImpl
{ {
return true; return true;
} }
else if (mapVfsExecutable(file) != file)
{
return true;
}
else else
{ {
return false; return false;

View File

@ -689,6 +689,8 @@ static class Java_java_lang_reflect_Proxy
{ {
return null; 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; TypeWrapper[] wrappers2 = tw.Interfaces;
if (wrappers.Length != wrappers.Length) 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) public static object[] getParameters0(java.lang.reflect.Executable _this)
{
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)
{ {
#if FIRST_PASS #if FIRST_PASS
return null; return null;
#else #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); object[][] objAnn = mw.DeclaringType.GetParameterAnnotations(mw);
if (objAnn == null) if (objAnn == null)
{ {
@ -758,10 +781,28 @@ static class Java_java_lang_reflect_Method
return ann; return ann;
#endif #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) public static object getDefaultValue(java.lang.reflect.Method thisMethod)
{ {
MethodWrapper mw = MethodWrapper.FromMethod(thisMethod); MethodWrapper mw = MethodWrapper.FromExecutable(thisMethod);
return mw.DeclaringType.GetAnnotationDefault(mw); return mw.DeclaringType.GetAnnotationDefault(mw);
} }
} }

View File

@ -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<java.net.InetAddress> addresses = new List<java.net.InetAddress>();
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<java.net.InetAddress> addresses = new List<java.net.InetAddress>();
List<java.net.InterfaceAddress> bindings = new List<java.net.InterfaceAddress>();
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
}
}

View File

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

View File

@ -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<java.security.ProtectionDomain> array = new List<java.security.ProtectionDomain>();
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<java.security.ProtectionDomain> 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<java.security.ProtectionDomain> 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<java.security.ProtectionDomain> list = new List<java.security.ProtectionDomain>();
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
}
}

View File

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -21,6 +21,7 @@
jeroen@frijters.net jeroen@frijters.net
*/ */
using System;
#if !FIRST_PASS #if !FIRST_PASS
using java.lang.management; using java.lang.management;
#endif #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 static class Java_sun_management_MemoryImpl
{ {
public static object getMemoryPools0() 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 static class Java_sun_management_ThreadImpl
{ {
public static object getThreads() 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; private const int JVMTI_THREAD_STATE_ALIVE = 0x0001;
@ -161,9 +244,28 @@ static class Java_sun_management_ThreadImpl
#endif #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) 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) public static void getThreadTotalCpuTime1(long[] ids, long[] result)
@ -188,7 +290,7 @@ static class Java_sun_management_ThreadImpl
public static void setThreadCpuTimeEnabled0(bool enable) public static void setThreadCpuTimeEnabled0(bool enable)
{ {
throw new System.NotImplementedException(); //ignoring, we need nothing to enable
} }
public static void setThreadAllocatedMemoryEnabled0(bool enable) public static void setThreadAllocatedMemoryEnabled0(bool enable)

View File

@ -1,4 +1,27 @@
<?xml version="1.0"?> <?xml version="1.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
-->
<project name="IKVM.Runtime" default="full"> <project name="IKVM.Runtime" default="full">
<include buildfile="../ikvm.include" /> <include buildfile="../ikvm.include" />
@ -20,7 +43,11 @@
<target name="signed"> <target name="signed">
<property name="signed" value="SIGNCODE" /> <property name="signed" value="SIGNCODE" />
<property name="signoption" value="-key:ikvm-key" /> <property name="signoption" value="-key:ikvm-key" />
<property name="ilasm_signoption" value="/key:@ikvm-key" /> <call target="full" />
</target>
<target name="no-ref-emit">
<property name="no-ref-emit" value="true" />
<call target="full" /> <call target="full" />
</target> </target>
@ -60,7 +87,7 @@
</target> </target>
<target name="defs"> <target name="defs">
<property name="defs" value="TRACE" /> <property name="defs" value="TRACE;EMITTERS" />
<if test="${property::exists('signed')}"> <if test="${property::exists('signed')}">
<property name="defs" value="${defs};${signed}" /> <property name="defs" value="${defs};${signed}" />
</if> </if>
@ -70,6 +97,9 @@
<if test="${first-pass}"> <if test="${first-pass}">
<property name="defs" value="${defs};FIRST_PASS" /> <property name="defs" value="${defs};FIRST_PASS" />
</if> </if>
<if test="${property::exists('no-ref-emit')}">
<property name="defs" value="${defs};NO_REF_EMIT" />
</if>
</target> </target>
<target name="IKVM.Runtime.JNI" depends="JniAssemblyInfo.cs defs"> <target name="IKVM.Runtime.JNI" depends="JniAssemblyInfo.cs defs">
@ -107,9 +137,11 @@
<include name="../CommonAssemblyInfo.cs" /> <include name="../CommonAssemblyInfo.cs" />
<include name="AssemblyInfo.cs" /> <include name="AssemblyInfo.cs" />
<include name="AssemblyClassLoader.cs" /> <include name="AssemblyClassLoader.cs" />
<include name="Assertions.cs" />
<include name="atomic.cs" /> <include name="atomic.cs" />
<include name="attributes.cs" /> <include name="attributes.cs" />
<include name="BigEndianBinaryReader.cs" /> <include name="BigEndianBinaryReader.cs" />
<include name="Boxer.cs" />
<include name="ByteCode.cs" /> <include name="ByteCode.cs" />
<include name="ByteCodeHelper.cs" /> <include name="ByteCodeHelper.cs" />
<include name="ClassFile.cs" /> <include name="ClassFile.cs" />
@ -120,14 +152,16 @@
<include name="CoreClasses.cs" /> <include name="CoreClasses.cs" />
<include name="DotNetTypeWrapper.cs" /> <include name="DotNetTypeWrapper.cs" />
<include name="DynamicClassLoader.cs" /> <include name="DynamicClassLoader.cs" />
<include name="DynamicMethodUtils.cs" />
<include name="DynamicTypeWrapper.cs" /> <include name="DynamicTypeWrapper.cs" />
<include name="ExceptionHelper.cs" /> <include name="ExceptionHelper.cs" />
<include name="intrinsics.cs" /> <include name="intrinsics.cs" />
<include name="JavaException.cs" /> <include name="JavaException.cs" />
<include name="JsrInliner.cs" /> <include name="JsrInliner.cs" />
<include name="LambdaMetafactory.cs" />
<include name="LocalVars.cs" /> <include name="LocalVars.cs" />
<include name="MemberWrapper.cs" /> <include name="MemberWrapper.cs" />
<include name="openjdk.cs" /> <include name="MethodHandleUtil.cs" />
<include name="PassiveWeakDictionary.cs" /> <include name="PassiveWeakDictionary.cs" />
<include name="profiler.cs" /> <include name="profiler.cs" />
<include name="ReflectUtil.cs" /> <include name="ReflectUtil.cs" />
@ -151,10 +185,22 @@
<include name="fdlibm/s_log1p.cs" /> <include name="fdlibm/s_log1p.cs" />
<include name="fdlibm/s_scalbn.cs" /> <include name="fdlibm/s_scalbn.cs" />
<include name="fdlibm/s_tan.cs" /> <include name="fdlibm/s_tan.cs" />
<include name="openjdk/java.io.cs" />
<include name="openjdk/java.lang.cs" />
<include name="openjdk/java.lang.invoke.cs" /> <include name="openjdk/java.lang.invoke.cs" />
<include name="openjdk/java.lang.reflect.cs" />
<include name="openjdk/java.net.cs" />
<include name="openjdk/java.nio.cs" />
<include name="openjdk/java.security.cs" />
<include name="openjdk/java.util.cs" />
<include name="openjdk/java.util.prefs.cs" />
<include name="openjdk/misc.cs" />
<include name="openjdk/sun.management.cs" /> <include name="openjdk/sun.management.cs" />
<include name="openjdk/sun.misc.cs" />
<include name="openjdk/sun.nio.ch.cs" /> <include name="openjdk/sun.nio.ch.cs" />
<include name="openjdk/sun.reflect.cs" />
<include name="openjdk/sun.security.krb5.cs" /> <include name="openjdk/sun.security.krb5.cs" />
<include name="openjdk/sun.util.locale.provider.cs" />
<include name="stubgen/ClassFileWriter.cs" /> <include name="stubgen/ClassFileWriter.cs" />
<include name="stubgen/SerialVersionUID.cs" /> <include name="stubgen/SerialVersionUID.cs" />
<include name="stubgen/StubGenerator.cs" /> <include name="stubgen/StubGenerator.cs" />

View File

@ -72,6 +72,11 @@ namespace IKVM.StubGen
stream.WriteByte(b); stream.WriteByte(b);
} }
public void WriteBytes(byte[] data)
{
stream.Write(data, 0, data.Length);
}
public void WriteUtf8(string str) public void WriteUtf8(string str)
{ {
byte[] buf = new byte[str.Length * 3 + 1]; 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 sealed class AnnotationDefaultClassFileAttribute : ClassFileAttribute
{ {
private ClassFileWriter classFile; private ClassFileWriter classFile;
@ -834,23 +857,31 @@ namespace IKVM.StubGen
{ {
private readonly ClassFileWriter classFile; private readonly ClassFileWriter classFile;
private readonly ushort[] names; 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")) : base(classFile.AddUtf8("MethodParameters"))
{ {
this.classFile = classFile; this.classFile = classFile;
this.names = names; this.names = names;
this.flags = flags;
} }
public override void Write(BigEndianStream bes) public override void Write(BigEndianStream bes)
{ {
base.Write(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.WriteUInt32((uint)(1 + names.Length * 4));
bes.WriteByte((byte)names.Length); bes.WriteByte((byte)names.Length);
foreach (ushort idx in names) for (int i = 0; i < names.Length; i++)
{ {
bes.WriteUInt16(idx); bes.WriteUInt16(names[i]);
bes.WriteUInt16(0); bes.WriteUInt16(flags[i]);
} }
} }
} }

View File

@ -93,6 +93,7 @@ namespace IKVM.StubGen
writer.AddStringAttribute("Signature", genericTypeSignature); writer.AddStringAttribute("Signature", genericTypeSignature);
} }
AddAnnotations(writer, writer, tw.TypeAsBaseType); AddAnnotations(writer, writer, tw.TypeAsBaseType);
AddTypeAnnotations(writer, writer, tw, tw.GetRawTypeAnnotations());
writer.AddStringAttribute("IKVM.NET.Assembly", GetAssemblyName(tw)); writer.AddStringAttribute("IKVM.NET.Assembly", GetAssemblyName(tw));
if (tw.TypeAsBaseType.IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false)) if (tw.TypeAsBaseType.IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false))
{ {
@ -103,7 +104,11 @@ namespace IKVM.StubGen
if (!mw.IsHideFromReflection && (mw.IsPublic || mw.IsProtected || includeNonPublicMembers)) if (!mw.IsHideFromReflection && (mw.IsPublic || mw.IsProtected || includeNonPublicMembers))
{ {
FieldOrMethod m; FieldOrMethod m;
if (mw.Name == "<init>") // 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 == "<init>" || (tw == CoreClasses.java.lang.invoke.MethodHandle.Wrapper && (mw.Modifiers & Modifiers.Native) == 0))
{ {
m = writer.AddMethod(mw.Modifiers, mw.Name, mw.Signature.Replace('.', '/')); m = writer.AddMethod(mw.Modifiers, mw.Name, mw.Signature.Replace('.', '/'));
CodeAttribute code = new CodeAttribute(writer); CodeAttribute code = new CodeAttribute(writer);
@ -187,18 +192,24 @@ namespace IKVM.StubGen
} }
if (includeParameterNames) if (includeParameterNames)
{ {
ParameterInfo[] parameters = mb.GetParameters(); MethodParametersEntry[] mp = tw.GetMethodParameters(mw);
if (parameters.Length != 0) 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++) 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()); AddAnnotations(writer, m, mw.GetMethod());
AddParameterAnnotations(writer, m, mw.GetMethod()); AddParameterAnnotations(writer, m, mw.GetMethod());
AddTypeAnnotations(writer, m, tw, tw.GetMethodRawTypeAnnotations(mw));
} }
} }
bool hasSerialVersionUID = false; bool hasSerialVersionUID = false;
@ -240,6 +252,7 @@ namespace IKVM.StubGen
f.AddAttribute(new DeprecatedAttribute(writer)); f.AddAttribute(new DeprecatedAttribute(writer));
} }
AddAnnotations(writer, f, fw.GetField()); AddAnnotations(writer, f, fw.GetField());
AddTypeAnnotations(writer, f, tw, tw.GetFieldRawTypeAnnotations(fw));
} }
} }
} }
@ -322,6 +335,143 @@ namespace IKVM.StubGen
#endif #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 #if !FIRST_PASS && !STUB_GENERATOR
private static object[] GetAnnotation(CustomAttributeData cad) private static object[] GetAnnotation(CustomAttributeData cad)
{ {
@ -525,7 +675,7 @@ namespace IKVM.StubGen
"value", "value",
targets.ToArray() targets.ToArray()
}); });
if (Experimental.JDK_8 && IsRepeatableAnnotation(tw)) if (IsRepeatableAnnotation(tw))
{ {
annot.Add(new object[] { annot.Add(new object[] {
AnnotationDefaultAttribute.TAG_ANNOTATION, AnnotationDefaultAttribute.TAG_ANNOTATION,

View File

@ -1 +1 @@
81b479291c9b3c8f98f03a54e464caea811df044 c0168e79b1441480a125c7c6db72132875a3f366

View File

@ -577,7 +577,7 @@ namespace IKVM.Internal
{ {
System.IO.MemoryStream mem = new System.IO.MemoryStream(); System.IO.MemoryStream mem = new System.IO.MemoryStream();
bool includeNonPublicInterfaces = !"true".Equals(java.lang.Props.props.getProperty("ikvm.stubgen.skipNonPublicInterfaces"), StringComparison.OrdinalIgnoreCase); 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(); buf = mem.ToArray();
} }
#endif #endif
@ -756,6 +756,7 @@ namespace IKVM.Internal
AddDummyLibrary(bin, "net"); AddDummyLibrary(bin, "net");
AddDummyLibrary(bin, "splashscreen"); AddDummyLibrary(bin, "splashscreen");
AddDummyLibrary(bin, "osx"); AddDummyLibrary(bin, "osx");
AddDummyLibrary(bin, "management");
bin.Add("java", new VfsJavaExe()); bin.Add("java", new VfsJavaExe());
bin.Add("javaw", new VfsJavaExe()); bin.Add("javaw", new VfsJavaExe());
bin.Add("java.exe", new VfsJavaExe()); bin.Add("java.exe", new VfsJavaExe());
@ -985,7 +986,7 @@ namespace IKVM.Internal
#if FIRST_PASS #if FIRST_PASS
return false; return false;
#else #else
return access == Java_java_io_Win32FileSystem.ACCESS_READ && GetVfsEntry(path) != null; return access == Java_java_io_WinNTFileSystem.ACCESS_READ && GetVfsEntry(path) != null;
#endif #endif
} }

View File

@ -90,11 +90,11 @@
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" title="">FAQ</a> <a href="http://sourceforge.net/p/ikvm/wiki/FAQ/" title="">FAQ</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" title="">License</a> <a href="http://sourceforge.net/p/ikvm/wiki/License/" title="">License</a>
</li> </li>
<li> <li>
@ -108,19 +108,19 @@
<ul> <ul>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide">Introduction</a> <a href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/">Introduction</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" title="">Installation</a> <a href="http://sourceforge.net/p/ikvm/wiki/Installation/" title="">Installation</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" title="">Tutorial</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" title="">Tutorial</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" title="">Tools Reference</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tools/" title="">Tools Reference</a>
</li> </li>
</ul> </ul>
@ -228,7 +228,7 @@
<h4>Class Loading in Dynamically Interpreted Java Applications</h4> <h4>Class Loading in Dynamically Interpreted Java Applications</h4>
<div style="margin-left: 0 ; border: 2px"> <div style="margin-left: 0 ; border: 2px">
<p>When you run a Java application using ikvm, ikvm finds and loads Java .class files much like <p>When you run a Java application using ikvm, ikvm finds and loads Java .class files much like
other Java VM's. See the <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvm">ikvm notes</a> for details.</p> other Java VM's. See the <a href="http://sourceforge.net/p/ikvm/wiki/Ikvm/">ikvm notes</a> for details.</p>
</div> </div>
<a name="N1002C"></a><a name="Class+Loading+in+ikvmc-compiled+Java+Applications"></a> <a name="N1002C"></a><a name="Class+Loading+in+ikvmc-compiled+Java+Applications"></a>
<h4>Class Loading in ikvmc-compiled Java Applications</h4> <h4>Class Loading in ikvmc-compiled Java Applications</h4>

View File

@ -90,11 +90,11 @@
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" title="">FAQ</a> <a href="http://sourceforge.net/p/ikvm/wiki/FAQ/" title="">FAQ</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" title="">License</a> <a href="http://sourceforge.net/p/ikvm/wiki/License/" title="">License</a>
</li> </li>
<li> <li>
@ -108,19 +108,19 @@
<ul> <ul>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide">Introduction</a> <a href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/">Introduction</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" title="">Installation</a> <a href="http://sourceforge.net/p/ikvm/wiki/Installation/" title="">Installation</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" title="">Tutorial</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" title="">Tutorial</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" title="">Tools Reference</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tools/" title="">Tools Reference</a>
</li> </li>
</ul> </ul>

View File

@ -90,11 +90,11 @@
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" title="">FAQ</a> <a href="http://sourceforge.net/p/ikvm/wiki/FAQ/" title="">FAQ</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" title="">License</a> <a href="http://sourceforge.net/p/ikvm/wiki/License/" title="">License</a>
</li> </li>
<li> <li>
@ -108,19 +108,19 @@
<ul> <ul>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide">Introduction</a> <a href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/">Introduction</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" title="">Installation</a> <a href="http://sourceforge.net/p/ikvm/wiki/Installation/" title="">Installation</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" title="">Tutorial</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" title="">Tutorial</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" title="">Tools Reference</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tools/" title="">Tools Reference</a>
</li> </li>
</ul> </ul>
@ -246,7 +246,7 @@
</li> </li>
<li>Use the <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvmstub">ikvmstub</a> application to generate a Java jar file for each dll you identified in step 2. <li>Use the <a href="http://sourceforge.net/p/ikvm/wiki/Ikvmstub/">ikvmstub</a> application to generate a Java jar file for each dll you identified in step 2.
<p>The ikvmstub tool analyzes the .NET classes in the designated dll <p>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 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.</p> knows nothing about .NET assemblies.</p>
@ -259,7 +259,7 @@
.NET classes you used; do <em>not</em> include the ikvmstub-generated jar files on the compiler classpath.</li> .NET classes you used; do <em>not</em> include the ikvmstub-generated jar files on the compiler classpath.</li>
</ol> </ol>
<p>For an example of this, see the <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial">tutorial</a>.</p> <p>For an example of this, see the <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/">tutorial</a>.</p>
</div> </div>

View File

@ -90,11 +90,11 @@
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" title="">FAQ</a> <a href="http://sourceforge.net/p/ikvm/wiki/FAQ/" title="">FAQ</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" title="">License</a> <a href="http://sourceforge.net/p/ikvm/wiki/License/" title="">License</a>
</li> </li>
<li> <li>
@ -108,19 +108,19 @@
<ul> <ul>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide">Introduction</a> <a href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/">Introduction</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" title="">Installation</a> <a href="http://sourceforge.net/p/ikvm/wiki/Installation/" title="">Installation</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" title="">Tutorial</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" title="">Tutorial</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" title="">Tools Reference</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tools/" title="">Tools Reference</a>
</li> </li>
</ul> </ul>
@ -234,7 +234,7 @@
<li>To use other Java API's, you can take one of the following approaches: <li>To use other Java API's, you can take one of the following approaches:
<ul> <ul>
<li>Convert the Java API to .NET CIL using <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvmc">ikvmc</a>. <li>Convert the Java API to .NET CIL using <a href="http://sourceforge.net/p/ikvm/wiki/Ikvmc/">ikvmc</a>.
This produces a .NET dll that you can reference in your project. </li> This produces a .NET dll that you can reference in your project. </li>
<li>Use the Java reflection API's to dynamically load and execute the Java bytecode using the <li>Use the Java reflection API's to dynamically load and execute the Java bytecode using the

View File

@ -90,11 +90,11 @@
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" title="">FAQ</a> <a href="http://sourceforge.net/p/ikvm/wiki/FAQ/" title="">FAQ</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" title="">License</a> <a href="http://sourceforge.net/p/ikvm/wiki/License/" title="">License</a>
</li> </li>
<li> <li>
@ -108,19 +108,19 @@
<ul> <ul>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide">Introduction</a> <a href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/">Introduction</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" title="">Installation</a> <a href="http://sourceforge.net/p/ikvm/wiki/Installation/" title="">Installation</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" title="">Tutorial</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" title="">Tutorial</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" title="">Tools Reference</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tools/" title="">Tools Reference</a>
</li> </li>
</ul> </ul>

View File

@ -90,11 +90,11 @@
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" title="">FAQ</a> <a href="http://sourceforge.net/p/ikvm/wiki/FAQ/" title="">FAQ</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" title="">License</a> <a href="http://sourceforge.net/p/ikvm/wiki/License/" title="">License</a>
</li> </li>
<li> <li>
@ -108,19 +108,19 @@
<ul> <ul>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide">Introduction</a> <a href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/">Introduction</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" title="">Installation</a> <a href="http://sourceforge.net/p/ikvm/wiki/Installation/" title="">Installation</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" title="">Tutorial</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" title="">Tutorial</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" title="">Tools Reference</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tools/" title="">Tools Reference</a>
</li> </li>
</ul> </ul>

View File

@ -90,11 +90,11 @@
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" title="">FAQ</a> <a href="http://sourceforge.net/p/ikvm/wiki/FAQ/" title="">FAQ</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" title="">License</a> <a href="http://sourceforge.net/p/ikvm/wiki/License/" title="">License</a>
</li> </li>
<li> <li>
@ -108,19 +108,19 @@
<ul> <ul>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide">Introduction</a> <a href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/">Introduction</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" title="">Installation</a> <a href="http://sourceforge.net/p/ikvm/wiki/Installation/" title="">Installation</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" title="">Tutorial</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" title="">Tutorial</a>
</li> </li>
<li> <li>
<a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" title="">Tools Reference</a> <a href="http://sourceforge.net/p/ikvm/wiki/Tools/" title="">Tools Reference</a>
</li> </li>
</ul> </ul>
@ -224,7 +224,7 @@
<a name="N1000F"></a><a name="Drop-in+JVM"></a> <a name="N1000F"></a><a name="Drop-in+JVM"></a>
<h3>Drop-in JVM</h3> <h3>Drop-in JVM</h3>
<div style="margin-left: 0 ; border: 2px"> <div style="margin-left: 0 ; border: 2px">
<p>The <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvm">ikvm application</a> included with the distribution is a .NET <p>The <a href="http://sourceforge.net/p/ikvm/wiki/Ikvm/">ikvm application</a> included with the distribution is a .NET
implementation of a Java Virtual Machine. In many cases, you can use it implementation of a Java Virtual Machine. In many cases, you can use it
as a drop-in replacement for java. For example, instead of typing</p> as a drop-in replacement for java. For example, instead of typing</p>
<div class="pre"> <div class="pre">
@ -239,7 +239,7 @@
<a name="N1002C"></a><a name="Use+Java+libraries+in+your+.NET+applications"></a> <a name="N1002C"></a><a name="Use+Java+libraries+in+your+.NET+applications"></a>
<h3>Use Java libraries in your .NET applications</h3> <h3>Use Java libraries in your .NET applications</h3>
<div style="margin-left: 0 ; border: 2px"> <div style="margin-left: 0 ; border: 2px">
<p>IKVM.NET includes <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvmc">ikvmc</a>, a Java bytecode to .NET IL translator. <p>IKVM.NET includes <a href="http://sourceforge.net/p/ikvm/wiki/Ikvmc/">ikvmc</a>, a Java bytecode to .NET IL translator.
If you have a Java library that you would like to use in a .NET application, If you have a Java library that you would like to use in a .NET application,
run <span class="codefrag">ikvmc -target:library mylib.jar</span> to create mylib.dll. run <span class="codefrag">ikvmc -target:library mylib.jar</span> to create mylib.dll.
</p> </p>
@ -258,7 +258,7 @@
you can use any Java compiler to compile Java source code to JVM bytecode, then use you can use any Java compiler to compile Java source code to JVM bytecode, then use
<span class="codefrag">ikvmc -target:exe myapp.jar</span> <span class="codefrag">ikvmc -target:exe myapp.jar</span>
to produce a .NET executable. You can even use .NET API's in your to produce a .NET executable. You can even use .NET API's in your
Java code using the included <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvmstub">ikvmstub</a> application. Java code using the included <a href="http://sourceforge.net/p/ikvm/wiki/Ikvmstub/">ikvmstub</a> application.
</p> </p>
</div> </div>

View File

@ -21,15 +21,15 @@ See http://xml.apache.org/forrest/linking.html for more info
<download label="Download" href="download.html" description="" /> <download label="Download" href="download.html" description="" />
<uses label="Uses" href="uses.html" description=""/> <uses label="Uses" href="uses.html" description=""/>
<weblog label="News" href="http://weblog.ikvm.net" description=""/> <weblog label="News" href="http://weblog.ikvm.net" description=""/>
<faq label="FAQ" href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" description=""/> <faq label="FAQ" href="http://sourceforge.net/p/ikvm/wiki/FAQ/" description=""/>
<license label="License" href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" description=""/> <license label="License" href="http://sourceforge.net/p/ikvm/wiki/License/" description=""/>
<stories label="Case Studies" href="stories.html" description="" /> <stories label="Case Studies" href="stories.html" description="" />
</about> </about>
<userguide label="User's Guide" href="userguide/"> <userguide label="User's Guide" href="userguide/">
<intro label="Introduction" href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide"/> <intro label="Introduction" href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/"/>
<install label="Installation" href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" description="" /> <install label="Installation" href="http://sourceforge.net/p/ikvm/wiki/Installation/" description="" />
<tutorial label="Tutorial" href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" description="" /> <tutorial label="Tutorial" href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" description="" />
<tools label="Tools Reference" href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" description=""/> <tools label="Tools Reference" href="http://sourceforge.net/p/ikvm/wiki/Tools/" description=""/>
</userguide> </userguide>
<devguide label="Developer's Guide" href="devguide/"> <devguide label="Developer's Guide" href="devguide/">
<intro label="Introduction" href="intro.html" description="" /> <intro label="Introduction" href="intro.html" description="" />
@ -51,10 +51,10 @@ See http://xml.apache.org/forrest/linking.html for more info
--> -->
<external-refs> <external-refs>
<ikvm href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvm" /> <ikvm href="http://sourceforge.net/p/ikvm/wiki/Ikvm/" />
<ikvmc href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvmc" /> <ikvmc href="http://sourceforge.net/p/ikvm/wiki/Ikvmc/" />
<ikvmstub href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvmstub" /> <ikvmstub href="http://sourceforge.net/p/ikvm/wiki/Ikvmstub/" />
<tutorial href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" /> <tutorial href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" />
<sourceforgedl href="http://sourceforge.net/project/showfiles.php?group_id=69637" /> <sourceforgedl href="http://sourceforge.net/project/showfiles.php?group_id=69637" />
<classpath href="http://www.gnu.org/software/classpath/classpath.html" /> <classpath href="http://www.gnu.org/software/classpath/classpath.html" />
<icedtea href="http://icedtea.classpath.org/wiki/Main_Page" /> <icedtea href="http://icedtea.classpath.org/wiki/Main_Page" />

View File

@ -1 +1 @@
ec75f52b4a09d98c0cc1707b0a0f796e4c7a91c0 8f066765940517df1ea0554208196aab32b6b19b

View File

@ -114,6 +114,17 @@ case "$THREADS" in
AC_DEFINE(THREAD_LOCAL_ALLOC) AC_DEFINE(THREAD_LOCAL_ALLOC)
THREADDLLIBS="-lpthread -lrt" THREADDLLIBS="-lpthread -lrt"
;; ;;
*-*-kfreebsd*-gnu)
AC_DEFINE(GC_FREEBSD_THREADS)
INCLUDES="$INCLUDES -pthread"
THREADDLLIBS=-pthread
AC_DEFINE(_REENTRANT)
if test "${enable_parallel_mark}" = yes; then
AC_DEFINE(PARALLEL_MARK)
fi
AC_DEFINE(THREAD_LOCAL_ALLOC)
AC_DEFINE(USE_COMPILER_TLS)
;;
*-*-freebsd*) *-*-freebsd*)
AC_DEFINE(GC_FREEBSD_THREADS) AC_DEFINE(GC_FREEBSD_THREADS)
if test "x$PTHREAD_CFLAGS" != "x"; then if test "x$PTHREAD_CFLAGS" != "x"; then

View File

@ -26,7 +26,7 @@
* None of this is safe with dlclose and incremental collection. * None of this is safe with dlclose and incremental collection.
* But then not much of anything is safe in the presence of dlclose. * But then not much of anything is safe in the presence of dlclose.
*/ */
#if (defined(__linux__) || defined(__native_client__)) && !defined(_GNU_SOURCE) #if (defined(__linux__) || defined(__GLIBC__) || defined(__native_client__)) && !defined(_GNU_SOURCE)
/* Can't test LINUX, since this must be define before other includes */ /* Can't test LINUX, since this must be define before other includes */
# define _GNU_SOURCE # define _GNU_SOURCE
#endif #endif
@ -394,7 +394,7 @@ GC_bool GC_register_main_static_data()
/* For glibc 2.2.4+. Unfortunately, it doesn't work for older */ /* For glibc 2.2.4+. Unfortunately, it doesn't work for older */
/* versions. Thanks to Jakub Jelinek for most of the code. */ /* versions. Thanks to Jakub Jelinek for most of the code. */
# if (defined(LINUX) || defined(NACL)) /* Are others OK here, too? */ \ # if (defined(LINUX) || defined (__GLIBC__) || defined(NACL)) /* Are others OK here, too? */ \
&& (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \ && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG))) || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))

View File

@ -497,7 +497,7 @@ GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROTO((size_t lb));
# define GC_RETURN_ADDR (GC_word)__return_address # define GC_RETURN_ADDR (GC_word)__return_address
#endif #endif
#ifdef __linux__ #if defined(__linux__) || defined(__GLIBC__)
# include <features.h> # include <features.h>
# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \ # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
&& !defined(__ia64__) && !defined(__ia64__)

View File

@ -55,7 +55,7 @@
# endif # endif
/* And one for FreeBSD: */ /* And one for FreeBSD: */
# if defined(__FreeBSD__) && !defined(FREEBSD) # if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && !defined(FREEBSD)
# define FREEBSD # define FREEBSD
# endif # endif
@ -1371,8 +1371,15 @@
# ifndef GC_FREEBSD_THREADS # ifndef GC_FREEBSD_THREADS
# define MPROTECT_VDB # define MPROTECT_VDB
# endif # endif
# define SIG_SUSPEND SIGTSTP # ifdef __GLIBC__
# define SIG_THR_RESTART SIGCONT # define SIG_SUSPEND (32+6)
# define SIG_THR_RESTART (32+5)
extern int _end[];
# define DATAEND (_end)
# else
# define SIG_SUSPEND SIGTSTP
# define SIG_THR_RESTART SIGCONT
# endif
# define FREEBSD_STACKBOTTOM # define FREEBSD_STACKBOTTOM
# ifdef __ELF__ # ifdef __ELF__
# define DYNAMIC_LOADING # define DYNAMIC_LOADING
@ -2132,8 +2139,15 @@
# ifndef GC_FREEBSD_THREADS # ifndef GC_FREEBSD_THREADS
# define MPROTECT_VDB # define MPROTECT_VDB
# endif # endif
# define SIG_SUSPEND SIGTSTP # ifdef __GLIBC__
# define SIG_THR_RESTART SIGCONT # define SIG_SUSPEND (32+6)
# define SIG_THR_RESTART (32+5)
extern int _end[];
# define DATAEND (_end)
# else
# define SIG_SUSPEND SIGUSR1
# define SIG_THR_RESTART SIGUSR2
# endif
# define NEED_FIND_LIMIT # define NEED_FIND_LIMIT
# define FREEBSD_STACKBOTTOM # define FREEBSD_STACKBOTTOM
# ifdef __ELF__ # ifdef __ELF__
@ -2230,7 +2244,7 @@
# define SUNOS5SIGS # define SUNOS5SIGS
# endif # endif
# if defined(FREEBSD) && (__FreeBSD__ >= 4) # if defined(FREEBSD) && ((__FreeBSD__ >= 4) || (__FreeBSD_kernel__ >= 4))
# define SUNOS5SIGS # define SUNOS5SIGS
# endif # endif
@ -2293,7 +2307,7 @@
# define CACHE_LINE_SIZE 32 /* Wild guess */ # define CACHE_LINE_SIZE 32 /* Wild guess */
# endif # endif
# ifdef LINUX # if defined(LINUX) || defined(__GLIBC__)
# define REGISTER_LIBRARIES_EARLY # define REGISTER_LIBRARIES_EARLY
/* We sometimes use dl_iterate_phdr, which may acquire an internal */ /* We sometimes use dl_iterate_phdr, which may acquire an internal */
/* lock. This isn't safe after the world has stopped. So we must */ /* lock. This isn't safe after the world has stopped. So we must */
@ -2374,7 +2388,7 @@
#if defined(SPARC) #if defined(SPARC)
# define CAN_SAVE_CALL_ARGS # define CAN_SAVE_CALL_ARGS
#endif #endif
#if (defined(I386) || defined(X86_64)) && defined(LINUX) #if (defined(I386) || defined(X86_64)) && (defined(LINUX) || defined(__GLIBC__))
/* SAVE_CALL_CHAIN is supported if the code is compiled to save */ /* SAVE_CALL_CHAIN is supported if the code is compiled to save */
/* frame pointers by default, i.e. no -fomit-frame-pointer flag. */ /* frame pointers by default, i.e. no -fomit-frame-pointer flag. */
# define CAN_SAVE_CALL_ARGS # define CAN_SAVE_CALL_ARGS

View File

@ -1216,6 +1216,17 @@ is used.
Performs a check to make sure that no references are left to an Performs a check to make sure that no references are left to an
unloaded AppDomain. unloaded AppDomain.
.TP .TP
\fBclear-at-tlab-creation\fR
Clears the nursery incrementally when the thread local allocation
buffers (TLAB) are created. The default setting clears the whole
nursery at GC time.
.TP
\fBdebug-clear-at-tlab-creation\fR
Clears the nursery incrementally when the thread local allocation
buffers (TLAB) are created, but at GC time fills it with the byte
`0xff`, which should result in a crash more quickly if
`clear-at-tlab-creation` doesn't work properly.
.TP
\fBclear-at-gc\fR \fBclear-at-gc\fR
This clears the nursery at GC time instead of doing it when the thread This clears the nursery at GC time instead of doing it when the thread
local allocation buffer (TLAB) is created. The default is to clear local allocation buffer (TLAB) is created. The default is to clear

View File

@ -82,7 +82,7 @@ all-local $(STD_TARGETS:=-local):
@: @:
dir-check: dir-check:
@if [ "$(NO_DIR_CHECK)" = "" -a "$(PROFILE)" != "basic" ]; then make -C ../runtime; fi @if [ "$(NO_DIR_CHECK)" = "" -a "$(PROFILE)" != "basic" ]; then $(MAKE) -C ../runtime; fi
# fun specialty targets # fun specialty targets

View File

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

View File

@ -17,3 +17,6 @@ FRAMEWORK_VERSION = 4.0
XBUILD_VERSION = 4.0 XBUILD_VERSION = 4.0
LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION) LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)
# Ignore tests on net_4_0 as the 4.0 IL code is never used for running (just for metadata), so it doesn't make sense to execute tests there
NO_TEST = yes

View File

@ -55,10 +55,8 @@ using System.Runtime.InteropServices;
[assembly: Guid ("1ea4dbf0-3c3b-11cf-810c-00aa00389b71")] [assembly: Guid ("1ea4dbf0-3c3b-11cf-810c-00aa00389b71")]
[assembly: AllowPartiallyTrustedCallers] [assembly: AllowPartiallyTrustedCallers]
#if !TARGET_JVM
[assembly: AssemblyDelaySign (true)] [assembly: AssemblyDelaySign (true)]
[assembly: AssemblyKeyFile ("../msfinal.pub")] [assembly: AssemblyKeyFile ("../msfinal.pub")]
#endif
[assembly: ImportedFromTypeLib ("Accessibility")] [assembly: ImportedFromTypeLib ("Accessibility")]

View File

@ -16,15 +16,6 @@ build_SUBDIRS := \
Mono.Posix \ Mono.Posix \
System.Core System.Core
net_1_1_java_SUBDIRS = \
System.Xml \
System.Data \
System.Drawing \
Novell.Directory.Ldap \
System.DirectoryServices \
System.Runtime.Serialization.Formatters.Soap \
System.Runtime.Remoting
net_2_0_dirs := \ net_2_0_dirs := \
corlib \ corlib \
System \ System \

View File

@ -100,7 +100,7 @@ TEST_DISTFILES = \
EXTRA_DISTFILES = \ EXTRA_DISTFILES = \
README System.Windows.Forms.dll.resources \ README System.Windows.Forms.dll.resources \
$(RESX_RESOURCES:.resources=.resx) $(CUR_RESOURCES) $(PREBUILT) build-csproj build-csproj2k5 \ $(RESX_RESOURCES:.resources=.resx) $(CUR_RESOURCES) $(PREBUILT) \
$(IMAGES_RESOURCES) \ $(IMAGES_RESOURCES) \
$(TEST_DISTFILES) $(TEST_DISTFILES)

View File

@ -1,217 +0,0 @@
#!/bin/bash
#
# I got tired of editing the SWF.csproj
# This script will generate it from our System.Windows.Forms.dll.sources
#
#
tr=tr
OutFile=SWF.csproj
Source=System.Windows.Forms.dll.sources
Resource=System.Windows.Forms.dll.resources
SWFhead()
{
cat << EOT
<VisualStudioProject>
<CSHARP
ProjectType = "Local"
ProductVersion = "7.10.3077"
SchemaVersion = "2.0"
ProjectGuid = "{5E6430B2-6B9F-4E76-802E-20207EF80391}"
>
<Build>
<Settings
ApplicationIcon = ""
AssemblyKeyContainerName = ""
AssemblyName = "System.Windows.Forms"
AssemblyOriginatorKeyFile = ""
DefaultClientScript = "JScript"
DefaultHTMLPageLayout = "Grid"
DefaultTargetSchema = "IE50"
DelaySign = "false"
OutputType = "Library"
PreBuildEvent = ""
PostBuildEvent = ""
RootNamespace = ""
RunPostBuildEvent = "OnBuildSuccess"
StartupObject = ""
>
<Config
Name = "Debug"
AllowUnsafeBlocks = "true"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "NET_1_1 ONLY_1_1"
DocumentationFile = ""
DebugSymbols = "true"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = ""
Optimize = "false"
OutputPath = "bin\Debug\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "1"
/>
<Config
Name = "Debug 2.0"
AllowUnsafeBlocks = "true"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "NET_2_0"
DocumentationFile = ""
DebugSymbols = "true"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = ""
Optimize = "false"
OutputPath = "bin\Debug\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "1"
/>
<Config
Name = "Release"
AllowUnsafeBlocks = "true"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "NET_1_1 ONLY_1_1"
DocumentationFile = ""
DebugSymbols = "false"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = ""
Optimize = "false"
OutputPath = "bin\Release\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "1"
/>
<Config
Name = "Release 2.0"
AllowUnsafeBlocks = "true"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "NET_2_0"
DocumentationFile = ""
DebugSymbols = "false"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = ""
Optimize = "false"
OutputPath = "bin\Release\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "1"
/>
</Settings>
<References>
<Reference
Name = "Accessibility"
AssemblyName = "Accessibility"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Accessibility.dll"
/>
<Reference
Name = "System"
AssemblyName = "System"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
/>
<Reference
Name = "System.Data"
AssemblyName = "System.Data"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
/>
<Reference
Name = "System.Drawing"
AssemblyName = "System.Drawing"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Drawing.dll"
/>
<Reference
Name = "System.Data"
AssemblyName = "System.Data"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
/>
<Reference
Name = "System.XML"
AssemblyName = "System.XML"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
/>
</References>
</Build>
<Files>
<Include>
EOT
}
SWFfilelist()
{
cat $Source | while read SRC; do
# Don't do AssemblyInfo, it's got signing requests and such that we don't want
if [ "x$SRC" != "xAssembly/AssemblyInfo.cs" ] ; then
SRC=`echo $SRC | $tr '/' '\\\\'`
cat << EOT
<File
RelPath = "$SRC"
SubType = "Code"
BuildAction = "Compile"
/>
EOT
fi
done
}
SWFresourcelist()
{
cat $Resource | while read SRC; do
SRC=`echo $SRC | $tr '/' '\\\\'`
SRC=`echo $SRC | sed 's/-resource://' | awk -F , '{print " RelPath = \"" $1 "\"\n CustomToolNameSpace = \"" $2 "\""}' | fgrep -v \"\"`
cat << EOT
<File
$SRC
BuildAction = "EmbeddedResource"
/>
EOT
done
}
SWFtail()
{
cat << EOT
<File
RelPath = "Consts.cs"
Link = "common/Consts.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "MonoTODOAttribute.cs"
Link = "common/MonoTODOAttribute.cs"
SubType = "Code"
BuildAction = "Compile"
/>
</Include>
</Files>
</CSHARP>
</VisualStudioProject>
EOT
}
SWFhead > $OutFile
SWFfilelist >> $OutFile
SWFresourcelist >> $OutFile
SWFtail >> $OutFile

View File

@ -1,247 +0,0 @@
#!/bin/bash
#
# This script will generate SWF.cs.target from our System.Windows.Forms.dll.sources
#
#
exec > SWF2k5.csproj
Source=System.Windows.Forms.dll.sources
Resource=System.Windows.Forms.dll.resources
SWFhead()
{
cat <<EOF
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{5E6430B2-6B9F-4E76-802E-20207EF80391}</ProjectGuid>
<Configuration Condition=" '\$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '\$(Platform)' == '' ">AnyCPU</Platform>
<ApplicationIcon>
</ApplicationIcon>
<AssemblyKeyContainerName>
</AssemblyKeyContainerName>
<AssemblyName>System.Windows.Forms</AssemblyName>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<DefaultClientScript>JScript</DefaultClientScript>
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
<DefaultTargetSchema>IE50</DefaultTargetSchema>
<DelaySign>false</DelaySign>
<OutputType>Library</OutputType>
<RootNamespace>
</RootNamespace>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<StartupObject>
</StartupObject>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
</PropertyGroup>
<PropertyGroup Condition=" '\$(Configuration)|\$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>bin\Debug\</OutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>NET_1_1 NET_2_0 MWF_ON_MSRUNTIME</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>612,618,3021</NoWarn>
<Optimize>false</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>3</WarningLevel>
<DebugType>full</DebugType>
<ErrorReport>prompt</ErrorReport>
<OutputType>Library</OutputType>
<AssemblyName>System.Windows.Forms</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '\$(Configuration)|\$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>NET_1_1 NET_2_0 MWF_ON_MSRUNTIME</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>false</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>612,618,3021</NoWarn>
<Optimize>false</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>3</WarningLevel>
<DebugType>none</DebugType>
<ErrorReport>prompt</ErrorReport>
<OutputType>Library</OutputType>
<AssemblyName>System.Windows.Forms</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '\$(Configuration)|\$(Platform)' == 'Debug 1.1|AnyCPU' ">
<OutputPath>bin\Debug\</OutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>NET_1_1 ONLY_1_1 MWF_ON_MSRUNTIME</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>612,618,3021</NoWarn>
<Optimize>false</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>3</WarningLevel>
<DebugType>full</DebugType>
<ErrorReport>prompt</ErrorReport>
<OutputType>Library</OutputType>
<AssemblyName>System.Windows.Forms</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '\$(Configuration)|\$(Platform)' == 'Release 1.1|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>NET_1_1 ONLY_1_1 MWF_ON_MSRUNTIME</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>false</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>612,618,3021</NoWarn>
<Optimize>false</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>3</WarningLevel>
<DebugType>none</DebugType>
<ErrorReport>prompt</ErrorReport>
<OutputType>Library</OutputType>
<AssemblyName>System.Windows.Forms</AssemblyName>
</PropertyGroup>
<ItemGroup>
<Reference Include="Accessibility">
<Name>Accessibility</Name>
</Reference>
<Reference Include="System">
<Name>System</Name>
</Reference>
<Reference Include="System.configuration" />
<Reference Include="System.Data">
<Name>System.Data</Name>
</Reference>
<Reference Include="System.Data">
<Name>System.Data</Name>
</Reference>
<Reference Include="System.Drawing">
<Name>System.Drawing</Name>
</Reference>
<Reference Include="System.Xml">
<Name>System.Xml</Name>
</Reference>
<Reference Include="Mono.WebBrowser2K5">
<Name>Mono.WebBrowser2K5</Name>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mono.WebBrowser\Mono.WebBrowser2K5.csproj">
<Project>{5E6C996A-007F-40CE-B244-006EFCFB77D2}</Project>
<Name>Mono.WebBrowser2K5</Name>
</ProjectReference>
</ItemGroup>
EOF
}
SWFtail()
{
cat <<EOF
<ItemGroup>
<None Include="System.Windows.Forms\ChangeLog" />
</ItemGroup>
<ItemGroup>
<None Include="ChangeLog" />
</ItemGroup>
<Import Project="\$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>
EOF
}
SWFfilelist()
{
echo " <ItemGroup>"
cat $Source | while read SRC; do
# Don't do AssemblyInfo, it's got signing requests and such that we don't want
if [ "x$SRC" != "xAssembly/AssemblyInfo.cs" ] ; then
SRC=`echo $SRC | sed 's/..\/..\/build\///'`
SRC=`echo $SRC | tr '/' '\\\\'`
cat <<EOF
<Compile Include="$SRC" />
EOF
fi
done
echo " </ItemGroup>"
}
SWFresourcelist()
{
echo " <ItemGroup>"
cat $Resource | while read SRC; do
CUSTOMTOOLNAMESPACE=""
# strip out that -resource:
SRC=`echo $SRC | sed 's/-resource://'`
CUSTOMTOOLNAMESPACE=`echo $SRC | awk -F, '{print $2}'`
INCLUDE=`echo $SRC | awk -F, '{print $1}'`
if test -f $INCLUDE.prebuilt; then
INCLUDE=$INCLUDE.prebuilt
fi
# strip off the path from the name of the resource and the .prebuilt if there is one
LOGICALNAME=`echo $INCLUDE | sed 's/resources\///;s/.prebuilt//'`
# convert all /'s to \\'s
INCLUDE=`echo $INCLUDE | sed 's/\//\\\\/'`
echo " <EmbeddedResource Include=\"$INCLUDE\">"
if test "x$CUSTOMTOOLNAMESPACE" != "x"; then
echo " <LogicalName>$CUSTOMTOOLNAMESPACE</LogicalName>"
else
echo " <LogicalName>$LOGICALNAME</LogicalName>"
fi
echo " </EmbeddedResource>"
done
echo " </ItemGroup>"
}
SWFhead
SWFfilelist
SWFresourcelist
SWFtail

View File

@ -78,43 +78,38 @@ namespace Microsoft.Build.BuildEngine {
if (propertyName != null) if (propertyName != null)
element.SetAttribute ("PropertyName", propertyName); element.SetAttribute ("PropertyName", propertyName);
} }
[MonoTODO]
public bool Execute () public bool Execute ()
{ {
bool result = false;
TaskEngine taskEngine; TaskEngine taskEngine;
LogTaskStarted (); LogTaskStarted ();
ITask task = null; ITask task;
try { try {
try { task = InitializeTask ();
task = InitializeTask (); } catch (Exception e) {
} catch (Exception e) { LogError ("Error initializing task {0}: {1}", taskElement.LocalName, e.Message);
LogError ("Error initializing task {0}: {1}", taskElement.LocalName, e.Message); LogMessage (MessageImportance.Low, "Error initializing task {0}: {1}",
LogMessage (MessageImportance.Low, "Error initializing task {0}: {1}", taskElement.LocalName, e.ToString ());
taskElement.LocalName, e.ToString ()); return false;
return false;
}
try {
taskEngine = new TaskEngine (parentTarget.Project);
taskEngine.Prepare (task, this.taskElement, GetParameters (), this.Type);
result = taskEngine.Execute ();
if (result)
taskEngine.PublishOutput ();
} catch (Exception e) {
task_logger.LogError ("Error executing task {0}: {1}", taskElement.LocalName, e.Message);
task_logger.LogMessage (MessageImportance.Low,
"Error executing task {0}: {1}", taskElement.LocalName, e.ToString ());
result = false;
}
} finally {
LogTaskFinished (result);
} }
return result; try {
taskEngine = new TaskEngine (parentTarget.Project, task, Type);
taskEngine.Prepare (GetParameters ());
var result = taskEngine.Execute ();
if (result)
taskEngine.PublishOutput (taskElement, taskEngine.ValueFromExecution);
LogTaskFinished (result);
return result;
} catch (Exception e) {
task_logger.LogError ("Error executing task {0}: {1}", taskElement.LocalName, e.Message);
task_logger.LogMessage (MessageImportance.Low,
"Error executing task {0}: {1}", taskElement.LocalName, e.ToString ());
return false;
}
} }
@ -140,6 +135,21 @@ namespace Microsoft.Build.BuildEngine {
return taskElement.GetAttribute (attributeName); return taskElement.GetAttribute (attributeName);
} }
bool IBuildTask.ResolveOutputItems ()
{
var taskEngine = new TaskEngine (parentTarget.Project, null, Type);
taskEngine.PublishOutput (taskElement, l => {
var pv = GetParameterValue (l.Name);
Expression exp = new Expression ();
exp.Parse (pv, ParseOptions.AllowItemsMetadataAndSplit);
return exp.ConvertTo (parentTarget.Project, l.PropertyType);
});
return true;
}
public void SetParameterValue (string parameterName, public void SetParameterValue (string parameterName,
string parameterValue) string parameterValue)

View File

@ -73,6 +73,11 @@ namespace Microsoft.Build.BuildEngine
foreach (XmlAttribute attrib in XmlElement.Attributes) foreach (XmlAttribute attrib in XmlElement.Attributes)
yield return attrib.Value; yield return attrib.Value;
} }
public bool ResolveOutputItems ()
{
return true;
}
} }
} }

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