mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-23 06:18:54 +00:00
implemented static field scanning. seems to work great.
This commit is contained in:
parent
cb5aacad9e
commit
e8a3321cf7
4 changed files with 103 additions and 2 deletions
|
|
@ -39,7 +39,7 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
|
||||
xOffset += SizeOfType( xInfo.FieldType );
|
||||
}
|
||||
string xDataName = "static_field__" + MethodInfoLabelGenerator.GetFullName( xField.DeclaringType ) + "." + xField.Name;
|
||||
string xDataName = "static_field__" + DataMember.FilterStringForIncorrectChars(MethodInfoLabelGenerator.GetFullName(xField.DeclaringType) + "." + xField.Name);
|
||||
if( xNeedsGC )
|
||||
{
|
||||
new CPUx86.Push { DestinationRef = ElementReference.New( xDataName ), DestinationIsIndirect = true };
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using System.IO;
|
|||
using System.Reflection;
|
||||
using Indy.IL2CPU;
|
||||
using Indy.IL2CPU.IL;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Cosmos.IL2CPU {
|
||||
|
||||
|
|
@ -464,5 +465,87 @@ namespace Cosmos.IL2CPU {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessField(FieldInfo aField) {
|
||||
string xFieldName = MethodInfoLabelGenerator.GetFullName(aField);
|
||||
xFieldName = DataMember.GetStaticFieldName(aField);
|
||||
if (DataMembers.Count(x => x.Name == xFieldName) == 0) {
|
||||
var xItemList = (from item in aField.GetCustomAttributes(false)
|
||||
where item.GetType().FullName == "ManifestResourceStreamAttribute"
|
||||
select item).ToList();
|
||||
|
||||
object xItem = null;
|
||||
if (xItemList.Count > 0)
|
||||
xItem = xItemList[0];
|
||||
string xManifestResourceName = null;
|
||||
if (xItem != null) {
|
||||
var xItemType = xItem.GetType();
|
||||
xManifestResourceName = (string)xItemType.GetField("ResourceName").GetValue(xItem);
|
||||
}
|
||||
if (xManifestResourceName != null) {
|
||||
// todo: add support for manifest streams again
|
||||
//RegisterType(xCurrentField.FieldType);
|
||||
//string xFileName = Path.Combine(mOutputDir,
|
||||
// (xCurrentField.DeclaringType.Assembly.FullName + "__" + xManifestResourceName).Replace(",",
|
||||
// "_") + ".res");
|
||||
//using (var xStream = xCurrentField.DeclaringType.Assembly.GetManifestResourceStream(xManifestResourceName)) {
|
||||
// if (xStream == null) {
|
||||
// throw new Exception("Resource '" + xManifestResourceName + "' not found!");
|
||||
// }
|
||||
// using (var xTarget = File.Create(xFileName)) {
|
||||
// // todo: abstract this array code out.
|
||||
// xTarget.Write(BitConverter.GetBytes(Engine.RegisterType(Engine.GetType("mscorlib",
|
||||
// "System.Array"))),
|
||||
// 0,
|
||||
// 4);
|
||||
// xTarget.Write(BitConverter.GetBytes((uint)InstanceTypeEnum.StaticEmbeddedArray),
|
||||
// 0,
|
||||
// 4);
|
||||
// xTarget.Write(BitConverter.GetBytes((int)xStream.Length), 0, 4);
|
||||
// xTarget.Write(BitConverter.GetBytes((int)1), 0, 4);
|
||||
// var xBuff = new byte[128];
|
||||
// while (xStream.Position < xStream.Length) {
|
||||
// int xBytesRead = xStream.Read(xBuff, 0, 128);
|
||||
// xTarget.Write(xBuff, 0, xBytesRead);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//mAssembler.DataMembers.Add(new DataMember("___" + xFieldName + "___Contents",
|
||||
// "incbin",
|
||||
// "\"" + xFileName + "\""));
|
||||
//mAssembler.DataMembers.Add(new DataMember(xFieldName,
|
||||
// "dd",
|
||||
// "___" + xFieldName + "___Contents"));
|
||||
throw new NotImplementedException();
|
||||
} else {
|
||||
uint xTheSize;
|
||||
//string theType = "db";
|
||||
Type xFieldTypeDef = aField.FieldType;
|
||||
if (!xFieldTypeDef.IsClass || xFieldTypeDef.IsValueType) {
|
||||
xTheSize = ILOp.SizeOfType(aField.FieldType);
|
||||
} else {
|
||||
xTheSize = 4;
|
||||
}
|
||||
byte[] xData = new byte[xTheSize];
|
||||
try {
|
||||
object xValue = aField.GetValue(null);
|
||||
if (xValue != null) {
|
||||
try {
|
||||
xData = new byte[xTheSize];
|
||||
if (xValue.GetType().IsValueType) {
|
||||
for (int x = 0; x < xTheSize; x++) {
|
||||
xData[x] = Marshal.ReadByte(xValue,
|
||||
x);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
DataMembers.Add(new DataMember(xFieldName, xData));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ namespace Cosmos.IL2CPU {
|
|||
// could be used for other things, profiling, analysis, reporting, etc
|
||||
public abstract void Execute(MethodInfo aMethod, ILOpCode aOpCode);
|
||||
|
||||
protected static uint SizeOfType(Type aType) {
|
||||
public static uint SizeOfType(Type aType) {
|
||||
if (aType.FullName == "System.Void") {
|
||||
return 0;
|
||||
} else if ((!aType.IsValueType && aType.IsClass) || aType.IsInterface) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ namespace Cosmos.IL2CPU {
|
|||
protected HashSet<Type> mTypesSet = new HashSet<Type>();
|
||||
protected List<Type> mTypes = new List<Type>();
|
||||
|
||||
protected HashSet<FieldInfo> mStaticFields = new HashSet<FieldInfo>();
|
||||
|
||||
// Logging
|
||||
// Only use for debugging and profiling.
|
||||
protected bool mLogEnabled = false;
|
||||
|
|
@ -442,6 +444,11 @@ namespace Cosmos.IL2CPU {
|
|||
((ILOpCodes.OpMethod)xOpCode).ValueUID = QueueMethod(aMethodInfo.MethodBase, "Call", ((ILOpCodes.OpMethod)xOpCode).Value, false);
|
||||
} else if (xOpCode is ILOpCodes.OpType) {
|
||||
QueueType(aMethodInfo.MethodBase, "OpCode Value", ((ILOpCodes.OpType)xOpCode).Value);
|
||||
} else if (xOpCode is ILOpCodes.OpField) {
|
||||
var xOpField = (ILOpCodes.OpField)xOpCode;
|
||||
if (xOpField.Value.IsStatic) {
|
||||
QueueField(aMethodInfo.MethodBase, "OpCode Value", xOpField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -452,6 +459,17 @@ namespace Cosmos.IL2CPU {
|
|||
}
|
||||
}
|
||||
|
||||
private void QueueField(object aSrc, string aSrcType, Cosmos.IL2CPU.ILOpCodes.OpField xOpField) {
|
||||
// todo: add log map thing?
|
||||
if (!mStaticFields.Contains(xOpField.Value)) {
|
||||
mStaticFields.Add(xOpField.Value);
|
||||
mAsmblr.ProcessField(xOpField.Value);
|
||||
|
||||
QueueType(xOpField.Value, "FieldType", xOpField.Value.FieldType);
|
||||
QueueType(xOpField.Value, "DeclaringType", xOpField.Value.FieldType);
|
||||
}
|
||||
}
|
||||
|
||||
// System.ThrowHelper exists in MS .NET twice...
|
||||
// Its an internal class that exists in both mscorlib and system assemblies.
|
||||
// They are separate types though, so normally the scanner scans both and
|
||||
|
|
|
|||
Loading…
Reference in a new issue