Skip to content

Commit bc5cd32

Browse files
committed
In JavaScriptEngineSwitcher.ChakraCore prevented an occurrence of the “Host may not have set any promise continuation callback. Promises may not be executed.” error
1 parent 45d1e61 commit bc5cd32

File tree

8 files changed

+136
-4
lines changed

8 files changed

+136
-4
lines changed

NuGet/JavaScriptEngineSwitcher.ChakraCore/JavaScriptEngineSwitcher.ChakraCore.nuspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ This package does not contain the native implementations of ChakraCore. Therefor
2121
* JavaScriptEngineSwitcher.ChakraCore.Native.osx-x64</description>
2222
<summary>JavaScriptEngineSwitcher.ChakraCore contains adapter `ChakraCoreJsEngine` (wrapper for the ChakraCore).</summary>
2323
<releaseNotes>1. ChakraCore was updated to version 1.8.1;
24-
2. JavaScriptEngineSwitcher.ChakraCore.Native.debian-x64 package has been replaced by the JavaScriptEngineSwitcher.ChakraCore.Native.linux-x64 package.</releaseNotes>
24+
2. JavaScriptEngineSwitcher.ChakraCore.Native.debian-x64 package has been replaced by the JavaScriptEngineSwitcher.ChakraCore.Native.linux-x64 package;
25+
3. Prevented an occurrence of the “Host may not have set any promise continuation callback. Promises may not be executed.” error.</releaseNotes>
2526
<copyright>Copyright (c) 2013-2018 Andrey Taritsyn - http://www.taritsyn.ru</copyright>
2627
<language>en-US</language>
2728
<tags>JavaScriptEngineSwitcher JavaScript ECMAScript ChakraCore</tags>

NuGet/JavaScriptEngineSwitcher.ChakraCore/readme.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
=============
3333
1. ChakraCore was updated to version 1.8.1;
3434
2. JavaScriptEngineSwitcher.ChakraCore.Native.debian-x64 package has been
35-
replaced by the JavaScriptEngineSwitcher.ChakraCore.Native.linux-x64 package.
35+
replaced by the JavaScriptEngineSwitcher.ChakraCore.Native.linux-x64 package;
36+
3. Prevented an occurrence of the “Host may not have set any promise
37+
continuation callback. Promises may not be executed.” error.
3638

3739
=============
3840
DOCUMENTATION

src/JavaScriptEngineSwitcher.ChakraCore/ChakraCoreJsEngine.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ public sealed class ChakraCoreJsEngine : JsEngineBase
5757
/// </summary>
5858
private JsObjectFinalizeCallback _externalObjectFinalizeCallback;
5959

60+
/// <summary>
61+
/// Callback for continuation of promise
62+
/// </summary>
63+
private JsPromiseContinuationCallback _promiseContinuationCallback;
64+
6065
/// <summary>
6166
/// List of native function callbacks
6267
/// </summary>
@@ -112,7 +117,7 @@ static ChakraCoreJsEngine()
112117
#endif
113118

114119
/// <summary>
115-
/// Constructs a instance of adapter for the ChakraCore JS engine
120+
/// Constructs an instance of adapter for the ChakraCore JS engine
116121
/// </summary>
117122
public ChakraCoreJsEngine()
118123
: this(new ChakraCoreSettings())
@@ -145,6 +150,7 @@ public ChakraCoreJsEngine(ChakraCoreSettings settings)
145150
}
146151

147152
_externalObjectFinalizeCallback = ExternalObjectFinalizeCallback;
153+
_promiseContinuationCallback = PromiseContinuationCallback;
148154

149155
_dispatcher.Invoke(() =>
150156
{
@@ -222,7 +228,23 @@ private static bool CanHaveReferences(JsValue value)
222228
/// <returns>Instance of JS scope</returns>
223229
private JsScope CreateJsScope()
224230
{
225-
return new JsScope(_jsContext);
231+
var jsScope = new JsScope(_jsContext);
232+
233+
JsRuntime.SetPromiseContinuationCallback(_promiseContinuationCallback, IntPtr.Zero);
234+
235+
return jsScope;
236+
}
237+
238+
/// <summary>
239+
/// The promise continuation callback
240+
/// </summary>
241+
/// <param name="task">The task, represented as a JavaScript function</param>
242+
/// <param name="callbackState">The data argument to be passed to the callback</param>
243+
private static void PromiseContinuationCallback(JsValue task, IntPtr callbackState)
244+
{
245+
task.AddRef();
246+
task.CallFunction(JsValue.GlobalObject);
247+
task.Release();
226248
}
227249

228250
#region Mapping
@@ -1254,6 +1276,7 @@ private void Dispose(bool disposing)
12541276
_nativeFunctions.Clear();
12551277
}
12561278

1279+
_promiseContinuationCallback = null;
12571280
_externalObjectFinalizeCallback = null;
12581281
}
12591282
}

src/JavaScriptEngineSwitcher.ChakraCore/JsRt/JsRuntime.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,24 @@ public static JsRuntime Create(JsRuntimeAttributes attributes, JsThreadServiceCa
131131
return handle;
132132
}
133133

