/// <summary> /// Performs addition on 2 StackValues /// This is used by the VM when adding strings /// </summary> /// <param name="sv1"></param> /// <param name="sv2"></param> /// <returns></returns> public static StackValue AddStackValueString(StackValue sv1, StackValue sv2, RuntimeCore runtimeCore) { Validity.Assert(sv1.IsString || sv2.IsString); if (sv1.IsString && sv2.IsString) { return(StringUtils.ConcatString(sv2, sv1, runtimeCore)); } else if (sv1.IsString || sv2.IsString) { StackValue newSV; if (sv1.IsNull || sv2.IsNull) { return(StackValue.BuildNull()); } else if (sv1.IsString) { newSV = StringUtils.ConvertToString(sv2, runtimeCore, runtimeCore.RuntimeMemory); return(StringUtils.ConcatString(newSV, sv1, runtimeCore)); } else if (sv2.IsString) { newSV = StringUtils.ConvertToString(sv1, runtimeCore, runtimeCore.RuntimeMemory); return(StringUtils.ConcatString(sv2, newSV, runtimeCore)); } } return(StackValue.BuildNull()); }
public void TestGCStringCleanup() { // Simulating the following graph /* * def generateString() { * return 1+"@" +2; * }; * * vv = [Imperative]{ * generateString(); * // "1@2" will be on the heap * // current stack has no reference type elements * // --------------------------------GC kicks in due to mem threshold---------------------------- * // "1@2" on the heap will be marked as white - since no stack elements have a reference to it * // * // Async VM execution computes a new generateString() fn Call * cc = generateString(); * // * // cc is pushed on the stack and holds a reference to the "1@2" heap element * // * // GC starts the sweep process in which it deletes "1@2" heap element * // ----------------------------------GC is finished--------------------------------------------- * return cc; * }; * // * // vv is still on the stack with a reference to a now null heap element */ var heap = new Heap(); string sseValue = "hello world"; // Allocate a string on the heap. // Similar to what would happen if a string stack element was pushed on the stack and then popped (due to out of scope). heap.AllocateString(sseValue); StackValue someStackValue = StackValue.BuildNull(); var notifications = new Dictionary <Heap.GCState, (Action, Action)>() { { Heap.GCState.Sweep, (() => { // Simulate a new string (with the same value as existing one on heap) stack element being created while GC is propagating or sweeping someStackValue = heap.AllocateString(sseValue); }, () => { }) } }; // Start GC with a random stack value as gcRoot (not the string stack element, because it was pushed out of the stack) heap.FullGCTest(new List <StackValue>() { StackValue.BuildInt(1) }, testExecutive, notifications); // The stack element that was pushed after GC start should be valid. Assert.IsNotNull(heap.ToHeapObject <DSString>(someStackValue)); }
public static StackValue BuildStackValueForPrimitive(AssociativeNode node) { Validity.Assert(IsPrimitiveASTNode(node) == true); if (node is IntNode) { return(StackValue.BuildInt((node as IntNode).Value)); } else if (node is DoubleNode) { return(StackValue.BuildDouble((node as DoubleNode).Value)); } else if (node is BooleanNode) { return(StackValue.BuildBoolean((node as BooleanNode).Value)); } return(StackValue.BuildNull()); }