/// <summary> Based on original callstack initializes a new callstack with decoded script callstack and script object type. </summary> public FCallStack(FCallStack InOriginal, FScriptCallStack InScriptCallStack, FScriptObjectType InScriptObjectType, int InCallStackIndex) : this() { Debug.Assert(InOriginal != null); Debug.Assert(ScriptCallStack == null || ScriptCallStack.Frames.Length > 0); Original = InOriginal; ScriptCallStack = InScriptCallStack; ScriptObjectType = InScriptObjectType; Original.Children.Add(this); Original.ChildIndices.Add(InCallStackIndex); CRC = Original.CRC; AddressIndices = new List <int>(Original.AddressIndices); FirstNonContainer = AddressIndices.Count - 1; bIsTruncated = Original.bIsTruncated; // If there is a script call stack, rename functions if (ScriptCallStack != null) { int ScriptFrameIndex = 0; for (int AddressIndex = AddressIndices.Count - 1; AddressIndex >= 0; AddressIndex--) { int FunctionNameIndex = FStreamInfo.GlobalInstance.CallStackAddressArray[AddressIndices[AddressIndex]].FunctionIndex; if (FunctionNameIndex == FStreamInfo.GlobalInstance.ProcessInternalNameIndex) { AddressIndices[AddressIndex] = ScriptCallStack.Frames[ScriptFrameIndex].CallStackAddressIndex; ScriptFrameIndex++; if (ScriptFrameIndex >= ScriptCallStack.Frames.Length) { break; } } } } // If the call stack has a script type allocation, replace the StaticAllocateObject call with the appropriate type-tagged one if (ScriptObjectType != null) { for (int AddressIndex = AddressIndices.Count - 1; AddressIndex >= 0; AddressIndex--) { int FunctionNameIndex = FStreamInfo.GlobalInstance.CallStackAddressArray[AddressIndices[AddressIndex]].FunctionIndex; if (FunctionNameIndex == FStreamInfo.GlobalInstance.StaticAllocateObjectNameIndex) { AddressIndices[AddressIndex] = ScriptObjectType.CallStackAddressIndex; break; } } } }
private static int GetVirtualCallStackIndex(FStreamToken StreamToken, StreamObserver Observer) { if (StreamToken.ScriptCallstackIndex == -1 && StreamToken.ScriptObjectTypeIndex == -1) { return(StreamToken.CallStackIndex); } FCallStack OriginalCallStack = FStreamInfo.GlobalInstance.CallStackArray[StreamToken.CallStackIndex]; FScriptCallStack ScriptCallStack = StreamToken.ScriptCallstackIndex == -1 ? null : FStreamInfo.GlobalInstance.ScriptCallstackArray[StreamToken.ScriptCallstackIndex]; // Get the script-object type for this index (if it's not cached, create a ScriptObjectType instance and cache it). FScriptObjectType ScriptObjectType = null; if (StreamToken.ScriptObjectTypeIndex != -1) { if (!FStreamInfo.GlobalInstance.ScriptObjectTypeMapping.TryGetValue(StreamToken.ScriptObjectTypeIndex, out ScriptObjectType)) { ScriptObjectType = new FScriptObjectType(FStreamInfo.GlobalInstance.ScriptNameArray[StreamToken.ScriptObjectTypeIndex]); FStreamInfo.GlobalInstance.ScriptObjectTypeMapping.Add(StreamToken.ScriptObjectTypeIndex, ScriptObjectType); } } for (int ChildIndex = 0; ChildIndex < OriginalCallStack.Children.Count; ChildIndex++) { if ((OriginalCallStack.Children[ChildIndex].ScriptCallStack == ScriptCallStack) && (OriginalCallStack.Children[ChildIndex].ScriptObjectType == ScriptObjectType)) { return(OriginalCallStack.ChildIndices[ChildIndex]); } } FCallStack NewCallStack = new FCallStack(OriginalCallStack, ScriptCallStack, ScriptObjectType, FStreamInfo.GlobalInstance.CallStackArray.Count); FStreamInfo.GlobalInstance.CallStackArray.Add(NewCallStack); return(FStreamInfo.GlobalInstance.CallStackArray.Count - 1); }
/// <summary> Based on original callstack initializes a new callstack with decoded script callstack and script object type. </summary> public FCallStack(FCallStack InOriginal, FScriptCallStack InScriptCallStack, FScriptObjectType InScriptObjectType, int InCallStackIndex) : this() { Debug.Assert(InOriginal != null); Debug.Assert(ScriptCallStack == null || ScriptCallStack.Frames.Length > 0); Original = InOriginal; ScriptCallStack = InScriptCallStack; ScriptObjectType = InScriptObjectType; Original.Children.Add(this); Original.ChildIndices.Add(InCallStackIndex); CRC = Original.CRC; AddressIndices = new List<int>(Original.AddressIndices); FirstNonContainer = AddressIndices.Count - 1; bIsTruncated = Original.bIsTruncated; // If there is a script call stack, rename functions if (ScriptCallStack != null) { int ScriptFrameIndex = 0; for (int AddressIndex = AddressIndices.Count - 1; AddressIndex >= 0; AddressIndex--) { int FunctionNameIndex = FStreamInfo.GlobalInstance.CallStackAddressArray[AddressIndices[AddressIndex]].FunctionIndex; if (FunctionNameIndex == FStreamInfo.GlobalInstance.ProcessInternalNameIndex) { AddressIndices[AddressIndex] = ScriptCallStack.Frames[ScriptFrameIndex].CallStackAddressIndex; ScriptFrameIndex++; if (ScriptFrameIndex >= ScriptCallStack.Frames.Length) { break; } } } } // If the call stack has a script type allocation, replace the StaticAllocateObject call with the appropriate type-tagged one if (ScriptObjectType != null) { for (int AddressIndex = AddressIndices.Count - 1; AddressIndex >= 0; AddressIndex--) { int FunctionNameIndex = FStreamInfo.GlobalInstance.CallStackAddressArray[AddressIndices[AddressIndex]].FunctionIndex; if (FunctionNameIndex == FStreamInfo.GlobalInstance.StaticAllocateObjectNameIndex) { AddressIndices[AddressIndex] = ScriptObjectType.CallStackAddressIndex; break; } } } }
private static int GetVirtualCallStackIndex( FStreamToken StreamToken, StreamObserver Observer ) { if( StreamToken.ScriptCallstackIndex == -1 && StreamToken.ScriptObjectTypeIndex == -1 ) { return StreamToken.CallStackIndex; } FCallStack OriginalCallStack = FStreamInfo.GlobalInstance.CallStackArray[ StreamToken.CallStackIndex ]; FScriptCallStack ScriptCallStack = StreamToken.ScriptCallstackIndex == -1 ? null : FStreamInfo.GlobalInstance.ScriptCallstackArray[ StreamToken.ScriptCallstackIndex ]; // Get the script-object type for this index (if it's not cached, create a ScriptObjectType instance and cache it). FScriptObjectType ScriptObjectType = null; if( StreamToken.ScriptObjectTypeIndex != -1 ) { if( !FStreamInfo.GlobalInstance.ScriptObjectTypeMapping.TryGetValue( StreamToken.ScriptObjectTypeIndex, out ScriptObjectType ) ) { ScriptObjectType = new FScriptObjectType( FStreamInfo.GlobalInstance.ScriptNameArray[ StreamToken.ScriptObjectTypeIndex ] ); FStreamInfo.GlobalInstance.ScriptObjectTypeMapping.Add( StreamToken.ScriptObjectTypeIndex, ScriptObjectType ); } } for( int ChildIndex = 0; ChildIndex < OriginalCallStack.Children.Count; ChildIndex++ ) { if( ( OriginalCallStack.Children[ ChildIndex ].ScriptCallStack == ScriptCallStack ) && ( OriginalCallStack.Children[ ChildIndex ].ScriptObjectType == ScriptObjectType ) ) { return OriginalCallStack.ChildIndices[ ChildIndex ]; } } FCallStack NewCallStack = new FCallStack( OriginalCallStack, ScriptCallStack, ScriptObjectType, FStreamInfo.GlobalInstance.CallStackArray.Count ); FStreamInfo.GlobalInstance.CallStackArray.Add( NewCallStack ); return FStreamInfo.GlobalInstance.CallStackArray.Count - 1; }