private void FillVars(List <ILVariable> vars) { if (thisMethod.HasThis) { var2Index.Add(vars.Where(V => V.Name == "this").FirstOrDefault() ?? new ILVariable() { Name = "this" }, nextVarIndex++); } for (int i = 0; i < thisMethod.Parameters.Count; i++) { InterParameter param = thisMethod.Parameters[i]; ILVariable var = vars.Where(V => ((V.IsParameter) && (V.OriginalParameter.Index == param.Index))).FirstOrDefault(); var2Index.Add(var, nextVarIndex++); if (param.Type.IsPrimitive) { JavaPrimitiveType varType = JavaHelpers.PrimitiveTypeToJavaPrimitive(param.Type.PrimitiveType); if ((varType == JavaPrimitiveType.Long) || (varType == JavaPrimitiveType.Double)) { nextVarIndex++; } } } if (thisMethod.IsVarArg) { var2Index.Add(new ILVariable() { Name = ClassNames.VarArgParamName }, nextVarIndex++); } }
private void CompileStfld(ILExpression e, ExpectType expectType) { InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments); bool needDup = ((e.ExpectedType != null) && (expectType != ExpectType.None)); bool boxed = operand.IsStatic && operand.IsThreadLocal; int argIndex = 0; if (e.Code == ILCode.Stfld) CompileExpression(e.Arguments[argIndex++], ExpectType.Reference); CompileExpression(e.Arguments[argIndex++], boxed ? ExpectType.Boxed : GetExpectType(operand)); if (needDup) { JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(operand.FieldType); if (e.Code == ILCode.Stfld) { if (jp.IsDoubleSlot()) codeGenerator.Add(Java.OpCodes.dup2_x1, null, e); else codeGenerator.Add(Java.OpCodes.dup_x1, null, e); } else { if (jp.IsDoubleSlot()) codeGenerator.Add(Java.OpCodes.dup2, null, e); else codeGenerator.Add(Java.OpCodes.dup, null, e); } } CompileFieldStore(operand, e); }
private void CompileNeg(ILExpression e, ExpectType expect) { CompileExpression(e.Arguments[0], ExpectType.Primitive); InterType opType = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments); JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(opType); OpCodes opcode = OpCodes.ineg; switch (jp) { case JavaPrimitiveType.Long: opcode = OpCodes.lneg; break; case JavaPrimitiveType.Float: opcode = OpCodes.fneg; break; case JavaPrimitiveType.Double: opcode = OpCodes.dneg; break; case JavaPrimitiveType.Ref: throw new Exception(); //TODO: normal error } codeGenerator.Add(opcode, null, e); TranslateType(opType, expect, e); }
private void CompileConvR8(ILExpression e, ExpectType expect) { InterType gettedType = resolver.Resolve(e.Arguments[0].InferredType, thisMethod.FullGenericArguments); JavaPrimitiveType gettedJava = JavaHelpers.InterTypeToJavaPrimitive(gettedType); CompileExpression(e.Arguments[0], ExpectType.Any); switch (gettedJava) { case JavaPrimitiveType.Bool: case JavaPrimitiveType.Byte: case JavaPrimitiveType.Short: case JavaPrimitiveType.Char: case JavaPrimitiveType.Int: codeGenerator.Add(Java.OpCodes.i2d, e); break; case JavaPrimitiveType.Long: codeGenerator.Add(Java.OpCodes.l2d, e); break; case JavaPrimitiveType.Float: codeGenerator.Add(Java.OpCodes.f2d, e); break; case JavaPrimitiveType.Double: break; default: Messages.Message(MessageCode.CantConvertType, gettedType.Fullname, "double"); return; } TranslateType(InterType.PrimitiveTypes[(int)PrimitiveType.Double], expect, e); }
private int GetVarIndex(ILVariable var) { if (var2Index.ContainsKey(var)) { return(var2Index[var]); } int result = nextVarIndex++; var2Index.Add(var, result); InterType varType = resolver.Resolve(var.Type, thisMethod.FullGenericArguments); if (varType.IsPrimitive) { JavaPrimitiveType javaPrimitiv = JavaHelpers.PrimitiveTypeToJavaPrimitive(varType.PrimitiveType); if ((javaPrimitiv == JavaPrimitiveType.Long) || (javaPrimitiv == JavaPrimitiveType.Double)) { nextVarIndex++; } } else if (varType.IsValueType) { valueTypesVars.Add(new ValueTypeVar(varType, result)); } return(result); }
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); }
private void CompileLdloca(ILExpression e, ExpectType expectType) { ILVariable operand = (ILVariable)e.Operand; int varIndex = GetVarIndex(operand); InterType operandType = resolver.Resolve(operand.Type, thisMethod.FullGenericArguments); if (operandType.IsValueType) { codeGenerator.AddLoad(JavaPrimitiveType.Ref, varIndex); return; } if ((operandType.IsPrimitive) && (expectType == ExpectType.Reference)) { codeGenerator.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(operandType), varIndex, e); TranslateType(operandType, ExpectType.Boxed, e); return; } string localByRefName = byRefController.GetLocalByRefTypeName(operandType); Java.Constants.Class localByRefNameClass = new Java.Constants.Class(namesController.TypeNameToJava(localByRefName)); Java.Constants.MethodRef localByRefInitMethodRef = byRefController.GetLocalByRefCtorMethodRef(operandType); Java.Constants.MethodRef getValueMethodRef = byRefController.GetByRefGetValueMethodRef(JavaHelpers.InterTypeToJavaPrimitive(operandType)); int localRefTempVar = GetNextFreeVar(JavaPrimitiveType.Ref); codeGenerator .Add(OpCodes._new, localByRefNameClass, e) .Add(OpCodes.dup, null, e) .AddLocalVarInstruction(LocalVarInstruction.Load, JavaHelpers.InterTypeToJavaPrimitive(operandType), varIndex, e) .Add(OpCodes.invokespecial, localByRefInitMethodRef, e) .Add(OpCodes.dup, null, e) .AddLocalVarInstruction(LocalVarInstruction.Store, JavaPrimitiveType.Ref, localRefTempVar, e); RegisterLocalByRef(() => { codeGenerator .AddLocalVarInstruction(LocalVarInstruction.Load, JavaPrimitiveType.Ref, localRefTempVar, e) .Add(OpCodes.invokevirtual, getValueMethodRef, e); if ((!operandType.IsPrimitive) && (!operandType.IsEnum)) { codeGenerator.Add(OpCodes.checkcast, new Java.Constants.Class(namesController.TypeNameToJava(operandType)), e); } codeGenerator.AddLocalVarInstruction(LocalVarInstruction.Store, JavaHelpers.InterTypeToJavaPrimitive(operandType), varIndex, e); FreeVar(localRefTempVar, JavaPrimitiveType.Ref); }); //TODO: TranslateType if neeeded }
Java.Constants.MethodRef IByRefController.GetFieldByRefCtorMethodRef(InterType type) { JavaByRefType byRefType = new JavaByRefType(ByRefPlace.Field, JavaHelpers.InterTypeToJavaPrimitive(type)); return(new Java.Constants.MethodRef( TypeNameToJava(byRefType.ToString()), ClassNames.JavaConstructorMethodName, ClassNames.ByRef.FieldCtorDescriptor)); }
private void CompileConvTo8(ILExpression e, ExpectType expect) { InterType gettedType = resolver.Resolve(e.Arguments[0].InferredType, thisMethod.FullGenericArguments); JavaPrimitiveType gettedJava = JavaHelpers.InterTypeToJavaPrimitive(gettedType); CompileExpression(e.Arguments[0], ExpectType.Any); bool isToUnsigned = e.Code.IsConvToUnsigned(); bool isFromUnsigned = e.Code.IsConvFromUnsigned(); bool isOvf = e.Code.IsOvf(); if (isOvf) { long mask = unchecked ((long)0xffffffffffffffffL); double minValue = (double)long.MinValue; double maxValue = (double)long.MaxValue; if (isToUnsigned) { minValue = (double)ulong.MinValue; maxValue = (double)ulong.MaxValue; } if ((isToUnsigned && !isFromUnsigned) || (!isToUnsigned && isFromUnsigned)) { mask = 0x7fffffffffffffffL; } CompileCheckOvf(e, gettedJava, mask, minValue, maxValue); } switch (gettedJava) { case JavaPrimitiveType.Bool: case JavaPrimitiveType.Byte: case JavaPrimitiveType.Char: case JavaPrimitiveType.Short: case JavaPrimitiveType.Int: codeGenerator.Add(OpCodes.i2l, null, e); break; case JavaPrimitiveType.Long: break; case JavaPrimitiveType.Float: codeGenerator.Add(OpCodes.f2l, null, e); break; case JavaPrimitiveType.Double: codeGenerator.Add(OpCodes.d2l, null, e); break; default: throw new Exception(); //TODO: Normal error } TranslateType(InterType.PrimitiveTypes[(int)(isToUnsigned ? PrimitiveType.UInt64 : PrimitiveType.Int64)], expect, e); }
private void CompileStelem(ILExpression e, ExpectType expect) { TypeReference typeRef = e.Operand as TypeReference ?? e.InferredType; InterType operand = null; if (typeRef != null) { operand = resolver.Resolve(typeRef, thisMethod.FullGenericArguments); } else { switch (e.Code) { case ILCode.Stelem_I: operand = InterType.PrimitiveTypes[(int)(Program.AsX64 ? PrimitiveType.Int64 : PrimitiveType.Int32)]; break; case ILCode.Stelem_I1: operand = InterType.PrimitiveTypes[(int)PrimitiveType.SByte]; break; case ILCode.Stelem_I2: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int16]; break; case ILCode.Stelem_I4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int32]; break; case ILCode.Stelem_I8: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int64]; break; case ILCode.Stelem_R4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Single]; break; case ILCode.Stelem_R8: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Double]; break; } } JavaPrimitiveType valueJPType = operand != null?JavaHelpers.InterTypeToJavaPrimitive(operand) : JavaPrimitiveType.Ref; JavaArrayType arrType = JavaHelpers.JavaPrimitiveToArrayType(valueJPType); ExpectType valueExpectType = operand != null?GetExpectType(operand) : ExpectType.Reference; bool needDup = ((e.ExpectedType != null) && (expect != ExpectType.None)); CompileExpression(e.Arguments[0], ExpectType.Reference); //array CompileExpression(e.Arguments[1], ExpectType.Primitive); //index CompileExpression(e.Arguments[2], valueExpectType); //value if (needDup) { if (valueJPType.IsDoubleSlot()) { codeGenerator.Add(Java.OpCodes.dup2_x2, null, e); } else { codeGenerator.Add(Java.OpCodes.dup_x2, null, e); } } codeGenerator.AddArrayStore(arrType, e); }
private void CompileRefanyval(ILExpression e, ExpectType expect) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); string byRefTypeName = byRefController.GetByRefGetValueMethodRef(JavaHelpers.InterTypeToJavaPrimitive(operand)).Class; CompileExpression(e.Arguments[0], ExpectType.Reference); codeGenerator .Add(OpCodes.getfield, ClassNames.SystemTypedReference.PointerFieldRef, e) .Add(OpCodes.checkcast, new Java.Constants.Class(byRefTypeName), e); }
string IByRefController.GetArrayByRefTypeName(InterType type) { JavaByRefType byRefType = new JavaByRefType(ByRefPlace.Array, JavaHelpers.InterTypeToJavaPrimitive(type)); if (!byRefToGenerate.Contains(byRefType)) { byRefToGenerate.Add(byRefType); } return(byRefType.ToString()); }
private void TranslateType(InterType type, ExpectType expected, object tag) { if ((Program.Unsigned) && (type.IsPrimitive) && (type.PrimitiveType.IsUnsigned())) { if ((type.PrimitiveType == PrimitiveType.Byte) || (type.PrimitiveType == PrimitiveType.UInt16)) { if (type.PrimitiveType == PrimitiveType.Byte) { codeGenerator.AddIntConst(0xff, tag); } else { codeGenerator.AddIntConst(0xffff, tag); } codeGenerator.Add(Java.OpCodes.iand, null, tag); } } if (expected == ExpectType.Any) { return; } if (expected == ExpectType.None) { codeGenerator.AddPop(JavaHelpers.InterTypeToJavaPrimitive(type), tag); } if ((type.IsByRef) && (expected != ExpectType.ByRef) && (!type.ElementType.IsValueType)) { JavaPrimitiveType javaType = JavaHelpers.InterTypeToJavaPrimitive(type.ElementType); MethodRef getMethodRef = byRefController.GetByRefGetValueMethodRef(javaType); Java.Constants.Class loadedTypeRef = new Java.Constants.Class(namesController.TypeNameToJava(type.ElementType)); codeGenerator.Add(OpCodes.invokevirtual, getMethodRef, tag); if (javaType == JavaPrimitiveType.Ref) { codeGenerator.Add(OpCodes.checkcast, loadedTypeRef, tag); } type = type.ElementType; } if (((expected == ExpectType.Boxed) || (expected == ExpectType.Reference)) && ((type.IsPrimitive) || (type.IsEnum) || (type.IsValueType))) { if ((!type.IsNullable) || (expected != ExpectType.Reference)) { BoxType(type, tag); } } }
private void CompileLdelem(ILExpression e, ExpectType expect) { TypeReference typeRef = e.Operand as TypeReference ?? e.InferredType; InterType operand = null; if (typeRef != null) { operand = resolver.Resolve(typeRef, thisMethod.FullGenericArguments); } else { switch (e.Code) { case ILCode.Ldelem_I: operand = InterType.PrimitiveTypes[(int)(Program.AsX64 ? PrimitiveType.Int64 : PrimitiveType.Int32)]; break; case ILCode.Ldelem_I1: operand = InterType.PrimitiveTypes[(int)PrimitiveType.SByte]; break; case ILCode.Ldelem_I2: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int16]; break; case ILCode.Ldelem_I4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int32]; break; case ILCode.Ldelem_I8: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int64]; break; case ILCode.Ldelem_R4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Single]; break; case ILCode.Ldelem_R8: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Double]; break; case ILCode.Ldelem_U1: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Byte]; break; case ILCode.Ldelem_U2: operand = InterType.PrimitiveTypes[(int)PrimitiveType.UInt16]; break; case ILCode.Ldelem_U4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.UInt32]; break; } } JavaArrayType arrType = operand != null?JavaHelpers.InterTypeToJavaArrayType(operand) : JavaArrayType.Ref; CompileExpression(e.Arguments[0], ExpectType.Reference); //array CompileExpression(e.Arguments[1], ExpectType.Primitive); //index codeGenerator.AddArrayLoad(arrType, e); if ((operand != null) && (operand.IsValueType)) { MethodRef getCopyRef = new MethodRef(namesController.TypeNameToJava(operand), ClassNames.ValueTypeGetCopy, "()" + namesController.GetFieldDescriptor(operand)); codeGenerator.Add(Java.OpCodes.invokevirtual, getCopyRef, e); } if (operand != null) { TranslateType(operand, expect, e); } }
private void CompileRemUn(ILExpression e, ExpectType expect) { if (!Program.Unsigned) { CompileMath(e, expect, OpCodes.irem, OpCodes.lrem, OpCodes.frem, OpCodes.drem); return; } InterType opType = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments); JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(opType); if ((jp == JavaPrimitiveType.Bool) || (jp == JavaPrimitiveType.Byte) || (jp == JavaPrimitiveType.Char) || (jp == JavaPrimitiveType.Short)) { //this types are already growed up to int CompileExpression(e.Arguments[0], ExpectType.Primitive); CompileExpression(e.Arguments[1], ExpectType.Primitive); codeGenerator.Add(OpCodes.irem); } else if (jp == JavaPrimitiveType.Int) { //grow up int to long CompileExpression(e.Arguments[0], ExpectType.Primitive); codeGenerator .Add(OpCodes.i2l, null, e) .AddLongConst(0xffffffff, e) .Add(OpCodes.land, e); CompileExpression(e.Arguments[0], ExpectType.Primitive); codeGenerator .Add(OpCodes.i2l, null, e) .AddLongConst(0xffffffff, e) .Add(OpCodes.land, e); codeGenerator .Add(OpCodes.lrem, e) .Add(OpCodes.l2i); } else if (jp == JavaPrimitiveType.Long) { //call special method from corlib CompileExpression(e.Arguments[0], ExpectType.Primitive); CompileExpression(e.Arguments[1], ExpectType.Primitive); resolver.Resolve(ClassNames.CIL2JavaVESInstructions.ClassName); codeGenerator.Add(OpCodes.invokestatic, ClassNames.CIL2JavaVESInstructions.UInt64RemainderRef); } else { throw new Exception(); //TODO: Normal error } TranslateType(opType, expect, e); }
private void PreprocessorPrepareUninitializedLocalVars() { foreach (ILVariable v in uninitializedLocals) { int varIndex = GetVarIndex(v); InterType varType = resolver.Resolve(v.Type, thisMethod.FullGenericArguments); JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(varType); codeGenerator .AddDefaultValue(jp) .AddStore(jp, varIndex); } }
private void CompileBrBool(ILExpression e, ExpectType expect, bool brOnTrue) { JavaPrimitiveType gettedType = JavaHelpers.InterTypeToJavaPrimitive(resolver.Resolve( e.InferredType, thisMethod.FullGenericArguments)); OpCodes brInstr = brOnTrue ? OpCodes.ifne : OpCodes.ifeq; if (gettedType == JavaPrimitiveType.Ref) { brInstr = brOnTrue ? OpCodes.ifnonnull : OpCodes.ifnull; } codeGenerator.Add(brInstr, ((ILLabel)e.Operand).Name, e); }
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 TranslateToBool(TypeReference inferredType, ref Java.OpCodes cmpOp, object tag) { JavaPrimitiveType gettedType = JavaHelpers.InterTypeToJavaPrimitive(resolver.Resolve( inferredType, thisMethod.FullGenericArguments)); switch (gettedType) { case JavaPrimitiveType.Double: codeGenerator.Add(Java.OpCodes.d2i, null, tag); break; case JavaPrimitiveType.Float: codeGenerator.Add(Java.OpCodes.f2i, null, tag); break; case JavaPrimitiveType.Long: codeGenerator.Add(Java.OpCodes.l2i, null, tag); break; case JavaPrimitiveType.Ref: cmpOp = (cmpOp == Java.OpCodes.ifne ? Java.OpCodes.ifnonnull : Java.OpCodes.ifnull); break; } }
private string GetByRefTypeName(InterType byRefType) { while (byRefType.IsByRef) { byRefType = byRefType.ElementType; } JavaByRefType javaType = new JavaByRefType(ByRefPlace.Unknown, JavaHelpers.InterTypeToJavaPrimitive(byRefType)); if (!byRefToGenerate.Contains(javaType)) { byRefToGenerate.Add(javaType); } return(javaType.ToString()); }
Java.Constants.MethodRef IByRefController.GetArrayByRefCtorMethodRef(InterType type) { JavaByRefType byRefType = new JavaByRefType(ByRefPlace.Array, JavaHelpers.InterTypeToJavaPrimitive(type)); string typeDescr = "[L" + TypeNameToJava(ClassNames.JavaObject) + ";"; if (byRefType.type != JavaPrimitiveType.Ref) { typeDescr = "[" + GetFieldDescriptor(type); } return(new Java.Constants.MethodRef( TypeNameToJava(byRefType.ToString()), ClassNames.JavaConstructorMethodName, "(" + typeDescr + "I)V")); }
Java.Constants.MethodRef IByRefController.GetLocalByRefCtorMethodRef(InterType type) { JavaByRefType byRefType = new JavaByRefType(ByRefPlace.Local, JavaHelpers.InterTypeToJavaPrimitive(type)); string descr = "L" + TypeNameToJava(ClassNames.JavaObject) + ";"; if (byRefType.type != JavaPrimitiveType.Ref) { descr = JavaPrimitive2FieldChar[(int)byRefType.type].ToString(); } return(new Java.Constants.MethodRef( TypeNameToJava(byRefType.ToString()), ClassNames.JavaConstructorMethodName, "(" + descr + ")V")); }
private void CompileRet(ILExpression e, ExpectType expect) { InterType returnType = thisMethod.ReturnParameter.Type; ExpectType returnExpect = GetExpectType(thisMethod.ReturnParameter); if ((returnExpect == ExpectType.Primitive) && (returnType.PrimitiveType == PrimitiveType.Void)) { codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes._return, null, e)); } else { //TODO: ArgIterator GetHashCode - blank; if (e == null) { codeGenerator.AddDefaultValue(JavaHelpers.InterTypeToJavaPrimitive(returnType)); } else { CompileExpression(e.Arguments[0], returnExpect); } if ((returnType.IsPrimitive) || (returnType.IsEnum)) { if (returnType.IsEnum) { returnType = returnType.ElementType; } if ((returnType.PrimitiveType == PrimitiveType.Byte) || (returnType.PrimitiveType == PrimitiveType.SByte) || (returnType.PrimitiveType == PrimitiveType.Bool)) { codeGenerator.Add(OpCodes.i2b, null, e); } else if (returnType.PrimitiveType == PrimitiveType.Char) { codeGenerator.Add(OpCodes.i2c, null, e); } else if ((returnType.PrimitiveType == PrimitiveType.UInt16) || (returnType.PrimitiveType == PrimitiveType.Int16)) { codeGenerator.Add(OpCodes.i2s, null, e); } } codeGenerator.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(returnType), e); } }
private void CompileLdloc(ILExpression e, ExpectType expectType) { ILVariable operand = (ILVariable)e.Operand; int varIndex = GetVarIndex(operand); InterType operandType = resolver.Resolve(operand.Type, thisMethod.FullGenericArguments); //TODO: GetExpectType(InterParameter); codeGenerator.AddLocalVarInstruction(LocalVarInstruction.Load, JavaHelpers.InterTypeToJavaPrimitive(operandType), varIndex, e); if ((operandType.IsValueType) && (expectType != ExpectType.ByRef)) { MethodRef getCopyRef = new MethodRef(namesController.TypeNameToJava(operandType), ClassNames.ValueTypeGetCopy, "()" + namesController.GetFieldDescriptor(operandType)); codeGenerator.Add(Java.OpCodes.invokevirtual, getCopyRef, e); } TranslateType(operandType, expectType, e); }
private void GenerateEnumGetUnboxed(InterType type) { string boxedEnumName = TypeNameToJava(type.Fullname); string elementDescriptor = GetFieldDescriptor(type.ElementType); Method result = new Method(); result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final; result.Name = ClassNames.EnumGetUnboxedMethodName; result.Descriptor = "()" + elementDescriptor; result.Attributes.Add(new JavaBytecodeWriter() .Add(OpCodes.aload_0) .Add(OpCodes.getfield, new FieldRef(boxedEnumName, ClassNames.EnumValueFieldName, elementDescriptor)) .AddReturn(JavaHelpers.InterTypeToJavaPrimitive(type.ElementType)) .End(currentJavaClass.ConstantPool)); currentJavaClass.Methods.Add(result); }
private void GenerateFieldAccessors(InterType type) { for (int i = 0; i < type.FieldAccessors.Count; i++) { FieldAccessor fld = type.FieldAccessors[i]; string fldTypeDescr = GetFieldDescriptor(fld.Field.FieldType); if ((fld.Field.IsStatic) && (fld.Field.IsThreadLocal)) { fldTypeDescr = "L" + TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName) + ";"; } JavaPrimitiveType javaFldType = JavaHelpers.InterTypeToJavaPrimitive(fld.Field.FieldType); FieldRef fldRef = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Field.Name), fldTypeDescr); Method result = new Method(); result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Static; result.Name = ClassNames.FieldAccessorPrefix + i.ToString(); JavaBytecodeWriter codeWriter = new JavaBytecodeWriter(); if (!fld.Field.IsStatic) { codeWriter.Add(OpCodes.aload_0); } if (fld.Type == FieldAccessorType.Getter) { result.Descriptor = "(" + (fld.Field.IsStatic ? "" : GetFieldDescriptor(type)) + ")" + fldTypeDescr; codeWriter .Add(fld.Field.IsStatic ? OpCodes.getstatic : OpCodes.getfield, fldRef) .AddReturn(javaFldType); } else { result.Descriptor = "(" + (fld.Field.IsStatic ? "" : GetFieldDescriptor(type)) + fldTypeDescr + ")V"; codeWriter .AddLoad(javaFldType, 1) .Add(fld.Field.IsStatic ? OpCodes.putstatic : OpCodes.putfield, fldRef) .Add(OpCodes._return); } result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool)); currentJavaClass.Methods.Add(result); } }
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); }
private void CompileLdind(ILExpression e, ExpectType expect) { InterType operand = resolver.Resolve((TypeReference)e.Arguments[0].InferredType, thisMethod.FullGenericArguments); CompileExpression(e.Arguments[0], ExpectType.ByRef); MethodRef getMethodRef = byRefController.GetByRefGetValueMethodRef(JavaHelpers.InterTypeToJavaPrimitive( operand.ElementType)); InterType loadType = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments); Java.Constants.Class loadedTypeRef = new Java.Constants.Class(namesController.TypeNameToJava(loadType)); codeGenerator.Add(OpCodes.invokevirtual, getMethodRef, e); if ((!operand.ElementType.IsPrimitive) && (!operand.ElementType.IsEnum)) { codeGenerator.Add(OpCodes.checkcast, loadedTypeRef, e); } }
private void CompileDefaultValue(ILExpression e, ExpectType expect) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); if (operand.IsValueType) { Java.Constants.Class operandRef = new Java.Constants.Class(namesController.TypeNameToJava(operand)); MethodRef operandCtorRef = new MethodRef(operandRef.Value, ClassNames.JavaConstructorMethodName, "()V"); codeGenerator .Add(Java.OpCodes._new, operandRef, e) .Add(Java.OpCodes.dup, null, e) .Add(Java.OpCodes.invokespecial, operandCtorRef, e); } else { codeGenerator.AddDefaultValue(JavaHelpers.InterTypeToJavaPrimitive(operand), e); } TranslateType(operand, expect, e); }
private void CompileLdelema(ILExpression e, ExpectType expectType) { TypeReference typeRef = e.Operand as TypeReference; InterType operand = resolver.Resolve(typeRef, thisMethod.FullGenericArguments); JavaArrayType arrType = JavaHelpers.InterTypeToJavaArrayType(operand); if (operand.IsValueType) { CompileExpression(e.Arguments[0], ExpectType.Reference); //array CompileExpression(e.Arguments[1], ExpectType.Primitive); //index codeGenerator.Add(OpCodes.aaload, null, e); return; } if ((operand.IsPrimitive) && (expectType == ExpectType.Reference)) { CompileExpression(e.Arguments[0], ExpectType.Reference); //array CompileExpression(e.Arguments[1], ExpectType.Primitive); //index codeGenerator.AddArrayLoad(arrType); TranslateType(operand, ExpectType.Boxed, e); return; } 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); //index codeGenerator.Add(OpCodes.invokespecial, arrayByRefInitMethodRef, e); }