From 80d321a0f728167376ac3f6a88b5ad0ee1eeda09 Mon Sep 17 00:00:00 2001 From: Craig Long Date: Tue, 7 Jun 2022 13:44:42 -0400 Subject: [PATCH] GraphicDataProvider Fix: Regression for pointer referencing non-clr objects (#12934) * Fix regression for pointer object referencing non-clr objects * Update comments * Add test Co-authored-by: Craig Long --- src/Engine/ProtoCore/ClassTable.cs | 10 ++++++++ .../Reflection/GraphicDataProvider.cs | 23 +++++++++++-------- test/DynamoCoreTests/Nodes/ListTests.cs | 13 +++++++++++ 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/Engine/ProtoCore/ClassTable.cs b/src/Engine/ProtoCore/ClassTable.cs index 5dddb2ec734..dd55446d686 100644 --- a/src/Engine/ProtoCore/ClassTable.cs +++ b/src/Engine/ProtoCore/ClassTable.cs @@ -494,6 +494,16 @@ public void SetClassNodeAt(ClassNode node, int index) symbol.Id = index; } + /// + /// Retreive the ClassNode at the index. + /// + /// + /// ClassNode if found, else null value + internal ClassNode GetClassNodeAtIndex(int index) + { + return index >= 0 && index < classNodes.Count ? classNodes[index] : null; + } + /// /// Find a matching class for given partial class name. /// diff --git a/src/Engine/ProtoCore/Reflection/GraphicDataProvider.cs b/src/Engine/ProtoCore/Reflection/GraphicDataProvider.cs index dce211006b3..80602067e8f 100644 --- a/src/Engine/ProtoCore/Reflection/GraphicDataProvider.cs +++ b/src/Engine/ProtoCore/Reflection/GraphicDataProvider.cs @@ -147,21 +147,24 @@ internal List GetGraphicItems(DSASM.StackValue svData, RuntimeCore internal object GetCLRObject(StackValue svData, RuntimeCore runtimeCore) { - if (marshaler != null) - { - return marshaler.UnMarshal(svData, null, interpreter, typeof(object)); - } - if (null == runtimeCore.DSExecutable.classTable) return null; - IList classNodes = runtimeCore.DSExecutable.classTable.ClassNodes; - if (null == classNodes || (classNodes.Count <= 0)) + //The GetCLRObject function is typically utilized to retrieve a ClrObject from a StackValue of type pointer. + //There is an edge cases for pointers where the pointer references a non CLR object. This code + //checks for this edge case by verifying that the requested StackValue pointer is associated with an + //imported library. An example is the "Function" pointer which does not have an associated CLRObject. + //In that case, the return value should be null. + var classNode = runtimeCore.DSExecutable.classTable.GetClassNodeAtIndex(svData.metaData.type); + if (classNode != null && !classNode.IsImportedClass) + { return null; + } - ClassNode classnode = runtimeCore.DSExecutable.classTable.ClassNodes[svData.metaData.type]; - if (!classnode.IsImportedClass) //TODO: look at properties to see if it contains any FFI objects. - return null; + if (marshaler != null) + { + return marshaler.UnMarshal(svData, null, interpreter, typeof(object)); + } try { diff --git a/test/DynamoCoreTests/Nodes/ListTests.cs b/test/DynamoCoreTests/Nodes/ListTests.cs index b85456dbc32..07e7c389d99 100644 --- a/test/DynamoCoreTests/Nodes/ListTests.cs +++ b/test/DynamoCoreTests/Nodes/ListTests.cs @@ -665,6 +665,19 @@ public void SortBy_SimpleTest() } [Test] + public void SortBy_PreviewValueIsCorrectForFunction() + { + string openPath = Path.Combine(TestDirectory, @"core\list\SortBy_SimpleTest.dyn"); + RunModel(openPath); + + var preview = GetPreviewValueInString("42ac0cec-442f-4e4a-b629-1260f6db3d86"); + Assert.AreEqual("Function()", preview); + + var value = GetPreviewValue("42ac0cec-442f-4e4a-b629-1260f6db3d86"); + Assert.Null(value); + } + + [Test] public void SortByKey_SimpleTest() { string openPath = Path.Combine(TestDirectory, @"core\list\ListSortByKey.dyn");