public override T Execute <T>(params object[] arguments) { using (SPEWrapper spe = new SPEWrapper()) { //TODO: Should be cached? spe.LoadELF(m_elf); LSBitConverter conv = new LSBitConverter(spe.LS); SPEObjectManager manager = new SPEObjectManager(conv); if (manager.ObjectTable.Memsize != spe.Size) { throw new Exception(string.Format("Unexpected size in loaded ELF {0} should be {1}", manager.ObjectTable.Memsize, spe.Size)); } Dictionary <uint, int> transferedObjects = base.LoadInitialArguments(conv, manager, arguments); int r = spe.Run(new CallbackHandlerDelegate(spe_callback)); if (r != (SPEJITCompiler.STOP_SUCCESSFULL & 0xff)) { throw new Exception("Unexpected return code: " + r); } return(base.FinalizeAndReturn <T>(conv, manager, transferedObjects, arguments)); } }
public override T Execute <T>(params object[] args) { bool showGui = this.ShowGUI; SPEEmulator.SPEProcessor spe; SPEEmulatorTestApp.Simulator sx = null; if (showGui) { // Run program sx = new SPEEmulatorTestApp.Simulator(new string[] { m_elf }); sx.StartAndPause(); spe = sx.SPE; } else { spe = new SPEEmulator.SPEProcessor(); spe.LoadELF(m_elf); m_workingEvent = new System.Threading.ManualResetEvent(false); } SPEEmulator.EndianBitConverter conv = new SPEEmulator.EndianBitConverter(spe.LS); SPEObjectManager manager = new SPEObjectManager(conv); Dictionary <uint, int> transferedObjects = base.LoadInitialArguments(conv, manager, args); spe.RegisterCallbackHandler(SPEJITCompiler.STOP_METHOD_CALL & 0xff, spe_callback); if (showGui) { System.Windows.Forms.Application.Run(sx); } else { m_exitCode = 0; m_workingEvent.Reset(); spe.SPEStopped += new SPEEmulator.StatusEventDelegate(spe_SPEStopped); spe.Exit += new SPEEmulator.ExitEventDelegate(spe_Exit); spe.Start(); m_workingEvent.WaitOne(); spe.SPEStopped -= new SPEEmulator.StatusEventDelegate(spe_SPEStopped); spe.Exit -= new SPEEmulator.ExitEventDelegate(spe_Exit); Console.WriteLine("Executed {0} instructions while running function {1}", spe.SPU.InstructionsExecuted, m_loadedMethod.DeclaringType.FullName + "::" + m_loadedMethod.Name); if (m_exitCode != SPEJITCompiler.STOP_SUCCESSFULL) { throw new Exception("Invalid exitcode: " + m_exitCode); } } spe.UnregisterCallbackHandler(SPEJITCompiler.STOP_METHOD_CALL & 0xff); return(base.FinalizeAndReturn <T>(conv, manager, transferedObjects, args)); }
protected T FinalizeAndReturn <T>(SPEEmulator.IEndianBitConverter conv, SPEObjectManager manager, Dictionary <uint, int> transferedObjects, object[] args) { SPEObjectManager newmanager = new SPEObjectManager(conv); //Now extract data back into the objects that are byref foreach (KeyValuePair <uint, int> k in transferedObjects) { if (m_typeSerializeOut[k.Value]) { newmanager.ReadObjectFromLS(k.Key, args[k.Value]); } //Remove the entry from the LS object table manager.DeleteObject(k.Key); } //Write back the old, unmodified object table, manager.SaveObjectTable(); Type rtype = typeof(T); if (rtype == typeof(ReturnTypeVoid)) { return(default(T)); } else if (rtype.IsPrimitive) { return((T)newmanager.ReadRegisterPrimitiveValue(rtype, 0)); } else { uint objindex = (uint)newmanager.ReadRegisterPrimitiveValue(typeof(uint), 0); if (objindex == 0) { return(default(T)); } return((T)newmanager.ReadObjectFromLS(objindex)); } }
protected Dictionary <uint, int> LoadInitialArguments(SPEEmulator.IEndianBitConverter conv, SPEObjectManager manager, object[] args) { conv.WriteUInt(0, 0); conv.WriteUInt(4, (uint)args.Length); uint lsoffset = manager.ObjectTable.Memsize - (16 * 8); //The -(16 * 8) is used to prevent the bootloader stack setup from overwriting the arguments Dictionary <uint, int> transferedObjects = new Dictionary <uint, int>(); for (int i = args.Length - 1; i >= 0; i--) { lsoffset -= 16; if (m_loadedMethodTypes[i].IsPrimitive) { manager.WriteRegisterPrimitiveValue(args[i], lsoffset); } else { uint objindex = manager.CreateObjectOnLS(args[i]); if (objindex != 0 && !transferedObjects.ContainsKey(objindex)) { transferedObjects[objindex] = i; } manager.WriteRegisterPrimitiveValue(objindex, lsoffset); } } conv.WriteUInt(8, lsoffset); conv.WriteUInt(12, 0); manager.SaveObjectTable(); return(transferedObjects); }
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 ArraySerializer(SPEObjectManager parent) { m_parent = parent; }
public StringSerializer(SPEObjectManager parent) { m_parent = parent; }