public static int GetClassObjectAddr(string name) { for (int i = 0; i < name.Length; i++) { if (name[i] != '[') { if (name[i] == 'L') { name = name.Substring(0, i) + name.Substring(i + 1, name.Length - i - 2); } break; } } if (name.Length == 1) { name = JavaHelper.PrimitiveFullName(name); } else { name = name.Replace('/', '.'); } int addr = 0; if (!classObjects.TryGetValue(name, out addr)) { HeapObject classObj = new HeapObject(ClassFileManager.GetClassFile("java/lang/Class")); addr = Heap.AddItem(classObj); classObjects.Add(name, addr); classObj.SetField("name", "Ljava/lang/String;", new FieldReferenceValue(JavaHelper.CreateJavaStringLiteral(name))); } return(addr); }
public static int Intern(int stringObjToInternAddr) { foreach (int stringObjAddr in StringAddresses) { if (JavaHelper.ReadJavaString(stringObjAddr) == JavaHelper.ReadJavaString(stringObjToInternAddr)) { return(stringObjAddr); } } StringAddresses.AddFirst(stringObjToInternAddr); return(stringObjToInternAddr); }
private static void WriteWideValue(char character, long argument) { if (character == 'J') { Console.ForegroundColor = longColor; Console.Write(argument.ToString()); } else { Console.ForegroundColor = doubleColor; Console.Write(JavaHelper.StoredDoubleToDouble(argument).ToString()); } }
private static void WriteObjectValue(string type, int argument) { if (argument == 0) { Console.ForegroundColor = classNameColor; Console.Write(type); Console.ForegroundColor = separatorColor; Console.Write('/'); Console.ForegroundColor = nullColor; Console.Write("Null"); } else { ClassFile argCFile = Heap.GetObject(argument).ClassFile; if (argCFile.Name == "java/lang/String") { Console.ForegroundColor = stringColor; FieldReferenceValue charArr = (FieldReferenceValue)Heap.GetObject(argument).GetField("value", "[C"); if (charArr.Address == 0) { Console.ForegroundColor = classNameColor; Console.Write(Heap.GetObject(argument).ClassFile.Name); } else { Console.Write('"' + JavaHelper.ReadJavaString(argument) + '"'); } } else if (argCFile.Name == "java/lang/Class") { Console.ForegroundColor = classObjColor; Console.Write(JavaHelper.ClassObjectName(argument)); } else { Console.ForegroundColor = classNameColor; Console.Write(Heap.GetObject(argument).ClassFile.Name); } Console.ForegroundColor = separatorColor; Console.Write('/'); Console.ForegroundColor = objAddrColor; Console.Write(argument); } }
private static void WriteArgs(string descriptor, bool isStatic, int[] args) { if (WriteDebugMessages) { ConsoleColor originalColor = Console.ForegroundColor; int argIndex = 0; int i; Console.Write("("); if (!isStatic) { int callerAddr = args[0]; if (Heap.GetObject(callerAddr) is HeapArray heapArr) { WriteArrayValue(JavaHelper.ClassObjectName(heapArr.ItemTypeClassObjAddr), callerAddr); } else { ClassFile argCFile = Heap.GetObject(callerAddr).ClassFile; WriteObjectValue(argCFile.Name, callerAddr); } argIndex++; } for (i = 1; descriptor[i] != ')';) { if (!isStatic || i != 1) { Console.Write(", "); } string argumentType = JavaHelper.ReadDescriptorArg(descriptor, ref i); if (argumentType[0] == 'J' || argumentType[0] == 'D') { long argument = (args[argIndex], args[argIndex + 1]).ToLong(); WriteWideValue(argumentType[0], argument); argIndex += 2; } else { int argument = args[argIndex]; WriteValue(argumentType, argument); argIndex++; } } Console.ForegroundColor = originalColor; Console.Write(')'); } }
private static void WriteValue(string argumentType, int argument) { if (argumentType[0] == 'L') { WriteObjectValue(argumentType.Substring(1, argumentType.Length - 2), argument); } else if (argumentType[0] == '[') { WriteArrayValue(argumentType.Substring(1), argument); } else if (argumentType[0] == 'Z') { Console.ForegroundColor = booleanColor; Console.Write(argument != 0 ? "True" : "False"); } else if (argumentType[0] == 'C') { Console.ForegroundColor = charColor; Console.Write("'" + (char)argument + "'"); } else if (argumentType[0] == 'F') { Console.ForegroundColor = floatColor; Console.Write(JavaHelper.StoredFloatToFloat(argument)); } else { switch (argumentType[0]) { case 'B': Console.ForegroundColor = byteColor; break; case 'I': Console.ForegroundColor = integerColor; break; case 'S': Console.ForegroundColor = shortColor; break; } Console.Write(argument); } }
private static void WriteArrayValue(string itemType, int argument) { if (argument != 0) { HeapArray heapArr = Heap.GetArray(argument); string itemTypeFromArg = JavaHelper.ClassObjectName(heapArr.ItemTypeClassObjAddr); if (!JavaHelper.IsPrimitiveType(itemTypeFromArg)) { itemType = JavaHelper.ClassObjectName(heapArr.ItemTypeClassObjAddr).Replace('.', '/'); } } Console.ForegroundColor = arrayBracketColor; int i = -1; do { Console.Write('['); i++; } while (itemType[i] == '['); Console.ForegroundColor = classNameColor; if (itemType[i] == 'L') { Console.Write(itemType.Substring(i + 1, itemType.Length - i - 2)); } else { Console.Write(itemType.Substring(i)); } Console.ForegroundColor = separatorColor; Console.Write("/"); if (argument == 0) { Console.ForegroundColor = nullColor; Console.Write("Null"); } else { Console.ForegroundColor = objAddrColor; Console.Write(argument); } }
public void SetItem(int index, long itemData) { Memory <byte> dataSlice = Heap.GetMemorySlice(Address + 8 + 8 + itemSize * index, itemSize); byte[] itemDataAsArray = itemSize == 8 ? itemData.AsByteArray() : ((int)itemData).AsByteArray(); itemDataAsArray.CopyTo(dataSlice); if (Array is int[] intArr) { intArr[index] = (int)itemData; } else if (Array is byte[] byteArr) { byteArr[index] = (byte)itemData; } else if (Array is char[] charArr) { charArr[index] = (char)itemData; } else if (Array is short[] shortArr) { shortArr[index] = (short)itemData; } else if (Array is long[] longArr) { longArr[index] = itemData; } else if (Array is bool[] boolArr) { boolArr[index] = itemData != 0; } else if (Array is double[] doubleArr) { doubleArr[index] = JavaHelper.StoredDoubleToDouble(itemData); } else if (Array is float[] floatArr) { floatArr[index] = (float)JavaHelper.StoredDoubleToDouble(itemData); } else { throw new InvalidOperationException(); } }
private static void WriteFieldValue(FieldInfo fieldInfo, FieldValue fieldValue) { Console.ForegroundColor = fieldTypeColor; Console.Write(fieldInfo.Descriptor); Console.ForegroundColor = separatorColor; Console.Write(':'); switch (fieldValue) { case FieldNumber number: switch (fieldInfo.Descriptor) { case "Z": Console.ForegroundColor = booleanColor; Console.Write(number.Value != 0 ? "True" : "False"); break; case "C": Console.ForegroundColor = charColor; Console.Write("'" + (char)number.Value + "'"); break; case "F": Console.ForegroundColor = floatColor; Console.Write(JavaHelper.StoredFloatToFloat(number.Value)); break; case "B": Console.ForegroundColor = byteColor; Console.Write(number.Value); break; case "I": Console.ForegroundColor = integerColor; Console.Write(number.Value); break; case "S": Console.ForegroundColor = shortColor; Console.Write(number.Value); break; } break; case FieldLargeNumber largeNumber: WriteWideValue(fieldInfo.Descriptor[0], largeNumber.Value); break; case FieldReferenceValue referenceValue: if (fieldInfo.Descriptor[0] == '[') { WriteArrayValue(fieldInfo.Descriptor.Substring(1), referenceValue.Address); } else { WriteObjectValue(fieldInfo.Descriptor.Substring(1, fieldInfo.Descriptor.Length - 2), referenceValue.Address); } break; default: throw new InvalidOperationException(); } }