/// <summary> /// Get an array's next key /// </summary> /// <param name="key"></param> /// <param name="core"></param> /// <returns></returns> public StackValue GetNextKey(RuntimeCore runtimeCore) { StackValue svArray; int index; if (!TryGetArrayKey(out svArray, out index)) { return(StackValue.Null); } int nextIndex = Constants.kInvalidIndex; if (svArray.IsArray) { DSArray array = runtimeCore.Heap.ToHeapObject <DSArray>(svArray); if (array.Values.Count() > index + 1) { nextIndex = index + 1; } } else if (svArray.IsString) { DSString str = runtimeCore.Heap.ToHeapObject <DSString>(svArray); if (str.Value.Length > index + 1) { nextIndex = index + 1; } } return(nextIndex == Constants.kInvalidIndex ? StackValue.Null : StackValue.BuildArrayKey(svArray, nextIndex)); }
/// <summary> /// Get string that pointer represents. /// </summary> /// <param name="pointer"></param> /// <returns></returns> public string GetString(DSString dsString) { int index = (int)dsString.Pointer.opdata; Validity.Assert(index >= 0 && index < heapElements.Count); string s; if (stringTable.TryGetString(index, out s)) return s; else return null; }
public override bool Equals(object obj) { DSString otherString = obj as DSString; if (otherString == null) { return(false); } if (object.ReferenceEquals(heap, otherString.heap) && Pointer.Equals(otherString.Pointer)) { return(true); } return(Value.Equals(otherString.Value)); }
/// <summary> /// Returns string that pointer represents. /// </summary> /// <param name="pointer"></param> /// <returns></returns> public string GetString(DSString dsString) { int index = dsString.Pointer.StringPointer; Validity.Assert(index >= 0 && index < heapElements.Count); string s; if (stringTable.TryGetString(index, out s)) { return(s); } else { return(null); } }
/// <summary> /// Allocate a string, the string will be put in string table. /// </summary> /// <param name="str"></param> /// <returns></returns> private StackValue AllocateStringInternal(string str, bool isConstant) { int index; if (!stringTable.TryGetPointer(str, out index)) { index = AllocateInternal(new StackValue[] {}, PrimitiveType.kTypeString); stringTable.AddString(index, str); } if (isConstant) fixedHeapElements.Add(index); var svString = StackValue.BuildString(index); DSString dsstring = ToHeapObject<DSString>(svString); dsstring.SetPointer(svString); return svString; }
/// <summary> /// Allocate a string, the string will be put in string table. /// </summary> /// <param name="str"></param> /// <returns></returns> private StackValue AllocateStringInternal(string str, bool isConstant) { int index; if (stringTable.TryGetPointer(str, out index)) { // Any existing heap elements, marked as white, that are in the sweepSet and that are referenced during the sweep cycle will be marked as Black. // This will ensure that no reachable data is mistakenly cleaned up. bool isDuringGCCriticalAsyncCycle = gcState != GCState.Pause;// Between the time the GC takes a snapshot of the stack and heap untill GC cycle is over. bool isValidHeapIndex = index >= 0 && index < heapElements.Count; if (isDuringGCCriticalAsyncCycle && isValidHeapIndex) { var he = heapElements[index]; Validity.Assert(he != null, "Heap element found at index {0} cannot be null", index); // If heap element is marked as white then it is either not processed by Propagate step yet or processed and found as garbage. // If the sweepSet does not contain the heap element's index then there is no need to mark it black (since cleanup will not even be tried) if (he.Mark == GCMark.White && sweepSet.Contains(index)) { // Set the heap element's Mark as Black so that it will not get cleaned up. // No need to do a recursive mark on the it since it is just a string and thus cannot have references to other heap elements. he.Mark = GCMark.Black; } } } else { index = AllocateInternal(new StackValue[] {}, PrimitiveType.String); stringTable.AddString(index, str); } if (isConstant) { fixedHeapElements.Add(index); } var svString = StackValue.BuildString(index); DSString dsstring = ToHeapObject <DSString>(svString); dsstring.SetPointer(svString); return(svString); }
private int AllocateInternal(int size, PrimitiveType type) { switch (type) { case PrimitiveType.kTypeArray: var dsArray = new DSArray(size, this); return(AddHeapElement(dsArray)); case PrimitiveType.kTypePointer: var dsObject = new DSObject(size, this); return(AddHeapElement(dsObject)); case PrimitiveType.kTypeString: var dsString = new DSString(size, this); return(AddHeapElement(dsString)); default: throw new ArgumentException("type"); } }
private int AllocateInternal(StackValue[] values, PrimitiveType type) { HeapElement hpe = null; switch (type) { case PrimitiveType.Array: hpe = new DSArray(values, this); break; case PrimitiveType.Pointer: hpe = new DSObject(values, this); break; case PrimitiveType.String: hpe = new DSString(values, this); break; default: throw new ArgumentException("type"); } return(AddHeapElement(hpe)); }
private int AllocateInternal(int size, PrimitiveType type) { HeapElement hpe = null; switch (type) { case PrimitiveType.kTypeArray: hpe = new DSArray(size, this); break; case PrimitiveType.kTypePointer: hpe = new DSObject(size, this); break; case PrimitiveType.kTypeString: hpe = new DSString(size, this); break; default: throw new ArgumentException("type"); } return AddHeapElement(hpe); }
//this method compares the values of the stack variables passed public static bool CompareStackValues(StackValue sv1, StackValue sv2, RuntimeCore rtCore1, RuntimeCore rtCore2, ProtoCore.Runtime.Context context = null) { if (sv1.optype != sv2.optype) { return(false); } switch (sv1.optype) { case AddressType.Invalid: return(true); case AddressType.Int: return(sv1.IntegerValue == sv2.IntegerValue); case AddressType.Char: return(sv1.CharValue == sv2.CharValue); case AddressType.Double: var value1 = sv1.DoubleValue; var value2 = sv2.DoubleValue; if (Double.IsInfinity(value1) && Double.IsInfinity(value2)) { return(true); } return(MathUtils.Equals(value1, value2)); case AddressType.Boolean: return(sv1.BooleanValue == sv2.BooleanValue); case AddressType.ArrayPointer: if (Object.ReferenceEquals(rtCore1, rtCore2) && sv1.ArrayPointer == sv2.ArrayPointer) //if both cores are same and the stack values point to the same heap element, then the stack values are equal { return(true); } DSArray array1 = rtCore1.Heap.ToHeapObject <DSArray>(sv1); DSArray array2 = rtCore2.Heap.ToHeapObject <DSArray>(sv2); return(DSArray.CompareFromDifferentCore(array1, array2, rtCore1, rtCore2, context)); case AddressType.String: if (Object.ReferenceEquals(rtCore1, rtCore2) && sv1.StringPointer == sv2.StringPointer) //if both cores are same and the stack values point to the same heap element, then the stack values are equal { return(true); } DSString s1 = rtCore1.Heap.ToHeapObject <DSString>(sv1); DSString s2 = rtCore1.Heap.ToHeapObject <DSString>(sv2); return(s1.Equals(s2)); case AddressType.Pointer: if (sv1.metaData.type != sv2.metaData.type) //if the type of class is different, then stack values can never be equal { return(false); } if (Object.ReferenceEquals(rtCore1, rtCore2) && sv1.Pointer == sv2.Pointer) //if both cores are same and the stack values point to the same heap element, then the stack values are equal { return(true); } ClassNode classnode = rtCore1.DSExecutable.classTable.ClassNodes[sv1.metaData.type]; if (classnode.IsImportedClass) { var helper = ProtoFFI.DLLFFIHandler.GetModuleHelper(ProtoFFI.FFILanguage.CSharp); var marshaller1 = helper.GetMarshaler(rtCore1); var marshaller2 = helper.GetMarshaler(rtCore2); try { //the interpreter is passed as null as it is not expected to be sued while unmarshalling in this scenario object dsObject1 = marshaller1.UnMarshal(sv1, context, null, typeof(Object)); object dsObject2 = marshaller2.UnMarshal(sv2, context, null, typeof(Object)); //cores are different in debugger nunit testing only. Most of the imported objects don't have implementation of Object.Equals. It //also does not make sense to compare these objects deeply, as only dummy objects are created in nunit testing, and these dummy objects //might have random values. So we just check whether the object tpye is the same for this testing. if (!object.ReferenceEquals(rtCore1, rtCore2)) { return(Object.ReferenceEquals(dsObject1.GetType(), dsObject2.GetType())); } return(Object.Equals(dsObject1, dsObject2)); } catch (System.Exception) { return(false); } } else { return(ComparePointerFromHeap(sv1, sv2, rtCore1, rtCore2, context)); } default: return(sv1.Equals(sv2)); } }