134+
/// <summary>
135+
/// Sets a promise continuation callback function that is called by the context when a task
136+
/// needs to be queued for future execution
137+
/// </summary>
138+
/// <remarks>
139+
/// <para>
140+
/// Requires an active script context.
141+
/// </para>
142+
/// </remarks>
143+
/// <param name="promiseContinuationCallback">The callback function being set</param>
144+
/// <param name="callbackState">User provided state that will be passed back to the callback</param>
145+
public static void SetPromiseContinuationCallback(JsPromiseContinuationCallback promiseContinuationCallback,
146+
IntPtr callbackState)
147+
{
148+
JsErrorHelpers.ThrowIfError(NativeMethods.JsSetPromiseContinuationCallback(promiseContinuationCallback,
149+
callbackState));
150+
}
151+
134152
/// <summary>
135153
/// Performs a full garbage collection
136154
/// </summary>

test/JavaScriptEngineSwitcher.Tests.Net4/JavaScriptEngineSwitcher.Tests.Net40.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@
9999
<Compile Include="..\JavaScriptEngineSwitcher.Tests\ChakraCore\CommonTests.cs">
100100
<Link>ChakraCore\CommonTests.cs</Link>
101101
</Compile>
102+
<Compile Include="..\JavaScriptEngineSwitcher.Tests\ChakraCore\Es2015Tests.cs">
103+
<Link>ChakraCore\Es2015Tests.cs</Link>
104+
</Compile>
102105
<Compile Include="..\JavaScriptEngineSwitcher.Tests\ChakraCore\Es5Tests.cs">
103106
<Link>ChakraCore\Es5Tests.cs</Link>
104107
</Compile>
@@ -108,6 +111,9 @@
108111
<Compile Include="..\JavaScriptEngineSwitcher.Tests\CommonTestsBase.cs">
109112
<Link>CommonTestsBase.cs</Link>
110113
</Compile>
114+
<Compile Include="..\JavaScriptEngineSwitcher.Tests\Es2015TestsBase.cs">
115+
<Link>Es2015TestsBase.cs</Link>
116+
</Compile>
111117
<Compile Include="..\JavaScriptEngineSwitcher.Tests\Es5TestsBase.cs">
112118
<Link>Es5TestsBase.cs</Link>
113119
</Compile>
@@ -198,6 +204,9 @@
198204
<Compile Include="..\JavaScriptEngineSwitcher.Tests\V8\CommonTests.cs">
199205
<Link>V8\CommonTests.cs</Link>
200206
</Compile>
207+
<Compile Include="..\JavaScriptEngineSwitcher.Tests\V8\Es2015Tests.cs">
208+
<Link>V8\Es2015Tests.cs</Link>
209+
</Compile>
201210
<Compile Include="..\JavaScriptEngineSwitcher.Tests\V8\Es5Tests.cs">
202211
<Link>V8\Es5Tests.cs</Link>
203212
</Compile>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace JavaScriptEngineSwitcher.Tests.ChakraCore
2+
{
3+
public class Es2015Tests : Es2015TestsBase
4+
{
5+
protected override string EngineName
6+
{
7+
get { return "ChakraCoreJsEngine"; }
8+
}
9+
}
10+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System;
2+
using System.Text;
3+
4+
using Xunit;
5+
6+
namespace JavaScriptEngineSwitcher.Tests
7+
{
8+
public abstract class Es2015TestsBase : TestsBase
9+
{
10+
#region Promises
11+
12+
[Fact]
13+
public virtual void ExecutionOfPromisesIsCorrect()
14+
{
15+
// Arrange
16+
var stringBuilder = new StringBuilder();
17+
const string input = @"var successfulWork = new Promise(function(resolve, reject) {
18+
resolve(""Success!"");
19+
});
20+
21+
var unsuccessfulWork = new Promise(function (resolve, reject) {
22+
reject(""Fail!"");
23+
});
24+
25+
function resolveCallback(result) {
26+
stringBuilder.AppendLine('Resolved: ' + result);
27+
}
28+
29+
function rejectCallback(reason) {
30+
stringBuilder.AppendLine('Rejected: ' + reason);
31+
}
32+
33+
successfulWork.then(resolveCallback, rejectCallback);
34+
unsuccessfulWork.then(resolveCallback, rejectCallback);";
35+
string targetOutput = "Resolved: Success!" + Environment.NewLine +
36+
"Rejected: Fail!" + Environment.NewLine
37+
;
38+
39+
// Act
40+
string output;
41+
42+
using (var jsEngine = CreateJsEngine())
43+
{
44+
jsEngine.EmbedHostObject("stringBuilder", stringBuilder);
45+
jsEngine.Execute(input);
46+
47+
output = stringBuilder.ToString();
48+
stringBuilder.Clear();
49+
}
50+
51+
// Assert
52+
Assert.Equal(targetOutput, output);
53+
}
54+
55+
#endregion
56+
}
57+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#if !NETCOREAPP1_0
2+
namespace JavaScriptEngineSwitcher.Tests.V8
3+
{
4+
public class Es2015Tests : Es2015TestsBase
5+
{
6+
protected override string EngineName
7+
{
8+
get { return "V8JsEngine"; }
9+
}
10+
}
11+
}
12+
#endif

0 commit comments

Comments
 (0)