public static StackValue Repack(Obj obj, ProtoCore.DSASM.Heap heap) { if (obj.Type.IsIndexable) { //Unpack each of the elements DsasmArray arr = (DsasmArray)obj.Payload; StackValue[] sv = new StackValue[arr.members.Length]; //recurse over the array for (int i = 0; i < sv.Length; i++) sv[i] = Repack(arr.members[i], heap); int size = sv.Length; lock (heap.cslock) { int ptr = heap.Allocate(size); ++heap.Heaplist[ptr].Refcount; for (int n = size - 1; n >= 0; --n) { heap.Heaplist[ptr].Stack[n] = sv[n]; } StackValue overallSv = StackUtils.BuildArrayPointer(ptr); return overallSv; } } // For non-arrays, there is nothing to repack so just return the original stackvalue return obj.DsasmValue; }
private List<Obj> UnpackToList(ExecutionMirror mirror, Obj obj) { if (obj == null || !obj.DsasmValue.IsArray) return null; return mirror.MirrorTarget.rmem.Heap.ToHeapObject<DSArray>(obj.DsasmValue).Values.Select(x => mirror.Unpack(x)).ToList(); }
public void ArrayRetrival1DEmpty() { String code = @" foo; [Associative] { foo = {}; } "; ProtoScript.Runners.ProtoScriptRunner fsr = new ProtoScript.Runners.ProtoScriptRunner(); runtimeCore = fsr.Execute(code, core); ExecutionMirror mirror = runtimeCore.Mirror; ProtoCore.Lang.Obj o = mirror.GetValue("foo"); ProtoCore.DSASM.Mirror.DsasmArray a = (ProtoCore.DSASM.Mirror.DsasmArray)o.Payload; Assert.IsTrue(a.members.Length == 0); }
// traverse an array Obj return its member public List<Obj> GetArrayElements(Obj obj) { if ( obj == null || !obj.DsasmValue.IsArray) return null; return core.Heap.GetHeapElement(obj.DsasmValue).Stack.Select(x => Unpack(x)).ToList(); }
public Obj GetWatchValue() { int count = MirrorTarget.Core.watchStack.Count; int n = MirrorTarget.Core.watchSymbolList.FindIndex(x => { return string.Equals(x.name, Constants.kWatchResultVar); }); if (n < 0 || n >= count) { core.watchSymbolList.Clear(); return new Obj { Payload = null }; } Obj retVal = null; try { StackValue sv = MirrorTarget.Core.watchStack[n]; if (sv.optype != AddressType.Invalid) { retVal = Unpack(MirrorTarget.Core.watchStack[n], MirrorTarget.rmem.Heap, core); } else { retVal = new Obj { Payload = null }; } } catch { retVal = new Obj { Payload = null }; } finally { core.watchSymbolList.Clear(); } return retVal; }
// traverse an class type object to get its property public Dictionary<string, Obj> GetProperties(Obj obj, bool excludeStatic = false) { if (obj == null || obj.DsasmValue.optype != AddressType.Pointer) return null; Dictionary<string, Obj> ret = new Dictionary<string, Obj>(); int classIndex = (int)obj.DsasmValue.metaData.type; Dictionary<int,SymbolNode> symbolList = core.ClassTable.ClassNodes[classIndex].symbols.symbolList; StackValue[] svs = core.Heap.Heaplist[(int)obj.DsasmValue.opdata].Stack; int index = 0; for (int ix = 0; ix < svs.Length; ++ix) { if (excludeStatic && symbolList[ix].isStatic) continue; string name = symbolList[ix].name; StackValue val = svs[index]; // check if the members are primitive type if (val.optype == AddressType.Pointer && core.Heap.Heaplist[(int)val.opdata].Stack.Length == 1 && core.Heap.Heaplist[(int)val.opdata].Stack[0].optype != AddressType.Pointer && core.Heap.Heaplist[(int)val.opdata].Stack[0].optype != AddressType.ArrayPointer) val = core.Heap.Heaplist[(int)val.opdata].Stack[0]; ret[name] = Unpack(val); index++; } return ret; }
public int GetArrayElementCount(Obj obj) { if (obj == null || obj.DsasmValue.optype != AddressType.ArrayPointer) return 0; return core.Heap.Heaplist[(int)obj.DsasmValue.opdata].VisibleSize; }
public static Obj Unpack(StackValue val, Core core) { switch (val.optype) { case AddressType.ArrayPointer: { //It was a pointer that we pulled, so the value lives on the heap Int64 ptr = val.opdata; DsasmArray ret = new DsasmArray(); HeapElement hs = core.Heap.Heaplist[(int)ptr]; StackValue[] nodes = hs.Stack; ret.members = new Obj[nodes.Length]; for (int i = 0; i < ret.members.Length; i++) { ret.members[i] = Unpack(nodes[i], core); } Obj retO = new Obj(val) { Payload = ret, Type = core.TypeSystem.BuildTypeObject((ret.members.Length > 0) ? core.TypeSystem.GetType(ret.members[0].Type.Name) : (int)ProtoCore.PrimitiveType.kTypeVar, true) }; return retO; } case AddressType.Int: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeInt, false) }; return o; } case AddressType.Boolean: { Obj o = new Obj(val) { Payload = val.opdata == 0 ? false : true, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeBool, false) }; return o; } case AddressType.Null: { Obj o = new Obj(val) { Payload = null, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeNull, false) }; return o; } case AddressType.Double: { double data = val.opdata_d; Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeDouble, false) }; return o; } case AddressType.Char: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeChar, false) }; return o; } case AddressType.Pointer: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject((int)val.metaData.type, false) }; return o; } case AddressType.DefaultArg: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeVar, false) }; return o; } case AddressType.FunctionPointer: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeFunctionPointer, false) }; return o; } default: { throw new NotImplementedException(string.Format("unknown datatype {0}", val.optype.ToString())); } } }
// TODO: Implement this to recurse through expressions in watch window and running expression interpreter for each of their sub-types - pratapa internal static void GetStringValue(Obj obj, ProtoCore.DSASM.Mirror.ExecutionMirror mirror) { switch (obj.DsasmValue.optype) { case AddressType.ArrayPointer: { List<Obj> ol = mirror.GetArrayElements(obj); foreach (Obj o in ol) { GetStringValue(o, mirror); } return; } case AddressType.Pointer: { Dictionary<string, Obj> os = mirror.GetProperties(obj); for (int i = 0; i < os.Count; ++i) { } return; } default: return; } }
public List<string> GetPropertyNames(Obj obj) { if (obj == null || !obj.DsasmValue.IsPointer) return null; List<string> ret = new List<string>(); int classIndex = obj.DsasmValue.metaData.type; StackValue[] svs = MirrorTarget.rmem.Heap.ToHeapObject<DSObject>(obj.DsasmValue).VisibleItems.ToArray(); for (int ix = 0; ix < svs.Length; ++ix) { string propertyName = runtimeCore.DSExecutable.classTable.ClassNodes[classIndex].symbols.symbolList[ix].name; ret.Add(propertyName); } return ret; }
// this method is used for the IDE to query object values // Copy from the the existing Unpack with some modifications // 1: It is a non-static method so there is no need to pass the core and heap // 2: It does not traverse the array, array traverse is done in method GetArrayElement // 3: The payload for boolean and null is changed to Boolean and null type in .NET, such that the watch windows can directly call ToString() // to print the value, otherwize for boolean it will print either 0 or 1, for null it will print 0 public Obj Unpack(StackValue val) { Obj obj = null; switch (val.optype) { case AddressType.Pointer: obj = new Obj(val) { Payload = val.Pointer, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Pointer, 0) }; break; case AddressType.ArrayPointer: obj = new Obj(val) { Payload = val.ArrayPointer, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Array, Constants.kArbitraryRank) }; break; case AddressType.Int: obj = new Obj(val) { Payload = val.IntegerValue, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Integer, 0) }; break; case AddressType.Boolean: obj = new Obj(val) { Payload = val.BooleanValue, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Bool, 0) }; break; case AddressType.Double: obj = new Obj(val) { Payload = val.DoubleValue, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Double, 0) }; break; case AddressType.Null: obj = new Obj(val) { Payload = null, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Null, 0) }; break; case AddressType.FunctionPointer: obj = new Obj(val) { Payload = val.FunctionPointer, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.FunctionPointer, 0) }; break; case AddressType.String: obj = new Obj(val) { Payload = val.StringPointer, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.String, Constants.kPrimitiveSize) }; break; case AddressType.Char: obj = new Obj(val) { Payload = val.CharValue, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Char, 0) }; break; } return obj; }
// // TODO Jun: Integrate this helper function into the reflection system private List<Obj> GetArrayElements(ProtoCore.Mirror.RuntimeMirror mirror, StackValue svArrayPointer) { Assert.IsTrue(svArrayPointer.optype == ProtoCore.DSASM.AddressType.ArrayPointer); Obj array = new Obj(svArrayPointer); return mirror.GetUtils().GetArrayElements(array); }
public List<string> GetPropertyNames(Obj obj) { if (obj == null || !obj.DsasmValue.IsPointer) return null; List<string> ret = new List<string>(); int classIndex = obj.DsasmValue.metaData.type; StackValue[] svs = core.Heap.GetHeapElement(obj.DsasmValue).Stack; for (int ix = 0; ix < svs.Length; ++ix) { string propertyName = core.ClassTable.ClassNodes[classIndex].symbols.symbolList[ix].name; ret.Add(propertyName); } return ret; }
// traverse an class type object to get its property public Dictionary<string, Obj> GetProperties(Obj obj, bool excludeStatic = false) { if (obj == null || !obj.DsasmValue.IsPointer) return null; Dictionary<string, Obj> ret = new Dictionary<string, Obj>(); int classIndex = obj.DsasmValue.metaData.type; IDictionary<int,SymbolNode> symbolList = core.ClassTable.ClassNodes[classIndex].symbols.symbolList; StackValue[] svs = core.Heap.GetHeapElement(obj.DsasmValue).Stack; int index = 0; for (int ix = 0; ix < svs.Length; ++ix) { if (excludeStatic && symbolList[ix].isStatic) continue; string name = symbolList[ix].name; StackValue val = svs[index]; // check if the members are primitive type if (val.IsPointer) { var heapElement = core.Heap.GetHeapElement(val); if (heapElement.Stack.Length == 1 && !heapElement.Stack[0].IsPointer && !heapElement.Stack[0].IsArray) { val = heapElement.Stack[0]; } } ret[name] = Unpack(val); index++; } return ret; }
// this method is used for the IDE to query object values // Copy from the the existing Unpack with some modifications // 1: It is a non-static method so there is no need to pass the core and heap // 2: It does not traverse the array, array traverse is done in method GetArrayElement // 3: The payload for boolean and null is changed to Boolean and null type in .NET, such that the watch windows can directly call ToString() // to print the value, otherwize for boolean it will print either 0 or 1, for null it will print 0 public Obj Unpack(StackValue val) { Obj obj = null; switch (val.optype) { case AddressType.Pointer: obj = new Obj(val) { Payload = val.Pointer, }; break; case AddressType.ArrayPointer: obj = new Obj(val) { Payload = val.ArrayPointer, }; break; case AddressType.Int: obj = new Obj(val) { Payload = val.IntegerValue, }; break; case AddressType.Boolean: obj = new Obj(val) { Payload = val.BooleanValue, }; break; case AddressType.Double: obj = new Obj(val) { Payload = val.DoubleValue, }; break; case AddressType.Null: obj = new Obj(val) { Payload = null, }; break; case AddressType.FunctionPointer: obj = new Obj(val) { Payload = val.FunctionPointer, }; break; case AddressType.String: obj = new Obj(val) { Payload = val.StringPointer, }; break; case AddressType.Char: obj = new Obj(val) { Payload = val.CharValue, }; break; } return obj; }
//@TODO(Luke): Add in the methods here that correspond to each of the internal datastructures in use by the executive //@TODO(Jun): if this method stays static, then the Heap needs to be referenced from a parameter /// <summary> /// Do the recursive unpacking of the data structure into mirror objects /// </summary> /// <param name="val"></param> /// <returns></returns> public static Obj Unpack(StackValue val, Heap heap, RuntimeCore runtimeCore, int type = (int)PrimitiveType.kTypePointer) { Executable exe = runtimeCore.DSExecutable; switch (val.optype) { case AddressType.ArrayPointer: { DsasmArray ret = new DsasmArray(); //Pull the item out of the heap var array = heap.ToHeapObject<DSArray>(val); StackValue[] nodes = array.VisibleItems.ToArray(); ret.members = new Obj[array.VisibleSize]; for (int i = 0; i < ret.members.Length; i++) { ret.members[i] = Unpack(nodes[i], heap, runtimeCore, type); } // TODO Jun: ret.members[0] is hardcoded and means we are assuming a homogenous collection // How to handle mixed-type arrays? Obj retO = new Obj(val) { Payload = ret, Type = exe.TypeSystem.BuildTypeObject( (ret.members.Length > 0) ? exe.TypeSystem.GetType(ret.members[0].Type.Name) : (int)ProtoCore.PrimitiveType.kTypeVoid, Constants.kArbitraryRank) }; return retO; } case AddressType.String: { string str = heap.ToHeapObject<DSString>(val).Value; Obj o = new Obj(val) { Payload = str, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeString, 0) }; return o; } case AddressType.Int: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeInt, 0) }; return o; } case AddressType.Boolean: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = (data != 0), Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeBool, 0) }; return o; } case AddressType.Null: { Obj o = new Obj(val) { Payload = null, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeNull, 0) }; return o; } case AddressType.Char: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeChar, 0) }; return o; } case AddressType.Double: { double data = val.RawDoubleValue; Obj o = new Obj(val) { Payload = data, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeDouble, 0) }; return o; } case AddressType.Pointer: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = exe.TypeSystem.BuildTypeObject(type, 0) }; return o; } case AddressType.FunctionPointer: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeFunctionPointer, 0) }; return o; } case AddressType.Invalid: { return new Obj(val) {Payload = null}; } default: { throw new NotImplementedException(string.Format("unknown datatype {0}", val.optype.ToString())); } } }
// traverse an array Obj return its member public List<Obj> GetArrayElements(Obj obj) { if ( obj == null || !obj.DsasmValue.IsArray) return null; return core.Heap.Heaplist[(int)obj.DsasmValue.opdata].Stack.Select(x => Unpack(x)).ToList(); }
public static Obj Unpack(StackValue val, RuntimeCore runtimeCore) { RuntimeMemory rmem = runtimeCore.RuntimeMemory; Executable exe = runtimeCore.DSExecutable; switch (val.optype) { case AddressType.ArrayPointer: { //It was a pointer that we pulled, so the value lives on the heap DsasmArray ret = new DsasmArray(); var array = rmem.Heap.ToHeapObject<DSArray>(val); StackValue[] nodes = array.VisibleItems.ToArray(); ret.members = new Obj[nodes.Length]; for (int i = 0; i < ret.members.Length; i++) { ret.members[i] = Unpack(nodes[i], runtimeCore); } Obj retO = new Obj(val) { Payload = ret, Type = exe.TypeSystem.BuildTypeObject((ret.members.Length > 0) ? exe.TypeSystem.GetType(ret.members[0].Type.Name) : (int)ProtoCore.PrimitiveType.kTypeVar, Constants.kArbitraryRank) }; return retO; } case AddressType.Int: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeInt, 0) }; return o; } case AddressType.Boolean: { Obj o = new Obj(val) { Payload = val.opdata == 0 ? false : true, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeBool, 0) }; return o; } case AddressType.Null: { Obj o = new Obj(val) { Payload = null, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeNull, 0) }; return o; } case AddressType.Double: { double data = val.RawDoubleValue; Obj o = new Obj(val) { Payload = data, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeDouble, 0) }; return o; } case AddressType.Char: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeChar, 0) }; return o; } case AddressType.Pointer: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = exe.TypeSystem.BuildTypeObject(val.metaData.type, 0) }; return o; } case AddressType.DefaultArg: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0) }; return o; } case AddressType.FunctionPointer: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeFunctionPointer, 0) }; return o; } default: { throw new NotImplementedException(string.Format("unknown datatype {0}", val.optype.ToString())); } } }
//@TODO(Luke): Add in the methods here that correspond to each of the internal datastructures in use by the executive //@TODO(Jun): if this method stays static, then the Heap needs to be referenced from a parameter /// <summary> /// Do the recursive unpacking of the data structure into mirror objects /// </summary> /// <param name="val"></param> /// <returns></returns> public static Obj Unpack(StackValue val, Heap heap, Core core, int type = (int)PrimitiveType.kTypePointer) { switch (val.optype) { case AddressType.ArrayPointer: case AddressType.String: { //It was a pointer that we pulled, so the value lives on the heap Int64 ptr = val.opdata; DsasmArray ret = new DsasmArray(); //Pull the item out of the heap HeapElement hs = heap.Heaplist[(int)ptr]; StackValue[] nodes = hs.Stack; ret.members = new Obj[hs.VisibleSize]; for (int i = 0; i < ret.members.Length; i++) { ret.members[i] = Unpack(nodes[i], heap, core, type); } // TODO Jun: ret.members[0] is hardcoded and means we are assuming a homogenous collection // How to handle mixed-type arrays? Obj retO = new Obj(val) { Payload = ret, Type = core.TypeSystem.BuildTypeObject((ret.members.Length > 0) ? core.TypeSystem.GetType(ret.members[0].Type.Name) : (int)ProtoCore.PrimitiveType.kTypeVoid, true) }; return retO; } case AddressType.Int: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeInt, false) }; return o; } case AddressType.Boolean: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = (data != 0), Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeBool, false) }; return o; } case AddressType.Null: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = null, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeNull, false) }; return o; } case AddressType.Char: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeChar, false) }; return o; } case AddressType.Double: { double data = val.opdata_d; Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeDouble, false) }; return o; } case AddressType.Pointer: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(type, false) }; return o; } case AddressType.FunctionPointer: { Int64 data = val.opdata; Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeFunctionPointer, false) }; return o; } case AddressType.Invalid: { return new Obj(val) {Payload = null}; } default: { throw new NotImplementedException(string.Format("unknown datatype {0}", val.optype.ToString())); } } }
public static StackValue Repack(Obj obj, ProtoCore.DSASM.Heap heap) { if (obj.Type.IsIndexable) { //Unpack each of the elements DsasmArray arr = (DsasmArray)obj.Payload; StackValue[] sv = new StackValue[arr.members.Length]; //recurse over the array for (int i = 0; i < sv.Length; i++) sv[i] = Repack(arr.members[i], heap); int size = sv.Length; StackValue ptr = heap.AllocateArray(sv); return ptr; } // For non-arrays, there is nothing to repack so just return the original stackvalue return obj.DsasmValue; }
public bool EqualDotNetObject(Obj dsObj, object dotNetObj) { // check for null first if (dotNetObj == null) { if (dsObj.DsasmValue.optype == AddressType.Null) return true; else return false; } System.Type t = dotNetObj.GetType(); switch (dsObj.DsasmValue.optype) { case AddressType.ArrayPointer: if (t.IsArray) { object[] dotNetValue = (object[])dotNetObj; Obj[] dsValue = GetArrayElements(dsObj).ToArray(); if (dotNetValue.Length == dsValue.Length) { for (int ix = 0; ix < dsValue.Length; ++ix) { if (!EqualDotNetObject(dsValue[ix], dotNetValue[ix])) return false; } return true; } } return false; case AddressType.Int: if (dotNetObj is int) return (Int64)dsObj.Payload == (int)dotNetObj; else return false; case AddressType.Double: if (dotNetObj is double) return (Double)dsObj.Payload == (Double)dotNetObj; else return false; case AddressType.Boolean: if (dotNetObj is bool) return (Boolean)dsObj.Payload == (Boolean)dotNetObj; else return false; case AddressType.Pointer: if (t == typeof(Dictionary<string, Object>)) { Dictionary<string, Obj> dsProperties = GetProperties(dsObj); foreach (KeyValuePair<string, object> dotNetProperty in dotNetObj as Dictionary<string, object>) { if (!(dsProperties.ContainsKey(dotNetProperty.Key) && EqualDotNetObject(dsProperties[dotNetProperty.Key], dotNetProperty.Value))) return false; } return true; } return false; default: throw new NotImplementedException(); } }
public Obj GetWatchValue() { RuntimeCore runtimeCore = MirrorTarget.RuntimeCore; int count = runtimeCore.watchStack.Count; int n = runtimeCore.WatchSymbolList.FindIndex(x => { return string.Equals(x.name, Constants.kWatchResultVar); }); if (n < 0 || n >= count) { runtimeCore.WatchSymbolList.Clear(); return new Obj { Payload = null }; } Obj retVal = null; try { StackValue sv = runtimeCore.watchStack[n]; if (!sv.IsInvalid) { retVal = Unpack(runtimeCore.watchStack[n], MirrorTarget.rmem.Heap, runtimeCore); } else { retVal = new Obj { Payload = null }; } } catch { retVal = new Obj { Payload = null }; } finally { runtimeCore.WatchSymbolList.Clear(); } return retVal; }
// traverse an array Obj return its member public List<Obj> GetArrayElements(Obj obj) { if ( obj == null || obj.DsasmValue.optype != AddressType.ArrayPointer) return null; return core.Heap.Heaplist[(int)obj.DsasmValue.opdata].Stack.Select(x => Unpack(x)).ToList(); }
// traverse an class type object to get its property public Dictionary<string, Obj> GetProperties(Obj obj, bool excludeStatic = false) { RuntimeMemory rmem = MirrorTarget.rmem; if (obj == null || !obj.DsasmValue.IsPointer) return null; Dictionary<string, Obj> ret = new Dictionary<string, Obj>(); int classIndex = obj.DsasmValue.metaData.type; IDictionary<int,SymbolNode> symbolList = runtimeCore.DSExecutable.classTable.ClassNodes[classIndex].Symbols.symbolList; StackValue[] svs = rmem.Heap.ToHeapObject<DSObject>(obj.DsasmValue).Values.ToArray(); int index = 0; for (int ix = 0; ix < svs.Length; ++ix) { if (excludeStatic && symbolList[ix].isStatic) continue; string name = symbolList[ix].name; StackValue val = svs[index]; // check if the members are primitive type if (val.IsPointer) { var pointer = rmem.Heap.ToHeapObject<DSObject>(val); var firstItem = pointer.Count == 1 ? pointer.GetValueFromIndex(0, runtimeCore) : StackValue.Null; if (pointer.Count == 1 && !firstItem.IsPointer && !firstItem.IsArray) { val = firstItem; } } ret[name] = Unpack(val); index++; } return ret; }
public List<string> GetPropertyNames(Obj obj) { if (obj == null || obj.DsasmValue.optype != AddressType.Pointer) return null; List<string> ret = new List<string>(); int classIndex = (int)obj.DsasmValue.metaData.type; StackValue[] svs = core.Heap.Heaplist[(int)obj.DsasmValue.opdata].Stack; for (int ix = 0; ix < svs.Length; ++ix) { string propertyName = core.ClassTable.ClassNodes[classIndex].symbols.symbolList[ix].name; ret.Add(propertyName); } return ret; }
// traverse an array Obj return its member public List<Obj> GetArrayElements(Obj obj) { if ( obj == null || !obj.DsasmValue.IsArray) return null; return MirrorTarget.rmem.Heap.ToHeapObject<DSArray>(obj.DsasmValue).Values.Select(x => Unpack(x)).ToList(); }
// overload version of GetType which takes an Obj instead of string for IDE debuger use // usually the IDE has already get an instance of Obj before they call GetType // there is no need to look up that symbol again public string GetType(Obj obj) { if (obj.DsasmValue.optype == AddressType.Pointer) { return core.ClassTable.ClassNodes[(int)obj.DsasmValue.metaData.type].name; } else { switch (obj.DsasmValue.optype) { case AddressType.ArrayPointer: return "array"; case AddressType.Int: return "int"; case AddressType.Double: return "double"; case AddressType.Null: return "null"; case AddressType.Boolean: return "bool"; case AddressType.String: return "string"; case AddressType.Char: return "char"; case AddressType.FunctionPointer: return "function pointer"; default: return null; } } }
//@TODO(Luke): Add in the methods here that correspond to each of the internal datastructures in use by the executive //@TODO(Jun): if this method stays static, then the Heap needs to be referenced from a parameter /// <summary> /// Do the recursive unpacking of the data structure into mirror objects /// </summary> /// <param name="val"></param> /// <returns></returns> public static Obj Unpack(StackValue val, Heap heap, RuntimeCore runtimeCore, int type = (int)PrimitiveType.Pointer) { Executable exe = runtimeCore.DSExecutable; switch (val.optype) { case AddressType.ArrayPointer: { DsasmArray ret = new DsasmArray(); //Pull the item out of the heap var array = heap.ToHeapObject<DSArray>(val); StackValue[] nodes = array.Values.ToArray(); ret.members = new Obj[array.Count]; for (int i = 0; i < ret.members.Length; i++) { ret.members[i] = Unpack(nodes[i], heap, runtimeCore, type); } // TODO Jun: ret.members[0] is hardcoded and means we are assuming a homogenous collection // How to handle mixed-type arrays? Obj retO = new Obj(val) { Payload = ret, }; return retO; } case AddressType.String: { string str = heap.ToHeapObject<DSString>(val).Value; Obj o = new Obj(val) { Payload = str, }; return o; } case AddressType.Int: { Obj o = new Obj(val) { Payload = val.IntegerValue, }; return o; } case AddressType.Boolean: { Obj o = new Obj(val) { Payload = val.BooleanValue, }; return o; } case AddressType.Null: { Obj o = new Obj(val) { Payload = null, }; return o; } case AddressType.Char: { Obj o = new Obj(val) { Payload = val.CharValue, }; return o; } case AddressType.Double: { Obj o = new Obj(val) { Payload = val.DoubleValue, }; return o; } case AddressType.Pointer: { Obj o = new Obj(val) { Payload = val.Pointer, }; return o; } case AddressType.FunctionPointer: { Obj o = new Obj(val) { Payload = val.FunctionPointer, }; return o; } case AddressType.Invalid: { return new Obj(val) {Payload = null}; } default: { throw new NotImplementedException(string.Format("unknown datatype {0}", val.optype.ToString())); } } }
// this method is used for the IDE to query object values // Copy from the the existing Unpack with some modifications // 1: It is a non-static method so there is no need to pass the core and heap // 2: It does not traverse the array, array traverse is done in method GetArrayElement // 3: The payload for boolean and null is changed to Boolean and null type in .NET, such that the watch windows can directly call ToString() // to print the value, otherwize for boolean it will print either 0 or 1, for null it will print 0 public Obj Unpack(StackValue val) { Obj obj = null; switch (val.optype) { case AddressType.Pointer: obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypePointer, false) }; break; case AddressType.ArrayPointer: obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeArray, true) }; break; case AddressType.Int: obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeInt, false) }; break; case AddressType.Boolean: obj = new Obj(val) { Payload = val.opdata == 0 ? false : true, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeBool, false) }; break; case AddressType.Double: obj = new Obj(val) { Payload = val.opdata_d, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeDouble, false) }; break; case AddressType.Null: obj = new Obj(val) { Payload = null, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeNull, false) }; break; case AddressType.FunctionPointer: obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeFunctionPointer, false) }; break; case AddressType.String: obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeString, true, Constants.kPrimitiveSize) }; break; case AddressType.Char: obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeChar, false) }; break; } return obj; }
public string GetDynamicType() { Validity.Assert(mirrorData != null); ProtoCore.DSASM.Mirror.ExecutionMirror mirror = GetUtils(); Obj obj = new Obj(mirrorData.GetStackValue()); return mirror.GetType(obj); }