internal EventBuilder(TypeBuilder typeBuilder, string name, EventAttributes attributes, Type eventtype) { this.typeBuilder = typeBuilder; this.name = name; this.attributes = attributes; this.eventtype = typeBuilder.ModuleBuilder.GetTypeTokenForMemberRef(eventtype); }
internal PropertyBuilder(TypeBuilder typeBuilder, string name, PropertyAttributes attributes, PropertySignature sig, bool patchCallingConvention) { this.typeBuilder = typeBuilder; this.name = name; this.attributes = attributes; this.sig = sig; this.patchCallingConvention = patchCallingConvention; }
internal MethodBuilder(TypeBuilder typeBuilder, string name, MethodAttributes attributes, CallingConventions callingConvention) { this.typeBuilder = typeBuilder; this.name = name; this.pseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken(); this.attributes = attributes; if ((attributes & MethodAttributes.Static) == 0) { callingConvention |= CallingConventions.HasThis; } this.callingConvention = callingConvention; }
internal FieldBuilder(TypeBuilder type, string name, Type fieldType, CustomModifiers customModifiers, FieldAttributes attribs) { this.typeBuilder = type; this.name = name; this.pseudoToken = type.ModuleBuilder.AllocPseudoToken(); this.nameIndex = type.ModuleBuilder.Strings.Add(name); this.fieldSig = FieldSignature.Create(fieldType, customModifiers); ByteBuffer sig = new ByteBuffer(5); fieldSig.WriteSig(this.typeBuilder.ModuleBuilder, sig); this.signature = this.typeBuilder.ModuleBuilder.Blobs.Add(sig); this.attribs = attribs; this.typeBuilder.ModuleBuilder.Field.AddVirtualRecord(); }
internal GenericTypeParameterBuilder(string name, TypeBuilder type, MethodBuilder method, int position) { this.name = name; this.type = type; this.method = method; this.position = position; GenericParamTable.Record rec = new GenericParamTable.Record(); rec.Number = (short)position; rec.Flags = 0; rec.Owner = type != null ? type.MetadataToken : method.MetadataToken; rec.Name = this.ModuleBuilder.Strings.Add(name); this.paramPseudoIndex = this.ModuleBuilder.GenericParam.AddRecord(rec); }
internal MethodBuilder(TypeBuilder typeBuilder, string name, MethodAttributes attributes, CallingConventions callingConvention) { this.typeBuilder = typeBuilder; this.name = name; this.pseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken(); // because all the MethodBuilders constitute a virtual MethodDef table, we cannot allocate the string during WriteMethodDefRecord, // since by then the metadata has already been frozen this.nameIndex = typeBuilder.ModuleBuilder.Strings.Add(name); this.attributes = attributes; if ((attributes & MethodAttributes.Static) == 0) { callingConvention |= CallingConventions.HasThis; } this.callingConvention = callingConvention; }
protected override MethodBuilder DefineGhostMethod(TypeBuilder typeBuilder, string name, MethodAttributes attribs, MethodWrapper mw) { if(typeBuilderGhostInterface != null && mw.IsVirtual) { DefineMethodHelper helper = mw.GetDefineMethodHelper(); MethodBuilder stub = helper.DefineMethod(this, typeBuilder, name, MethodAttributes.Public); ((GhostMethodWrapper)mw).SetGhostMethod(stub); return helper.DefineMethod(this, typeBuilderGhostInterface, name, attribs); } return null; }
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()); }
protected override void FinishGhost(TypeBuilder typeBuilder, MethodWrapper[] methods) { if(typeBuilderGhostInterface != null) { // TODO consider adding methods from base interface and java.lang.Object as well for(int i = 0; i < methods.Length; i++) { // skip <clinit> if(!methods[i].IsStatic) { TypeWrapper[] args = methods[i].GetParameters(); MethodBuilder stub = methods[i].GetDefineMethodHelper().DefineMethod(this, typeBuilder, methods[i].Name, MethodAttributes.Public); AddParameterMetadata(stub, methods[i]); AttributeHelper.SetModifiers(stub, methods[i].Modifiers, methods[i].IsInternal); CodeEmitter ilgen = CodeEmitter.Create(stub); CodeEmitterLabel end = ilgen.DefineLabel(); TypeWrapper[] implementers = classLoader.GetGhostImplementers(this); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldfld, ghostRefField); ilgen.Emit(OpCodes.Dup); ilgen.Emit(OpCodes.Isinst, typeBuilderGhostInterface); CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.EmitBrfalse(label); ilgen.Emit(OpCodes.Castclass, typeBuilderGhostInterface); for(int k = 0; k < args.Length; k++) { ilgen.EmitLdarg(k + 1); } ilgen.Emit(OpCodes.Callvirt, (MethodInfo)methods[i].GetMethod()); ilgen.EmitBr(end); ilgen.MarkLabel(label); for(int j = 0; j < implementers.Length; j++) { ilgen.Emit(OpCodes.Dup); ilgen.Emit(OpCodes.Isinst, implementers[j].TypeAsTBD); label = ilgen.DefineLabel(); ilgen.EmitBrfalse(label); ilgen.Emit(OpCodes.Castclass, implementers[j].TypeAsTBD); for(int k = 0; k < args.Length; k++) { ilgen.EmitLdarg(k + 1); } MethodWrapper mw = implementers[j].GetMethodWrapper(methods[i].Name, methods[i].Signature, true); mw.EmitCallvirt(ilgen); ilgen.EmitBr(end); ilgen.MarkLabel(label); } // we need to do a null check (null fails all the isinst checks) ilgen.EmitNullCheck(); ilgen.EmitThrow("java.lang.IncompatibleClassChangeError", Name); ilgen.MarkLabel(end); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } } // HACK create a scope to enable reuse of "implementers" name if(true) { MethodBuilder mb; CodeEmitter ilgen; CodeEmitterLocal local; // add implicit conversions for all the ghost implementers TypeWrapper[] implementers = classLoader.GetGhostImplementers(this); for(int i = 0; i < implementers.Length; i++) { mb = typeBuilder.DefineMethod("op_Implicit", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, TypeAsSignatureType, new Type[] { implementers[i].TypeAsSignatureType }); AttributeHelper.HideFromJava(mb); ilgen = CodeEmitter.Create(mb); local = ilgen.DeclareLocal(TypeAsSignatureType); ilgen.Emit(OpCodes.Ldloca, local); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Stfld, ghostRefField); ilgen.Emit(OpCodes.Ldloca, local); ilgen.Emit(OpCodes.Ldobj, TypeAsSignatureType); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } // Implement the "IsInstance" method mb = ghostIsInstanceMethod; AttributeHelper.HideFromJava(mb); ilgen = CodeEmitter.Create(mb); CodeEmitterLabel end = ilgen.DefineLabel(); for(int i = 0; i < implementers.Length; i++) { ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Isinst, implementers[i].TypeAsTBD); CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.EmitBrfalse(label); ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.EmitBr(end); ilgen.MarkLabel(label); } ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Isinst, typeBuilderGhostInterface); ilgen.Emit(OpCodes.Ldnull); ilgen.Emit(OpCodes.Cgt_Un); ilgen.MarkLabel(end); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // Implement the "IsInstanceArray" method mb = ghostIsInstanceArrayMethod; AttributeHelper.HideFromJava(mb); ilgen = CodeEmitter.Create(mb); CodeEmitterLocal localType = ilgen.DeclareLocal(Types.Type); CodeEmitterLocal localRank = ilgen.DeclareLocal(Types.Int32); ilgen.Emit(OpCodes.Ldarg_0); CodeEmitterLabel skip = ilgen.DefineLabel(); ilgen.EmitBrtrue(skip); ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.Emit(OpCodes.Ret); ilgen.MarkLabel(skip); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Call, Compiler.getTypeMethod); ilgen.Emit(OpCodes.Stloc, localType); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Stloc, localRank); skip = ilgen.DefineLabel(); ilgen.EmitBr(skip); CodeEmitterLabel iter = ilgen.DefineLabel(); ilgen.MarkLabel(iter); ilgen.Emit(OpCodes.Ldloc, localType); ilgen.Emit(OpCodes.Callvirt, Types.Type.GetMethod("GetElementType")); ilgen.Emit(OpCodes.Stloc, localType); ilgen.Emit(OpCodes.Ldloc, localRank); ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Sub); ilgen.Emit(OpCodes.Stloc, localRank); ilgen.Emit(OpCodes.Ldloc, localRank); CodeEmitterLabel typecheck = ilgen.DefineLabel(); ilgen.EmitBrfalse(typecheck); ilgen.MarkLabel(skip); ilgen.Emit(OpCodes.Ldloc, localType); ilgen.Emit(OpCodes.Callvirt, Types.Type.GetMethod("get_IsArray")); ilgen.EmitBrtrue(iter); ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.Emit(OpCodes.Ret); ilgen.MarkLabel(typecheck); for(int i = 0; i < implementers.Length; i++) { ilgen.Emit(OpCodes.Ldtoken, implementers[i].TypeAsTBD); ilgen.Emit(OpCodes.Call, Types.Type.GetMethod("GetTypeFromHandle")); ilgen.Emit(OpCodes.Ldloc, localType); ilgen.Emit(OpCodes.Callvirt, Types.Type.GetMethod("IsAssignableFrom")); CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.EmitBrfalse(label); ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Ret); ilgen.MarkLabel(label); } ilgen.Emit(OpCodes.Ldtoken, typeBuilderGhostInterface); ilgen.Emit(OpCodes.Call, Types.Type.GetMethod("GetTypeFromHandle")); ilgen.Emit(OpCodes.Ldloc, localType); ilgen.Emit(OpCodes.Callvirt, Types.Type.GetMethod("IsAssignableFrom")); skip = ilgen.DefineLabel(); ilgen.EmitBrfalse(skip); ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Ret); ilgen.MarkLabel(skip); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldtoken, typeBuilder); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Call, StaticCompiler.GetRuntimeType("IKVM.Runtime.GhostTag").GetMethod("IsGhostArrayInstance", BindingFlags.NonPublic | BindingFlags.Static)); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // Implement the "Cast" method mb = ghostCastMethod; AttributeHelper.HideFromJava(mb); ilgen = CodeEmitter.Create(mb); end = ilgen.DefineLabel(); for(int i = 0; i < implementers.Length; i++) { ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Isinst, implementers[i].TypeAsTBD); ilgen.EmitBrtrue(end); } ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Castclass, typeBuilderGhostInterface); ilgen.Emit(OpCodes.Pop); ilgen.MarkLabel(end); local = ilgen.DeclareLocal(TypeAsSignatureType); ilgen.Emit(OpCodes.Ldloca, local); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Stfld, ghostRefField); ilgen.Emit(OpCodes.Ldloca, local); ilgen.Emit(OpCodes.Ldobj, TypeAsSignatureType); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // Add "ToObject" methods mb = typeBuilder.DefineMethod("ToObject", MethodAttributes.HideBySig | MethodAttributes.Public, Types.Object, Type.EmptyTypes); AttributeHelper.HideFromJava(mb); ilgen = CodeEmitter.Create(mb); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldfld, ghostRefField); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // Implement the "CastArray" method // NOTE unlike "Cast" this doesn't return anything, it just throws a ClassCastException if the // cast is unsuccessful. Also, because of the complexity of this test, we call IsInstanceArray // instead of reimplementing the check here. mb = ghostCastArrayMethod; AttributeHelper.HideFromJava(mb); ilgen = CodeEmitter.Create(mb); end = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldarg_0); ilgen.EmitBrfalse(end); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Call, ghostIsInstanceArrayMethod); ilgen.EmitBrtrue(end); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldtoken, typeBuilder); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Call, StaticCompiler.GetRuntimeType("IKVM.Runtime.GhostTag").GetMethod("ThrowClassCastException", BindingFlags.NonPublic | BindingFlags.Static)); ilgen.MarkLabel(end); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // Implement the "Equals" method mb = typeBuilder.DefineMethod("Equals", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual, Types.Boolean, new Type[] { Types.Object }); AttributeHelper.HideFromJava(mb); ilgen = CodeEmitter.Create(mb); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldfld, ghostRefField); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ceq); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // Implement the "GetHashCode" method mb = typeBuilder.DefineMethod("GetHashCode", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual, Types.Int32, Type.EmptyTypes); AttributeHelper.HideFromJava(mb); ilgen = CodeEmitter.Create(mb); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldfld, ghostRefField); ilgen.Emit(OpCodes.Callvirt, Types.Object.GetMethod("GetHashCode")); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // Implement the "op_Equality" method mb = typeBuilder.DefineMethod("op_Equality", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, Types.Boolean, new Type[] { typeBuilder, typeBuilder }); AttributeHelper.HideFromJava(mb); ilgen = CodeEmitter.Create(mb); ilgen.EmitLdarga(0); ilgen.Emit(OpCodes.Ldfld, ghostRefField); ilgen.EmitLdarga(1); ilgen.Emit(OpCodes.Ldfld, ghostRefField); ilgen.Emit(OpCodes.Ceq); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // Implement the "op_Inequality" method mb = typeBuilder.DefineMethod("op_Inequality", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, Types.Boolean, new Type[] { typeBuilder, typeBuilder }); AttributeHelper.HideFromJava(mb); ilgen = CodeEmitter.Create(mb); ilgen.EmitLdarga(0); ilgen.Emit(OpCodes.Ldfld, ghostRefField); ilgen.EmitLdarga(1); ilgen.Emit(OpCodes.Ldfld, ghostRefField); ilgen.Emit(OpCodes.Ceq); ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.Emit(OpCodes.Ceq); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } } }
protected override void EmitMapXmlMetadata(TypeBuilder typeBuilder, ClassFile classFile, FieldWrapper[] fields, MethodWrapper[] methods) { Dictionary<string, IKVM.Internal.MapXml.Class> mapxml = classLoader.GetMapXmlClasses(); if(mapxml != null) { IKVM.Internal.MapXml.Class clazz; if(mapxml.TryGetValue(classFile.Name, out clazz)) { if(clazz.Attributes != null) { PublishAttributes(typeBuilder, clazz); } if(clazz.Properties != null) { PublishProperties(typeBuilder, clazz); } if(clazz.Fields != null) { foreach(IKVM.Internal.MapXml.Field field in clazz.Fields) { if(field.Attributes != null) { foreach(FieldWrapper fw in fields) { if(fw.Name == field.Name && fw.Signature == field.Sig) { FieldBuilder fb = fw.GetField() as FieldBuilder; if(fb != null) { foreach(IKVM.Internal.MapXml.Attribute attr in field.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, fb, attr); } } } } } } } if(clazz.Constructors != null) { // HACK this isn't the right place to do this, but for now it suffices foreach(IKVM.Internal.MapXml.Constructor constructor in clazz.Constructors) { // are we adding a new constructor? if(GetMethodWrapper(StringConstants.INIT, constructor.Sig, false) == null) { if(constructor.body == null) { Console.Error.WriteLine("Error: Constructor {0}.<init>{1} in xml remap file doesn't have a body.", clazz.Name, constructor.Sig); continue; } bool setmodifiers = false; MethodAttributes attribs = 0; MapModifiers(constructor.Modifiers, true, out setmodifiers, ref attribs); Type returnType; Type[] parameterTypes; MapSignature(constructor.Sig, out returnType, out parameterTypes); MethodBuilder cb = ReflectUtil.DefineConstructor(typeBuilder, attribs, parameterTypes); if(setmodifiers) { AttributeHelper.SetModifiers(cb, (Modifiers)constructor.Modifiers, false); } CompilerClassLoader.AddDeclaredExceptions(cb, constructor.throws); CodeEmitter ilgen = CodeEmitter.Create(cb); constructor.Emit(classLoader, ilgen); ilgen.DoEmit(); if(constructor.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute attr in constructor.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, cb, attr); } } } } foreach(IKVM.Internal.MapXml.Constructor constructor in clazz.Constructors) { if(constructor.Attributes != null) { foreach(MethodWrapper mw in methods) { if(mw.Name == "<init>" && mw.Signature == constructor.Sig) { MethodBuilder mb = mw.GetMethod() as MethodBuilder; if(mb != null) { foreach(IKVM.Internal.MapXml.Attribute attr in constructor.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, mb, attr); } } } } } } } if(clazz.Methods != null) { // HACK this isn't the right place to do this, but for now it suffices foreach(IKVM.Internal.MapXml.Method method in clazz.Methods) { // are we adding a new method? if(GetMethodWrapper(method.Name, method.Sig, false) == null) { if(method.body == null) { Console.Error.WriteLine("Error: Method {0}.{1}{2} in xml remap file doesn't have a body.", clazz.Name, method.Name, method.Sig); continue; } bool setmodifiers = false; MethodAttributes attribs = method.MethodAttributes; MapModifiers(method.Modifiers, false, out setmodifiers, ref attribs); Type returnType; Type[] parameterTypes; MapSignature(method.Sig, out returnType, out parameterTypes); MethodBuilder mb = typeBuilder.DefineMethod(method.Name, attribs, returnType, parameterTypes); if(setmodifiers) { AttributeHelper.SetModifiers(mb, (Modifiers)method.Modifiers, false); } if(method.@override != null) { MethodWrapper mw = GetClassLoader().LoadClassByDottedName([email protected]).GetMethodWrapper([email protected], method.Sig, true); mw.Link(); typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); } CompilerClassLoader.AddDeclaredExceptions(mb, method.throws); CodeEmitter ilgen = CodeEmitter.Create(mb); method.Emit(classLoader, ilgen); ilgen.DoEmit(); if(method.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute attr in method.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, mb, attr); } } } } foreach(IKVM.Internal.MapXml.Method method in clazz.Methods) { if(method.Attributes != null) { foreach(MethodWrapper mw in methods) { if(mw.Name == method.Name && mw.Signature == method.Sig) { MethodBuilder mb = mw.GetMethod() as MethodBuilder; if(mb != null) { foreach(IKVM.Internal.MapXml.Attribute attr in method.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, mb, attr); } } } } } } } if(clazz.Interfaces != null) { foreach(IKVM.Internal.MapXml.Interface iface in clazz.Interfaces) { TypeWrapper tw = GetClassLoader().LoadClassByDottedName(iface.Name); // NOTE since this interface won't be part of the list in the ImplementAttribute, // it won't be visible from Java that the type implements this interface. typeBuilder.AddInterfaceImplementation(tw.TypeAsBaseType); if(iface.Methods != null) { foreach(IKVM.Internal.MapXml.Method m in iface.Methods) { MethodWrapper mw = tw.GetMethodWrapper(m.Name, m.Sig, false); if(mw == null) { throw new InvalidOperationException("Method " + m.Name + m.Sig + " not found in interface " + tw.Name); } mw.Link(); MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(this, typeBuilder, tw.Name + "/" + m.Name, MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.CheckAccessOnOverride); AttributeHelper.HideFromJava(mb); typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); CodeEmitter ilgen = CodeEmitter.Create(mb); m.Emit(classLoader, ilgen); ilgen.DoEmit(); } } } } } } }
protected override TypeBuilder DefineGhostType(string mangledTypeName, TypeAttributes typeAttribs) { typeAttribs &= ~(TypeAttributes.Interface | TypeAttributes.Abstract); typeAttribs |= TypeAttributes.Class | TypeAttributes.Sealed; TypeBuilder typeBuilder = classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs, Types.ValueType); AttributeHelper.SetGhostInterface(typeBuilder); AttributeHelper.SetModifiers(typeBuilder, Modifiers, IsInternal); ghostRefField = typeBuilder.DefineField("__<ref>", Types.Object, FieldAttributes.Public | FieldAttributes.SpecialName); typeBuilderGhostInterface = typeBuilder.DefineNestedType("__Interface", TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.NestedPublic); AttributeHelper.HideFromJava(typeBuilderGhostInterface); ghostIsInstanceMethod = typeBuilder.DefineMethod("IsInstance", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Types.Boolean, new Type[] { Types.Object }); ghostIsInstanceMethod.DefineParameter(1, ParameterAttributes.None, "obj"); ghostIsInstanceArrayMethod = typeBuilder.DefineMethod("IsInstanceArray", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Types.Boolean, new Type[] { Types.Object, Types.Int32 }); ghostIsInstanceArrayMethod.DefineParameter(1, ParameterAttributes.None, "obj"); ghostIsInstanceArrayMethod.DefineParameter(2, ParameterAttributes.None, "rank"); ghostCastMethod = typeBuilder.DefineMethod("Cast", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, typeBuilder, new Type[] { Types.Object }); ghostCastMethod.DefineParameter(1, ParameterAttributes.None, "obj"); ghostCastArrayMethod = typeBuilder.DefineMethod("CastArray", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Types.Void, new Type[] { Types.Object, Types.Int32 }); ghostCastArrayMethod.DefineParameter(1, ParameterAttributes.None, "obj"); ghostCastArrayMethod.DefineParameter(2, ParameterAttributes.None, "rank"); return typeBuilder; }
internal WorkaroundBaseClass(AotTypeWrapper wrapper, TypeBuilder typeBuilder, MethodWrapper[] methods) { this.wrapper = wrapper; this.typeBuilder = typeBuilder; this.methods = methods; }
internal BakedType(TypeBuilder typeBuilder) { this.typeBuilder = typeBuilder; }
private void PublishProperties(TypeBuilder typeBuilder, IKVM.Internal.MapXml.Class clazz) { foreach(IKVM.Internal.MapXml.Property prop in clazz.Properties) { TypeWrapper typeWrapper = GetClassLoader().RetTypeWrapperFromSigNoThrow(prop.Sig); TypeWrapper[] propargs = GetClassLoader().ArgTypeWrapperListFromSigNoThrow(prop.Sig); Type[] indexer = new Type[propargs.Length]; for(int i = 0; i < propargs.Length; i++) { indexer[i] = propargs[i].TypeAsSignatureType; } PropertyBuilder propbuilder = typeBuilder.DefineProperty(prop.Name, PropertyAttributes.None, typeWrapper.TypeAsSignatureType, indexer); AttributeHelper.HideFromJava(propbuilder); if(prop.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute attr in prop.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, propbuilder, attr); } } MethodWrapper getter = null; MethodWrapper setter = null; if(prop.getter != null) { getter = GetMethodWrapper(prop.getter.Name, prop.getter.Sig, true); if(getter == null) { Console.Error.WriteLine("Warning: getter not found for {0}::{1}", clazz.Name, prop.Name); } } if(prop.setter != null) { setter = GetMethodWrapper(prop.setter.Name, prop.setter.Sig, true); if(setter == null) { Console.Error.WriteLine("Warning: setter not found for {0}::{1}", clazz.Name, prop.Name); } } bool final = (getter != null && getter.IsFinal) || (setter != null && setter.IsFinal); if(getter != null) { MethodWrapper mw = getter; if(!CheckPropertyArgs(mw.GetParametersForDefineMethod(), indexer) || mw.ReturnType != typeWrapper) { Console.Error.WriteLine("Warning: ignoring invalid property getter for {0}::{1}", clazz.Name, prop.Name); } else { MethodBuilder mb = mw.GetMethod() as MethodBuilder; if(mb == null || mb.DeclaringType != typeBuilder || (!mb.IsFinal && final)) { mb = typeBuilder.DefineMethod("get_" + prop.Name, GetPropertyMethodAttributes(mw, final), typeWrapper.TypeAsSignatureType, indexer); AttributeHelper.HideFromJava(mb); CodeEmitter ilgen = CodeEmitter.Create(mb); if(mw.IsStatic) { for(int i = 0; i < indexer.Length; i++) { ilgen.EmitLdarg(i); } mw.EmitCall(ilgen); } else { ilgen.Emit(OpCodes.Ldarg_0); for(int i = 0; i < indexer.Length; i++) { ilgen.EmitLdarg(i + 1); } mw.EmitCallvirt(ilgen); } ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } propbuilder.SetGetMethod(mb); } } if(setter != null) { MethodWrapper mw = setter; Type[] args = new Type[indexer.Length + 1]; indexer.CopyTo(args, 0); args[args.Length - 1] = typeWrapper.TypeAsSignatureType; if(!CheckPropertyArgs(args, mw.GetParametersForDefineMethod())) { Console.Error.WriteLine("Warning: ignoring invalid property setter for {0}::{1}", clazz.Name, prop.Name); } else { MethodBuilder mb = mw.GetMethod() as MethodBuilder; if(mb == null || mb.DeclaringType != typeBuilder || (!mb.IsFinal && final)) { mb = typeBuilder.DefineMethod("set_" + prop.Name, GetPropertyMethodAttributes(mw, final), mw.ReturnTypeForDefineMethod, args); AttributeHelper.HideFromJava(mb); CodeEmitter ilgen = CodeEmitter.Create(mb); if(mw.IsStatic) { for(int i = 0; i <= indexer.Length; i++) { ilgen.EmitLdarg(i); } mw.EmitCall(ilgen); } else { ilgen.Emit(OpCodes.Ldarg_0); for(int i = 0; i <= indexer.Length; i++) { ilgen.EmitLdarg(i + 1); } mw.EmitCallvirt(ilgen); } ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } propbuilder.SetSetMethod(mb); } } } }
private void PublishAttributes(TypeBuilder typeBuilder, IKVM.Internal.MapXml.Class clazz) { foreach(IKVM.Internal.MapXml.Attribute attr in clazz.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, typeBuilder, attr); } }
private static void CreateConstructor(TypeBuilder tb) { CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineConstructor(tb, MethodAttributes.Public, new Type[] { invocationHandlerClass.TypeAsSignatureType })); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldarg_1); proxyConstructor.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(); }
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 CreateConstructor(TypeBuilder tb) { ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { invocationHandlerClass.TypeAsSignatureType }); CodeEmitter ilgen = CodeEmitter.Create(cb); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldarg_1); proxyConstructor.EmitCall(ilgen); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); }
internal BakedType(TypeBuilder typeBuilder) : base(typeBuilder) { }
internal ConstructorForwarder(TypeWrapperFactory context, TypeBuilder typeBuilder, MethodWrapper ctor) : base(ctor.DeclaringType, ctor.Name, ctor.Signature, null, null, null, ctor.Modifiers, MemberFlags.None) { this.context = context; this.typeBuilder = typeBuilder; this.ctor = ctor; }
internal GenericTypeParameterBuilder(string name, TypeBuilder type, int position) : this(name, type, null, position, Signature.ELEMENT_TYPE_VAR) { }
internal EnumBuilder(TypeBuilder typeBuilder, FieldBuilder fieldBuilder) : base(typeBuilder) { this.typeBuilder = typeBuilder; this.fieldBuilder = fieldBuilder; }