public void Compile() { PrecompilePass(); Messages.Verbose("Start of compilation"); foreach (InterType type in typesToCompile) { if ((type.IsFromJava) || (type.IsArray) || (type.IsByRef)) { continue; } if (type.IsPrimitive) { CompilePrimitive(type); continue; } Java.Class javaClass = ComplileType(type); WriteClass(javaClass); } GenerateByRefTypesCode(); GenerateMethodPointerInterfaces(); }
void INamesController.WriteAnonumousClass(Java.Class javaClass) { WriteClass(javaClass); Java.Attributes.InnerClasses.InnerClass descr = new Java.Attributes.InnerClasses.InnerClass(); descr.AccessFlags = Java.Attributes.InnerClasses.InnerClassAccessFlags.Public; descr.InnerClassInfo = javaClass.ThisClass; descr.OuterClassInfo = currentJavaClass.ThisClass; descr.InnerName = javaClass.ThisClass.Substring(javaClass.ThisClass.LastIndexOf('$') + 1); currentJavaInnerClasses.Classes.Add(descr); }
private void GenerateBaseByRefType(JavaPrimitiveType type) { if ((baseTypesGenerated & (1 << (int)type)) != 0) { return; } Java.Class javaClass = new Java.Class(); javaClass.AccessFlag = Java.ClassAccessFlag.Abstract | Java.ClassAccessFlag.Public | Java.ClassAccessFlag.Super; javaClass.ThisClass = TypeNameToJava(new JavaByRefType(ByRefPlace.Unknown, type).ToString()); javaClass.SuperClass = TypeNameToJava(ClassNames.JavaObject); Java.Method ctor = new Java.Method(); ctor.AccessFlags = Java.MethodAccessFlags.Public; ctor.Name = ClassNames.JavaConstructorMethodName; ctor.Descriptor = "()V"; JavaBytecodeWriter ctorCodeGenerator = new JavaBytecodeWriter(); ctorCodeGenerator .AddLocalVarInstruction(LocalVarInstruction.Load, JavaPrimitiveType.Ref, 0, null) .AddInstruction(new JavaInstruction(Java.OpCodes.invokespecial, ClassNames.JavaObjectCtorMethodRef)) .AddReturn(JavaPrimitiveType.Void, null); Java.Attributes.Code ctorCode = new Java.Attributes.Code(); ctorCode.CodeBytes = ctorCodeGenerator.Link(javaClass.ConstantPool); ctorCode.MaxLocals = 1; ctorCode.MaxStack = 1; ctor.Attributes.Add(ctorCode); javaClass.Methods.Add(ctor); Java.Method getValue = new Java.Method(); getValue.AccessFlags = Java.MethodAccessFlags.Abstract | Java.MethodAccessFlags.Public; getValue.Name = ClassNames.ByRef.GetValueMethodName; getValue.Descriptor = GetByRefGetValueDescriptor(type); javaClass.Methods.Add(getValue); Java.Method setValue = new Java.Method(); setValue.AccessFlags = Java.MethodAccessFlags.Abstract | Java.MethodAccessFlags.Public; setValue.Name = ClassNames.ByRef.SetValueMethodName; setValue.Descriptor = GetByRefSetValueDescriptor(type); javaClass.Methods.Add(setValue); WriteClass(javaClass); baseTypesGenerated |= (1 << (int)type); }
private void GenerateMethodPointerInterfaces() { Messages.Verbose(" Generating method pointers interfaces..."); foreach (var mp in methodPointerInterfaces) { Java.Class interfaceClass = new Java.Class(); interfaceClass.AccessFlag = ClassAccessFlag.Abstract | ClassAccessFlag.Interface | ClassAccessFlag.Public; interfaceClass.ThisClass = TypeNameToJava(mp.Key); interfaceClass.SuperClass = TypeNameToJava(ClassNames.JavaObject); Method invokeMethod = new Method(); invokeMethod.AccessFlags = MethodAccessFlags.Abstract | MethodAccessFlags.Public; invokeMethod.Name = ClassNames.MethodPointerInvokeName; invokeMethod.Descriptor = "(L" + TypeNameToJava(ClassNames.JavaObject) + ";" + GetMethodDescriptor(mp.Value).Substring(1); interfaceClass.Methods.Add(invokeMethod); WriteClass(interfaceClass); } }
private string GenerateMethodPointerClass(InterMethod operand) { string mpInterfaceName = namesController.GetMethodPointerInterface(operand); string anonClassName = namesController.GetAnonimousClassName(); Java.Class anonClass = new Java.Class(); anonClass.AccessFlag = Java.ClassAccessFlag.Super | ClassAccessFlag.Public; anonClass.ThisClass = namesController.TypeNameToJava(anonClassName); anonClass.SuperClass = namesController.TypeNameToJava(ClassNames.JavaObject); anonClass.Interfaces.Add(namesController.TypeNameToJava(mpInterfaceName)); Method invokeMethod = new Method(); invokeMethod.AccessFlags = MethodAccessFlags.Public; invokeMethod.Name = ClassNames.MethodPointerInvokeName; invokeMethod.Descriptor = "(L" + namesController.TypeNameToJava(ClassNames.JavaObject) + ";" + namesController.GetMethodDescriptor(operand).Substring(1); JavaBytecodeWriter codeWriter = new JavaBytecodeWriter(); if (!operand.IsStatic) { codeWriter .Add(OpCodes.aload_1) .Add(OpCodes.checkcast, new Java.Constants.Class(namesController.TypeNameToJava(operand.DeclaringType))); } for (int i = 0; i < operand.Parameters.Count; i++) { codeWriter.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(operand.Parameters[i].Type), i + 2); } MethodRef invokingMethodRef = new MethodRef(namesController.TypeNameToJava(operand.DeclaringType), namesController.MethodNameToJava(operand.NewName), namesController.GetMethodDescriptor(operand));; if (!operand.IsPublic) { Method access = namesController.GetAnonumousAccessMethod(); access.AccessFlags = MethodAccessFlags.Public; if (operand.IsStatic) { access.AccessFlags |= MethodAccessFlags.Static; } access.Descriptor = namesController.GetMethodDescriptor(operand); JavaBytecodeWriter accessCodeWriter = new JavaBytecodeWriter(); if (!operand.IsStatic) { accessCodeWriter.Add(OpCodes.aload_0); } int firstParameter = operand.IsStatic ? 0 : 1; for (int i = 0; i < operand.Parameters.Count; i++) { accessCodeWriter.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(operand.Parameters[i].Type), i + firstParameter); } if (operand.IsStatic) { accessCodeWriter.Add(OpCodes.invokestatic, invokingMethodRef); } else if (operand.IsPrivate) { accessCodeWriter.Add(OpCodes.invokespecial, invokingMethodRef); } else { accessCodeWriter.Add(OpCodes.invokevirtual, invokingMethodRef); } access.Attributes.Add(accessCodeWriter.AddReturn(JavaHelpers.InterTypeToJavaPrimitive( operand.ReturnParameter.Type)).End(this.constsPool)); invokingMethodRef = new MethodRef(namesController.TypeNameToJava(operand.DeclaringType), access.Name, namesController.GetMethodDescriptor(operand)); } if (operand.IsStatic) { codeWriter.Add(OpCodes.invokestatic, invokingMethodRef); } else if (operand.DeclaringType.IsInterface) { codeWriter.Add(OpCodes.invokeinterface, invokingMethodRef); } else { codeWriter.Add(OpCodes.invokevirtual, invokingMethodRef); } invokeMethod.Attributes.Add(codeWriter.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(operand.ReturnParameter.Type)) .End(anonClass.ConstantPool)); anonClass.Methods.Add(invokeMethod); Method ctor = new Method(); ctor.AccessFlags = MethodAccessFlags.Public; ctor.Name = ClassNames.JavaConstructorMethodName; ctor.Descriptor = "()V"; ctor.Attributes.Add(new JavaBytecodeWriter() .Add(OpCodes.aload_0) .Add(OpCodes.invokespecial, ClassNames.JavaObjectCtorMethodRef) .Add(OpCodes._return).End(anonClass.ConstantPool)); anonClass.Methods.Add(ctor); namesController.WriteAnonumousClass(anonClass); return(anonClassName); }
private void CompilePrimitive(InterType type) { if (Program.BoxType == BoxingType.Java) { return; } if (type.PrimitiveType == PrimitiveType.Void) { return; //Skip compiling void type. It's never will boxed } JavaPrimitiveType javaType = JavaHelpers.InterTypeToJavaPrimitive(type); currentJavaClass = new Java.Class(); currentJavaClass.AccessFlag = Java.ClassAccessFlag.Public | Java.ClassAccessFlag.Super | ClassAccessFlag.Final; currentJavaClass.ThisClass = TypeNameToJava(type.CILBoxType); currentJavaClass.SuperClass = TypeNameToJava(ClassNames.JavaObject); Field valueField = new Field(); valueField.AccessFlags = FieldAccessFlags.Private; valueField.Name = "value"; valueField.Descriptor = GetFieldDescriptor(type); currentJavaClass.Fields.Add(valueField); FieldRef valueFieldRef = new FieldRef(currentJavaClass.ThisClass, valueField.Name, valueField.Descriptor); Method ctorMethod = new Method(); ctorMethod.AccessFlags = MethodAccessFlags.Public; ctorMethod.Name = ClassNames.JavaConstructorMethodName; ctorMethod.Descriptor = "()V"; ctorMethod.Attributes.Add(new JavaBytecodeWriter() .Add(OpCodes.aload_0) .Add(OpCodes.invokespecial, ClassNames.JavaObjectCtorMethodRef) .Add(OpCodes.aload_0) .AddDefaultValue(javaType) .Add(OpCodes.putfield, valueFieldRef) .Add(OpCodes._return) .End(currentJavaClass.ConstantPool)); currentJavaClass.Methods.Add(ctorMethod); Method ctorValueMethod = new Method(); ctorValueMethod.AccessFlags = MethodAccessFlags.Public; ctorValueMethod.Name = ClassNames.JavaConstructorMethodName; ctorValueMethod.Descriptor = "(" + valueField.Descriptor + ")V"; ctorValueMethod.Attributes.Add(new JavaBytecodeWriter() .Add(OpCodes.aload_0) .Add(OpCodes.invokespecial, ClassNames.JavaObjectCtorMethodRef) .Add(OpCodes.aload_0) .AddLoad(javaType, 1) .Add(OpCodes.putfield, valueFieldRef) .Add(OpCodes._return) .End(currentJavaClass.ConstantPool)); currentJavaClass.Methods.Add(ctorValueMethod); MethodRef ctorValueMethodRef = new MethodRef(currentJavaClass.ThisClass, ctorValueMethod.Name, ctorValueMethod.Descriptor); Method valueOfMethod = new Method(); valueOfMethod.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Static; valueOfMethod.Name = "valueOf"; valueOfMethod.Descriptor = "(" + valueField.Descriptor + ")L" + TypeNameToJava(type.CILBoxType) + ";"; valueOfMethod.Attributes.Add(new JavaBytecodeWriter() .Add(OpCodes._new, new Java.Constants.Class(TypeNameToJava(type.CILBoxType))) .Add(OpCodes.dup) .AddLoad(javaType, 0) .Add(OpCodes.invokespecial, ctorValueMethodRef) .Add(OpCodes.areturn) .End(currentJavaClass.ConstantPool)); currentJavaClass.Methods.Add(valueOfMethod); Method getValueMethod = new Method(); getValueMethod.AccessFlags = MethodAccessFlags.Public; getValueMethod.Name = Utils.GetJavaTypeName(type.PrimitiveType) + "Value"; getValueMethod.Descriptor = "()" + GetFieldDescriptor(type); getValueMethod.Attributes.Add(new JavaBytecodeWriter() .Add(OpCodes.aload_0) .Add(OpCodes.getfield, valueFieldRef) .AddReturn(JavaHelpers.InterTypeToJavaPrimitive(type)) .End(currentJavaClass.ConstantPool)); currentJavaClass.Methods.Add(getValueMethod); currentJavaInnerClasses = new Java.Attributes.InnerClasses(); foreach (InterField field in type.Fields) { currentJavaClass.Fields.Add(CompileField(field)); } foreach (InterMethod method in type.Methods) { currentJavaClass.Methods.Add(CompileMethod(method)); } if (currentJavaInnerClasses.Classes.Count > 0) { currentJavaClass.Attributes.Add(currentJavaInnerClasses); } WriteClass(currentJavaClass); }
private Java.Class ComplileType(InterType type) { sourceFileNameCounter = new Counter <string>(); Messages.Verbose(" Compiling type {0}...", type.ToString()); currentType = type; currentJavaClass = new Java.Class(); currentJavaClass.AccessFlag = (Java.ClassAccessFlag)GetClassAccessFlags(type, false); currentJavaClass.ThisClass = TypeNameToJava(type.Fullname); if (type.BaseType == null) { currentJavaClass.SuperClass = TypeNameToJava(ClassNames.JavaObject); } else { currentJavaClass.SuperClass = TypeNameToJava(type.BaseType.Fullname); } foreach (InterType i in type.Interfaces) { currentJavaClass.Interfaces.Add(TypeNameToJava(i.Fullname)); } if (type.IsValueType) { CompileValueType(type); } if (type.IsEnum) { CompileEnum(type); } currentJavaInnerClasses = new Java.Attributes.InnerClasses(); if (type.DeclaringType != null) { Java.Attributes.InnerClasses.InnerClass innerClass = new Java.Attributes.InnerClasses.InnerClass(); innerClass.AccessFlags = (Java.Attributes.InnerClasses.InnerClassAccessFlags)GetClassAccessFlags(type, true); innerClass.InnerClassInfo = TypeNameToJava(type.Fullname); innerClass.InnerName = TypeNameToJava(type.Name); innerClass.OuterClassInfo = TypeNameToJava(type.DeclaringType.Fullname); currentJavaInnerClasses.Classes.Add(innerClass); } foreach (InterType nestedClass in type.NestedClasses) { Java.Attributes.InnerClasses.InnerClass innerClass = new Java.Attributes.InnerClasses.InnerClass(); innerClass.AccessFlags = (Java.Attributes.InnerClasses.InnerClassAccessFlags)GetClassAccessFlags(nestedClass, true); innerClass.InnerClassInfo = TypeNameToJava(nestedClass.Fullname); innerClass.InnerName = TypeNameToJava(nestedClass.Name); innerClass.OuterClassInfo = TypeNameToJava(type.Fullname); currentJavaInnerClasses.Classes.Add(innerClass); } if (type.IsDelegate) { CompileDelegate(type); } else { foreach (InterField field in type.Fields) { currentJavaClass.Fields.Add(CompileField(field)); } foreach (InterMethod method in type.Methods) { currentJavaClass.Methods.Add(CompileMethod(method)); } if (type.BaseType != null) { CompileOverridedMethods(type, type.BaseType); } foreach (InterType iface in type.Interfaces) { CompileOverridedMethods(type, iface); } GenerateFieldAccessors(type); } bool hasStaticCtor = type.Methods.Where(M => ((M.IsConstructor) && (M.IsStatic))).Count() > 0; bool needStaticCtor = type.Fields.Where(F => ((F.FieldType.IsValueType) && (F.IsStatic))).Count() > 0; needStaticCtor |= type.Fields.Where(F => F.IsStatic && F.IsThreadLocal).Count() > 0; if ((needStaticCtor) && (!hasStaticCtor)) { GenerateStaticCtor(type); } if (currentJavaInnerClasses.Classes.Count > 0) { currentJavaClass.Attributes.Add(currentJavaInnerClasses); } if ((Program.Debug) && (sourceFileNameCounter != null) && (sourceFileNameCounter.IsStarted)) { string fileName = sourceFileNameCounter.MostUsed; if (!Program.FullPathInSourceFileName) { fileName = System.IO.Path.GetFileName(fileName); } currentJavaClass.Attributes.Add(new Java.Attributes.SourceFile(fileName)); } return(currentJavaClass); }
private void GenerateArrayByRefType(JavaPrimitiveType type) { GenerateBaseByRefType(type); string valueFieldDesc = "L" + TypeNameToJava(ClassNames.JavaObject) + ";"; if (type != JavaPrimitiveType.Ref) { valueFieldDesc = JavaPrimitive2FieldChar[(int)type].ToString(); } Java.Class javaClass = new Java.Class(); javaClass.AccessFlag = Java.ClassAccessFlag.Final | Java.ClassAccessFlag.Public | Java.ClassAccessFlag.Super; javaClass.ThisClass = TypeNameToJava(new JavaByRefType(ByRefPlace.Array, type).ToString()); javaClass.SuperClass = TypeNameToJava(new JavaByRefType(ByRefPlace.Unknown, type).ToString()); Field arrayField = new Field(); arrayField.AccessFlags = FieldAccessFlags.Private; arrayField.Name = "array"; arrayField.Descriptor = "[" + valueFieldDesc; javaClass.Fields.Add(arrayField); FieldRef arrayFieldRef = new FieldRef(javaClass.ThisClass, arrayField.Name, arrayField.Descriptor); Field indexField = new Field(); indexField.AccessFlags = FieldAccessFlags.Private; indexField.Name = "index"; indexField.Descriptor = "I"; javaClass.Fields.Add(indexField); FieldRef indexFieldRef = new FieldRef(javaClass.ThisClass, indexField.Name, indexField.Descriptor); Field valueField = new Field(); valueField.AccessFlags = FieldAccessFlags.Private; valueField.Name = "value"; valueField.Descriptor = valueFieldDesc; javaClass.Fields.Add(valueField); FieldRef valueFieldRef = new FieldRef(javaClass.ThisClass, valueField.Name, valueField.Descriptor); Java.Constants.MethodRef superCtorRef = new Java.Constants.MethodRef(javaClass.SuperClass, ClassNames.JavaConstructorMethodName, "()V"); Method ctorMethod = new Method(); ctorMethod.AccessFlags = MethodAccessFlags.Public; ctorMethod.Name = ClassNames.JavaConstructorMethodName; ctorMethod.Descriptor = "(" + arrayField.Descriptor + "I)V"; ctorMethod.Attributes.Add(new JavaBytecodeWriter() .Add(OpCodes.aload_0) .Add(OpCodes.invokespecial, superCtorRef) //this.array = array .Add(OpCodes.aload_0) .Add(OpCodes.aload_1) .Add(OpCodes.putfield, arrayFieldRef) //this.index = index .Add(OpCodes.aload_0) .Add(OpCodes.iload_2) .Add(OpCodes.putfield, indexFieldRef) //this.value = array[index] .Add(OpCodes.aload_0) .Add(OpCodes.aload_1) .Add(OpCodes.iload_2) .AddArrayLoad(JavaHelpers.JavaPrimitiveToArrayType(type)) .Add(OpCodes.putfield, valueFieldRef) .Add(OpCodes._return) .End(javaClass.ConstantPool)); javaClass.Methods.Add(ctorMethod); Java.Method getMethod = new Method(); getMethod.AccessFlags = Java.MethodAccessFlags.Public; getMethod.Name = ClassNames.ByRef.GetValueMethodName; getMethod.Descriptor = "()" + valueFieldDesc; getMethod.Attributes.Add(new JavaBytecodeWriter() //return this.value .Add(OpCodes.aload_0) .Add(OpCodes.getfield, valueFieldRef) .AddReturn(type) .End(javaClass.ConstantPool)); javaClass.Methods.Add(getMethod); Java.Method setMethod = new Method(); setMethod.AccessFlags = MethodAccessFlags.Public; setMethod.Name = ClassNames.ByRef.SetValueMethodName; setMethod.Descriptor = "(" + valueFieldDesc + ")V"; setMethod.Attributes.Add(new JavaBytecodeWriter() //this.array[this.index] = value .Add(OpCodes.aload_0) .Add(OpCodes.getfield, arrayFieldRef) .Add(OpCodes.aload_0) .Add(OpCodes.getfield, indexFieldRef) .AddLoad(type, 1) .AddArrayStore(JavaHelpers.JavaPrimitiveToArrayType(type)) //this.value = value .Add(OpCodes.aload_0) .AddLoad(type, 1) .Add(OpCodes.putfield, valueFieldRef) .AddReturn(JavaPrimitiveType.Void) .End(javaClass.ConstantPool)); javaClass.Methods.Add(setMethod); WriteClass(javaClass); }
private void GenerateFieldByRefType(JavaPrimitiveType type) { GenerateBaseByRefType(type); string valueFieldDesc = "L" + TypeNameToJava(ClassNames.JavaObject) + ";"; MethodRef getMethodRef = ClassNames.JavaLangReflectField.get; MethodRef setMethodRef = ClassNames.JavaLangReflectField.set; if (type != JavaPrimitiveType.Ref) { valueFieldDesc = JavaPrimitive2FieldChar[(int)type].ToString(); getMethodRef = fieldGetPrimitiveMethods[(int)type]; setMethodRef = fieldSetPrimitiveMethods[(int)type]; } Java.Class javaClass = new Java.Class(); javaClass.AccessFlag = ClassAccessFlag.Final | ClassAccessFlag.Public | ClassAccessFlag.Super; javaClass.ThisClass = TypeNameToJava(new JavaByRefType(ByRefPlace.Field, type).ToString()); javaClass.SuperClass = TypeNameToJava(new JavaByRefType(ByRefPlace.Unknown, type).ToString()); MethodRef baseTypeCtorRef = new MethodRef(javaClass.SuperClass, ClassNames.JavaConstructorMethodName, "()V"); Java.Field targetField = new Field(); targetField.AccessFlags = FieldAccessFlags.Private; targetField.Name = "target"; targetField.Descriptor = "L" + TypeNameToJava(ClassNames.JavaObject) + ";"; javaClass.Fields.Add(targetField); Java.Field fieldField = new Field(); fieldField.AccessFlags = FieldAccessFlags.Private; fieldField.Name = "field"; fieldField.Descriptor = "L" + TypeNameToJava(ClassNames.JavaLangReflectField.ClassName) + ";"; javaClass.Fields.Add(fieldField); Java.Field valueField = new Java.Field(); valueField.AccessFlags = FieldAccessFlags.Private; valueField.Name = "value"; valueField.Descriptor = valueFieldDesc; javaClass.Fields.Add(valueField); FieldRef targetFieldRef = new FieldRef(javaClass.ThisClass, "target", targetField.Descriptor); FieldRef fieldFieldRef = new FieldRef(javaClass.ThisClass, "field", fieldField.Descriptor); FieldRef valueFieldRef = new FieldRef(javaClass.ThisClass, "value", valueField.Descriptor); Java.Method ctorMethod = new Method(); ctorMethod.AccessFlags = MethodAccessFlags.Public; ctorMethod.Name = ClassNames.JavaConstructorMethodName; ctorMethod.Descriptor = ClassNames.ByRef.FieldCtorDescriptor; ctorMethod.Attributes.Add(new JavaBytecodeWriter() //super .Add(OpCodes.aload_0) //this .Add(OpCodes.invokespecial, baseTypeCtorRef) //super() //this.target = target .Add(OpCodes.aload_0) //this .Add(OpCodes.aload_1) //target .Add(OpCodes.putfield, targetFieldRef) //this.fied = field .Add(OpCodes.aload_0) //this .Add(OpCodes.aload_2) //field .Add(OpCodes.putfield, fieldFieldRef) //field.setAccessible(true) .Add(OpCodes.aload_2) //field .Add(OpCodes.iconst_1) .Add(OpCodes.invokevirtual, ClassNames.JavaLangReflectField.setAccessible) //this.value = field.get[type](target) .Add(OpCodes.aload_0) //this .Add(OpCodes.aload_2) //field .Add(OpCodes.aload_1) //target .Add(OpCodes.invokevirtual, getMethodRef) .Add(OpCodes.putfield, valueFieldRef) .AddReturn(JavaPrimitiveType.Void) .End(javaClass.ConstantPool) ); javaClass.Methods.Add(ctorMethod); Java.Method getMethod = new Method(); getMethod.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final; getMethod.Name = ClassNames.ByRef.GetValueMethodName; getMethod.Descriptor = "()" + valueFieldDesc; getMethod.Attributes.Add(new JavaBytecodeWriter() //return this.value .Add(OpCodes.aload_0) .Add(OpCodes.getfield, valueFieldRef) .AddReturn(type) .End(javaClass.ConstantPool)); javaClass.Methods.Add(getMethod); Java.Method setMethod = new Method(); setMethod.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final; setMethod.Name = ClassNames.ByRef.SetValueMethodName; setMethod.Descriptor = "(" + valueFieldDesc + ")V"; setMethod.Attributes.Add(new JavaBytecodeWriter() //field.set[type](target, value) .Add(OpCodes.aload_0) .Add(OpCodes.getfield, fieldFieldRef) .Add(OpCodes.aload_0) .Add(OpCodes.getfield, targetFieldRef) .AddLoad(type, 1) .Add(OpCodes.invokevirtual, setMethodRef) //this.value = value .Add(OpCodes.aload_0) .AddLoad(type, 1) .Add(OpCodes.putfield, valueFieldRef) .AddReturn(JavaPrimitiveType.Void) .End(javaClass.ConstantPool)); javaClass.Methods.Add(setMethod); WriteClass(javaClass); }
private void GenerateLocalByRefType(JavaPrimitiveType type) { GenerateBaseByRefType(type); string valueFieldDesc = "L" + TypeNameToJava(ClassNames.JavaObject) + ";"; if (type != JavaPrimitiveType.Ref) { valueFieldDesc = JavaPrimitive2FieldChar[(int)type].ToString(); } Java.Class javaClass = new Java.Class(); javaClass.AccessFlag = Java.ClassAccessFlag.Final | Java.ClassAccessFlag.Public | Java.ClassAccessFlag.Super; javaClass.ThisClass = TypeNameToJava(new JavaByRefType(ByRefPlace.Local, type).ToString()); javaClass.SuperClass = TypeNameToJava(new JavaByRefType(ByRefPlace.Unknown, type).ToString()); Java.Field valueField = new Java.Field(); valueField.AccessFlags = Java.FieldAccessFlags.Private; valueField.Name = "value"; valueField.Descriptor = valueFieldDesc; javaClass.Fields.Add(valueField); Java.Constants.FieldRef valueRef = new Java.Constants.FieldRef(javaClass.ThisClass, "value", valueFieldDesc); Java.Constants.MethodRef superCtorRef = new Java.Constants.MethodRef(javaClass.SuperClass, ClassNames.JavaConstructorMethodName, "()V"); Java.Method ctor = new Java.Method(); ctor.AccessFlags = Java.MethodAccessFlags.Public; ctor.Name = ClassNames.JavaConstructorMethodName; ctor.Descriptor = "(" + valueFieldDesc + ")V"; ctor.Attributes.Add(new JavaBytecodeWriter() .Add(OpCodes.aload_0) .Add(OpCodes.invokespecial, superCtorRef) .Add(OpCodes.aload_0) .AddLoad(type, 1) .Add(OpCodes.putfield, valueRef) .AddReturn(JavaPrimitiveType.Void) .End(javaClass.ConstantPool) ); javaClass.Methods.Add(ctor); Java.Method get = new Method(); get.AccessFlags = Java.MethodAccessFlags.Public; get.Name = ClassNames.ByRef.GetValueMethodName; get.Descriptor = "()" + valueFieldDesc; get.Attributes.Add(new JavaBytecodeWriter() .Add(OpCodes.aload_0) .Add(OpCodes.getfield, valueRef) .AddReturn(type) .End(javaClass.ConstantPool)); javaClass.Methods.Add(get); Java.Method set = new Method(); set.AccessFlags = MethodAccessFlags.Public; set.Name = ClassNames.ByRef.SetValueMethodName; set.Descriptor = "(" + valueFieldDesc + ")V"; set.Attributes.Add(new JavaBytecodeWriter() .Add(OpCodes.aload_0) .AddLoad(type, 1) .Add(OpCodes.putfield, valueRef) .AddReturn(JavaPrimitiveType.Void) .End(javaClass.ConstantPool)); javaClass.Methods.Add(set); WriteClass(javaClass); }
private void GenerateDelegateRunner(InterType type) { Java.Class runner = new Java.Class(); runner.AccessFlag = ClassAccessFlag.Final; runner.ThisClass = currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName; runner.SuperClass = TypeNameToJava(ClassNames.CIL2JavaDelegateRunner.ClassName); Java.Attributes.InnerClasses.InnerClass inner = new Java.Attributes.InnerClasses.InnerClass() { AccessFlags = Java.Attributes.InnerClasses.InnerClassAccessFlags.Final | Java.Attributes.InnerClasses.InnerClassAccessFlags.Private, InnerClassInfo = runner.ThisClass, InnerName = ClassNames.DelegateRunnerClassName, OuterClassInfo = currentJavaClass.ThisClass }; Java.Attributes.InnerClasses innerAttr = new Java.Attributes.InnerClasses(); innerAttr.Classes.Add(inner); runner.Attributes.Add(innerAttr); currentJavaInnerClasses.Classes.Add(inner); InterMethod invokeMethod = type.Methods.Where(M => M.Name == ClassNames.DelegateInvokeMethodName).FirstOrDefault(); Field selfField = new Field(); selfField.AccessFlags = FieldAccessFlags.Private | FieldAccessFlags.Final; selfField.Name = ClassNames.DelegateRunnerSelfFieldName; selfField.Descriptor = GetFieldDescriptor(type); runner.Fields.Add(selfField); FieldRef selfFieldRef = new FieldRef(runner.ThisClass, selfField.Name, selfField.Descriptor); JavaBytecodeWriter ctorCodeWriter = new JavaBytecodeWriter(); JavaBytecodeWriter runCodeWriter = new JavaBytecodeWriter(); ctorCodeWriter //super() .Add(OpCodes.aload_0) .Add(OpCodes.invokespecial, ClassNames.CIL2JavaDelegateRunner.CtorMethodRef) //this.self = self; .Add(OpCodes.aload_0) .Add(OpCodes.aload_1) .Add(OpCodes.putfield, selfFieldRef); if (invokeMethod.ReturnParameter.Type.PrimitiveType != PrimitiveType.Void) { runCodeWriter.Add(OpCodes.aload_0); } runCodeWriter .Add(OpCodes.aload_0) .Add(OpCodes.getfield, selfFieldRef); for (int i = 0; i < invokeMethod.Parameters.Count; i++) { InterType paramType = invokeMethod.Parameters[i].Type; JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(paramType); Field paramField = new Field(); paramField.AccessFlags = FieldAccessFlags.Final | FieldAccessFlags.Private; paramField.Name = ClassNames.DelegateRunnerParamFieldNamePrefix + i.ToString();; paramField.Descriptor = GetFieldDescriptor(paramType); runner.Fields.Add(paramField); FieldRef paramFieldRef = new FieldRef(runner.ThisClass, paramField.Name, paramField.Descriptor); ctorCodeWriter .Add(OpCodes.aload_0) .AddLoad(jp, i + 2) .Add(OpCodes.putfield, paramFieldRef); runCodeWriter .Add(OpCodes.aload_0) .Add(OpCodes.getfield, paramFieldRef); } if (invokeMethod.ReturnParameter.Type.PrimitiveType != PrimitiveType.Void) { Field resultField = new Field(); resultField.AccessFlags = FieldAccessFlags.Private; resultField.Name = ClassNames.DelegateRunnerResultFieldName; resultField.Descriptor = GetFieldDescriptor(invokeMethod.ReturnParameter.Type); runner.Fields.Add(resultField); runCodeWriter.Add(OpCodes.putfield, new FieldRef(runner.ThisClass, resultField.Name, resultField.Descriptor)); } runCodeWriter .Add(OpCodes.invokevirtual, new MethodRef(TypeNameToJava(type.Fullname), ClassNames.DelegateInvokeMethodName, GetMethodDescriptor(invokeMethod))) .Add(OpCodes.aload_0) .Add(OpCodes.getfield, ClassNames.CIL2JavaDelegateRunner.OnEndedFieldRef) .Add(OpCodes.dup) .Add(OpCodes.ifnull, "noOnEnd") .Add(OpCodes.aload_0) .Add(OpCodes.getfield, ClassNames.CIL2JavaDelegateRunner.AsyncResultFieldResult) .Add(OpCodes.invokevirtual, ClassNames.SystemAsyncCallback.InvokeMethodRef) .Add(OpCodes._goto, "exit") .Label("noOnEnd") .Add(OpCodes.pop) .Label("exit"); ctorCodeWriter.Add(OpCodes._return); runCodeWriter.Add(OpCodes._return); string paramsDescriptor = GetMethodDescriptor(invokeMethod); paramsDescriptor = paramsDescriptor.Substring(1, paramsDescriptor.LastIndexOf(')') - 1); Method ctorMethod = new Method(); ctorMethod.AccessFlags = MethodAccessFlags.Public; ctorMethod.Name = ClassNames.JavaConstructorMethodName; ctorMethod.Descriptor = "(" + GetFieldDescriptor(type) + paramsDescriptor + ")V"; ctorMethod.Attributes.Add(ctorCodeWriter.End(runner.ConstantPool)); runner.Methods.Add(ctorMethod); Method runMethod = new Method(); runMethod.AccessFlags = MethodAccessFlags.Public; runMethod.Name = ClassNames.CIL2JavaDelegateRunner.RunMethodName; runMethod.Descriptor = "()V"; runMethod.Attributes.Add(runCodeWriter.End(runner.ConstantPool)); runner.Methods.Add(runMethod); WriteClass(runner); }