private object MarshalToScriptInternal()

in ClearScript/Windows/Core/WindowsScriptEngine.cs [294:385]


        private object MarshalToScriptInternal(object obj, HostItemFlags flags, HashSet<Array> marshaledArraySet)
        {
            if (obj == null)
            {
                if (engineFlags.HasFlag(WindowsScriptEngineFlags.MarshalNullAsDispatch))
                {
                    return nullDispatch;
                }

                return DBNull.Value;
            }

            if (obj is Undefined)
            {
                return null;
            }

            if (obj is Nonexistent)
            {
                return null;
            }

            if (obj is Nothing)
            {
                return nullDispatch;
            }

            if (engineFlags.HasFlag(WindowsScriptEngineFlags.MarshalDateTimeAsDate) && (obj is DateTime))
            {
                return obj;
            }

            if (engineFlags.HasFlag(WindowsScriptEngineFlags.MarshalDecimalAsCurrency) && (obj is decimal))
            {
                return new CurrencyWrapper(obj);
            }

            if (obj is HostItem hostItem)
            {
                if ((hostItem.Engine == this) && (hostItem.Flags == flags))
                {
                    return obj;
                }

                obj = hostItem.Target;
            }

            var hostTarget = obj as HostTarget;
            if ((hostTarget != null) && !(hostTarget is IHostVariable))
            {
                obj = hostTarget.Target;
            }

            if (obj is ScriptItem scriptItem)
            {
                if (scriptItem.Engine == this)
                {
                    return scriptItem.Unwrap();
                }
            }

            if (engineFlags.HasFlag(WindowsScriptEngineFlags.MarshalArraysByValue))
            {
                if ((obj is Array array) && ((hostTarget == null) || (typeof(Array).IsAssignableFrom(hostTarget.Type))))
                {
                    bool alreadyMarshaled;
                    if (marshaledArraySet != null)
                    {
                        alreadyMarshaled = marshaledArraySet.Contains(array);
                    }
                    else
                    {
                        marshaledArraySet = new HashSet<Array>();
                        alreadyMarshaled = false;
                    }

                    if (!alreadyMarshaled)
                    {
                        marshaledArraySet.Add(array);
                        var dimensions = Enumerable.Range(0, array.Rank).ToArray();
                        var marshaledArray = Array.CreateInstance(typeof(object), dimensions.Select(array.GetLength).ToArray(), dimensions.Select(array.GetLowerBound).ToArray());
                        array.Iterate(indices => marshaledArray.SetValue(MarshalToScriptInternal(array.GetValue(indices), flags, marshaledArraySet), indices));
                        return marshaledArray;
                    }

                    // COM interop can't handle circularly referenced arrays
                    return MarshalToScriptInternal(null, flags, marshaledArraySet);
                }
            }

            return HostItem.Wrap(this, hostTarget ?? obj, flags);
        }