diff --git a/ikvmc/AotTypeWrapper.cs b/ikvmc/AotTypeWrapper.cs index 2bf176ea..d7a2c836 100644 --- a/ikvmc/AotTypeWrapper.cs +++ b/ikvmc/AotTypeWrapper.cs @@ -135,7 +135,7 @@ namespace IKVM.Internal MethodBuilder mb = typeBuilder.DefineMethod(mw.Name, MethodAttributes.FamORAssem | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.CheckAccessOnOverride, mw.ReturnTypeForDefineMethod, mw.GetParametersForDefineMethod()); AttributeHelper.HideFromJava(mb); CodeEmitter ilgen = CodeEmitter.Create(mb); - EmitHelper.Throw(ilgen, "java.lang.AbstractMethodError"); + ilgen.EmitThrow("java.lang.AbstractMethodError"); } typeBuilder.CreateType(); } @@ -831,8 +831,8 @@ namespace IKVM.Internal ilgen.MarkLabel(label); } // we need to do a null check (null fails all the isinst checks) - EmitHelper.NullCheck(ilgen); - EmitHelper.Throw(ilgen, "java.lang.IncompatibleClassChangeError", Name); + ilgen.EmitNullCheck(); + ilgen.EmitThrow("java.lang.IncompatibleClassChangeError", Name); ilgen.MarkLabel(end); ilgen.Emit(OpCodes.Ret); } diff --git a/ikvmc/CompilerClassLoader.cs b/ikvmc/CompilerClassLoader.cs index 460b87d2..5d8e7054 100644 --- a/ikvmc/CompilerClassLoader.cs +++ b/ikvmc/CompilerClassLoader.cs @@ -1407,7 +1407,7 @@ namespace IKVM.Internal else if(!m.NoNullCheck) { ilgen.Emit(OpCodes.Ldarg_0); - EmitHelper.NullCheck(ilgen); + ilgen.EmitNullCheck(); } if(mbCore != null && (m.@override == null || m.redirect != null) && @@ -1967,7 +1967,7 @@ namespace IKVM.Internal } } ilgen.Emit(OpCodes.Ldarg_0); - EmitHelper.Castclass(ilgen, shadowType); + ilgen.EmitCastclass(shadowType); ilgen.Emit(OpCodes.Ret); if(hasfail) diff --git a/runtime/CodeEmitter.cs b/runtime/CodeEmitter.cs index f881ef7c..ca432fdd 100644 --- a/runtime/CodeEmitter.cs +++ b/runtime/CodeEmitter.cs @@ -66,8 +66,12 @@ namespace IKVM.Internal } } - class CodeEmitter + sealed class CodeEmitter { + private static readonly MethodInfo objectToString = typeof(object).GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); + private static readonly MethodInfo verboseCastFailure = JVM.SafeGetEnvironmentVariable("IKVM_VERBOSE_CAST") == null ? null : ByteCodeHelperMethods.VerboseCastFailure; + private static readonly MethodInfo getTypeHandle = typeof(Type).GetMethod("GetTypeHandle", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(object) }, null); + private static readonly MethodInfo get_Value = typeof(RuntimeTypeHandle).GetMethod("get_Value", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); private ILGenerator ilgen_real; #if !IKVM_REF_EMIT private int offset; @@ -648,6 +652,82 @@ namespace IKVM.Internal } #endif // STATIC_COMPILER + internal void EmitThrow(string dottedClassName) + { + TypeWrapper exception = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(dottedClassName); + MethodWrapper mw = exception.GetMethodWrapper("", "()V", false); + mw.Link(); + mw.EmitNewobj(this); + Emit(OpCodes.Throw); + } + + internal void EmitThrow(string dottedClassName, string message) + { + TypeWrapper exception = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(dottedClassName); + Emit(OpCodes.Ldstr, message); + MethodWrapper mw = exception.GetMethodWrapper("", "(Ljava.lang.String;)V", false); + mw.Link(); + mw.EmitNewobj(this); + Emit(OpCodes.Throw); + } + + internal void EmitNullCheck() + { + // I think this is the most efficient way to generate a NullReferenceException if the reference is null + Emit(OpCodes.Ldvirtftn, objectToString); + Emit(OpCodes.Pop); + } + + internal void EmitCastclass(Type type) + { + if (verboseCastFailure != null) + { + LocalBuilder lb = DeclareLocal(typeof(object)); + Emit(OpCodes.Stloc, lb); + Emit(OpCodes.Ldloc, lb); + Emit(OpCodes.Isinst, type); + Emit(OpCodes.Dup); + CodeEmitterLabel ok = DefineLabel(); + Emit(OpCodes.Brtrue_S, ok); + Emit(OpCodes.Ldloc, lb); + Emit(OpCodes.Brfalse_S, ok); // handle null + Emit(OpCodes.Ldtoken, type); + Emit(OpCodes.Ldloc, lb); + Emit(OpCodes.Call, verboseCastFailure); + MarkLabel(ok); + } + else + { + Emit(OpCodes.Castclass, type); + } + } + + // This is basically the same as Castclass, except that it + // throws an IncompatibleClassChangeError on failure. + internal void EmitAssertType(Type type) + { + LocalBuilder lb = DeclareLocal(typeof(object)); + Emit(OpCodes.Stloc, lb); + Emit(OpCodes.Ldloc, lb); + Emit(OpCodes.Isinst, type); + Emit(OpCodes.Dup); + CodeEmitterLabel ok = DefineLabel(); + Emit(OpCodes.Brtrue_S, ok); + Emit(OpCodes.Ldloc, lb); + Emit(OpCodes.Brfalse_S, ok); // handle null + EmitThrow("java.lang.IncompatibleClassChangeError"); + MarkLabel(ok); + } + + internal void EmitGetTypeHandleValue() + { + Emit(OpCodes.Call, getTypeHandle); + LocalBuilder local = DeclareLocal(typeof(RuntimeTypeHandle)); + Emit(OpCodes.Stloc, local); + Emit(OpCodes.Ldloca, local); + Emit(OpCodes.Call, get_Value); + } + internal void LazyEmitPop() { Expr exp = PeekStack(); diff --git a/runtime/MemberWrapper.cs b/runtime/MemberWrapper.cs index 53948110..971e8ed9 100644 --- a/runtime/MemberWrapper.cs +++ b/runtime/MemberWrapper.cs @@ -1644,7 +1644,7 @@ namespace IKVM.Internal CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.Emit(OpCodes.Brtrue_S, label); - EmitHelper.Throw(ilgen, "java.lang.NoSuchMethodError"); + ilgen.EmitThrow("java.lang.NoSuchMethodError"); ilgen.MarkLabel(label); if (!isStatic) { @@ -1686,7 +1686,7 @@ namespace IKVM.Internal CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.Emit(OpCodes.Brtrue_S, label); - EmitHelper.Throw(ilgen, "java.lang.NoSuchMethodError"); + ilgen.EmitThrow("java.lang.NoSuchMethodError"); ilgen.MarkLabel(label); ilgen.Emit(OpCodes.Pop); if (!isStatic) diff --git a/runtime/TypeWrapper.cs b/runtime/TypeWrapper.cs index 5e289ef6..701d5914 100644 --- a/runtime/TypeWrapper.cs +++ b/runtime/TypeWrapper.cs @@ -48,91 +48,6 @@ namespace IKVM.Internal } } - static class EmitHelper - { - private static MethodInfo objectToString = typeof(object).GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); - private static MethodInfo verboseCastFailure = JVM.SafeGetEnvironmentVariable("IKVM_VERBOSE_CAST") == null ? null : ByteCodeHelperMethods.VerboseCastFailure; - private static MethodInfo getTypeHandle = typeof(Type).GetMethod("GetTypeHandle", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(object) }, null); - private static MethodInfo get_Value = typeof(RuntimeTypeHandle).GetMethod("get_Value", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); - - internal static void Throw(CodeEmitter ilgen, string dottedClassName) - { - TypeWrapper exception = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(dottedClassName); - MethodWrapper mw = exception.GetMethodWrapper("", "()V", false); - mw.Link(); - mw.EmitNewobj(ilgen); - ilgen.Emit(OpCodes.Throw); - } - - internal static void Throw(CodeEmitter ilgen, string dottedClassName, string message) - { - TypeWrapper exception = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(dottedClassName); - ilgen.Emit(OpCodes.Ldstr, message); - MethodWrapper mw = exception.GetMethodWrapper("", "(Ljava.lang.String;)V", false); - mw.Link(); - mw.EmitNewobj(ilgen); - ilgen.Emit(OpCodes.Throw); - } - - internal static void NullCheck(CodeEmitter ilgen) - { - // I think this is the most efficient way to generate a NullReferenceException if the - // reference is null - ilgen.Emit(OpCodes.Ldvirtftn, objectToString); - ilgen.Emit(OpCodes.Pop); - } - - internal static void Castclass(CodeEmitter ilgen, Type type) - { - if(verboseCastFailure != null) - { - LocalBuilder lb = ilgen.DeclareLocal(typeof(object)); - ilgen.Emit(OpCodes.Stloc, lb); - ilgen.Emit(OpCodes.Ldloc, lb); - ilgen.Emit(OpCodes.Isinst, type); - ilgen.Emit(OpCodes.Dup); - CodeEmitterLabel ok = ilgen.DefineLabel(); - ilgen.Emit(OpCodes.Brtrue_S, ok); - ilgen.Emit(OpCodes.Ldloc, lb); - ilgen.Emit(OpCodes.Brfalse_S, ok); // handle null - ilgen.Emit(OpCodes.Ldtoken, type); - ilgen.Emit(OpCodes.Ldloc, lb); - ilgen.Emit(OpCodes.Call, verboseCastFailure); - ilgen.MarkLabel(ok); - } - else - { - ilgen.Emit(OpCodes.Castclass, type); - } - } - - // This is basically the same as Castclass, except that it - // throws an IncompatibleClassChangeError on failure. - internal static void EmitAssertType(CodeEmitter ilgen, Type type) - { - LocalBuilder lb = ilgen.DeclareLocal(typeof(object)); - ilgen.Emit(OpCodes.Stloc, lb); - ilgen.Emit(OpCodes.Ldloc, lb); - ilgen.Emit(OpCodes.Isinst, type); - ilgen.Emit(OpCodes.Dup); - CodeEmitterLabel ok = ilgen.DefineLabel(); - ilgen.Emit(OpCodes.Brtrue_S, ok); - ilgen.Emit(OpCodes.Ldloc, lb); - ilgen.Emit(OpCodes.Brfalse_S, ok); // handle null - EmitHelper.Throw(ilgen, "java.lang.IncompatibleClassChangeError"); - ilgen.MarkLabel(ok); - } - - internal static void GetTypeHandleValue(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, getTypeHandle); - LocalBuilder local = ilgen.DeclareLocal(typeof(RuntimeTypeHandle)); - ilgen.Emit(OpCodes.Stloc, local); - ilgen.Emit(OpCodes.Ldloca, local); - ilgen.Emit(OpCodes.Call, get_Value); - } - } - static class AttributeHelper { private static CustomAttributeBuilder hideFromJavaAttribute; @@ -3278,7 +3193,7 @@ namespace IKVM.Internal { MethodBuilder mb = typeBuilder.DefineMethod(mangledName, MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final, ifmethod.ReturnTypeForDefineMethod, ifmethod.GetParametersForDefineMethod()); AttributeHelper.HideFromJava(mb); - EmitHelper.Throw(CodeEmitter.Create(mb), "java.lang.LinkageError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature); + CodeEmitter.Create(mb).EmitThrow("java.lang.LinkageError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature); typeBuilder.DefineMethodOverride(mb, (MethodInfo)ifmethod.GetMethod()); return; } @@ -3295,7 +3210,7 @@ namespace IKVM.Internal // methods. Sigh! So I have to use private methods and mangle the name MethodBuilder mb = typeBuilder.DefineMethod(mangledName, MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final, ifmethod.ReturnTypeForDefineMethod, ifmethod.GetParametersForDefineMethod()); AttributeHelper.HideFromJava(mb); - EmitHelper.Throw(CodeEmitter.Create(mb), "java.lang.IllegalAccessError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature); + CodeEmitter.Create(mb).EmitThrow("java.lang.IllegalAccessError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature); typeBuilder.DefineMethodOverride(mb, (MethodInfo)ifmethod.GetMethod()); wrapper.HasIncompleteInterfaceImplementation = true; } @@ -3341,7 +3256,7 @@ namespace IKVM.Internal // so we have to create a stub method that throws an AbstractMethodError MethodBuilder mb = typeBuilder.DefineMethod(mangledName, MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final, ifmethod.ReturnTypeForDefineMethod, ifmethod.GetParametersForDefineMethod()); AttributeHelper.HideFromJava(mb); - EmitHelper.Throw(CodeEmitter.Create(mb), "java.lang.AbstractMethodError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature); + CodeEmitter.Create(mb).EmitThrow("java.lang.AbstractMethodError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature); typeBuilder.DefineMethodOverride(mb, (MethodInfo)ifmethod.GetMethod()); wrapper.HasIncompleteInterfaceImplementation = true; } @@ -3453,7 +3368,7 @@ namespace IKVM.Internal // for any interface reference else if(IsInterfaceOrInterfaceArray && (sourceType == null || sourceType.IsUnloadable || !sourceType.IsAssignableTo(this))) { - EmitHelper.EmitAssertType(ilgen, TypeAsTBD); + ilgen.EmitAssertType(TypeAsTBD); Profiler.Count("InterfaceDownCast"); } else if(IsNonPrimitiveValueType) @@ -3497,7 +3412,7 @@ namespace IKVM.Internal } else { - EmitHelper.Castclass(ilgen, TypeAsTBD); + ilgen.EmitCastclass(TypeAsTBD); } } @@ -6421,7 +6336,7 @@ namespace IKVM.Internal } else if(!wrapper.IsAbstract) { - EmitHelper.Throw(CodeEmitter.Create(mb), "java.lang.AbstractMethodError", wrapper.Name + "." + methods[index].Name + methods[index].Signature); + CodeEmitter.Create(mb).EmitThrow("java.lang.AbstractMethodError", wrapper.Name + "." + methods[index].Name + methods[index].Signature); } return mb; } @@ -7464,7 +7379,7 @@ namespace IKVM.Internal typeBuilder.DefineMethodOverride(mb, mi); } AttributeHelper.HideFromJava(mb); - EmitHelper.Throw(CodeEmitter.Create(mb), "java.lang.AbstractMethodError", mw.DeclaringType.Name + "." + mw.Name + mw.Signature); + CodeEmitter.Create(mb).EmitThrow("java.lang.AbstractMethodError", mw.DeclaringType.Name + "." + mw.Name + mw.Signature); } } } @@ -7524,7 +7439,7 @@ namespace IKVM.Internal { CodeEmitter ilGenerator = CodeEmitter.Create((MethodBuilder)mb); TraceHelper.EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature); - EmitHelper.Throw(ilGenerator, "java.lang.AbstractMethodError", classFile.Name + "." + m.Name + m.Signature); + ilGenerator.EmitThrow("java.lang.AbstractMethodError", classFile.Name + "." + m.Name + m.Signature); } } else if (m.IsNative) @@ -7609,7 +7524,7 @@ namespace IKVM.Internal { // since NoJniStubs can only be set when we're statically compiling, it is safe to use the "compiler" trace switch Tracer.Warning(Tracer.Compiler, "Native method not implemented: {0}.{1}.{2}", classFile.Name, m.Name, m.Signature); - EmitHelper.Throw(ilGenerator, "java.lang.UnsatisfiedLinkError", "Native method not implemented (compiled with -nojni): " + classFile.Name + "." + m.Name + m.Signature); + ilGenerator.EmitThrow("java.lang.UnsatisfiedLinkError", "Native method not implemented (compiled with -nojni): " + classFile.Name + "." + m.Name + m.Signature); } else { @@ -8480,7 +8395,7 @@ namespace IKVM.Internal } MethodAttributes attr = MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Private; MethodBuilder m = typeBuilder.DefineMethod("__" + mb.DeclaringType.FullName + "/" + mb.Name, attr, ((MethodInfo)mb).ReturnType, parameterTypes); - EmitHelper.Throw(CodeEmitter.Create(m), "java.lang.AbstractMethodError", "Method " + mb.DeclaringType.FullName + "." + mb.Name + " is unsupported by IKVM."); + CodeEmitter.Create(m).EmitThrow("java.lang.AbstractMethodError", "Method " + mb.DeclaringType.FullName + "." + mb.Name + " is unsupported by IKVM."); typeBuilder.DefineMethodOverride(m, (MethodInfo)mb); } @@ -12005,9 +11920,9 @@ namespace IKVM.Internal ilgen.Emit(OpCodes.Brtrue_S, label1); CodeEmitterLabel label2 = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Brfalse_S, label2); - EmitHelper.Throw(ilgen, "java.lang.CloneNotSupportedException"); + ilgen.EmitThrow("java.lang.CloneNotSupportedException"); ilgen.MarkLabel(label2); - EmitHelper.Throw(ilgen, "java.lang.NullPointerException"); + ilgen.EmitThrow("java.lang.NullPointerException"); ilgen.MarkLabel(label1); ilgen.Emit(OpCodes.Call, typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null)); } @@ -12661,7 +12576,7 @@ namespace IKVM.Internal return; } } - EmitHelper.Castclass(ilgen, type); + ilgen.EmitCastclass(type); } internal override void Finish() diff --git a/runtime/compiler.cs b/runtime/compiler.cs index 8499271b..f836562d 100644 --- a/runtime/compiler.cs +++ b/runtime/compiler.cs @@ -876,7 +876,7 @@ class Compiler clazz.HasVerifyError = true; // because in Java the method is only verified if it is actually called, // we generate code here to throw the VerificationError - EmitHelper.Throw(ilGenerator, "java.lang.VerifyError", x.Message); + ilGenerator.EmitThrow("java.lang.VerifyError", x.Message); return; } catch(ClassFormatError x) @@ -886,7 +886,7 @@ class Compiler #endif Tracer.Error(Tracer.Verifier, x.ToString()); clazz.HasClassFormatError = true; - EmitHelper.Throw(ilGenerator, "java.lang.ClassFormatError", x.Message); + ilGenerator.EmitThrow("java.lang.ClassFormatError", x.Message); return; } Profiler.Enter("Compile"); @@ -2961,8 +2961,8 @@ class Compiler break; case NormalizedByteCode.__intrinsic_gettypehandlevalue: ilGenerator.Emit(OpCodes.Dup); - EmitHelper.NullCheck(ilGenerator); - EmitHelper.GetTypeHandleValue(ilGenerator); + ilGenerator.EmitNullCheck(); + ilGenerator.EmitGetTypeHandleValue(); break; case NormalizedByteCode.__static_error: { @@ -3149,7 +3149,7 @@ class Compiler TypeWrapper tw = ma.GetStackTypeWrapper(instructionIndex, args.Length - 1 - i); if(tw.IsUnloadable || (args[i].IsInterfaceOrInterfaceArray && !tw.IsAssignableTo(args[i]))) { - EmitHelper.EmitAssertType(ilGenerator, args[i].TypeAsTBD); + ilGenerator.EmitAssertType(args[i].TypeAsTBD); Profiler.Count("InterfaceDownCast"); } } diff --git a/runtime/intrinsics.cs b/runtime/intrinsics.cs index f885c27b..027fa5c4 100644 --- a/runtime/intrinsics.cs +++ b/runtime/intrinsics.cs @@ -124,7 +124,7 @@ namespace IKVM.Internal if (code[opcodeIndex + 1].NormalizedOpCode == NormalizedByteCode.__pop) { ilgen.Emit(OpCodes.Dup); - EmitHelper.NullCheck(ilgen); + ilgen.EmitNullCheck(); return true; } // this optimizes obj1.getClass() ==/!= obj2.getClass() @@ -139,8 +139,8 @@ namespace IKVM.Internal { // we can't patch the current opcode, so we have to emit the first call to GetTypeHandle here ilgen.Emit(OpCodes.Dup); - EmitHelper.NullCheck(ilgen); - EmitHelper.GetTypeHandleValue(ilgen); + ilgen.EmitNullCheck(); + ilgen.EmitGetTypeHandleValue(); code[opcodeIndex + 2].PatchOpCode(NormalizedByteCode.__intrinsic_gettypehandlevalue); return true; } diff --git a/runtime/openjdk.cs b/runtime/openjdk.cs index f239c043..faa4e799 100644 --- a/runtime/openjdk.cs +++ b/runtime/openjdk.cs @@ -5859,7 +5859,7 @@ namespace IKVM.NativeCode.sun.reflect { // check target for null ilgen.Emit(OpCodes.Ldarg_0); - EmitHelper.NullCheck(ilgen); + ilgen.EmitNullCheck(); } // check args length @@ -5874,7 +5874,7 @@ namespace IKVM.NativeCode.sun.reflect ilgen.Emit(OpCodes.Ldlen); ilgen.Emit(OpCodes.Ldc_I4, mw.GetParameters().Length); ilgen.Emit(OpCodes.Beq_S, argsLengthOK); - EmitHelper.Throw(ilgen, "java.lang.IllegalArgumentException"); + ilgen.EmitThrow("java.lang.IllegalArgumentException"); ilgen.MarkLabel(argsLengthOK); int thisCount = mw.IsStatic ? 0 : 1; @@ -5907,9 +5907,9 @@ namespace IKVM.NativeCode.sun.reflect ilgen.Emit(OpCodes.Stloc, args[i]); } ilgen.BeginCatchBlock(typeof(InvalidCastException)); - EmitHelper.Throw(ilgen, "java.lang.IllegalArgumentException"); + ilgen.EmitThrow("java.lang.IllegalArgumentException"); ilgen.BeginCatchBlock(typeof(NullReferenceException)); - EmitHelper.Throw(ilgen, "java.lang.IllegalArgumentException"); + ilgen.EmitThrow("java.lang.IllegalArgumentException"); ilgen.EndExceptionBlock(); // this is the actual call @@ -6188,7 +6188,7 @@ namespace IKVM.NativeCode.sun.reflect ilgen.Emit(OpCodes.Ldlen); ilgen.Emit(OpCodes.Ldc_I4, mw.GetParameters().Length); ilgen.Emit(OpCodes.Beq_S, argsLengthOK); - EmitHelper.Throw(ilgen, "java.lang.IllegalArgumentException"); + ilgen.EmitThrow("java.lang.IllegalArgumentException"); ilgen.MarkLabel(argsLengthOK); LocalBuilder[] args = new LocalBuilder[mw.GetParameters().Length]; @@ -6209,9 +6209,9 @@ namespace IKVM.NativeCode.sun.reflect ilgen.Emit(OpCodes.Stloc, args[i]); } ilgen.BeginCatchBlock(typeof(InvalidCastException)); - EmitHelper.Throw(ilgen, "java.lang.IllegalArgumentException"); + ilgen.EmitThrow("java.lang.IllegalArgumentException"); ilgen.BeginCatchBlock(typeof(NullReferenceException)); - EmitHelper.Throw(ilgen, "java.lang.IllegalArgumentException"); + ilgen.EmitThrow("java.lang.IllegalArgumentException"); ilgen.EndExceptionBlock(); // this is the actual call