private void CompileOverridedMethods(InterType type, InterType iface) { var renamedMethods = iface.Methods.Where(I => I.NewName != I.Name); foreach (InterMethod renamedMethod in renamedMethods) { InterMethod overrideMethod = type.Methods.Where(M => M.Overrides.Contains(renamedMethod)).FirstOrDefault(); if (overrideMethod == null) { overrideMethod = type.Methods.Where(M => M.IsSame(renamedMethod)).FirstOrDefault(); } if (overrideMethod == null) { // In CIL interfaces didn't duplicate methods from base interfaces if (!type.IsInterface) { Messages.Message(MessageCode.CantFindInterfaceImplMethod, renamedMethod.ToString(), type.Fullname); } continue; } GenerateInterfaceMethodAccessor(renamedMethod, overrideMethod); } }
private string GetMethodDescriptor(InterMethod method) { if ((Program.MethodPointersType == MethodPointerImplementation.Fast) && (method.IsConstructor) && (method.DeclaringType.IsDelegate)) { return("(L" + TypeNameToJava(ClassNames.JavaObject) + ";L" + TypeNameToJava(((INamesController)this).GetMethodPointerInterface( method.DeclaringType.Methods.Where(M => M.Name == ClassNames.DelegateInvokeMethodName).FirstOrDefault())) + ";)V"); } StringBuilder result = new StringBuilder("("); foreach (InterParameter param in method.Parameters) { result.Append(GetFieldDescriptor(param.Type)); } if (method.IsVarArg) { result.Append("[L" + TypeNameToJava(ClassNames.JavaObject) + ";"); } result .Append(')') .Append(GetFieldDescriptor(method.ReturnParameter.Type)); return(result.ToString()); }
InterMethod IResolver.Resolve(MethodReference methodRef, List <InterGenericArgument> genericArgs) { InterMethod founded = null; InterMethod tmp = new InterMethod(methodRef, genericArgs, this, M => founded = M); if (founded == null) { Messages.Verbose("Adding method {0} to compile...", tmp.ToString()); tmp.DeclaringType.Methods.Add(tmp); founded = tmp; var unionedGenericArgs = tmp.FullGenericArguments; if (tmp.HasBody) { MethodDefinition methodDef = tmp.Body.Method; ILAstBuilder builder = new ILAstBuilder(); ILBlock ilBody = new ILBlock(); DecompilerContext context = new DecompilerContext(methodDef.Module) { CurrentType = methodDef.DeclaringType, CurrentMethod = methodDef }; Utils.SetDecompillerSettings(context.Settings); ilBody.Body = builder.Build(methodDef, true, context); new ILAstOptimizer().Optimize(context, ilBody); ProcessMethodDecencies(tmp, ilBody, tmp.FullGenericArguments); } } return(founded); }
public bool Equals(InterMethod m) { if (declType != m.declType) { return(false); } if (name != m.name) { return(false); } if (returnParam.Type != m.returnParam.Type) { return(false); } if (parameters.Count != m.parameters.Count) { return(false); } for (int i = 0; i < parameters.Count; i++) { if (parameters[i].Type != m.parameters[i].Type) { return(false); } } return(true); }
public CodeCompiler(IResolver resolver, INamesController namesController, IByRefController byRefController, InterMethod method, Java.ConstantPool constsPool) { this.resolver = resolver; this.namesController = namesController; this.byRefController = byRefController; this.thisMethod = method; this.constsPool = constsPool; }
private void CompileAddressOf(ILExpression e, ExpectType expectType) { e = e.Arguments[0]; if (e.Operand is TypeReference) { //ValueType CompileExpression(e, expectType); return; } else if (!(e.Operand is MethodReference)) { CompileExpression(e, ExpectType.Boxed); return; } InterMethod method = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); InterType operand = method.DeclaringType; if (!operand.IsArray) { //Getter if (method.ReturnParameter.Type.IsPrimitive) { CompileExpression(e, ExpectType.Boxed); } else { CompileExpression(e, GetExpectType(method.ReturnParameter)); } return; } JavaArrayType arrType = JavaHelpers.InterTypeToJavaArrayType(operand); string arrayByRefName = byRefController.GetArrayByRefTypeName(operand); Java.Constants.Class arrayByRefNameClass = new Java.Constants.Class(namesController.TypeNameToJava(arrayByRefName)); Java.Constants.MethodRef arrayByRefInitMethodRef = byRefController.GetArrayByRefCtorMethodRef(operand); codeGenerator .Add(OpCodes._new, arrayByRefNameClass, e) .Add(OpCodes.dup, null, e); CompileExpression(e.Arguments[0], ExpectType.Reference); //array CompileExpression(e.Arguments[1], ExpectType.Primitive); //first index for (int i = 0; i < operand.ArrayRank - 1; i++) { codeGenerator.Add(Java.OpCodes.aaload, null, e); CompileExpression(e.Arguments[i + 2], ExpectType.Primitive); } codeGenerator.Add(OpCodes.invokespecial, arrayByRefInitMethodRef, e); }
public override bool Equals(object obj) { InterMethod o = obj as InterMethod; if (o == null) { return(false); } return(Equals(o)); }
string INamesController.GetMethodPointerInterface(InterMethod method) { string result = ClassNames.MethodPointerPrefix + escapeTypeName(method.ReturnParameter.Type.Fullname) + "_" + string.Join("_", method.Parameters.Select(P => escapeTypeName(P.Type.Fullname)).ToArray()); if (!methodPointerInterfaces.ContainsKey(result)) { methodPointerInterfaces.Add(result, method); } return(result); }
private void RenameMethod(InterMethod method, string newName) { method.NewName = newName; foreach (InterType derivedType in typesToCompile.Where(T => T.BaseType == method.DeclaringType)) { InterMethod derivedMethod = derivedType.Methods.Where(M => M.IsSame(method)).FirstOrDefault(); if (derivedMethod != null) { RenameMethod(derivedMethod, newName); } } }
private void CompileArrayGet(ILExpression e, ExpectType expect) { InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); JavaArrayType arrType = JavaHelpers.InterTypeToJavaArrayType(operand.DeclaringType.ElementType); codeGenerator.AddArrayLoad(arrType, e); if (operand.DeclaringType.ElementType.IsValueType) { MethodRef getCopyRef = new MethodRef(namesController.TypeNameToJava(operand.DeclaringType.ElementType), ClassNames.ValueTypeGetCopy, "()" + namesController.GetFieldDescriptor(operand.DeclaringType.ElementType)); codeGenerator.Add(Java.OpCodes.invokevirtual, getCopyRef, e); } }
private void CompileNewmultiarray(ILExpression e, ExpectType expect) { InterMethod ctor = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); InterType arrType = ctor.DeclaringType; for (int i = 0; i < arrType.ArrayRank; i++) { CompileExpression(e.Arguments[i], ExpectType.Primitive); } //TODO: lower and apper bounds codeGenerator.AddMultianewarray(new Java.Constants.Class(namesController.GetFieldDescriptor(arrType)), (byte)arrType.ArrayRank); }
private void CompileDelegateBeginInvoke(InterType type) { InterMethod beginInvokeMethod = type.Methods.Where(M => M.Name == ClassNames.DelegateBeginInvokeMethodName).FirstOrDefault(); Method result = new Method(); result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final; result.Name = ClassNames.DelegateBeginInvokeMethodName; result.Descriptor = GetMethodDescriptor(beginInvokeMethod); string runnerName = currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName; JavaBytecodeWriter codeWriter = new JavaBytecodeWriter(); codeWriter .Add(OpCodes._new, new Java.Constants.Class(TypeNameToJava(ClassNames.SystemRuntimeRemotingMessagingAsyncResult.ClassName))) .Add(OpCodes.dup) .Add(OpCodes._new, new Java.Constants.Class(runnerName)) .Add(OpCodes.dup) .Add(OpCodes.aload_0); int paramsCount = beginInvokeMethod.Parameters.Count; string paramsDescriptors = ""; for (int i = 0; i < paramsCount - 2; i++) { InterType paramType = beginInvokeMethod.Parameters[i].Type; codeWriter.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(paramType), i + 1); paramsDescriptors += GetFieldDescriptor(paramType); } codeWriter .Add(OpCodes.invokespecial, new MethodRef(runnerName, ClassNames.JavaConstructorMethodName, "(" + GetFieldDescriptor(type) + paramsDescriptors + ")V")) .Add(OpCodes.aload_0) .AddLoad(JavaPrimitiveType.Ref, paramsCount - 1) .AddLoad(JavaPrimitiveType.Ref, paramsCount) .Add(OpCodes.invokespecial, ClassNames.SystemRuntimeRemotingMessagingAsyncResult.CtorMethodRef) .Add(OpCodes.areturn); result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool)); currentJavaClass.Methods.Add(result); }
//Find this() or super() calls in ctor to move it to begin of method private void PreprocessorFindAndMoveSuperOrThisCalls() { if (!thisMethod.IsConstructor) { return; } ILExpression call = null; foreach (ILNode node in ilBody.Body) { ILExpression e = node as ILExpression; if (e == null) { continue; } if (e.Code != ILCode.Call) { continue; } InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); if (!operand.IsConstructor) { continue; } if (operand.DeclaringType != thisMethod.DeclaringType) { if (operand.DeclaringType != thisMethod.DeclaringType.BaseType) { continue; } } call = e; break; } if (call != null) { ilBody.Body.Remove(call); firstCall = call; } }
private void CompileNewobj(ILExpression e, ExpectType expect) { InterMethod ctor = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); if (ctor.DeclaringType.IsArray) { CompileNewmultiarray(e, expect); } else { Java.Constants.Class declTypeClassRef = new Java.Constants.Class( namesController.TypeNameToJava(ctor.DeclaringType)); codeGenerator .Add(Java.OpCodes._new, declTypeClassRef, e) .Add(Java.OpCodes.dup, null, e); CompileCall(e, expect); } }
private void CompileIntrinsicCreatePointerToArray(ILExpression e) { InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); InterType refType = operand.GenericArguments[0].Type; string arrayByRefName = byRefController.GetArrayByRefTypeName(refType); Java.Constants.Class arrayByRefNameClass = new Java.Constants.Class(namesController.TypeNameToJava(arrayByRefName)); Java.Constants.MethodRef arrayByRefInitMethodRef = byRefController.GetArrayByRefCtorMethodRef(refType); codeGenerator .Add(OpCodes._new, arrayByRefNameClass, e) .Add(OpCodes.dup, null, e); CompileExpression(e.Arguments[0], ExpectType.Reference); //array CompileExpression(e.Arguments[1], ExpectType.Primitive); //index codeGenerator.Add(OpCodes.invokespecial, arrayByRefInitMethodRef, e); }
private void CompileArrayCall(ILExpression e, ExpectType expect) { InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); CompileExpression(e.Arguments[0], ExpectType.Reference); //array CompileExpression(e.Arguments[1], ExpectType.Primitive); //first index for (int i = 0; i < operand.DeclaringType.ArrayRank - 1; i++) { codeGenerator.Add(Java.OpCodes.aaload, null, e); CompileExpression(e.Arguments[i + 2], ExpectType.Primitive); } if (operand.Name == "Set") { CompileArraySet(e, expect); } else if (operand.Name == "Get") { CompileArrayGet(e, expect); } }
private void CompileLdftn(ILExpression e, ExpectType expect) { InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); string methodPointerClass = GenerateMethodPointerClass(operand); if (Program.MethodPointersType == MethodPointerImplementation.Fast) { Java.Constants.Class mpClassRef = new Java.Constants.Class(namesController.TypeNameToJava(methodPointerClass)); MethodRef mpInitRef = new MethodRef(mpClassRef.Value, ClassNames.JavaConstructorMethodName, "()V"); codeGenerator .Add(OpCodes._new, mpClassRef, e) .Add(OpCodes.dup, null, e) .Add(OpCodes.invokespecial, mpInitRef, e); } else { codeGenerator .Add(OpCodes.ldc, new Java.Constants.String(methodPointerClass.Replace('/', '$'))) .Add(OpCodes.invokestatic, ClassNames.GlobalMethodPointersAdd); } }
private void GenerateInterfaceMethodAccessor(InterMethod ifaceMethod, InterMethod typeMethod) { Method result = new Method(); result.AccessFlags = MethodAccessFlags.Public; if (ifaceMethod.IsVarArg) { result.AccessFlags |= MethodAccessFlags.VarArgs; } result.Name = MethodNameToJava(ifaceMethod.NewName); result.Descriptor = GetMethodDescriptor(ifaceMethod); JavaBytecodeWriter code = new JavaBytecodeWriter(); code.Add(OpCodes.aload_0); for (int i = 0; i < ifaceMethod.Parameters.Count; i++) { code.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(ifaceMethod.Parameters[i].Type), i + 1); } MethodRef typeMethodRef = new MethodRef(TypeNameToJava(typeMethod.DeclaringType.Fullname), MethodNameToJava(typeMethod.NewName), GetMethodDescriptor(typeMethod)); if (typeMethod.IsPrivate) { code.Add(OpCodes.invokespecial, typeMethodRef); } else { code.Add(OpCodes.invokevirtual, typeMethodRef); } code.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(ifaceMethod.ReturnParameter.Type)); result.Attributes.Add(code.End(currentJavaClass.ConstantPool)); currentJavaClass.Methods.Add(result); }
private void CompileDelegateEndInvoke(InterType type) { InterMethod endInvokeMethod = type.Methods.Where(M => M.Name == ClassNames.DelegateEndInvokeMethodName).FirstOrDefault(); Method result = new Method(); result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final; result.Name = ClassNames.DelegateEndInvokeMethodName; result.Descriptor = GetMethodDescriptor(endInvokeMethod); JavaBytecodeWriter codeWriter = new JavaBytecodeWriter(); codeWriter .Add(OpCodes.aload_1) .Add(OpCodes.checkcast, new Java.Constants.Class(TypeNameToJava(ClassNames.SystemRuntimeRemotingMessagingAsyncResult.ClassName))) .Add(OpCodes.invokevirtual, ClassNames.SystemRuntimeRemotingMessagingAsyncResult.EndInvokeMethodRef); if (endInvokeMethod.ReturnParameter.Type.PrimitiveType == PrimitiveType.Void) { codeWriter.Add(OpCodes.pop); } else { codeWriter .Add(OpCodes.checkcast, new Java.Constants.Class(currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName)) .Add(OpCodes.getfield, new Java.Constants.FieldRef( currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName, ClassNames.DelegateRunnerResultFieldName, GetFieldDescriptor(endInvokeMethod.ReturnParameter.Type))); } codeWriter.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(endInvokeMethod.ReturnParameter.Type)); result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool)); currentJavaClass.Methods.Add(result); }
private void CompileArraySet(ILExpression e, ExpectType expect) { InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); CompileExpression(e.Arguments.Last(), GetExpectType(operand.DeclaringType.ElementType)); JavaArrayType arrType = JavaHelpers.InterTypeToJavaArrayType(operand.DeclaringType); bool needDup = ((e.ExpectedType != null) && (expect != ExpectType.None)); if (needDup) { if (JavaHelpers.InterTypeToJavaPrimitive(operand.DeclaringType).IsDoubleSlot()) { codeGenerator.Add(Java.OpCodes.dup2_x2, null, e); } else { codeGenerator.Add(Java.OpCodes.dup_x2, null, e); } } codeGenerator.AddArrayStore(arrType, e); }
private void CompileLdtoken(ILExpression e, ExpectType expect) { if (e.Operand is TypeReference) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); codeGenerator .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.SystemRuntimeTypeHandle.ClassName)), e) .Add(OpCodes.dup, null, e) .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand)), e) .Add(OpCodes.invokespecial, ClassNames.SystemRuntimeTypeHandle.CtorMethodRef, e); } else if (e.Operand is FieldReference) { InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments); codeGenerator .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.SystemRuntimeFieldHandle.ClassName)), e) .Add(OpCodes.dup, null, e) .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand.DeclaringType)), e) .Add(OpCodes.ldc, new Java.Constants.String(operand.Name), e) .Add(OpCodes.invokevirtual, ClassNames.JavaLangClass.getDeclaredFieldRef, e) .Add(OpCodes.invokespecial, ClassNames.SystemRuntimeFieldHandle.CtorMethodRef, e); } else if (e.Operand is MethodReference) { InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); codeGenerator .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.SystemRuntimeMethodHandle.ClassName)), e) .Add(OpCodes.dup, null, e) .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand.DeclaringType)), e); if (!operand.IsConstructor) { codeGenerator.Add(OpCodes.ldc, new Java.Constants.String(operand.NewName), e); } codeGenerator .AddIntConst(operand.Parameters.Count, e) .Add(OpCodes.anewarray, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.JavaLangClass.ClassName)), e); for (int i = 0; i < operand.Parameters.Count; i++) { codeGenerator .Add(OpCodes.dup) .AddIntConst(i, e) .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand.Parameters[i].Type))) .Add(OpCodes.aastore, null, e); } if (operand.IsConstructor) { codeGenerator.Add(OpCodes.invokevirtual, ClassNames.JavaLangClass.getDeclaredConstructorRef, e); } else { codeGenerator.Add(OpCodes.invokevirtual, ClassNames.JavaLangClass.getDeclaredMethodRef, e); } codeGenerator.Add(OpCodes.invokespecial, ClassNames.SystemRuntimeMethodHandle.CtorMethodRef, e); } }
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); }
public MethodSignature(InterMethod method) { this.Name = method.Name; this.Parameters = method.Parameters.Select(IP => IP.Type.Fullname).ToArray(); }
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); }
public InterMethod(MethodReference methodRef, List <InterGenericArgument> genericArgs, IResolver resolver, Action <InterMethod> onFounded) { originalName = methodRef.Name; genericArgs = genericArgs ?? InterGenericArgument.EmptyGenericArgsList; MethodDefinition methodDef = methodRef.Resolve(); CustomAttribute methodMapCustomAttr = null; if (methodDef != null) { methodMapCustomAttr = methodDef.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.MethodMapAttribute).FirstOrDefault(); if ((methodMapCustomAttr == null) && (Program.BoxType == BoxingType.Java)) { methodMapCustomAttr = methodDef.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.JavaBoxMethodMapAttribute).FirstOrDefault(); } } declType = resolver.Resolve(methodRef.DeclaringType, genericArgs); #region Mapping if (methodMapCustomAttr != null) { TypeReference realDeclType = methodMapCustomAttr.ConstructorArguments[0].Value as TypeReference; TypeDefinition realDeclTypeDef = realDeclType.Resolve(); string mappedName = (string)methodMapCustomAttr.ConstructorArguments[1].Value; MethodDefinition md = null; int paramsOffset = 0; if ((methodMapCustomAttr.ConstructorArguments.Count > 2) && ((bool)methodMapCustomAttr.ConstructorArguments[2].Value)) { paramsOffset = 1; } foreach (var method in realDeclTypeDef.Methods) { if (method.Name != mappedName) { continue; } if (method.HasGenericParameters != methodDef.HasGenericParameters) { continue; } if (method.HasGenericParameters && method.GenericParameters.Count != methodDef.GenericParameters.Count) { continue; } if (!Utils.AreSame(method.ReturnType, methodDef.ReturnType)) { continue; } if (paramsOffset == 0) { if ((!method.HasParameters) && (methodDef.HasParameters)) { md = method; break; } } else { if (!method.HasParameters) { continue; } if ((!methodRef.HasParameters) && (method.Parameters.Count == 1)) { md = method; break; } } if (!Utils.AreSame(method.Parameters, methodDef.Parameters, paramsOffset)) { continue; } md = method; break; } if (md == null) { throw new Exception(); //TODO: mapping error } MethodReference newMethodRef = md; if (methodRef is GenericInstanceMethod) { GenericInstanceMethod oldGIM = (GenericInstanceMethod)methodRef; GenericInstanceMethod newGIM = new GenericInstanceMethod(newMethodRef); oldGIM.GenericArguments.ForEach(T => newGIM.GenericArguments.Add(T)); newMethodRef = newGIM; } onFounded(resolver.Resolve(newMethodRef, genericArgs)); return; } else #endregion { name = methodRef.Name; } genericArgs.AddRange(declType.GenericArguments); if ((methodDef ?? methodRef).HasGenericParameters) { GenericInstanceMethod gim = methodRef as GenericInstanceMethod; for (int i = 0; i < (methodDef ?? methodRef).GenericParameters.Count; i++) { GenericParameter gp = (methodDef ?? methodRef).GenericParameters[i]; TypeReference genericArg = null; if (gim != null) { genericArg = gim.GenericArguments[i]; } if (genericArg is GenericParameter) { gp = (GenericParameter)genericArg; genericArg = null; } InterType resolvedGenericArg = null; if (genericArg == null) { var resolvedInterGenericArg = genericArgs.Where(G => G.Owner == Utils.CecilGenericOwnerToC2JGenericOwner(gp.Type) && G.Position == gp.Position); if (resolvedInterGenericArg.Count() > 0) { resolvedGenericArg = resolvedInterGenericArg.First().Type; } } if (resolvedGenericArg != null) { this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Method, i, resolvedGenericArg)); } else if (genericArg != null) { this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Method, i, resolver.Resolve(genericArg, genericArgs))); } else { Messages.Message(MessageCode.CantResolveGenericParameter, gp.ToString(), methodRef.ToString()); this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Method, i, resolver.Resolve(ClassNames.ObjectTypeName))); } } string genericsSufix = "<" + string.Join(",", this.genericArgs.Select(G => G.Type.Fullname)) + ">"; this.name = this.name + "_GIM_" + resolver.GetGenericsArgsIndex(genericsSufix).ToString(); } if (methodDef != null) { CustomAttribute fromJavaCustomAttr = methodDef.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.FromJavaAttribute).FirstOrDefault(); if (fromJavaCustomAttr != null) { FromJava = true; if (fromJavaCustomAttr.ConstructorArguments.Count > 0) { name = fromJavaCustomAttr.ConstructorArguments[0].Value.ToString(); } } } if (methodRef.HasThis) { thisParam = new InterParameter(0, declType, "this"); } this.returnParam = new InterParameter(-1, resolver.Resolve(methodRef.ReturnType, this.FullGenericArguments), "return", methodRef.MethodReturnType.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.BoxedAttribute).Count() > 0, methodRef.MethodReturnType.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.JavaBoxedAttribute).Count() > 0); foreach (ParameterDefinition paramDef in methodRef.Parameters) { if (paramDef.ParameterType.IsSentinel) { break; } parameters.Add(new InterParameter(paramDef, this.FullGenericArguments, resolver)); } if (methodDef != null) { if (methodDef.HasBody) { body = methodDef.Body; } IsPublic = methodDef.IsPublic || methodDef.IsAssembly; IsProtected = methodDef.IsFamily || methodDef.IsFamilyAndAssembly || methodDef.IsFamilyOrAssembly; IsPrivate = methodDef.IsPrivate; IsAbstract = methodDef.IsAbstract; IsFinal = methodDef.IsFinal; IsVirtual = methodDef.IsVirtual; IsNewSlot = methodDef.IsNewSlot; IsStatic = methodDef.IsStatic; IsSynchronized = methodDef.IsSynchronized; IsConstructor = methodDef.IsConstructor; IsVarArg = methodDef.CallingConvention == MethodCallingConvention.VarArg; HasThis = methodDef.HasThis; HasBody = methodDef.HasBody; foreach (MethodReference overridedMethod in methodDef.Overrides) { overrides.Add(resolver.Resolve(overridedMethod, this.FullGenericArguments)); } } else { IsPublic = true; IsFinal = true; HasThis = methodRef.HasThis; IsStatic = !methodRef.HasThis; } if ((!IsConstructor) && (!declType.IsDelegate)) { //TODO: change params in ctors var changedParams = parameters.Where(P => ((P.Type.IsEnum) || ((P.Type.IsPrimitive) && (Utils.IsUnsigned(P.Type.PrimitiveType))))); if (changedParams.Count() > 0) { name += "$" + string.Join("_", changedParams.Select(P => P.Index + P.Type.Fullname)); } } InterMethod thisFromDecl = declType.Methods.Where(M => M.Equals(this)).FirstOrDefault(); if (thisFromDecl != null) { onFounded(thisFromDecl); } }
private Method CompileMethod(InterMethod method) { Messages.Verbose(" Compiling method {0}...", method.ToString()); Method result = new Method(); if (method.IsPublic) { result.AccessFlags |= MethodAccessFlags.Public; } else if (method.IsProtected) { result.AccessFlags |= MethodAccessFlags.Protected; } else { result.AccessFlags |= MethodAccessFlags.Private; } if (method.IsAbstract) { result.AccessFlags |= MethodAccessFlags.Abstract; } if ((method.IsFinal) || ((!method.IsVirtual) && (!method.IsConstructor)) && (!method.IsStatic)) { result.AccessFlags |= MethodAccessFlags.Final; } if (method.IsStatic) { result.AccessFlags |= MethodAccessFlags.Static; } if (method.IsSynchronized) { result.AccessFlags |= MethodAccessFlags.Synchronized; } if ((method.IsPrivate) && (method.IsVirtual)) { Messages.Message(MessageCode.MethodPrivateAndVirtual, method.ToString()); } if (method.IsVarArg) { result.AccessFlags |= MethodAccessFlags.VarArgs; } result.Name = MethodNameToJava(method.NewName); result.Descriptor = GetMethodDescriptor(method); if (method.HasBody) { CodeCompiler codeCompiler = new CodeCompiler(this, this, this, method, currentJavaClass.ConstantPool); codeCompiler.Compile(); result.Attributes.Add(codeCompiler.Result); if (Program.Debug) { string sourceFileName = codeCompiler.SourceFile; if (sourceFileName != null) { sourceFileNameCounter.Add(sourceFileName); } } } if ((method.IsStatic) && (method.IsConstructor)) { result.AccessFlags = MethodAccessFlags.Static; } return(result); }
private void ProcessMethodDecencies(InterMethod method, ILNode node, List <InterGenericArgument> genericArgs) { if (node is ILBlock) { ILBlock block = node as ILBlock; foreach (ILNode n in block.Body) { ProcessMethodDecencies(method, n, genericArgs); } } else if (node is ILBasicBlock) { ILBasicBlock block = node as ILBasicBlock; foreach (ILNode n in block.Body) { ProcessMethodDecencies(method, n, genericArgs); } } else if (node is ILTryCatchBlock) { ILTryCatchBlock block = node as ILTryCatchBlock; foreach (ILNode n in block.TryBlock.Body) { ProcessMethodDecencies(method, n, genericArgs); } if (block.FaultBlock != null) { foreach (ILNode n in block.FaultBlock.Body) { ProcessMethodDecencies(method, n, genericArgs); } } if (block.FinallyBlock != null) { foreach (ILNode n in block.FinallyBlock.Body) { ProcessMethodDecencies(method, n, genericArgs); } } foreach (var catchBlock in block.CatchBlocks) { ((IResolver)this).Resolve(catchBlock.ExceptionType, genericArgs); ProcessMethodDecencies(method, catchBlock, genericArgs); } } else if (node is ILExpression) { ILExpression e = node as ILExpression; foreach (var n in e.Arguments) { ProcessMethodDecencies(method, n, genericArgs); } if ((e.Code == ILCode.Mkrefany) || (e.Code == ILCode.Refanyval)) { ((IResolver)this).Resolve(ClassNames.SystemTypedReference.ClassName); } if (e.Code == ILCode.Refanytype) { ((IResolver)this).Resolve(ClassNames.SystemTypedReference.ClassName); ((IResolver)this).Resolve(ClassNames.SystemRuntimeTypeHandle.ClassName); } if (e.Code == ILCode.Arglist) { ((IResolver)this).Resolve(ClassNames.SystemRuntimeArgumentHandle.ClassName); } if (e.Code.IsExternalRealization()) { ((IResolver)this).Resolve(ClassNames.CIL2JavaVESInstructions.ClassName); } if (e.Code == ILCode.Ldc_Decimal) { ((IResolver)this).Resolve(ClassNames.SystemDecimal.ClassNames); } if (e.Code == ILCode.Ldtoken) { if (e.Operand is TypeReference) { ((IResolver)this).Resolve(ClassNames.SystemRuntimeTypeHandle.ClassName); } else if (e.Operand is FieldReference) { ((IResolver)this).Resolve(ClassNames.SystemRuntimeFieldHandle.ClassName); } else if (e.Operand is MethodReference) { ((IResolver)this).Resolve(ClassNames.SystemRuntimeMethodHandle.ClassName); } } if (e.Operand is ILVariable) { ((IResolver)this).Resolve(((ILVariable)e.Operand).Type, genericArgs); } if (e.Operand is TypeReference) { ((IResolver)this).Resolve((TypeReference)e.Operand, genericArgs); } if (e.Operand is MethodReference) { ((IResolver)this).Resolve((MethodReference)e.Operand, genericArgs); } if (e.Operand is FieldReference) { InterField fld = ((IResolver)this).Resolve((FieldReference)e.Operand, genericArgs); bool needAccessor = false; if ((fld.IsPrivate) && (fld.DeclaringType != method.DeclaringType)) { needAccessor = true; } else if ((fld.IsProtected) && (fld.DeclaringType != method.DeclaringType) && (!method.DeclaringType.IsSuper(fld.DeclaringType))) { needAccessor = true; } if (needAccessor) { switch (e.Code) { case ILCode.Ldflda: case ILCode.Ldsflda: if (fld.FieldType.IsValueType) { fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Getter, fld)); } break; case ILCode.Ldfld: case ILCode.Ldsfld: fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Getter, fld)); break; case ILCode.Stfld: case ILCode.Stsfld: fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Setter, fld)); break; } } } InterType expected = null; InterType inferred = null; if (e.ExpectedType != null) { expected = ((IResolver)this).Resolve(e.ExpectedType, genericArgs); } if (e.InferredType != null) { inferred = ((IResolver)this).Resolve(e.InferredType, genericArgs); } if ((expected != null) && (expected.IsInterface) && (inferred != null) && (inferred.IsArray)) { ((IResolver)this).Resolve(ClassNames.ArraysInterfaceAdapterTypeName, new List <InterGenericArgument>() { new InterGenericArgument(GenericArgumentOwnerType.Type, 0, inferred.ElementType) }); } } else if (node is ILWhileLoop) { ILWhileLoop loop = node as ILWhileLoop; ProcessMethodDecencies(method, loop.Condition, genericArgs); ProcessMethodDecencies(method, loop.BodyBlock, genericArgs); } else if (node is ILCondition) { ILCondition cond = node as ILCondition; ProcessMethodDecencies(method, cond.Condition, genericArgs); ProcessMethodDecencies(method, cond.TrueBlock, genericArgs); ProcessMethodDecencies(method, cond.FalseBlock, genericArgs); } else if (node is ILSwitch) { ILSwitch sw = node as ILSwitch; ProcessMethodDecencies(method, sw.Condition, genericArgs); foreach (var c in sw.CaseBlocks) { ProcessMethodDecencies(method, c, genericArgs); } } else if (node is ILFixedStatement) { ILFixedStatement fs = node as ILFixedStatement; foreach (var n in fs.Initializers) { ProcessMethodDecencies(method, n, genericArgs); } ProcessMethodDecencies(method, fs.BodyBlock, genericArgs); } }
private void CompileCondition(ILCondition node, ExpectType expectType) { ILExpression condition = node.Condition; while (condition != null) { if (condition.Code == ILCode.Call) { InterMethod callMethod = resolver.Resolve((MethodReference)condition.Operand, thisMethod.FullGenericArguments); if (callMethod.DeclaringType.Fullname == ClassNames.Intrinsics.ClassName) { if (callMethod.Name == ClassNames.Intrinsics.IsCILBoxing) { if (Program.BoxType == BoxingType.Cil) { CompileBlock(node.TrueBlock); } return; } if (callMethod.Name == ClassNames.Intrinsics.IsJavaBoxing) { if (Program.BoxType == BoxingType.Java) { CompileBlock(node.TrueBlock); } return; } } break; } condition = condition.Arguments.FirstOrDefault(); } string labelsSufix = rnd.Next().ToString(); string falseLabel = "false" + labelsSufix; string exitLabel = "exit" + labelsSufix; if (node.FalseBlock.Body.Count == 0) { falseLabel = exitLabel; } CompileCondition(new ILExpression(ILCode.LogicNot, null, node.Condition), falseLabel); //CompileExpression(node.Condition, ExpectType.Primitive); //Java.OpCodes branchInstr = Java.OpCodes.ifeq; //TranslateToBool(node.Condition.InferredType, ref branchInstr, node); //codeGenerator.Add(branchInstr, falseLabel, node); CompileBlock(node.TrueBlock, expectType); if (node.FalseBlock.Body.Count > 0) { codeGenerator.Add(Java.OpCodes._goto, exitLabel, node) .Label(falseLabel); CompileBlock(node.FalseBlock, expectType); } codeGenerator.Label(exitLabel); }
private void CompileCall(ILExpression e, ExpectType expect) { InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); if (operand.DeclaringType.Fullname == ClassNames.SystemThreadingMonitor.ClassName) { if (operand.Name == ClassNames.SystemThreadingMonitor.Enter) { CompileMonitorEnter(e); return; } if (operand.Name == ClassNames.SystemThreadingMonitor.Exit) { CompileMonitorExit(e); return; } } // Intrinsics that not poping real arguments if (operand.DeclaringType.Fullname == ClassNames.Intrinsics.ClassName) { if (operand.Name.Contains(ClassNames.Intrinsics.CreatePointerToArray)) { CompileIntrinsicCreatePointerToArray(e); return; } if (operand.Name == ClassNames.Intrinsics.GetBoxedDataFromPointer) { CompileIntrinsicGetBoxedDataFromPointer(e); return; } if (operand.Name == ClassNames.Intrinsics.GetClass) { CompileIntrinsicGetClass(e); return; } } if ((Program.BoxType == BoxingType.Java) && (operand.DeclaringType.Fullname == ClassNames.CorlibUtils) && (operand.Name == ClassNames.ReboxMethod)) { //Skip CIL2Java.Utils::Rebox in java boxing mode due optimizations CompileExpression(e.Arguments[0], expect); return; } if ((operand.IsConstructor) && (operand.DeclaringType.IsValueType) && (operand.Parameters.Count < e.Arguments.Count) && (!thisMethod.IsConstructor)) { // rebuild nodes from `call ctor(getVar(), [params])` to // setVar(newObj([params]) ILExpression getVar = e.Arguments[0]; e.Arguments.RemoveAt(0); e.Code = ILCode.Newobj; getVar.Code = LoadVarInvert[getVar.Code]; getVar.Arguments.Add(e); CompileExpression(getVar, expect); return; } if (operand.DeclaringType.IsArray) { CompileArrayCall(e, expect); return; } int argIndex = 0; if ((operand.HasThis) && (operand.Parameters.Count < e.Arguments.Count)) { if (e.Prefixes != null) { ILExpressionPrefix constrained = e.Prefixes.Where(P => P.Code == ILCode.Constrained).FirstOrDefault(); if (constrained != null) { InterType thisType = resolver.Resolve((TypeReference)constrained.Operand, thisMethod.FullGenericArguments); if (thisType.IsPrimitive) { e.Arguments[argIndex].Code = GetAddrInvert[e.Arguments[argIndex].Code]; e.Arguments[argIndex] = new ILExpression(ILCode.Box, null, e.Arguments[argIndex]); } } } CompileExpression(e.Arguments[argIndex++], ExpectType.Reference); } foreach (InterParameter param in operand.Parameters) { CompileExpression(e.Arguments[argIndex++], GetExpectType(param)); } if (operand.IsVarArg) { codeGenerator .AddIntConst(e.Arguments.Count - argIndex) .Add(OpCodes.anewarray, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.JavaObject)), e); int i = 0; while (argIndex < e.Arguments.Count) { codeGenerator .Add(OpCodes.dup, null, e) .AddIntConst(i++, e); CompileExpression(e.Arguments[argIndex++], ExpectType.Boxed); codeGenerator.Add(OpCodes.aastore, null, e); } } // Intrinsics that poping real arguments if (operand.DeclaringType.Fullname == ClassNames.Intrinsics.ClassName) { if (operand.Name == ClassNames.Intrinsics.monitorenter) { codeGenerator.Add(Java.OpCodes.monitorenter, null, e); } if (operand.Name == ClassNames.Intrinsics.monitorexit) { codeGenerator.Add(Java.OpCodes.monitorexit, null, e); } if (operand.Name == ClassNames.Intrinsics.lshr) { codeGenerator.Add(Java.OpCodes.lshr, null, e); } if (operand.Name == ClassNames.Intrinsics.lushr) { codeGenerator.Add(Java.OpCodes.lushr, null, e); } // UnsafeTypeConvert skip because: // Not any compiling. Just push argument, and it will auto became object type return; } CallType callType = CallType.Virtual; if (operand.IsStatic) { callType = CallType.Static; } else if (operand.DeclaringType.IsInterface) { callType = CallType.Interface; } else if ((operand.IsConstructor) || (operand.IsPrivate) || ((operand.IsSame(thisMethod)) && (thisMethod.DeclaringType.BaseType == operand.DeclaringType))) { callType = CallType.Special; } Java.Constant javaOperand = null; if (callType == CallType.Interface) { javaOperand = new Java.Constants.InterfaceMethodRef( namesController.TypeNameToJava(operand.DeclaringType), namesController.MethodNameToJava(operand.NewName), namesController.GetMethodDescriptor(operand)); } else { javaOperand = new Java.Constants.MethodRef( namesController.TypeNameToJava(operand.DeclaringType), namesController.MethodNameToJava(operand.NewName), namesController.GetMethodDescriptor(operand)); } switch (callType) { case CallType.Interface: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokeinterface, javaOperand, e)); break; case CallType.Special: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokespecial, javaOperand, e)); break; case CallType.Static: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokestatic, javaOperand, e)); break; case CallType.Virtual: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokevirtual, javaOperand, e)); break; } OnRestoreLocalByRefs(); if ((!operand.ReturnParameter.Type.IsPrimitive) || (operand.ReturnParameter.Type.PrimitiveType != PrimitiveType.Void) || (operand.ReturnParameter.IsBoxed) || (operand.ReturnParameter.IsJavaBoxed)) { TranslateType(operand.ReturnParameter.Type, expect, e); } }
private void CompileJmp(ILExpression e, ExpectType expect) { int argIndex = 0; if (thisMethod.HasThis) { codeGenerator.Add(Java.OpCodes.aload_0, null, e); argIndex++; } for (int i = 0; i < thisMethod.Parameters.Count; i++) { JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(thisMethod.Parameters[i].Type); codeGenerator.AddLoad(jp, argIndex++); if (jp.IsDoubleSlot()) { argIndex++; } } InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); CallType callType = CallType.Virtual; if (operand.IsStatic) { callType = CallType.Static; } else if (operand.DeclaringType.IsInterface) { callType = CallType.Interface; } else if ((operand.IsConstructor) || (operand.IsPrivate) || ((operand.IsSame(thisMethod)) && (thisMethod.DeclaringType.BaseType == operand.DeclaringType))) { callType = CallType.Special; } Java.Constant javaOperand = null; if (callType == CallType.Interface) { javaOperand = new Java.Constants.InterfaceMethodRef( namesController.TypeNameToJava(operand.DeclaringType), namesController.MethodNameToJava(operand.NewName), namesController.GetMethodDescriptor(operand)); } else { javaOperand = new Java.Constants.MethodRef( namesController.TypeNameToJava(operand.DeclaringType), namesController.MethodNameToJava(operand.NewName), namesController.GetMethodDescriptor(operand)); } switch (callType) { case CallType.Interface: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokeinterface, javaOperand, e)); break; case CallType.Special: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokespecial, javaOperand, e)); break; case CallType.Static: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokestatic, javaOperand, e)); break; case CallType.Virtual: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokevirtual, javaOperand, e)); break; } codeGenerator.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(thisMethod.ReturnParameter.Type)); }