зеркало из https://github.com/mono/ikvm-fork.git
no message
This commit is contained in:
Родитель
c2845d2179
Коммит
e13321abc4
|
@ -32,6 +32,8 @@ using System.Diagnostics;
|
||||||
|
|
||||||
class ClassLoaderWrapper
|
class ClassLoaderWrapper
|
||||||
{
|
{
|
||||||
|
private delegate object LoadClassDelegate(object classLoader, string className);
|
||||||
|
private static LoadClassDelegate loadClassDelegate;
|
||||||
private static bool arrayConstructionHack;
|
private static bool arrayConstructionHack;
|
||||||
private static ArrayList ikvmAssemblies = new ArrayList();
|
private static ArrayList ikvmAssemblies = new ArrayList();
|
||||||
private static Hashtable assemblyToClassLoaderWrapper = new Hashtable();
|
private static Hashtable assemblyToClassLoaderWrapper = new Hashtable();
|
||||||
|
@ -42,7 +44,6 @@ class ClassLoaderWrapper
|
||||||
private static Hashtable typeToTypeWrapper = new Hashtable();
|
private static Hashtable typeToTypeWrapper = new Hashtable();
|
||||||
private static ClassLoaderWrapper bootstrapClassLoader;
|
private static ClassLoaderWrapper bootstrapClassLoader;
|
||||||
private object javaClassLoader;
|
private object javaClassLoader;
|
||||||
private MethodInfo loadClassMethod;
|
|
||||||
private Hashtable types = new Hashtable();
|
private Hashtable types = new Hashtable();
|
||||||
private Hashtable nativeMethods;
|
private Hashtable nativeMethods;
|
||||||
// HACK moduleBuilder is static, because multiple dynamic assemblies is broken (TypeResolve doesn't fire)
|
// HACK moduleBuilder is static, because multiple dynamic assemblies is broken (TypeResolve doesn't fire)
|
||||||
|
@ -117,13 +118,9 @@ class ClassLoaderWrapper
|
||||||
internal void SetJavaClassLoader(object javaClassLoader)
|
internal void SetJavaClassLoader(object javaClassLoader)
|
||||||
{
|
{
|
||||||
this.javaClassLoader = javaClassLoader;
|
this.javaClassLoader = javaClassLoader;
|
||||||
if(javaClassLoader != null)
|
if(javaClassLoader != null && loadClassDelegate == null)
|
||||||
{
|
{
|
||||||
loadClassMethod = javaClassLoader.GetType().GetMethod("loadClass", BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Standard, new Type[] { typeof(string) }, null);
|
loadClassDelegate = (LoadClassDelegate)Delegate.CreateDelegate(typeof(LoadClassDelegate), GetType("java.lang.Class"), "__loadClassHelper");
|
||||||
if(loadClassMethod == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,51 +246,29 @@ class ClassLoaderWrapper
|
||||||
throw JavaException.ClassNotFoundException(name);
|
throw JavaException.ClassNotFoundException(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// OPTIMIZE this should be optimized
|
// NOTE just like Java does (I think), we take the classloader lock before calling the loadClass method
|
||||||
try
|
lock(javaClassLoader)
|
||||||
{
|
{
|
||||||
object clazz;
|
Profiler.Enter("ClassLoader.loadClass");
|
||||||
// NOTE just like Java does (I think), we take the classloader lock before calling the loadClass method
|
try
|
||||||
lock(javaClassLoader)
|
|
||||||
{
|
{
|
||||||
Profiler.Enter("ClassLoader.loadClass");
|
type = (TypeWrapper)loadClassDelegate(javaClassLoader, name);
|
||||||
try
|
|
||||||
{
|
|
||||||
clazz = loadClassMethod.Invoke(javaClassLoader, new object[] { name });
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
Profiler.Leave("ClassLoader.loadClass");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
type = (TypeWrapper)clazz.GetType().GetField("wrapper", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(clazz);
|
finally
|
||||||
if(type == null)
|
|
||||||
{
|
{
|
||||||
Type t = (Type)clazz.GetType().GetField("type", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(clazz);
|
Profiler.Leave("ClassLoader.loadClass");
|
||||||
ClassLoaderWrapper loader = GetClassLoader(t);
|
|
||||||
type = (TypeWrapper)loader.types[name];
|
|
||||||
if(type == null)
|
|
||||||
{
|
|
||||||
// this shouldn't be possible
|
|
||||||
throw new InvalidOperationException(name + ", this = " + javaClassLoader);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// NOTE we're caching types loaded by parent classloaders as well!
|
|
||||||
// TODO not sure if this is correct
|
|
||||||
if(type.GetClassLoader() != this)
|
|
||||||
{
|
|
||||||
if(types[name] != type)
|
|
||||||
{
|
|
||||||
types.Add(name, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
}
|
||||||
catch(TargetInvocationException x)
|
// NOTE we're caching types loaded by parent classloaders as well!
|
||||||
|
// TODO not sure if this is correct
|
||||||
|
if(type.GetClassLoader() != this)
|
||||||
{
|
{
|
||||||
ExceptionHelper.MapExceptionFast(x);
|
if(types[name] != type)
|
||||||
throw x.InnerException;
|
{
|
||||||
|
types.Add(name, type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,9 @@ public class ExceptionHelper
|
||||||
private class ExceptionInfoHelper
|
private class ExceptionInfoHelper
|
||||||
{
|
{
|
||||||
private static readonly Exception CAUSE_NOT_SET = new Exception();
|
private static readonly Exception CAUSE_NOT_SET = new Exception();
|
||||||
private ArrayList stackTrace = new ArrayList();
|
private StackTrace tracePart1;
|
||||||
|
private StackTrace tracePart2;
|
||||||
|
private ArrayList stackTrace;
|
||||||
private Exception cause;
|
private Exception cause;
|
||||||
|
|
||||||
[StackTraceInfo(Hidden = true)]
|
[StackTraceInfo(Hidden = true)]
|
||||||
|
@ -48,13 +50,8 @@ public class ExceptionHelper
|
||||||
Profiler.Enter("new ExceptionInfoHelper");
|
Profiler.Enter("new ExceptionInfoHelper");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Append(new StackTrace(x, true));
|
tracePart1 = new StackTrace(x, true);
|
||||||
bool chopFirst = stackTrace.Count != 0;
|
tracePart2 = new StackTrace(true);
|
||||||
Append(new StackTrace(true));
|
|
||||||
if(chopFirst && stackTrace.Count > 0 && JVM.CleanStackTraces)
|
|
||||||
{
|
|
||||||
stackTrace.RemoveAt(0);
|
|
||||||
}
|
|
||||||
cause = x.InnerException;
|
cause = x.InnerException;
|
||||||
if(cause == null)
|
if(cause == null)
|
||||||
{
|
{
|
||||||
|
@ -88,8 +85,9 @@ public class ExceptionHelper
|
||||||
|
|
||||||
internal void ResetStackTrace()
|
internal void ResetStackTrace()
|
||||||
{
|
{
|
||||||
stackTrace.Clear();
|
stackTrace = null;
|
||||||
Append(new StackTrace(true));
|
tracePart1 = new StackTrace(true);
|
||||||
|
tracePart2 = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsPrivateScope(MethodBase mb)
|
private static bool IsPrivateScope(MethodBase mb)
|
||||||
|
@ -238,11 +236,29 @@ public class ExceptionHelper
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
if(stackTrace == null)
|
||||||
|
{
|
||||||
|
stackTrace = new ArrayList();
|
||||||
|
Append(tracePart1);
|
||||||
|
if(tracePart2 != null)
|
||||||
|
{
|
||||||
|
bool chopFirst = stackTrace.Count != 0;
|
||||||
|
Append(tracePart2);
|
||||||
|
if(chopFirst && stackTrace.Count > 0 && JVM.CleanStackTraces)
|
||||||
|
{
|
||||||
|
stackTrace.RemoveAt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tracePart1 = null;
|
||||||
|
tracePart2 = null;
|
||||||
|
}
|
||||||
return (StackTraceElement[])stackTrace.ToArray(typeof(StackTraceElement));
|
return (StackTraceElement[])stackTrace.ToArray(typeof(StackTraceElement));
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
stackTrace = new ArrayList(value);
|
stackTrace = new ArrayList(value);
|
||||||
|
tracePart1 = null;
|
||||||
|
tracePart2 = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -492,7 +508,7 @@ public class ExceptionHelper
|
||||||
{
|
{
|
||||||
t = (Exception)Activator.CreateInstance(ClassLoaderWrapper.GetType("java.lang.ArrayIndexOutOfBoundsException"));
|
t = (Exception)Activator.CreateInstance(ClassLoaderWrapper.GetType("java.lang.ArrayIndexOutOfBoundsException"));
|
||||||
}
|
}
|
||||||
// HACK for String methods, we remap ArgumentOutOfRangeException to StringIndexOutOfBoundsException
|
// HACK for String methods, we remap ArgumentOutOfRangeException to StringIndexOutOfBoundsException
|
||||||
else if(type == typeof(ArgumentOutOfRangeException))
|
else if(type == typeof(ArgumentOutOfRangeException))
|
||||||
{
|
{
|
||||||
t = (Exception)Activator.CreateInstance(ClassLoaderWrapper.GetType("java.lang.StringIndexOutOfBoundsException"));
|
t = (Exception)Activator.CreateInstance(ClassLoaderWrapper.GetType("java.lang.StringIndexOutOfBoundsException"));
|
||||||
|
@ -559,9 +575,17 @@ public class ExceptionHelper
|
||||||
}
|
}
|
||||||
else if(type.FullName.StartsWith("System.") && type != typeof(TargetInvocationException))
|
else if(type.FullName.StartsWith("System.") && type != typeof(TargetInvocationException))
|
||||||
{
|
{
|
||||||
// TODO this is just for debugging
|
if(handler != typeof(Exception) && handler.FullName.StartsWith("System."))
|
||||||
Console.WriteLine("caught: {0}, handler: {1}", t.GetType().FullName, handler.FullName);
|
{
|
||||||
Console.WriteLine(t);
|
// this is Java code explicitly handling a .NET exception (e.g. System.IO.IOException in java.io.FileDescriptor)
|
||||||
|
// so we don't need to print this
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO this is just for debugging
|
||||||
|
Console.WriteLine("caught: {0}, handler: {1}", t.GetType().FullName, handler.FullName);
|
||||||
|
Console.WriteLine(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(!exceptions.ContainsKey(t))
|
if(!exceptions.ContainsKey(t))
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
BaseAddress = "285212672"
|
BaseAddress = "285212672"
|
||||||
CheckForOverflowUnderflow = "false"
|
CheckForOverflowUnderflow = "false"
|
||||||
ConfigurationOverrideFile = ""
|
ConfigurationOverrideFile = ""
|
||||||
DefineConstants = "DEBUG;TRACE"
|
DefineConstants = "DEBUG;TRACE;PROFILE"
|
||||||
DocumentationFile = ""
|
DocumentationFile = ""
|
||||||
DebugSymbols = "true"
|
DebugSymbols = "true"
|
||||||
FileAlignment = "4096"
|
FileAlignment = "4096"
|
||||||
|
|
|
@ -278,6 +278,30 @@ public class StringHelper
|
||||||
// TODO
|
// TODO
|
||||||
return s.ToLower();
|
return s.ToLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int indexOf(string s, char ch, int fromIndex)
|
||||||
|
{
|
||||||
|
// Java allow fromIndex to both below zero or above the length of the string, .NET doesn't
|
||||||
|
return s.IndexOf(ch, Math.Max(0, Math.Min(s.Length, fromIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int indexOf(string s, string o, int fromIndex)
|
||||||
|
{
|
||||||
|
// Java allow fromIndex to both below zero or above the length of the string, .NET doesn't
|
||||||
|
return s.IndexOf(o, Math.Max(0, Math.Min(s.Length, fromIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int lastIndexOf(string s, char ch, int fromIndex)
|
||||||
|
{
|
||||||
|
// Java allow fromIndex to both below zero or above the length of the string, .NET doesn't
|
||||||
|
return s.LastIndexOf(ch, Math.Max(0, Math.Min(s.Length - 1, fromIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int lastIndexOf(string s, string o, int fromIndex)
|
||||||
|
{
|
||||||
|
// Java allow fromIndex to both below zero or above the length of the string, .NET doesn't
|
||||||
|
return s.LastIndexOf(o, Math.Max(0, Math.Min(s.Length - 1, fromIndex)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StringBufferHelper
|
public class StringBufferHelper
|
||||||
|
|
|
@ -717,7 +717,10 @@ class DynamicTypeWrapper : TypeWrapper
|
||||||
|
|
||||||
public override void Finish()
|
public override void Finish()
|
||||||
{
|
{
|
||||||
impl = impl.Finish();
|
lock(GetType())
|
||||||
|
{
|
||||||
|
impl = impl.Finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class DynamicImpl
|
private abstract class DynamicImpl
|
||||||
|
|
|
@ -451,7 +451,7 @@ namespace NativeCode.java
|
||||||
|
|
||||||
public static object execInternal(object obj, string[] cmd, string[] env, object dir)
|
public static object execInternal(object obj, string[] cmd, string[] env, object dir)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO this was moved to the Java class ikvm.lang.DotNetProcess
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -863,6 +863,11 @@ namespace NativeCode.java
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static object getWrapperFromType(Type t)
|
||||||
|
{
|
||||||
|
return ClassLoaderWrapper.GetWrapperFromType(t);
|
||||||
|
}
|
||||||
|
|
||||||
public static Type getType(object clazz)
|
public static Type getType(object clazz)
|
||||||
{
|
{
|
||||||
if(getTypeMethod == null)
|
if(getTypeMethod == null)
|
||||||
|
@ -1094,6 +1099,8 @@ namespace NativeCode.java
|
||||||
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
||||||
}
|
}
|
||||||
// we need to finish the type otherwise all methods will not be in the method map yet
|
// we need to finish the type otherwise all methods will not be in the method map yet
|
||||||
|
// TODO since this can be called from Java code while finishing is in progress (finishing triggers
|
||||||
|
// class loading, which runs Java code which might call this method), we shouldn't finish here
|
||||||
wrapper.Finish();
|
wrapper.Finish();
|
||||||
return wrapper.GetMethods();
|
return wrapper.GetMethods();
|
||||||
}
|
}
|
||||||
|
@ -1106,6 +1113,8 @@ namespace NativeCode.java
|
||||||
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
||||||
}
|
}
|
||||||
// we need to finish the type otherwise all fields will not be in the field map yet
|
// we need to finish the type otherwise all fields will not be in the field map yet
|
||||||
|
// TODO since this can be called from Java code while finishing is in progress (finishing triggers
|
||||||
|
// class loading, which runs Java code which might call this method), we shouldn't finish here
|
||||||
wrapper.Finish();
|
wrapper.Finish();
|
||||||
return wrapper.GetFields();
|
return wrapper.GetFields();
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,23 +177,26 @@
|
||||||
<redirect name="IndexOf" sig="(C)I" />
|
<redirect name="IndexOf" sig="(C)I" />
|
||||||
</method>
|
</method>
|
||||||
<method name="indexOf" sig="(II)I" modifiers="public">
|
<method name="indexOf" sig="(II)I" modifiers="public">
|
||||||
<redirect name="IndexOf" sig="(CI)I" />
|
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;CI)I" />
|
||||||
</method>
|
</method>
|
||||||
<method name="indexOf" sig="(Ljava/lang/String;)I" modifiers="public">
|
<method name="indexOf" sig="(Ljava/lang/String;)I" modifiers="public">
|
||||||
<redirect name="IndexOf" />
|
<redirect name="IndexOf" />
|
||||||
</method>
|
</method>
|
||||||
<method name="indexOf" sig="(Ljava/lang/String;I)I" modifiers="public">
|
<method name="indexOf" sig="(Ljava/lang/String;I)I" modifiers="public">
|
||||||
<redirect name="IndexOf" />
|
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;I)I" />
|
||||||
</method>
|
</method>
|
||||||
<method name="lastIndexOf" sig="(I)I" modifiers="public">
|
<method name="lastIndexOf" sig="(I)I" modifiers="public">
|
||||||
<redirect name="LastIndexOf" sig="(C)I" />
|
<redirect name="LastIndexOf" sig="(C)I" />
|
||||||
</method>
|
</method>
|
||||||
<method name="lastIndexOf" sig="(II)I" modifiers="public">
|
<method name="lastIndexOf" sig="(II)I" modifiers="public">
|
||||||
<redirect name="LastIndexOf" sig="(CI)I" />
|
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;CI)I" />
|
||||||
</method>
|
</method>
|
||||||
<method name="lastIndexOf" sig="(Ljava/lang/String;)I" modifiers="public">
|
<method name="lastIndexOf" sig="(Ljava/lang/String;)I" modifiers="public">
|
||||||
<redirect name="LastIndexOf" />
|
<redirect name="LastIndexOf" />
|
||||||
</method>
|
</method>
|
||||||
|
<method name="lastIndexOf" sig="(Ljava/lang/String;I)I" modifiers="public">
|
||||||
|
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;I)I" />
|
||||||
|
</method>
|
||||||
<method name="toCharArray" sig="()[C" modifiers="public">
|
<method name="toCharArray" sig="()[C" modifiers="public">
|
||||||
<redirect name="ToCharArray" />
|
<redirect name="ToCharArray" />
|
||||||
</method>
|
</method>
|
||||||
|
@ -452,5 +455,15 @@
|
||||||
<ret />
|
<ret />
|
||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
|
<class name="java.lang.Runtime">
|
||||||
|
<method name="execInternal" sig="([Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process;">
|
||||||
|
<ldarg_0 />
|
||||||
|
<ldarg_1 />
|
||||||
|
<ldarg_2 />
|
||||||
|
<ldarg_3 />
|
||||||
|
<call class="ikvm.lang.DotNetProcess" name="execInternal" />
|
||||||
|
<ret />
|
||||||
|
</method>
|
||||||
|
</class>
|
||||||
</nativeMethods>
|
</nativeMethods>
|
||||||
</root>
|
</root>
|
|
@ -54,11 +54,27 @@ namespace MapXml
|
||||||
{
|
{
|
||||||
string sig = Sig;
|
string sig = Sig;
|
||||||
Type[] argTypes = ClassLoaderWrapper.GetBootstrapClassLoader().ArgTypeListFromSig(sig);
|
Type[] argTypes = ClassLoaderWrapper.GetBootstrapClassLoader().ArgTypeListFromSig(sig);
|
||||||
|
// TODO use our own reflection, because the type might not have been finished
|
||||||
method = Type.GetType(Class, true).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, null);
|
method = Type.GetType(Class, true).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
method = Type.GetType(Class, true).GetMethod(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
if(Type.GetType(Class, true).Assembly is AssemblyBuilder)
|
||||||
|
{
|
||||||
|
MethodWrapper[] methods = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(Class).GetMethods();
|
||||||
|
for(int i = 0; i < methods.Length; i++)
|
||||||
|
{
|
||||||
|
if(methods[i].Name == name)
|
||||||
|
{
|
||||||
|
method = methods[i].GetMethod();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
method = Type.GetType(Class, true).GetMethod(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(method == null)
|
if(method == null)
|
||||||
{
|
{
|
||||||
|
@ -253,6 +269,30 @@ namespace MapXml
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[XmlType("ldarg_1")]
|
||||||
|
public sealed class LdArg_1 : Simple
|
||||||
|
{
|
||||||
|
public LdArg_1() : base(OpCodes.Ldarg_1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlType("ldarg_2")]
|
||||||
|
public sealed class LdArg_2 : Simple
|
||||||
|
{
|
||||||
|
public LdArg_2() : base(OpCodes.Ldarg_2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlType("ldarg_3")]
|
||||||
|
public sealed class LdArg_3 : Simple
|
||||||
|
{
|
||||||
|
public LdArg_3() : base(OpCodes.Ldarg_3)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[XmlType("ret")]
|
[XmlType("ret")]
|
||||||
public sealed class Ret : Simple
|
public sealed class Ret : Simple
|
||||||
{
|
{
|
||||||
|
@ -276,6 +316,9 @@ namespace MapXml
|
||||||
[XmlElement(typeof(StLoc))]
|
[XmlElement(typeof(StLoc))]
|
||||||
[XmlElement(typeof(LdLoc))]
|
[XmlElement(typeof(LdLoc))]
|
||||||
[XmlElement(typeof(LdArg_0))]
|
[XmlElement(typeof(LdArg_0))]
|
||||||
|
[XmlElement(typeof(LdArg_1))]
|
||||||
|
[XmlElement(typeof(LdArg_2))]
|
||||||
|
[XmlElement(typeof(LdArg_3))]
|
||||||
[XmlElement(typeof(Ret))]
|
[XmlElement(typeof(Ret))]
|
||||||
public Instruction[] invoke;
|
public Instruction[] invoke;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
C:\ikvm\classpath\ikvm\lang\DotNetProcess.java
|
||||||
C:\ikvm\classpath\gnu\classpath\Configuration.java
|
C:\ikvm\classpath\gnu\classpath\Configuration.java
|
||||||
C:\ikvm\classpath\gnu\java\net\protocol\ikvmres\Handler.java
|
C:\ikvm\classpath\gnu\java\net\protocol\ikvmres\Handler.java
|
||||||
C:\ikvm\classpath\java\io\FileDescriptor.java
|
C:\ikvm\classpath\java\io\FileDescriptor.java
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2002 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 ikvm.lang;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import system.text.StringBuilder;
|
||||||
|
import system.diagnostics.ProcessStartInfo;
|
||||||
|
|
||||||
|
public class DotNetProcess extends Process
|
||||||
|
{
|
||||||
|
private system.diagnostics.Process proc;
|
||||||
|
|
||||||
|
private DotNetProcess(system.diagnostics.Process proc)
|
||||||
|
{
|
||||||
|
this.proc = proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OutputStream getOutputStream()
|
||||||
|
{
|
||||||
|
return new java.io.FileOutputStream(new java.io.FileDescriptor(proc.get_StandardInput().get_BaseStream()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getInputStream()
|
||||||
|
{
|
||||||
|
return new java.io.FileInputStream(new java.io.FileDescriptor(proc.get_StandardOutput().get_BaseStream()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getErrorStream()
|
||||||
|
{
|
||||||
|
return new java.io.FileInputStream(new java.io.FileDescriptor(proc.get_StandardError().get_BaseStream()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int waitFor() throws InterruptedException
|
||||||
|
{
|
||||||
|
proc.WaitForExit();
|
||||||
|
return proc.get_ExitCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int exitValue()
|
||||||
|
{
|
||||||
|
if(proc.get_HasExited())
|
||||||
|
{
|
||||||
|
return proc.get_ExitCode();
|
||||||
|
}
|
||||||
|
throw new IllegalThreadStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(false) throw new system.InvalidOperationException();
|
||||||
|
proc.Kill();
|
||||||
|
}
|
||||||
|
catch(system.InvalidOperationException x)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Process execInternal(Runtime runtime, String[] cmd, String[] env, File dir)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for(int i = 1; i < cmd.length; i++)
|
||||||
|
{
|
||||||
|
if(i > 1)
|
||||||
|
{
|
||||||
|
sb.Append(' ');
|
||||||
|
}
|
||||||
|
// HACK if the arg contains a space, we surround it with quotes
|
||||||
|
// this isn't nearly good enough, but for now it'll have to do
|
||||||
|
if(cmd[i].indexOf(' ') >= 0)
|
||||||
|
{
|
||||||
|
sb.Append('"').Append(cmd[i]).Append('"');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Append(cmd[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ProcessStartInfo si = new ProcessStartInfo(cmd[0], sb.ToString());
|
||||||
|
si.set_UseShellExecute(false);
|
||||||
|
si.set_RedirectStandardError(true);
|
||||||
|
si.set_RedirectStandardOutput(true);
|
||||||
|
si.set_RedirectStandardInput(true);
|
||||||
|
si.set_CreateNoWindow(true);
|
||||||
|
if(dir != null)
|
||||||
|
{
|
||||||
|
si.set_WorkingDirectory(dir.toString());
|
||||||
|
}
|
||||||
|
if(env != null)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < env.length; i++)
|
||||||
|
{
|
||||||
|
int pos = env[i].indexOf('=');
|
||||||
|
si.get_EnvironmentVariables().Add(env[i].substring(0, pos), env[i].substring(pos + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO map the exceptions
|
||||||
|
return new DotNetProcess(system.diagnostics.Process.Start(si));
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче