public JavaBytecodeWriter AddDefaultValue(JavaPrimitiveType jp, object tag) { Java.OpCodes opcode = Java.OpCodes.aconst_null; switch (jp) { case JavaPrimitiveType.Bool: case JavaPrimitiveType.Byte: case JavaPrimitiveType.Char: case JavaPrimitiveType.Int: case JavaPrimitiveType.Short: opcode = Java.OpCodes.iconst_0; break; case JavaPrimitiveType.Long: opcode = Java.OpCodes.lconst_0; break; case JavaPrimitiveType.Float: opcode = Java.OpCodes.fconst_0; break; case JavaPrimitiveType.Double: opcode = Java.OpCodes.dconst_0; break; } AddInstruction(new JavaInstruction(opcode, null, tag)); return(this); }
private void AddLocalVarStore(JavaPrimitiveType varType, int varIndex, object tag) { Java.OpCodes shortOpcode = Java.OpCodes.astore_0; Java.OpCodes longOpcode = Java.OpCodes.astore; switch (varType) { case JavaPrimitiveType.Bool: case JavaPrimitiveType.Byte: case JavaPrimitiveType.Char: case JavaPrimitiveType.Short: case JavaPrimitiveType.Int: shortOpcode = Java.OpCodes.istore_0; longOpcode = Java.OpCodes.istore; break; case JavaPrimitiveType.Long: shortOpcode = Java.OpCodes.lstore_0; longOpcode = Java.OpCodes.lstore; break; case JavaPrimitiveType.Float: shortOpcode = Java.OpCodes.fstore_0; longOpcode = Java.OpCodes.fstore; break; case JavaPrimitiveType.Double: shortOpcode = Java.OpCodes.dstore_0; longOpcode = Java.OpCodes.dstore; break; } AddLocalVarInstruction(shortOpcode, longOpcode, varIndex, tag); }
public static JavaArrayType JavaPrimitiveToArrayType(JavaPrimitiveType jp) { switch (jp) { case JavaPrimitiveType.Bool: return(JavaArrayType.Boolean); case JavaPrimitiveType.Byte: return(JavaArrayType.Byte); case JavaPrimitiveType.Char: return(JavaArrayType.Char); case JavaPrimitiveType.Double: return(JavaArrayType.Double); case JavaPrimitiveType.Float: return(JavaArrayType.Float); case JavaPrimitiveType.Int: return(JavaArrayType.Int); case JavaPrimitiveType.Long: return(JavaArrayType.Long); case JavaPrimitiveType.Ref: return(JavaArrayType.Ref); case JavaPrimitiveType.Short: return(JavaArrayType.Short); default: return(JavaArrayType.Ref); } }
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 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 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); }
public JavaBytecodeWriter AddReturn(JavaPrimitiveType jp, object tag) { Java.OpCodes opcode = Java.OpCodes.areturn; switch (jp) { case JavaPrimitiveType.Bool: case JavaPrimitiveType.Byte: case JavaPrimitiveType.Char: case JavaPrimitiveType.Int: case JavaPrimitiveType.Short: opcode = Java.OpCodes.ireturn; break; case JavaPrimitiveType.Long: opcode = Java.OpCodes.lreturn; break; case JavaPrimitiveType.Float: opcode = Java.OpCodes.freturn; break; case JavaPrimitiveType.Double: opcode = Java.OpCodes.dreturn; break; case JavaPrimitiveType.Void: opcode = Java.OpCodes._return; break; } AddInstruction(new JavaInstruction(opcode, null, tag)); return(this); }
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 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 ExpectType GetExpectType(JavaPrimitiveType type) { if (type == JavaPrimitiveType.Ref) { return(ExpectType.Reference); } else { return(ExpectType.Primitive); } }
private string GetByRefGetValueDescriptor(JavaPrimitiveType type) { if (type == JavaPrimitiveType.Ref) { return("()L" + TypeNameToJava(ClassNames.JavaObject) + ";"); } else { return("()" + JavaPrimitive2FieldChar[(int)type] + ""); } }
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); }
public JavaBytecodeWriter AddLocalVarInstruction(LocalVarInstruction instr, JavaPrimitiveType varType, int varIndex, object tag) { if (instr == LocalVarInstruction.Load) { AddLocalVarLoad(varType, varIndex, tag); } else { AddLocalVarStore(varType, varIndex, tag); } return(this); }
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); } }
public JavaBytecodeWriter AddPop(JavaPrimitiveType javaPrimitiveType, object tag) { if ((javaPrimitiveType == JavaPrimitiveType.Long) || (javaPrimitiveType == JavaPrimitiveType.Double)) { AddInstruction(new JavaInstruction(Java.OpCodes.pop2, null, tag)); } else { AddInstruction(new JavaInstruction(Java.OpCodes.pop, null, tag)); } return(this); }
public static bool IsIntSlot(this JavaPrimitiveType jp) { switch (jp) { case JavaPrimitiveType.Bool: case JavaPrimitiveType.Byte: case JavaPrimitiveType.Char: case JavaPrimitiveType.Int: case JavaPrimitiveType.Short: return(true); default: return(false); } }
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 int GetNextFreeVar(JavaPrimitiveType type) { int result = -1; if (freeVars.Count > 0) { if ((type == JavaPrimitiveType.Long) || (type == JavaPrimitiveType.Double)) { for (int i = 0; i < freeVars.Count; i++) { if (freeVars.Contains(freeVars[i] + 1)) { result = freeVars[i]; break; } } if (result > 0) { freeVars.Remove(result); freeVars.Remove(result + 1); tempVars.Add(new TempVar() { type = type, index = result, startInstr = codeGenerator.NextInstructionIndex, endInstr = -1 }); return(result); } } else { result = freeVars.Last(); freeVars.Remove(result); tempVars.Add(new TempVar() { type = type, index = result, startInstr = codeGenerator.NextInstructionIndex, endInstr = -1 }); return(result); } } result = nextVarIndex++; if ((type == JavaPrimitiveType.Long) || (type == JavaPrimitiveType.Double)) { nextVarIndex++; } tempVars.Add(new TempVar() { type = type, index = result, startInstr = codeGenerator.NextInstructionIndex, endInstr = -1 }); return(result); }
Java.Constants.MethodRef IByRefController.GetByRefSetValueMethodRef(JavaPrimitiveType type) { JavaByRefType byRefType = new JavaByRefType(ByRefPlace.Unknown, type); string descr = "L" + TypeNameToJava(ClassNames.JavaObject) + ";"; if (type != JavaPrimitiveType.Ref) { descr = JavaPrimitive2FieldChar[(int)type].ToString(); } return(new Java.Constants.MethodRef( TypeNameToJava(byRefType.ToString()), ClassNames.ByRef.SetValueMethodName, "(" + descr + ")V")); }
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 void FreeVar(int varType, JavaPrimitiveType type) { freeVars.Add(varType); if ((type == JavaPrimitiveType.Double) || (type == JavaPrimitiveType.Long)) { freeVars.Add(varType + 1); } var tmpVar = tempVars.Where(TV => TV.index == varType && TV.type == type).FirstOrDefault(); int tmpVarIndex = tempVars.IndexOf(tmpVar); if (tmpVarIndex >= 0) { tmpVar.endInstr = codeGenerator.NextInstructionIndex; tempVars[tmpVarIndex] = tmpVar; } }
private void GenerateBaseByRefType(JavaPrimitiveType type) { if ((baseTypesGenerated & (1 << (int)type)) != 0) { return; } Java.Class javaClass = new Java.Class(); javaClass.AccessFlag = Java.ClassAccessFlag.Abstract | Java.ClassAccessFlag.Public | Java.ClassAccessFlag.Super; javaClass.ThisClass = TypeNameToJava(new JavaByRefType(ByRefPlace.Unknown, type).ToString()); javaClass.SuperClass = TypeNameToJava(ClassNames.JavaObject); Java.Method ctor = new Java.Method(); ctor.AccessFlags = Java.MethodAccessFlags.Public; ctor.Name = ClassNames.JavaConstructorMethodName; ctor.Descriptor = "()V"; JavaBytecodeWriter ctorCodeGenerator = new JavaBytecodeWriter(); ctorCodeGenerator .AddLocalVarInstruction(LocalVarInstruction.Load, JavaPrimitiveType.Ref, 0, null) .AddInstruction(new JavaInstruction(Java.OpCodes.invokespecial, ClassNames.JavaObjectCtorMethodRef)) .AddReturn(JavaPrimitiveType.Void, null); Java.Attributes.Code ctorCode = new Java.Attributes.Code(); ctorCode.CodeBytes = ctorCodeGenerator.Link(javaClass.ConstantPool); ctorCode.MaxLocals = 1; ctorCode.MaxStack = 1; ctor.Attributes.Add(ctorCode); javaClass.Methods.Add(ctor); Java.Method getValue = new Java.Method(); getValue.AccessFlags = Java.MethodAccessFlags.Abstract | Java.MethodAccessFlags.Public; getValue.Name = ClassNames.ByRef.GetValueMethodName; getValue.Descriptor = GetByRefGetValueDescriptor(type); javaClass.Methods.Add(getValue); Java.Method setValue = new Java.Method(); setValue.AccessFlags = Java.MethodAccessFlags.Abstract | Java.MethodAccessFlags.Public; setValue.Name = ClassNames.ByRef.SetValueMethodName; setValue.Descriptor = GetByRefSetValueDescriptor(type); javaClass.Methods.Add(setValue); WriteClass(javaClass); baseTypesGenerated |= (1 << (int)type); }
private void 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 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 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 CompileStind(ILExpression e, ExpectType expectType) { JavaPrimitiveType type = JavaPrimitiveType.Ref; if (e.Operand != null) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); if ((operand.IsPrimitive) && ((operand.PrimitiveType == PrimitiveType.Byte) || (operand.PrimitiveType == PrimitiveType.SByte))) { operand = resolver.Resolve(e.Arguments[0].InferredType, thisMethod.FullGenericArguments).ElementType; } type = JavaHelpers.InterTypeToJavaPrimitive(operand); } bool needDup = ((e.ExpectedType != null) && (expectType != ExpectType.None)); CompileExpression(e.Arguments[0], ExpectType.ByRef); CompileExpression(e.Arguments[1], GetExpectType(type)); Java.Constants.MethodRef setMethodRef = byRefController.GetByRefSetValueMethodRef(type); if (needDup) { if (type.IsDoubleSlot()) { codeGenerator.Add(OpCodes.dup2_x1, null, e); } else { codeGenerator.Add(OpCodes.dup_x1, null, e); } } codeGenerator.Add(OpCodes.invokevirtual, setMethodRef, 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")); } }