ClearScript 7.0 RC2: Fixed task-promise conversion issues (GitHub Issue #198).
This commit is contained in:
Родитель
d4ac519b4c
Коммит
03038deb57
|
@ -7,5 +7,5 @@
|
|||
|
||||
#define CLEARSCRIPT_VERSION_STRING "7.0.0"
|
||||
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 7,0,0
|
||||
#define CLEARSCRIPT_VERSION_STRING_INFORMATIONAL "7.0.0-rc"
|
||||
#define CLEARSCRIPT_VERSION_STRING_INFORMATIONAL "7.0.0-rc2"
|
||||
#define CLEARSCRIPT_FILE_FLAGS VS_FF_PRERELEASE
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
namespace Microsoft.ClearScript.JavaScript
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.ClearScript.JavaScript
|
||||
{
|
||||
internal interface IJavaScriptEngine
|
||||
{
|
||||
uint BaseLanguageVersion { get; }
|
||||
|
||||
void CompletePromiseWithResult<T>(Task<T> task, object resolve, object reject);
|
||||
void CompletePromise(Task task, object resolve, object reject);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace Microsoft.ClearScript.JavaScript
|
|||
|
||||
return engine.Script.EngineInternal.createPromise(new Executor((resolve, reject) =>
|
||||
{
|
||||
Action<Task> continuation = thisTask => engine.Script.EngineInternal.onTaskWithResultCompleted(thisTask, resolve, reject);
|
||||
Action<Task<TResult>> continuation = thisTask => javaScriptEngine.CompletePromiseWithResult(thisTask, resolve, reject);
|
||||
task.ContinueWith(continuation, TaskContinuationOptions.ExecuteSynchronously);
|
||||
}));
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ namespace Microsoft.ClearScript.JavaScript
|
|||
|
||||
return engine.Script.EngineInternal.createPromise(new Executor((resolve, reject) =>
|
||||
{
|
||||
Action<Task> continuation = thisTask => engine.Script.EngineInternal.onTaskCompleted(thisTask, resolve, reject);
|
||||
Action<Task> continuation = thisTask => javaScriptEngine.CompletePromise(thisTask, resolve, reject);
|
||||
task.ContinueWith(continuation, TaskContinuationOptions.ExecuteSynchronously);
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -17,13 +17,13 @@ using System.Runtime.InteropServices;
|
|||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("7.0.0")]
|
||||
[assembly: AssemblyFileVersion("7.0.0")]
|
||||
[assembly: AssemblyInformationalVersion("7.0.0-rc")]
|
||||
[assembly: AssemblyInformationalVersion("7.0.0-rc2")]
|
||||
|
||||
namespace Microsoft.ClearScript.Properties
|
||||
{
|
||||
internal static class ClearScriptVersion
|
||||
{
|
||||
public const string Triad = "7.0.0";
|
||||
public const string Informational = "7.0.0-rc";
|
||||
public const string Informational = "7.0.0-rc2";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -288,7 +288,7 @@ namespace Microsoft.ClearScript.V8
|
|||
return value instanceof savedPromise;
|
||||
},
|
||||
|
||||
onTaskWithResultCompleted: function (task, resolve, reject) {
|
||||
completePromiseWithResult: function (task, resolve, reject) {
|
||||
try {
|
||||
resolve(task.Result);
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ namespace Microsoft.ClearScript.V8
|
|||
}
|
||||
},
|
||||
|
||||
onTaskCompleted: function (task, resolve, reject) {
|
||||
completePromise: function (task, resolve, reject) {
|
||||
try {
|
||||
task.Wait();
|
||||
resolve();
|
||||
|
@ -1291,18 +1291,29 @@ namespace Microsoft.ClearScript.V8
|
|||
|
||||
if (engineFlags.HasFlag(V8ScriptEngineFlags.EnableTaskPromiseConversion) && !bypassTaskPromiseConversion)
|
||||
{
|
||||
if (obj.GetType().IsAssignableToGenericType(typeof(Task<>), out var typeArgs))
|
||||
// .NET Core async functions return Task subclass instances that trigger result wrapping
|
||||
|
||||
var testObject = obj;
|
||||
if (testObject is HostObject testHostObject)
|
||||
{
|
||||
using (Scope.Create(() => bypassTaskPromiseConversion = true, () => bypassTaskPromiseConversion = false))
|
||||
{
|
||||
obj = typeof(TaskConverter<>).MakeSpecificType(typeArgs).InvokeMember("ToPromise", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new[] { obj, this });
|
||||
}
|
||||
testObject = testHostObject.Target;
|
||||
}
|
||||
else if (obj is Task task)
|
||||
|
||||
if (testObject != null)
|
||||
{
|
||||
using (Scope.Create(() => bypassTaskPromiseConversion = true, () => bypassTaskPromiseConversion = false))
|
||||
if (testObject.GetType().IsAssignableToGenericType(typeof(Task<>), out var typeArgs))
|
||||
{
|
||||
obj = task.ToPromise(this);
|
||||
using (Scope.Create(() => MiscHelpers.Exchange(ref bypassTaskPromiseConversion, true), oldValue => bypassTaskPromiseConversion = oldValue))
|
||||
{
|
||||
obj = typeof(TaskConverter<>).MakeSpecificType(typeArgs).InvokeMember("ToPromise", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new[] {testObject, this});
|
||||
}
|
||||
}
|
||||
else if (testObject is Task task)
|
||||
{
|
||||
using (Scope.Create(() => MiscHelpers.Exchange(ref bypassTaskPromiseConversion, true), oldValue => bypassTaskPromiseConversion = oldValue))
|
||||
{
|
||||
obj = task.ToPromise(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1369,7 +1380,7 @@ namespace Microsoft.ClearScript.V8
|
|||
var scriptItem = V8ScriptItem.Wrap(this, obj);
|
||||
if (engineFlags.HasFlag(V8ScriptEngineFlags.EnableTaskPromiseConversion) && !bypassTaskPromiseConversion && (obj is IV8Object v8Object) && v8Object.IsPromise())
|
||||
{
|
||||
using (Scope.Create(() => bypassTaskPromiseConversion = true, () => bypassTaskPromiseConversion = false))
|
||||
using (Scope.Create(() => MiscHelpers.Exchange(ref bypassTaskPromiseConversion, true), oldValue => bypassTaskPromiseConversion = oldValue))
|
||||
{
|
||||
return scriptItem.ToTask();
|
||||
}
|
||||
|
@ -1494,6 +1505,22 @@ namespace Microsoft.ClearScript.V8
|
|||
|
||||
uint IJavaScriptEngine.BaseLanguageVersion => 8;
|
||||
|
||||
void IJavaScriptEngine.CompletePromiseWithResult<T>(Task<T> task, object resolve, object reject)
|
||||
{
|
||||
using (Scope.Create(() => MiscHelpers.Exchange(ref bypassTaskPromiseConversion, true), oldValue => bypassTaskPromiseConversion = oldValue))
|
||||
{
|
||||
Script.EngineInternal.completePromiseWithResult(task, resolve, reject);
|
||||
}
|
||||
}
|
||||
|
||||
void IJavaScriptEngine.CompletePromise(Task task, object resolve, object reject)
|
||||
{
|
||||
using (Scope.Create(() => MiscHelpers.Exchange(ref bypassTaskPromiseConversion, true), oldValue => bypassTaskPromiseConversion = oldValue))
|
||||
{
|
||||
Script.EngineInternal.completePromise(task, resolve, reject);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region unit test support
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.ClearScript.JavaScript;
|
||||
|
||||
namespace Microsoft.ClearScript.Windows
|
||||
|
@ -88,6 +90,16 @@ namespace Microsoft.ClearScript.Windows
|
|||
|
||||
uint IJavaScriptEngine.BaseLanguageVersion => 3;
|
||||
|
||||
void IJavaScriptEngine.CompletePromiseWithResult<T>(Task<T> task, object resolve, object reject)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IJavaScriptEngine.CompletePromise(Task task, object resolve, object reject)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.ClearScript.JavaScript;
|
||||
using Microsoft.ClearScript.Util;
|
||||
|
||||
|
@ -298,6 +299,16 @@ namespace Microsoft.ClearScript.Windows
|
|||
|
||||
uint IJavaScriptEngine.BaseLanguageVersion => 3;
|
||||
|
||||
void IJavaScriptEngine.CompletePromiseWithResult<T>(Task<T> task, object resolve, object reject)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IJavaScriptEngine.CompletePromise(Task task, object resolve, object reject)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,4 +13,4 @@ using System.Runtime.InteropServices;
|
|||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("7.0.0")]
|
||||
[assembly: AssemblyFileVersion("7.0.0")]
|
||||
[assembly: AssemblyInformationalVersion("7.0.0-rc")]
|
||||
[assembly: AssemblyInformationalVersion("7.0.0-rc2")]
|
||||
|
|
|
@ -13,4 +13,4 @@ using System.Runtime.InteropServices;
|
|||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("7.0.0")]
|
||||
[assembly: AssemblyFileVersion("7.0.0")]
|
||||
[assembly: AssemblyInformationalVersion("7.0.0-rc")]
|
||||
[assembly: AssemblyInformationalVersion("7.0.0-rc2")]
|
||||
|
|
|
@ -13,6 +13,7 @@ using System.Linq.Expressions;
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.ClearScript.V8;
|
||||
using Microsoft.ClearScript.Util;
|
||||
|
@ -1383,6 +1384,21 @@ namespace Microsoft.ClearScript.Test
|
|||
testObject.FireEvent(456);
|
||||
}
|
||||
|
||||
[TestMethod, TestCategory("BugFix")]
|
||||
public void BugFix_V8ScriptEngine_TaskPromiseConversion()
|
||||
{
|
||||
engine.Dispose();
|
||||
engine = new V8ScriptEngine(V8ScriptEngineFlags.EnableDebugging | V8ScriptEngineFlags.EnableTaskPromiseConversion);
|
||||
|
||||
engine.AddHostType(typeof(TaskPromiseConversionTest));
|
||||
engine.Execute("value = TaskPromiseConversionTest.GetStringAsync();");
|
||||
Assert.AreEqual("Promise", engine.Evaluate("value.constructor.name"));
|
||||
Task.Delay(200).Wait();
|
||||
|
||||
engine.Execute("value.then(value => result = value);");
|
||||
Assert.AreEqual("foo", engine.Script.result);
|
||||
}
|
||||
|
||||
// ReSharper restore InconsistentNaming
|
||||
|
||||
#endregion
|
||||
|
@ -1688,6 +1704,15 @@ namespace Microsoft.ClearScript.Test
|
|||
public bool IsValid { get; set; }
|
||||
}
|
||||
|
||||
public class TaskPromiseConversionTest
|
||||
{
|
||||
public static async Task<string> GetStringAsync()
|
||||
{
|
||||
await Task.Delay(100);
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,4 +13,4 @@ using System.Runtime.InteropServices;
|
|||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("7.0.0")]
|
||||
[assembly: AssemblyFileVersion("7.0.0")]
|
||||
[assembly: AssemblyInformationalVersion("7.0.0-rc")]
|
||||
[assembly: AssemblyInformationalVersion("7.0.0-rc2")]
|
||||
|
|
|
@ -173,10 +173,10 @@
|
|||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8ScriptImpl.cs" Link="V8\SplitProxy\V8ScriptImpl.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyHelpers.cs" Link="V8\SplitProxy\V8SplitProxyHelpers.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyManaged.cs" Link="V8\SplitProxy\V8SplitProxyManaged.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyNative.cs" Link="V8\SplitProxy\SplitProxyNative.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyNative.cs" Link="V8\SplitProxy\V8SplitProxyNative.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyNative.Windows.32.cs" Link="V8\SplitProxy\V8SplitProxyNative.Windows.32.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyNative.Windows.64.cs" Link="V8\SplitProxy\V8SplitProxyNative.Windows.64.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyNative.Windows.cs" Link="V8\SplitProxy\SplitProxyNative.Windows.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyNative.Windows.cs" Link="V8\SplitProxy\V8SplitProxyNative.Windows.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8ContextProxyImpl.cs" Link="V8\SplitProxy\V8ContextProxyImpl.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8IsolateProxyImpl.cs" Link="V8\SplitProxy\V8IsolateProxyImpl.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8ObjectImpl.cs" Link="V8\SplitProxy\V8ObjectImpl.cs" />
|
||||
|
@ -224,6 +224,7 @@
|
|||
<Folder Include="Util\COM\" />
|
||||
<Folder Include="Util\Test\" />
|
||||
<Folder Include="Util\Web\" />
|
||||
<Folder Include="V8\SplitProxy\" />
|
||||
<Folder Include="Windows\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -167,8 +167,8 @@
|
|||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8ScriptImpl.cs" Link="V8\SplitProxy\V8ScriptImpl.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyHelpers.cs" Link="V8\SplitProxy\V8SplitProxyHelpers.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyManaged.cs" Link="V8\SplitProxy\V8SplitProxyManaged.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyNative.cs" Link="V8\SplitProxy\SplitProxyNative.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyNative.Unix.cs" Link="V8\SplitProxy\SplitProxyNative.Unix.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyNative.cs" Link="V8\SplitProxy\V8SplitProxyNative.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8SplitProxyNative.Unix.cs" Link="V8\SplitProxy\V8SplitProxyNative.Unix.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8ContextProxyImpl.cs" Link="V8\SplitProxy\V8ContextProxyImpl.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8IsolateProxyImpl.cs" Link="V8\SplitProxy\V8IsolateProxyImpl.cs" />
|
||||
<Compile Include="..\..\ClearScript\V8\SplitProxy\V8ObjectImpl.cs" Link="V8\SplitProxy\V8ObjectImpl.cs" />
|
||||
|
@ -211,6 +211,7 @@
|
|||
<Folder Include="Util\COM\" />
|
||||
<Folder Include="Util\Test\" />
|
||||
<Folder Include="Util\Web\" />
|
||||
<Folder Include="V8\SplitProxy\" />
|
||||
<Folder Include="Windows\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<#
|
||||
var version = new Version(7, 0, 0);
|
||||
var versionSuffix = "-rc";
|
||||
var versionSuffix = "-rc2";
|
||||
new Random(versionSuffix.Length); // suppress "versionSuffix not used" warning
|
||||
#>
|
||||
|
|
Загрузка…
Ссылка в новой задаче