private static void AddReadResolve(DynamicTypeWrapper wrapper, TypeBuilder tb) { MethodWrapper mw = wrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", false); if (mw != null && !wrapper.IsSubTypeOf(iobjectreference)) { tb.AddInterfaceImplementation(JVM.Import(typeof(IObjectReference))); MethodBuilder getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final, Types.Object, new Type[] { JVM.Import(typeof(StreamingContext)) }); getRealObject.SetCustomAttribute(securityCriticalAttribute); AttributeHelper.HideFromJava(getRealObject); tb.DefineMethodOverride(getRealObject, JVM.Import(typeof(IObjectReference)).GetMethod("GetRealObject")); CodeEmitter ilgen = CodeEmitter.Create(getRealObject); mw.Link(); if (!wrapper.IsFinal) { // readResolve is only applicable if it exists on the actual type of the object, so if we're a subclass don't call it ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Callvirt, Compiler.getTypeMethod); ilgen.Emit(OpCodes.Ldtoken, wrapper.TypeAsBaseType); ilgen.Emit(OpCodes.Call, Compiler.getTypeFromHandleMethod); CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Beq_S, label); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ret); ilgen.MarkLabel(label); } ilgen.Emit(OpCodes.Ldarg_0); mw.EmitCall(ilgen); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } }
private static void CreateStaticInitializer(TypeBuilder tb, List <ProxyMethod> methods) { ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes); CodeEmitter ilgen = CodeEmitter.Create(cb); CodeEmitterLocal callerID = ilgen.DeclareLocal([email protected]); TypeBuilder tbCallerID = DynamicTypeWrapper.FinishContext.EmitCreateCallerID(tb, ilgen); ilgen.Emit(OpCodes.Stloc, callerID); // HACK we shouldn't create the nested type here (the outer type must be created first) tbCallerID.CreateType(); ilgen.BeginExceptionBlock(); foreach (ProxyMethod method in methods) { method.mw.DeclaringType.EmitClassLiteral(ilgen); ilgen.Emit(OpCodes.Ldstr, method.mw.Name); TypeWrapper[] parameters = method.mw.GetParameters(); ilgen.Emit(OpCodes.Ldc_I4, parameters.Length); ilgen.Emit(OpCodes.Newarr, CoreClasses.java.lang.Class.Wrapper.TypeAsArrayType); for (int i = 0; i < parameters.Length; i++) { ilgen.Emit(OpCodes.Dup); ilgen.Emit(OpCodes.Ldc_I4, i); parameters[i].EmitClassLiteral(ilgen); ilgen.Emit(OpCodes.Stelem_Ref); } if (javaLangClass_getMethod.HasCallerID) { ilgen.Emit(OpCodes.Ldloc, callerID); } javaLangClass_getMethod.EmitCallvirt(ilgen); ilgen.Emit(OpCodes.Stsfld, method.fb); } CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Leave_S, label); ilgen.BeginCatchBlock(javaLangNoSuchMethodException.TypeAsExceptionType); javaLangThrowable_getMessage.EmitCallvirt(ilgen); javaLangNoClassDefFoundErrorConstructor.EmitNewobj(ilgen); ilgen.Emit(OpCodes.Throw); ilgen.EndExceptionBlock(); ilgen.MarkLabel(label); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); }
internal static void EmitThrowNoSuchMethodErrorForSetter(CodeEmitter ilgen, bool isStatic) { // HACK the branch around the throw is to keep the verifier happy CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.Emit(OpCodes.Brtrue_S, label); ilgen.EmitThrow("java.lang.NoSuchMethodError"); ilgen.MarkLabel(label); ilgen.Emit(OpCodes.Pop); if (!isStatic) { ilgen.Emit(OpCodes.Pop); } }
internal static void EmitThrowNoSuchMethodErrorForGetter(CodeEmitter ilgen, TypeWrapper type, bool isStatic) { // HACK the branch around the throw is to keep the verifier happy CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.Emit(OpCodes.Brtrue_S, label); ilgen.EmitThrow("java.lang.NoSuchMethodError"); ilgen.MarkLabel(label); if (!isStatic) { ilgen.Emit(OpCodes.Pop); } ilgen.Emit(OpCodes.Ldloc, ilgen.DeclareLocal(type.TypeAsLocalOrStackType)); }
internal void Emit(IKVM.Internal.MapXml.CodeGenContext context, CodeEmitter ilgen) { MethodWrapper mwSuppressFillInStackTrace = CoreClasses.java.lang.Throwable.Wrapper.GetMethodWrapper("__<suppressFillInStackTrace>", "()V", false); mwSuppressFillInStackTrace.Link(); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Callvirt, Compiler.getTypeMethod); for(int i = 0; i < map.Length; i++) { ilgen.Emit(OpCodes.Dup); ilgen.Emit(OpCodes.Ldtoken, StaticCompiler.Universe.GetType(map[i].src, true)); ilgen.Emit(OpCodes.Call, Compiler.getTypeFromHandleMethod); ilgen.Emit(OpCodes.Ceq); CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Brfalse_S, label); ilgen.Emit(OpCodes.Pop); if(map[i].code != null) { ilgen.Emit(OpCodes.Ldarg_0); if(map[i].code.invoke != null) { foreach(MapXml.Instruction instr in map[i].code.invoke) { MapXml.NewObj newobj = instr as MapXml.NewObj; if(newobj != null && newobj.Class != null && context.ClassLoader.LoadClassByDottedName(newobj.Class).IsSubTypeOf(CoreClasses.java.lang.Throwable.Wrapper)) { mwSuppressFillInStackTrace.EmitCall(ilgen); } instr.Generate(context, ilgen); } } ilgen.Emit(OpCodes.Ret); } else { TypeWrapper tw = context.ClassLoader.LoadClassByDottedName(map[i].dst); MethodWrapper mw = tw.GetMethodWrapper("<init>", "()V", false); mw.Link(); mwSuppressFillInStackTrace.EmitCall(ilgen); mw.EmitNewobj(ilgen); ilgen.Emit(OpCodes.Ret); } ilgen.MarkLabel(label); } ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ret); }
internal override void EmitCall(CodeEmitter ilgen) { ilgen.Emit(OpCodes.Dup); ilgen.Emit(OpCodes.Isinst, CoreClasses.java.lang.Cloneable.Wrapper.TypeAsBaseType); CodeEmitterLabel label1 = ilgen.DefineLabel(); ilgen.EmitBrtrue(label1); CodeEmitterLabel label2 = ilgen.DefineLabel(); ilgen.EmitBrfalse(label2); ilgen.EmitThrow("java.lang.CloneNotSupportedException"); ilgen.MarkLabel(label2); ilgen.EmitThrow("java.lang.NullPointerException"); ilgen.MarkLabel(label1); ilgen.Emit(OpCodes.Call, Types.Object.GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null)); }
internal static void EmitThrowNoSuchMethodErrorForSetter(CodeEmitter ilgen, MemberWrapper member) { #if STATIC_COMPILER StaticCompiler.IssueMessage(Message.EmittedNoSuchMethodError, "<unknown>", member.DeclaringType.Name + "." + member.Name + member.Signature); #endif // HACK the branch around the throw is to keep the verifier happy CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.EmitBrtrue(label); ilgen.EmitThrow("java.lang.NoSuchMethodError"); ilgen.MarkLabel(label); ilgen.Emit(OpCodes.Pop); if (!member.IsStatic) { ilgen.Emit(OpCodes.Pop); } }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { CodeEmitterLabel l; if(context[Name] == null) { l = ilgen.DefineLabel(); context[Name] = l; } else { l = (CodeEmitterLabel)context[Name]; } ilgen.MarkLabel(l); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { base.Generate(context, ilgen); if(typeType != null) { ilgen.Emit(OpCodes.Isinst, typeType); } else { if(typeWrapper.IsGhost || typeWrapper.IsGhostArray) { ilgen.Emit(OpCodes.Dup); // NOTE we pass a null context, but that shouldn't be a problem, because // typeWrapper should never be an UnloadableTypeWrapper typeWrapper.EmitInstanceOf(null, ilgen); CodeEmitterLabel endLabel = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Brtrue_S, endLabel); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Ldnull); ilgen.MarkLabel(endLabel); } else { ilgen.Emit(OpCodes.Isinst, typeWrapper.TypeAsTBD); } } }
private static void CreateMethod(CompilerClassLoader loader, TypeBuilder tb, ProxyMethod pm) { MethodBuilder mb = pm.mw.GetDefineMethodHelper().DefineMethod(loader.GetTypeWrapperFactory(), tb, pm.mw.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final); List <string> exceptions = new List <string>(); foreach (TypeWrapper tw in pm.exceptions) { exceptions.Add(tw.Name); } AttributeHelper.SetThrowsAttribute(mb, exceptions.ToArray()); CodeEmitter ilgen = CodeEmitter.Create(mb); ilgen.BeginExceptionBlock(); ilgen.Emit(OpCodes.Ldarg_0); invocationHandlerField.EmitGet(ilgen); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldsfld, pm.fb); TypeWrapper[] parameters = pm.mw.GetParameters(); if (parameters.Length == 0) { ilgen.Emit(OpCodes.Ldnull); } else { ilgen.EmitLdc_I4(parameters.Length); ilgen.Emit(OpCodes.Newarr, Types.Object); for (int i = 0; i < parameters.Length; i++) { ilgen.Emit(OpCodes.Dup); ilgen.EmitLdc_I4(i); ilgen.EmitLdarg(i); if (parameters[i].IsNonPrimitiveValueType) { parameters[i].EmitBox(ilgen); } else if (parameters[i].IsPrimitive) { Boxer.EmitBox(ilgen, parameters[i]); } ilgen.Emit(OpCodes.Stelem_Ref); } } invokeMethod.EmitCallvirt(ilgen); TypeWrapper returnType = pm.mw.ReturnType; CodeEmitterLocal returnValue = null; if (returnType != PrimitiveTypeWrapper.VOID) { returnValue = ilgen.DeclareLocal(returnType.TypeAsSignatureType); if (returnType.IsNonPrimitiveValueType) { returnType.EmitUnbox(ilgen); } else if (returnType.IsPrimitive) { Boxer.EmitUnbox(ilgen, returnType); } else if (returnType != CoreClasses.java.lang.Object.Wrapper) { ilgen.EmitCastclass(returnType.TypeAsSignatureType); } ilgen.Emit(OpCodes.Stloc, returnValue); } CodeEmitterLabel returnLabel = ilgen.DefineLabel(); ilgen.EmitLeave(returnLabel); // TODO consider using a filter here (but we would need to add filter support to CodeEmitter) ilgen.BeginCatchBlock(Types.Exception); ilgen.EmitLdc_I4(0); ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.mapException.MakeGenericMethod(Types.Exception)); CodeEmitterLocal exception = ilgen.DeclareLocal(Types.Exception); ilgen.Emit(OpCodes.Stloc, exception); CodeEmitterLabel rethrow = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldloc, exception); errorClass.EmitInstanceOf(ilgen); ilgen.EmitBrtrue(rethrow); ilgen.Emit(OpCodes.Ldloc, exception); runtimeExceptionClass.EmitInstanceOf(ilgen); ilgen.EmitBrtrue(rethrow); foreach (TypeWrapper tw in pm.exceptions) { ilgen.Emit(OpCodes.Ldloc, exception); tw.EmitInstanceOf(ilgen); ilgen.EmitBrtrue(rethrow); } ilgen.Emit(OpCodes.Ldloc, exception); undeclaredThrowableExceptionConstructor.EmitNewobj(ilgen); ilgen.Emit(OpCodes.Throw); ilgen.MarkLabel(rethrow); ilgen.Emit(OpCodes.Rethrow); ilgen.EndExceptionBlock(); ilgen.MarkLabel(returnLabel); if (returnValue != null) { ilgen.Emit(OpCodes.Ldloc, returnValue); } ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { base.Generate(context, ilgen); if(typeType != null) { ilgen.Emit(OpCodes.Isinst, typeType); } else { if(typeWrapper.IsGhost || typeWrapper.IsGhostArray) { ilgen.Emit(OpCodes.Dup); typeWrapper.EmitInstanceOf(ilgen); CodeEmitterLabel endLabel = ilgen.DefineLabel(); ilgen.EmitBrtrue(endLabel); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Ldnull); ilgen.MarkLabel(endLabel); } else { ilgen.Emit(OpCodes.Isinst, typeWrapper.TypeAsTBD); } } }