private static ObjectTableWrapper ReadObjectTable(SPEEmulator.IEndianBitConverter conv) { uint object_table_size = conv.ReadUInt(SPEJITCompiler.OBJECT_TABLE_OFFSET); SPEEmulator.EndianBitConverter obj_tb_tmp = new SPEEmulator.EndianBitConverter(new byte[(object_table_size + 1) * 16]); conv.ReadBytes(SPEJITCompiler.OBJECT_TABLE_OFFSET, obj_tb_tmp.Data); uint[] object_table = new uint[(object_table_size + 1) * 4]; for (int i = 0; i < object_table.Length; i++) { object_table[i] = obj_tb_tmp.ReadUInt(); } ObjectTableWrapper objtable = new ObjectTableWrapper(object_table); /*Console.WriteLine("#Size {0}, nextFree: {1}, nextOffset: {2}, memSize: {3}", objtable.Size, objtable.NextFree, objtable.NextOffset, objtable.Memsize); * foreach (var e in objtable) * Console.WriteLine(e.ToString());*/ foreach (var v in objtable.Where(c => c.KnownType == AccCIL.KnownObjectTypes.String)) { byte[] localdata = new byte[v.AlignedSize]; conv.ReadBytes(v.Offset, localdata); objtable.Strings.Add(System.Text.Encoding.UTF8.GetString(localdata, 0, (int)v.Size), v.Index); } return(objtable); }
protected bool MethodCallback(SPEEmulator.IEndianBitConverter c, uint offset) { uint sp = c.ReadUInt(offset); //Stack size is 77 elements, and return address is next next instruction uint call_address = (c.ReadUInt(sp + (16 * 77)) - 4) / 4; Mono.Cecil.MethodReference calledmethod; m_callpoints.TryGetValue((int)call_address, out calledmethod); if (calledmethod == null) { foreach (KeyValuePair <int, Mono.Cecil.MethodReference> f in m_callpoints) { Console.WriteLine("Call registered at {0} for method {1}", f.Key, f.Value.DeclaringType.FullName + "::" + f.Value.Name); } throw new Exception("No method call registered at " + call_address); } //All good, we have a real function, now load all required arguments onto PPE object[] arguments = new object[calledmethod.Parameters.Count]; System.Reflection.MethodInfo m = AccCIL.AccCIL.FindReflectionMethod(calledmethod); if (m == null) { throw new Exception("Unable to find function called: " + calledmethod.DeclaringType.FullName + "::" + calledmethod.Name); } uint arg_base = sp + 32; uint sp_offset = arg_base; object @this = null; SPEObjectManager manager = new SPEObjectManager(c); if (!m.IsStatic) { Type argtype = m.DeclaringType; uint objindex = (uint)manager.ReadRegisterPrimitiveValue(typeof(uint), sp_offset); @this = manager.ReadObjectFromLS(objindex); sp_offset += 16; } for (int i = 0; i < arguments.Length; i++) { Type argtype = Type.GetType(calledmethod.Parameters[i].ParameterType.FullName); arguments[i] = manager.ReadRegisterPrimitiveValue(argtype.IsPrimitive ? argtype : typeof(uint), sp_offset); if (!argtype.IsPrimitive) { arguments[i] = manager.ReadObjectFromLS((uint)arguments[i]); } sp_offset += 16; } if (calledmethod.Name != "WriteLine" && calledmethod.Name != "Format" && calledmethod.Name != "ToString") { Console.WriteLine("Invoking {0} with arguments: ", calledmethod.DeclaringType.FullName + "::" + calledmethod.Name); foreach (object o in arguments) { Console.WriteLine("\t{0}", o == null ? "<null>" : o.ToString()); } } object result = m.Invoke(@this, arguments); int resultIndex = result == null ? 0 : -1; foreach (KeyValuePair <uint, object> t in manager.KnownObjectsById) { if (t.Value != null) { //Strings are imutable, so there is no reason to transfer them back if (manager.ObjectTable[t.Key].KnownType == AccCIL.KnownObjectTypes.String) { if (t.Value.Equals(result)) { resultIndex = (int)t.Key; } continue; } manager.WriteObjectToLS(t.Key, t.Value); if (t.Value == result) { resultIndex = (int)t.Key; } } } if (m.ReturnType != null) { if (m.ReturnType.IsPrimitive) { manager.WriteRegisterPrimitiveValue(result, arg_base); } else { if (resultIndex < 0) { resultIndex = (int)manager.CreateObjectOnLS(result); manager.ObjectTable[(uint)resultIndex].Refcount = 1; manager.SaveObjectTable(); } manager.WriteRegisterPrimitiveValue((uint)resultIndex, arg_base); } } return(true); }
public object Deserialize(SPEEmulator.IEndianBitConverter conv, ObjectTableEntry e, object storage) { return(conv.ReadUInt()); }