Skip to content

Commit

Permalink
GraphicDataProvider Fix: Regression for pointer referencing non-clr o…
Browse files Browse the repository at this point in the history
…bjects (#12934)

* Fix regression for pointer object referencing non-clr objects

* Update comments

* Add test

Co-authored-by: Craig Long <[email protected]>
  • Loading branch information
saintentropy and saintentropy authored Jun 7, 2022
1 parent 911ba41 commit 80d321a
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 10 deletions.
10 changes: 10 additions & 0 deletions src/Engine/ProtoCore/ClassTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,16 @@ public void SetClassNodeAt(ClassNode node, int index)
symbol.Id = index;
}

/// <summary>
/// Retreive the ClassNode at the index.
/// </summary>
/// <param name="index"></param>
/// <returns>ClassNode if found, else null value</returns>
internal ClassNode GetClassNodeAtIndex(int index)
{
return index >= 0 && index < classNodes.Count ? classNodes[index] : null;
}

/// <summary>
/// Find a matching class for given partial class name.
/// </summary>
Expand Down
23 changes: 13 additions & 10 deletions src/Engine/ProtoCore/Reflection/GraphicDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,21 +147,24 @@ internal List<IGraphicItem> 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<ClassNode> 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
{
Expand Down
13 changes: 13 additions & 0 deletions test/DynamoCoreTests/Nodes/ListTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit 80d321a

Please sign in to comment.