in ClearScript/V8/V8ScriptEngine.cs [1369:1486]
internal override object MarshalToScript(object obj, HostItemFlags flags)
{
const long maxIntInDouble = (1L << 53) - 1;
if (obj == null)
{
return DBNull.Value;
}
if (obj is Undefined)
{
return null;
}
if (obj is Nonexistent)
{
return obj;
}
if (obj is INothingTag)
{
return null;
}
if (obj is BigInteger)
{
return obj;
}
if (obj is long longValue)
{
if (engineFlags.HasFlag(V8ScriptEngineFlags.MarshalAllLongAsBigInt))
{
return new BigInteger(longValue);
}
if (engineFlags.HasFlag(V8ScriptEngineFlags.MarshalUnsafeLongAsBigInt) && (Math.Abs(longValue) > maxIntInDouble))
{
return new BigInteger(longValue);
}
}
if (obj is ulong ulongValue)
{
if (engineFlags.HasFlag(V8ScriptEngineFlags.MarshalAllLongAsBigInt))
{
return new BigInteger(ulongValue);
}
if (engineFlags.HasFlag(V8ScriptEngineFlags.MarshalUnsafeLongAsBigInt) && (ulongValue > maxIntInDouble))
{
return new BigInteger(ulongValue);
}
}
if (engineFlags.HasFlag(V8ScriptEngineFlags.EnableDateTimeConversion) && (obj is DateTime))
{
return obj;
}
if (engineFlags.HasFlag(V8ScriptEngineFlags.EnableTaskPromiseConversion))
{
// .NET Core async functions return Task subclass instances that trigger result wrapping
var testObject = obj;
if (testObject is HostObject testHostObject)
{
testObject = testHostObject.Target;
}
if (testObject != null)
{
if (testObject.GetType().IsAssignableToGenericType(typeof(Task<>), out var typeArgs))
{
obj = typeof(TaskConverter<>).MakeSpecificType(typeArgs).InvokeMember("ToPromise", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new[] { testObject, this });
}
else if (testObject is Task task)
{
obj = task.ToPromise(this);
}
else if (engineFlags.HasFlag(V8ScriptEngineFlags.EnableValueTaskPromiseConversion))
{
TryConvertValueTaskToPromise(testObject, result => obj = result);
}
}
}
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 is V8ScriptEngine that) && (that.runtime == runtime))
{
return scriptItem.Unwrap();
}
if ((scriptItem is V8ScriptItem v8ScriptItem) && v8ScriptItem.IsShared)
{
return scriptItem.Unwrap();
}
}
return HostItem.Wrap(this, hostTarget ?? obj, flags);
}