private void CompileStobj(ILExpression e, ExpectType expect) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); if (operand.IsValueType) { // stobj(destPtr, src) compiling to // src.CopyTo(destPtr) CompileExpression(e.Arguments[1], ExpectType.Any); CompileExpression(e.Arguments[0], ExpectType.ByRef); MethodRef copyToRef = new MethodRef(namesController.TypeNameToJava(operand), ClassNames.ValueTypeCopyTo, "(" + namesController.GetFieldDescriptor(operand) + ")V"); bool needDup = ((e.ExpectedType != null) && (expect != ExpectType.None)); if (needDup) { codeGenerator.Add(Java.OpCodes.dup_x1, null, e); } codeGenerator.Add(Java.OpCodes.invokevirtual, copyToRef, e); } else { // From ECMA-335, III.4.29 // The stobj instruction copies the value src to the address dest. If typeTok is not // a generic parameter and either a reference type or a built-in value class, then // the stind instruction provides a shorthand for the stobj instruction. CompileStind(e, expect); } }
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 CompileIsinst(ILExpression e, ExpectType expect) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); CompileExpression(e.Arguments[0], ExpectType.Reference); // dup // instanceof operand // ifne :end // pop // aconst_null //:end // checkcast operand string endLabel = rnd.Next().ToString() + "end"; Java.Constants.Class operandRef = new Java.Constants.Class(namesController.TypeNameToJava(GetBoxType(operand))); codeGenerator .Add(Java.OpCodes.dup, null, e) .Add(Java.OpCodes.instanceof, operandRef, e) .Add(Java.OpCodes.ifne, endLabel, e) .Add(Java.OpCodes.pop, null, e) .Add(Java.OpCodes.aconst_null, null, e) .Label(endLabel) .Add(Java.OpCodes.checkcast, operandRef, e); }
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 void CompileLdobj(ILExpression e, ExpectType expect) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); if ((operand.IsPrimitive) && (e.Arguments[0].Code == ILCode.Ldloc) && (((ILVariable)e.Arguments[0].Operand).Name == "this")) { //Special treatment. Value for primitive types codeGenerator .Add(Java.OpCodes.aload_0, null, e) .Add(Java.OpCodes.getfield, new Java.Constants.FieldRef( namesController.TypeNameToJava(operand.CILBoxType), "value", namesController.GetFieldDescriptor(operand)), e); } else if (operand.IsValueType) { CompileExpression(e.Arguments[0], ExpectType.ByRef); MethodRef getCopyRef = new MethodRef(namesController.TypeNameToJava(operand), ClassNames.ValueTypeGetCopy, "()" + namesController.GetFieldDescriptor(operand)); codeGenerator.Add(Java.OpCodes.invokevirtual, getCopyRef, e); } else { // From ECMA-335, III.4.29 // If typeTok is not a generic parameter and either a reference type or a built-in value // class, then the ldind instruction provides a shorthand for the ldobj instruction. CompileLdind(e, expect); } }
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 InterGenericArgument(GenericArgumentOwnerType owner, int position, InterType type) : this() { this.Owner = owner; this.Position = position; this.Type = type; }
private void PreprocessorCheckUninitializedLocalVarsExpression(ILExpression e, List <ILVariable> initializedVars) { if (e == null) { return; } if (e.Code == ILCode.Stloc) { if (!initializedVars.Contains((ILVariable)e.Operand)) { initializedVars.Add((ILVariable)e.Operand); } } if ((e.Code == ILCode.Ldloc) || (e.Code == ILCode.Ldloca)) { ILVariable op = (ILVariable)e.Operand; InterType varType = resolver.Resolve(op.Type, thisMethod.FullGenericArguments); if ((!varType.IsValueType) && (!op.IsParameter) && (!initializedVars.Contains(op))) { if (!uninitializedLocals.Contains((ILVariable)e.Operand)) { uninitializedLocals.Add((ILVariable)e.Operand); } } } foreach (ILExpression arg in e.Arguments) { PreprocessorCheckUninitializedLocalVarsExpression(arg, initializedVars); } }
private void GenerateValueTypeGetCopy(InterType type) { Method result = new Method(); result.AccessFlags = MethodAccessFlags.Public; result.Name = ClassNames.ValueTypeGetCopy; result.Descriptor = "()" + GetFieldDescriptor(type); Java.Constants.Class typeRef = new Java.Constants.Class(TypeNameToJava(type.Fullname)); MethodRef defaultCtorRef = new MethodRef(typeRef.Value, ClassNames.JavaConstructorMethodName, "()V"); MethodRef copyToRef = new MethodRef(typeRef.Value, ClassNames.ValueTypeCopyTo, "(" + GetFieldDescriptor(type) + ")V"); result.Attributes.Add(new JavaBytecodeWriter() //tmp = new type(); .Add(OpCodes._new, typeRef) .Add(OpCodes.dup) .Add(OpCodes.invokespecial, defaultCtorRef) .Add(OpCodes.astore_1) //this.CopyTo(tmp) .Add(OpCodes.aload_0) .Add(OpCodes.aload_1) .Add(OpCodes.invokevirtual, copyToRef) //return tmp .Add(OpCodes.aload_1) .AddReturn(JavaPrimitiveType.Ref) .End(currentJavaClass.ConstantPool)); currentJavaClass.Methods.Add(result); }
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 BoxTypeImpl(Dictionary <InterType, string> BoxTypes, InterType type, object tag) { if (type.IsNullable) { InterType instant = type.GenericArguments[0].Type; string labelsSufix = rnd.Next().ToString(); string hasValueLabel = "hasValue" + labelsSufix; string exitLabel = "exit" + labelsSufix; MethodRef hasValueMethodRef = new MethodRef(namesController.TypeNameToJava(type), ClassNames.SystemNullable_1.GetHasValueMethodName, "()Z"); MethodRef valueMethodRef = new MethodRef(hasValueMethodRef.Class, ClassNames.SystemNullable_1.GetValueMethodName, "()" + namesController.GetFieldDescriptor(instant)); codeGenerator .Add(OpCodes.dup, null, tag) .Add(OpCodes.invokevirtual, hasValueMethodRef, tag) .Add(OpCodes.ifne, hasValueLabel, tag) .Add(OpCodes.pop, null, tag) .Add(OpCodes.aconst_null, null, tag) .Add(OpCodes._goto, exitLabel, tag) .Label(hasValueLabel) .Add(OpCodes.invokevirtual, valueMethodRef, tag); BoxType(instant, tag); codeGenerator.Label(exitLabel); return; } if (type.IsEnum) { codeGenerator.Add(Java.OpCodes.invokestatic, new Java.Constants.MethodRef( namesController.TypeNameToJava(type), ClassNames.EnumGetBoxedMethodName, "(" + namesController.GetFieldDescriptor(type.ElementType) + ")L" + namesController.TypeNameToJava(type.Fullname) + ";")); return; } if (type.IsValueType) { return; } if (!BoxTypes.ContainsKey(type)) { Messages.Message(MessageCode.UnknownPrimitiveType, type.ToString()); type = InterType.PrimitiveTypes[(int)PrimitiveType.Int32]; } string boxType = BoxTypes[type]; Java.Constants.MethodRef valueOfRef = new Java.Constants.MethodRef( namesController.TypeNameToJava(boxType), "valueOf", "(" + namesController.GetFieldDescriptor(type) + ")L" + namesController.TypeNameToJava(boxType) + ";"); codeGenerator.Add(Java.OpCodes.invokestatic, valueOfRef, tag); }
public InterField(FieldReference fldRef, List <InterGenericArgument> genericArgs, IResolver resolver, Action <InterField> onMapped) { genericArgs = genericArgs ?? InterGenericArgument.EmptyGenericArgsList; this.declType = resolver.Resolve(fldRef.DeclaringType, genericArgs); this.fldType = resolver.Resolve(fldRef.FieldType, genericArgs.Union(this.declType.GenericArguments).ToList()); this.name = fldRef.Name; FieldDefinition fldDef = fldRef.Resolve(); CustomAttribute mappedAttr = fldDef.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.FieldMapAttribute).FirstOrDefault(); if (mappedAttr != null) { TypeReference mappedToType = mappedAttr.ConstructorArguments[0].Value as TypeReference; if (mappedToType != null) { string mappedToName = null; if (mappedAttr.ConstructorArguments.Count > 1) { mappedToName = mappedAttr.ConstructorArguments[1].Value as string; } mappedToName = mappedToName ?? this.name; TypeDefinition mappedToTypeDef = mappedToType.Resolve(); if (mappedToTypeDef != null) { FieldReference newFldRef = mappedToTypeDef.Fields.Where(F => F.Name == mappedToName).FirstOrDefault(); if (newFldRef != null) { onMapped(resolver.Resolve(newFldRef, genericArgs)); return; } } } } this.IsPublic = fldDef.IsPublic || fldDef.IsAssembly; this.IsProtected = fldDef.IsFamily || fldDef.IsFamilyAndAssembly || fldDef.IsFamilyOrAssembly; this.IsPrivate = fldDef.IsPrivate; this.IsStatic = fldDef.IsStatic; this.IsReadonly = fldDef.IsInitOnly; this.IsLiteral = fldDef.IsLiteral; this.IsThreadLocal = fldDef.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.ThreadStaticAttribute).Count() > 0; if (fldRef.FieldType is RequiredModifierType) { RequiredModifierType modreq = (RequiredModifierType)fldRef.FieldType; if (modreq.ModifierType.FullName == ClassNames.IsVolatileModReq) { this.IsVolatile = true; } } this.constant = fldDef.Constant; this.initialValue = fldDef.InitialValue; }
private void CompileCastclass(ILExpression e, ExpectType expect) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); CompileExpression(e.Arguments[0], expect); codeGenerator.Add(Java.OpCodes.checkcast, new Java.Constants.Class(namesController.TypeNameToJava(operand)), e); }
private void CompileIntrinsicGetClass(ILExpression e) { e = e.Arguments[0].Arguments[0]; InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); codeGenerator.Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava( operand.Fullname)), 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 }
private void CompileValueType(InterType type) { Messages.Verbose(" Generating value type internal methods..."); GenerateValueTypeDefaultCtor(type); GenerateValueTypeZeroFill(type); GenerateValueTypeCopyTo(type); GenerateValueTypeGetCopy(type); GenerateValueTypeEquals(type); }
private void CompileValueOf(ILExpression e, ExpectType expect) { InterType returnType = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments); InterType nullableType = resolver.Resolve(e.Arguments[0].InferredType, thisMethod.FullGenericArguments); CompileExpression(e.Arguments[0], ExpectType.ByRef); codeGenerator.Add(OpCodes.invokevirtual, new MethodRef(namesController.TypeNameToJava(nullableType), ClassNames.SystemNullable_1.GetValueOrDefaultMethodName, "()" + namesController.GetFieldDescriptor(returnType))); }
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 InterParameter(int index, InterType type, string name, bool isBoxed = false, bool isJavaBoxed = false) : this() { this.Index = index; this.Type = type; this.Name = name; this.IsBoxed = isBoxed; this.IsJavaBoxed = isJavaBoxed; }
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); }
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 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); }
private void BoxType(InterType type, object tag) { if (Program.BoxType == BoxingType.Java) { BoxTypeImpl(JavaBoxTypes, type, tag); } else { BoxTypeImpl(CilBoxTypes, type, tag); } }
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 CompileNullableOf(ILExpression e, ExpectType expect) { InterType result = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments); InterType nullableType = result.GenericArguments[0].Type; codeGenerator .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(result)), e) .Add(OpCodes.dup); CompileExpression(e.Arguments[0], GetExpectType(result)); codeGenerator.Add(OpCodes.invokespecial, new MethodRef(namesController.TypeNameToJava(result), ClassNames.JavaConstructorMethodName, "(" + namesController.GetFieldDescriptor(nullableType) + ")V"), e); }
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 CompileDelegate(InterType type) { CompileDelegateCtor(type); CompileDelegateInvoke(type); if (type.Methods.Where(M => M.Name == ClassNames.DelegateBeginInvokeMethodName).Count() > 0) { GenerateDelegateRunner(type); CompileDelegateBeginInvoke(type); CompileDelegateEndInvoke(type); } }
private void CompileUnbox_Any(ILExpression e, ExpectType expect) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); InterType nullableType = null; if (operand.IsNullable) { nullableType = operand; operand = operand.GenericArguments[0].Type; codeGenerator .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(nullableType)), e) .Add(OpCodes.dup, null, e); } CompileExpression(e.Arguments[0], ExpectType.Boxed); string boxType = GetBoxType(operand); Java.Constants.Class operandRef = new Java.Constants.Class(namesController.TypeNameToJava(boxType)); Java.Constants.MethodRef valueRef; if (operand.IsValueType) { valueRef = new Java.Constants.MethodRef(operandRef.Value, ClassNames.ValueTypeGetCopy, "()" + namesController.GetFieldDescriptor(operand)); } else if (operand.IsEnum) { valueRef = new MethodRef(operandRef.Value, ClassNames.EnumGetUnboxedMethodName, "()" + namesController.GetFieldDescriptor(operand.ElementType)); } else { valueRef = new Java.Constants.MethodRef(operandRef.Value, Utils.GetJavaTypeName(operand.PrimitiveType) + "Value", "()" + namesController.GetFieldDescriptor(operand)); } codeGenerator .Add(Java.OpCodes.checkcast, operandRef, e) .Add(Java.OpCodes.invokevirtual, valueRef, e); if (nullableType != null) { codeGenerator.Add(OpCodes.invokespecial, new MethodRef( namesController.TypeNameToJava(nullableType), ClassNames.JavaConstructorMethodName, "(" + namesController.GetFieldDescriptor(operand) + ")V")); } }