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)); }
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 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 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.EmitBrtrue(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.EmitBrtrue(label); ilgen.EmitThrow("java.lang.NoSuchMethodError"); ilgen.MarkLabel(label); if (!isStatic) { ilgen.Emit(OpCodes.Pop); } ilgen.Emit(OpCodes.Ldloc, ilgen.DeclareLocal(type.TypeAsLocalOrStackType)); }
internal override void Emit(CodeEmitter ilgen, CodeEmitterLabel label) { ilgen.EmitBrtrue(label); }
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.EmitBrtrue(endLabel); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Ldnull); ilgen.MarkLabel(endLabel); } else { ilgen.Emit(OpCodes.Isinst, typeWrapper.TypeAsTBD); } } }
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); } } }