private static void EmitClassLiteral(CompilerClassLoader ccl) { TypeBuilder tb = ccl.GetTypeWrapperFactory().ModuleBuilder.DefineType("ikvm.internal.ClassLiteral`1", TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.Class | TypeAttributes.BeforeFieldInit); GenericTypeParameterBuilder typeParam = tb.DefineGenericParameters("T")[0]; Type classType = CoreClasses.java.lang.Class.Wrapper.TypeAsSignatureType; classLiteralField = tb.DefineField("Value", classType, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly); CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineTypeInitializer(tb)); ilgen.Emit(OpCodes.Ldtoken, typeParam); ilgen.Emit(OpCodes.Call, Types.Type.GetMethod("GetTypeFromHandle", new Type[] { Types.RuntimeTypeHandle })); MethodWrapper mw = CoreClasses.java.lang.Class.Wrapper.GetMethodWrapper("<init>", "(Lcli.System.Type;)V", false); mw.Link(); mw.EmitNewobj(ilgen); ilgen.Emit(OpCodes.Stsfld, classLiteralField); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); classLiteralType = tb.CreateType(); }
internal RemapperTypeWrapper(CompilerClassLoader classLoader, IKVM.Internal.MapXml.Class c, IKVM.Internal.MapXml.Root map) : base((Modifiers)c.Modifiers, c.Name) { this.classLoader = classLoader; this.baseTypeWrapper = GetBaseWrapper(c); classDef = c; bool baseIsSealed = false; shadowType = StaticCompiler.Universe.GetType(c.Shadows, true); classLoader.SetRemappedType(shadowType, this); Type baseType = shadowType; Type baseInterface = null; if(baseType.IsInterface) { baseInterface = baseType; } TypeAttributes attrs = TypeAttributes.Public; if((c.Modifiers & IKVM.Internal.MapXml.MapModifiers.Interface) == 0) { attrs |= TypeAttributes.Class; if(baseType.IsSealed) { baseIsSealed = true; attrs |= TypeAttributes.Abstract | TypeAttributes.Sealed; } } else { attrs |= TypeAttributes.Interface | TypeAttributes.Abstract; baseType = null; } if((c.Modifiers & IKVM.Internal.MapXml.MapModifiers.Abstract) != 0) { attrs |= TypeAttributes.Abstract; } string name = c.Name.Replace('/', '.'); typeBuilder = classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(name, attrs, baseIsSealed ? Types.Object : baseType); if(c.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute custattr in c.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, typeBuilder, custattr); } } if(baseInterface != null) { typeBuilder.AddInterfaceImplementation(baseInterface); } if(classLoader.EmitStackTraceInfo) { AttributeHelper.SetSourceFile(typeBuilder, Path.GetFileName(classLoader.options.remapfile)); } if(baseIsSealed) { AttributeHelper.SetModifiers(typeBuilder, (Modifiers)c.Modifiers, false); } if(c.scope == IKVM.Internal.MapXml.Scope.Public) { // FXBUG we would like to emit an attribute with a Type argument here, but that doesn't work because // of a bug in SetCustomAttribute that causes type arguments to be serialized incorrectly (if the type // is in the same assembly). Normally we use AttributeHelper.FreezeDry to get around this, but that doesn't // work in this case (no attribute is emitted at all). So we work around by emitting a string instead AttributeHelper.SetRemappedClass(classLoader.assemblyBuilder, name, shadowType); AttributeHelper.SetRemappedType(typeBuilder, shadowType); } List<MethodWrapper> methods = new List<MethodWrapper>(); if(c.Constructors != null) { foreach(IKVM.Internal.MapXml.Constructor m in c.Constructors) { methods.Add(new RemappedConstructorWrapper(this, m)); } } if(c.Methods != null) { foreach(IKVM.Internal.MapXml.Method m in c.Methods) { methods.Add(new RemappedMethodWrapper(this, m, map, false)); } } // add methods from our super classes (e.g. Throwable should have Object's methods) if(!this.IsFinal && !this.IsInterface && this.BaseTypeWrapper != null) { foreach(MethodWrapper mw in BaseTypeWrapper.GetMethods()) { RemappedMethodWrapper rmw = mw as RemappedMethodWrapper; if(rmw != null && (rmw.IsPublic || rmw.IsProtected)) { if(!FindMethod(methods, rmw.Name, rmw.Signature)) { methods.Add(new RemappedMethodWrapper(this, rmw.XmlMethod, map, true)); } } } } SetMethods(methods.ToArray()); }
private static void CreateNoFail(CompilerClassLoader loader, TypeWrapper[] interfaces, List<ProxyMethod> methods) { DynamicClassLoader factory = (DynamicClassLoader)loader.GetTypeWrapperFactory(); TypeBuilder tb = factory.DefineProxy(proxyClass, interfaces); AttributeHelper.SetImplementsAttribute(tb, interfaces); CreateConstructor(tb); for (int i = 0; i < methods.Count; i++) { methods[i].fb = tb.DefineField("m" + i, javaLangReflectMethod.TypeAsSignatureType, FieldAttributes.Private | FieldAttributes.Static); } foreach (ProxyMethod method in methods) { CreateMethod(loader, tb, method); } CreateStaticInitializer(tb, methods); }
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.Emit_Ldc_I4(parameters.Length); ilgen.Emit(OpCodes.Newarr, Types.Object); for (int i = 0; i < parameters.Length; i++) { ilgen.Emit(OpCodes.Dup); ilgen.Emit_Ldc_I4(i); ilgen.Emit(OpCodes.Ldarg, (short)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.Emit(OpCodes.Leave, returnLabel); // TODO consider using a filter here (but we would need to add filter support to CodeEmitter) ilgen.BeginCatchBlock(Types.Exception); ilgen.Emit_Ldc_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(null, ilgen); ilgen.Emit(OpCodes.Brtrue, rethrow); ilgen.Emit(OpCodes.Ldloc, exception); runtimeExceptionClass.EmitInstanceOf(null, ilgen); ilgen.Emit(OpCodes.Brtrue, rethrow); foreach (TypeWrapper tw in pm.exceptions) { ilgen.Emit(OpCodes.Ldloc, exception); tw.EmitInstanceOf(null, ilgen); ilgen.Emit(OpCodes.Brtrue, 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(); }
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(); TypeBuilder tb = factory.DefineProxy(TypeNameUtil.GetProxyNestedName(interfaces), attr, proxyClass.TypeAsBaseType, interfaceTypes); 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); for (int i = 0; i < methods.Count; i++) { methods[i].fb = tb.DefineField("m" + i, javaLangReflectMethod.TypeAsSignatureType, FieldAttributes.Private | FieldAttributes.Static); } foreach (ProxyMethod method in methods) { CreateMethod(loader, tb, method); } CreateStaticInitializer(tb, methods, loader); }