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 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 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 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 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; } }
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")); }
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")); }
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()); }
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 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 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 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 CompileNullCoalescing(ILExpression e, ExpectType expect) { InterType inferredType = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments); JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(inferredType); string exitLabel = "exit" + rnd.Next().ToString(); CompileExpression(e.Arguments[0], expect); codeGenerator.Add(jp.IsDoubleSlot() ? OpCodes.dup2 : OpCodes.dup, null, e); if (jp == JavaPrimitiveType.Ref) { codeGenerator.Add(Java.OpCodes.ifnonnull, exitLabel, e); } else if (jp.IsIntSlot()) { codeGenerator.Add(Java.OpCodes.ifne, exitLabel, e); } else { if (jp == JavaPrimitiveType.Float) { codeGenerator.Add(OpCodes.fconst_0, null, e).Add(OpCodes.fcmpg, null, e); } else if (jp == JavaPrimitiveType.Double) { codeGenerator.Add(OpCodes.dconst_0, null, e).Add(OpCodes.dcmpg, null, e); } else if (jp == JavaPrimitiveType.Long) { codeGenerator.Add(OpCodes.lconst_0, null, e).Add(OpCodes.lcmp, null, e); } codeGenerator.Add(OpCodes.ifeq, exitLabel, e); } codeGenerator.Add(jp.IsDoubleSlot() ? OpCodes.pop2 : OpCodes.pop); CompileExpression(e.Arguments[1], expect); codeGenerator.Label(exitLabel); }
private void GenerateEnumGetBoxed(InterType type) { string boxedEnumName = TypeNameToJava(type.Fullname); string elementDescriptor = GetFieldDescriptor(type.ElementType); Method result = new Method(); result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final | MethodAccessFlags.Static; result.Name = ClassNames.EnumGetBoxedMethodName; result.Descriptor = "(" + elementDescriptor + ")" + "L" + boxedEnumName + ";"; result.Attributes.Add(new JavaBytecodeWriter() .Add(OpCodes._new, new Java.Constants.Class(boxedEnumName)) .Add(OpCodes.dup) .Add(OpCodes.invokespecial, new MethodRef(boxedEnumName, ClassNames.JavaConstructorMethodName, "()V")) .Add(OpCodes.dup) .AddLoad(JavaHelpers.InterTypeToJavaPrimitive(type.ElementType), 0) .Add(OpCodes.putfield, new FieldRef(boxedEnumName, ClassNames.EnumValueFieldName, elementDescriptor)) .Add(OpCodes.areturn) .End(currentJavaClass.ConstantPool) ); currentJavaClass.Methods.Add(result); }
private void GenerateValueTypeZeroFill(InterType type) { Method result = new Method(); result.AccessFlags = MethodAccessFlags.Public; result.Name = ClassNames.ValueTypeZeroFill; result.Descriptor = "()V"; JavaBytecodeWriter codeWriter = new JavaBytecodeWriter(); foreach (InterField fld in type.Fields) { FieldRef fldRef = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Name), GetFieldDescriptor(fld.FieldType)); if (fld.FieldType.IsValueType) { MethodRef fldZeroFill = new MethodRef(TypeNameToJava(fld.FieldType.Fullname), ClassNames.ValueTypeZeroFill, "()V"); codeWriter .Add(OpCodes.aload_0) .Add(OpCodes.getfield, fldRef) .Add(OpCodes.invokevirtual, fldZeroFill); } else { codeWriter .Add(OpCodes.aload_0) .AddDefaultValue(JavaHelpers.InterTypeToJavaPrimitive(fld.FieldType)) .Add(OpCodes.putfield, fldRef); } } codeWriter.AddReturn(JavaPrimitiveType.Void); result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool)); currentJavaClass.Methods.Add(result); }
private void CompileNot(ILExpression e, ExpectType expect) { CompileExpression(e.Arguments[0], ExpectType.Primitive); InterType opType = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments); JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(opType); if (jp == JavaPrimitiveType.Long) { codeGenerator .AddLongConst(-1L, e) .Add(OpCodes.lxor, null, e); } else { codeGenerator .Add(OpCodes.iconst_m1, null, e) .Add(OpCodes.ixor, null, e); } TranslateType(opType, expect, e); }
private void CompileStloc(ILExpression e, ExpectType expectType) { ILVariable operand = (ILVariable)e.Operand; int varIndex = GetVarIndex(operand); InterType operandType = resolver.Resolve(operand.Type, thisMethod.FullGenericArguments); if ((operandType.IsValueType) && (e.Arguments[0].Code == ILCode.DefaultValue)) { // In il this looks like `initobj(ldloca(var))` // But ILSpy optimizing it to `stloc(var, defaultvalue())` MethodRef zeroFillRef = new MethodRef(namesController.TypeNameToJava(operandType), ClassNames.ValueTypeZeroFill, "()V"); codeGenerator .AddLoad(JavaPrimitiveType.Ref, varIndex) .Add(Java.OpCodes.invokevirtual, zeroFillRef); } else { //TODO: GetExpectType(InterParameter); CompileNode(e.Arguments[0], GetExpectType(operandType)); if ((expectType != ExpectType.None) && (e.ExpectedType != null)) { if ((operandType.IsPrimitive) && ((operandType.PrimitiveType == PrimitiveType.UInt64) || (operandType.PrimitiveType == PrimitiveType.Int64) || (operandType.PrimitiveType == PrimitiveType.Double))) { codeGenerator.Add(Java.OpCodes.dup2); } else { codeGenerator.Add(Java.OpCodes.dup); } } codeGenerator.AddLocalVarInstruction(LocalVarInstruction.Store, JavaHelpers.InterTypeToJavaPrimitive(operandType), varIndex, e); } }
private void CompileInitobj(ILExpression e, ExpectType expect) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); CompileExpression(e.Arguments[0], ExpectType.ByRef); if (!operand.IsValueType) { JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(operand); MethodRef setValueRef = byRefController.GetByRefSetValueMethodRef(jp); switch (jp) { case JavaPrimitiveType.Bool: case JavaPrimitiveType.Byte: case JavaPrimitiveType.Char: case JavaPrimitiveType.Int: case JavaPrimitiveType.Short: codeGenerator.AddIntConst(0, e); break; case JavaPrimitiveType.Long: codeGenerator.AddLongConst(0L, e); break; case JavaPrimitiveType.Float: codeGenerator.AddFloatConst(0.0f, e); break; case JavaPrimitiveType.Double: codeGenerator.AddDoubleConst(0.0, e); break; case JavaPrimitiveType.Ref: codeGenerator.Add(OpCodes.aconst_null, e); break; } codeGenerator.Add(OpCodes.invokevirtual, setValueRef, e); } else { codeGenerator.Add(OpCodes.invokevirtual, new MethodRef(namesController.TypeNameToJava(operand), ClassNames.ValueTypeZeroFill, "()V")); } }