public ConstantPool Read(BinaryReader Reader) { ushort Count = Reader.ReadUInt16BE(); ResultPool = new ConstantPool(); FiledConsts = new bool[Count]; FiledConsts[0] = true; RawData = new byte[Count][]; for (int i = 1; i < Count; i++) { Constant Result = null; ConstantTag Tag = (ConstantTag)Reader.ReadByte(); switch (Tag) { case ConstantTag.Utf8: Result = new Constants.Utf8(); break; case ConstantTag.Integer: Result = new Constants.Integer(); break; case ConstantTag.Float: Result = new Constants.Float(); break; case ConstantTag.Long: Result = new Constants.Long(); break; case ConstantTag.Double: Result = new Constants.Double(); break; case ConstantTag.Class: Result = new Constants.Class(); break; case ConstantTag.String: Result = new Constants.String(); break; case ConstantTag.FieldRef: Result = new Constants.FieldRef(); break; case ConstantTag.MethodRef: Result = new Constants.MethodRef(); break; case ConstantTag.InterfaceMethodRef: Result = new Constants.InterfaceMethodRef(); break; case ConstantTag.NameAndType: Result = new Constants.NameAndType(); break; case ConstantTag.MethodHandle: Result = new Constants.MethodHandle(); break; case ConstantTag.MethodType: Result = new Constants.MethodType(); break; case ConstantTag.InvokeDynamic: Result = new Constants.InvokeDynamic(); break; } if (Result == null) { ResultPool.ForceAddConstant(new Constants.Skip(), (ushort)i); Messages.Message(MessageCode.JavaUnknownConstantTag, ((byte)Tag).ToString()); continue; } RawData[i] = Result.ReadData(Reader); ResultPool.ForceAddConstant(Result, (ushort)i); if (Result.Is8Byte()) { FiledConsts[++i] = true; } } for (int i = 1; i < Count; i++) { GetFilledConstant((ushort)i); } return(ResultPool); }
protected override bool CompareEqwals(Constant c) { InterfaceMethodRef Another = (InterfaceMethodRef)c; return((Class == Another.Class) && (Name == Another.Name) && (Descriptor == Another.Descriptor)); }
private void CompileJmp(ILExpression e, ExpectType expect) { int argIndex = 0; if (thisMethod.HasThis) { codeGenerator.Add(Java.OpCodes.aload_0, null, e); argIndex++; } for (int i = 0; i < thisMethod.Parameters.Count; i++) { JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(thisMethod.Parameters[i].Type); codeGenerator.AddLoad(jp, argIndex++); if (jp.IsDoubleSlot()) { argIndex++; } } InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); CallType callType = CallType.Virtual; if (operand.IsStatic) { callType = CallType.Static; } else if (operand.DeclaringType.IsInterface) { callType = CallType.Interface; } else if ((operand.IsConstructor) || (operand.IsPrivate) || ((operand.IsSame(thisMethod)) && (thisMethod.DeclaringType.BaseType == operand.DeclaringType))) { callType = CallType.Special; } Java.Constant javaOperand = null; if (callType == CallType.Interface) { javaOperand = new Java.Constants.InterfaceMethodRef( namesController.TypeNameToJava(operand.DeclaringType), namesController.MethodNameToJava(operand.NewName), namesController.GetMethodDescriptor(operand)); } else { javaOperand = new Java.Constants.MethodRef( namesController.TypeNameToJava(operand.DeclaringType), namesController.MethodNameToJava(operand.NewName), namesController.GetMethodDescriptor(operand)); } switch (callType) { case CallType.Interface: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokeinterface, javaOperand, e)); break; case CallType.Special: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokespecial, javaOperand, e)); break; case CallType.Static: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokestatic, javaOperand, e)); break; case CallType.Virtual: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokevirtual, javaOperand, e)); break; } codeGenerator.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(thisMethod.ReturnParameter.Type)); }
private void CompileCall(ILExpression e, ExpectType expect) { InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); if (operand.DeclaringType.Fullname == ClassNames.SystemThreadingMonitor.ClassName) { if (operand.Name == ClassNames.SystemThreadingMonitor.Enter) { CompileMonitorEnter(e); return; } if (operand.Name == ClassNames.SystemThreadingMonitor.Exit) { CompileMonitorExit(e); return; } } // Intrinsics that not poping real arguments if (operand.DeclaringType.Fullname == ClassNames.Intrinsics.ClassName) { if (operand.Name.Contains(ClassNames.Intrinsics.CreatePointerToArray)) { CompileIntrinsicCreatePointerToArray(e); return; } if (operand.Name == ClassNames.Intrinsics.GetBoxedDataFromPointer) { CompileIntrinsicGetBoxedDataFromPointer(e); return; } if (operand.Name == ClassNames.Intrinsics.GetClass) { CompileIntrinsicGetClass(e); return; } } if ((Program.BoxType == BoxingType.Java) && (operand.DeclaringType.Fullname == ClassNames.CorlibUtils) && (operand.Name == ClassNames.ReboxMethod)) { //Skip CIL2Java.Utils::Rebox in java boxing mode due optimizations CompileExpression(e.Arguments[0], expect); return; } if ((operand.IsConstructor) && (operand.DeclaringType.IsValueType) && (operand.Parameters.Count < e.Arguments.Count) && (!thisMethod.IsConstructor)) { // rebuild nodes from `call ctor(getVar(), [params])` to // setVar(newObj([params]) ILExpression getVar = e.Arguments[0]; e.Arguments.RemoveAt(0); e.Code = ILCode.Newobj; getVar.Code = LoadVarInvert[getVar.Code]; getVar.Arguments.Add(e); CompileExpression(getVar, expect); return; } if (operand.DeclaringType.IsArray) { CompileArrayCall(e, expect); return; } int argIndex = 0; if ((operand.HasThis) && (operand.Parameters.Count < e.Arguments.Count)) { if (e.Prefixes != null) { ILExpressionPrefix constrained = e.Prefixes.Where(P => P.Code == ILCode.Constrained).FirstOrDefault(); if (constrained != null) { InterType thisType = resolver.Resolve((TypeReference)constrained.Operand, thisMethod.FullGenericArguments); if (thisType.IsPrimitive) { e.Arguments[argIndex].Code = GetAddrInvert[e.Arguments[argIndex].Code]; e.Arguments[argIndex] = new ILExpression(ILCode.Box, null, e.Arguments[argIndex]); } } } CompileExpression(e.Arguments[argIndex++], ExpectType.Reference); } foreach (InterParameter param in operand.Parameters) { CompileExpression(e.Arguments[argIndex++], GetExpectType(param)); } if (operand.IsVarArg) { codeGenerator .AddIntConst(e.Arguments.Count - argIndex) .Add(OpCodes.anewarray, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.JavaObject)), e); int i = 0; while (argIndex < e.Arguments.Count) { codeGenerator .Add(OpCodes.dup, null, e) .AddIntConst(i++, e); CompileExpression(e.Arguments[argIndex++], ExpectType.Boxed); codeGenerator.Add(OpCodes.aastore, null, e); } } // Intrinsics that poping real arguments if (operand.DeclaringType.Fullname == ClassNames.Intrinsics.ClassName) { if (operand.Name == ClassNames.Intrinsics.monitorenter) { codeGenerator.Add(Java.OpCodes.monitorenter, null, e); } if (operand.Name == ClassNames.Intrinsics.monitorexit) { codeGenerator.Add(Java.OpCodes.monitorexit, null, e); } if (operand.Name == ClassNames.Intrinsics.lshr) { codeGenerator.Add(Java.OpCodes.lshr, null, e); } if (operand.Name == ClassNames.Intrinsics.lushr) { codeGenerator.Add(Java.OpCodes.lushr, null, e); } // UnsafeTypeConvert skip because: // Not any compiling. Just push argument, and it will auto became object type return; } CallType callType = CallType.Virtual; if (operand.IsStatic) { callType = CallType.Static; } else if (operand.DeclaringType.IsInterface) { callType = CallType.Interface; } else if ((operand.IsConstructor) || (operand.IsPrivate) || ((operand.IsSame(thisMethod)) && (thisMethod.DeclaringType.BaseType == operand.DeclaringType))) { callType = CallType.Special; } Java.Constant javaOperand = null; if (callType == CallType.Interface) { javaOperand = new Java.Constants.InterfaceMethodRef( namesController.TypeNameToJava(operand.DeclaringType), namesController.MethodNameToJava(operand.NewName), namesController.GetMethodDescriptor(operand)); } else { javaOperand = new Java.Constants.MethodRef( namesController.TypeNameToJava(operand.DeclaringType), namesController.MethodNameToJava(operand.NewName), namesController.GetMethodDescriptor(operand)); } switch (callType) { case CallType.Interface: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokeinterface, javaOperand, e)); break; case CallType.Special: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokespecial, javaOperand, e)); break; case CallType.Static: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokestatic, javaOperand, e)); break; case CallType.Virtual: codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokevirtual, javaOperand, e)); break; } OnRestoreLocalByRefs(); if ((!operand.ReturnParameter.Type.IsPrimitive) || (operand.ReturnParameter.Type.PrimitiveType != PrimitiveType.Void) || (operand.ReturnParameter.IsBoxed) || (operand.ReturnParameter.IsJavaBoxed)) { TranslateType(operand.ReturnParameter.Type, expect, e); } }
private void LinkPass1(Java.ConstantPool pool) { int offset = StartOffset; bool lastWide = false; for (int i = 0; i < outputCode.Count; i++) { JavaInstruction instr = outputCode[i]; outputCodeOffsets.Add(instr, offset); object lastOperand = instr.Operand; if (instr.Operand is Java.Constant) { instr.Operand = pool.AddConstant((Java.Constant)instr.Operand); } else if (instr.Operand is MultianewarrayOperand) { MultianewarrayOperand operand = (MultianewarrayOperand)instr.Operand; instr.Operand = pool.AddConstant(operand.ClassOperand) | (operand.DimensionsOperand << 16); } if (instr.Opcode == Java.OpCodes.ldc) { if (((ushort)instr.Operand) > byte.MaxValue) { instr.Opcode = Java.OpCodes.ldc_w; } } if (instr.Opcode == Java.OpCodes.invokeinterface) { if (lastOperand is Java.Constants.MethodRef) { Java.Constants.MethodRef m = (Java.Constants.MethodRef)lastOperand; lastOperand = new Java.Constants.InterfaceMethodRef(m.Class, m.Name, m.Descriptor); } byte argsCount = CalculateInterfaceCallArgsCount(((Java.Constants.InterfaceMethodRef)lastOperand).Descriptor); ushort constIndex = (ushort)instr.Operand; instr.Operand = (uint)(constIndex | ((argsCount + 1) << 24)); } int size = Java.ByteCode.JavaInstructions[instr.Opcode].Size; if ((size == -1) && (instr.Opcode == Java.OpCodes.lookupswitch)) { LookupswitchOperand op = (LookupswitchOperand)lastOperand; instr.Operand = op; int paddingLendth = (4 - ((offset + 1) % 4)) % 4; size = 1 //opcode + paddingLendth //padding + 4 //default + 4 //npairs + op.Pairs.Length * 8; //pairs count * pairs size (8 = 4 + 4) } if (lastWide) { size = (size - 1) * 2 + 1; lastWide = false; } offset += size; if (instr.Opcode == Java.OpCodes.wide) { lastWide = true; } } }