Skip to content

Commit 0d3274a

Browse files
committed
In JavaScriptEngineSwitcher.ChakraCore fixed a error “Out of stack space”
1 parent 096931c commit 0d3274a

File tree

6 files changed

+390
-73
lines changed

6 files changed

+390
-73
lines changed

NuGet/JavaScriptEngineSwitcher.ChakraCore/JavaScriptEngineSwitcher.ChakraCore.nuspec

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ This package does not contain the native implementations of ChakraCore. Therefor
2020
* JavaScriptEngineSwitcher.ChakraCore.Native.debian-x64
2121
* JavaScriptEngineSwitcher.ChakraCore.Native.osx-x64</description>
2222
<summary>JavaScriptEngineSwitcher.ChakraCore contains adapter `ChakraCoreJsEngine` (wrapper for the ChakraCore).</summary>
23-
<releaseNotes>Attempt to prevent occurrence of the access violation exception in the `CallFunction` method.</releaseNotes>
23+
<releaseNotes>1. Attempt to prevent occurrence of the access violation exception in the `CallFunction` method;
24+
2. Fixed a error “Out of stack space”.</releaseNotes>
2425
<copyright>Copyright (c) 2013-2016 Andrey Taritsyn - http://www.taritsyn.ru</copyright>
2526
<language>en-US</language>
2627
<tags>JavaScriptEngineSwitcher JavaScript ECMAScript ChakraCore</tags>
@@ -35,6 +36,7 @@ This package does not contain the native implementations of ChakraCore. Therefor
3536
<dependency id="System.Diagnostics.Tools" version="4.0.1" />
3637
<dependency id="System.Reflection.Extensions" version="4.0.1" />
3738
<dependency id="System.Reflection.TypeExtensions" version="4.1.0" />
39+
<dependency id="System.Threading.Thread" version="4.0.0" />
3840
<dependency id="Microsoft.Extensions.PlatformAbstractions" version="1.0.0" />
3941
<dependency id="JavaScriptEngineSwitcher.Core" version="2.1.2" />
4042
</group>

NuGet/JavaScriptEngineSwitcher.ChakraCore/readme.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@
3030
=============
3131
RELEASE NOTES
3232
=============
33-
Attempt to prevent occurrence of the access violation exception in the
34-
`CallFunction` method.
33+
1. Attempt to prevent occurrence of the access violation exception in the
34+
`CallFunction` method;
35+
2. Fixed a error “Out of stack space”.
3536

3637
=============
3738
DOCUMENTATION

src/JavaScriptEngineSwitcher.ChakraCore.Net4/JavaScriptEngineSwitcher.ChakraCore.Net40.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@
187187
<Compile Include="..\JavaScriptEngineSwitcher.ChakraCore\Resources\Strings.ru-ru.Designer.cs">
188188
<Link>Resources\Strings.ru-ru.Designer.cs</Link>
189189
</Compile>
190+
<Compile Include="..\JavaScriptEngineSwitcher.ChakraCore\ScriptDispatcher.cs">
191+
<Link>ScriptDispatcher.cs</Link>
192+
</Compile>
190193
</ItemGroup>
191194
<ItemGroup>
192195
<EmbeddedResource Include="..\JavaScriptEngineSwitcher.ChakraCore\Resources\Strings.resx">

src/JavaScriptEngineSwitcher.ChakraCore/ChakraCoreJsEngine.cs

Lines changed: 76 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,10 @@ public sealed class ChakraCoreJsEngine : JsEngineBase
4040
/// <summary>
4141
/// Instance of JS context
4242
/// </summary>
43-
private readonly JsContext _jsContext;
43+
private JsContext _jsContext;
4444

4545
/// <summary>
46-
/// Synchronizer of code execution
47-
/// </summary>
48-
private readonly object _executionSynchronizer = new object();
49-
50-
/// <summary>
51-
/// List of external objects
46+
/// Set of external objects
5247
/// </summary>
5348
private readonly HashSet<object> _externalObjects = new HashSet<object>();
5449

@@ -62,6 +57,11 @@ public sealed class ChakraCoreJsEngine : JsEngineBase
6257
/// </summary>
6358
private readonly HashSet<JsNativeFunction> _nativeFunctions = new HashSet<JsNativeFunction>();
6459

60+
/// <summary>
61+
/// Script dispatcher
62+
/// </summary>
63+
private readonly ScriptDispatcher _dispatcher = new ScriptDispatcher();
64+
6565
/// <summary>
6666
/// Gets a name of JS engine
6767
/// </summary>
@@ -108,7 +108,7 @@ public ChakraCoreJsEngine()
108108
{ }
109109

110110
/// <summary>
111-
/// Constructs a instance of adapter for the ChakraCore JS engine
111+
/// Constructs an instance of adapter for the ChakraCore JS engine
112112
/// </summary>
113113
/// <param name="settings">Settings of the ChakraCore JS engine</param>
114114
public ChakraCoreJsEngine(ChakraCoreSettings settings)
@@ -135,21 +135,24 @@ public ChakraCoreJsEngine(ChakraCoreSettings settings)
135135

136136
_externalObjectFinalizeCallback = ExternalObjectFinalizeCallback;
137137

138-
try
139-
{
140-
_jsRuntime = JsRuntime.Create(attributes, null);
141-
_jsContext = _jsRuntime.CreateContext();
142-
}
143-
catch (Exception e)
138+
_dispatcher.Invoke(() =>
144139
{
145-
throw new JsEngineLoadException(
146-
string.Format(CoreStrings.Runtime_JsEngineNotLoaded,
147-
EngineName, e.Message), EngineName, EngineVersion, e);
148-
}
140+
try
141+
{
142+
_jsRuntime = JsRuntime.Create(attributes, null);
143+
_jsContext = _jsRuntime.CreateContext();
144+
}
145+
catch (Exception e)
146+
{
147+
throw new JsEngineLoadException(
148+
string.Format(CoreStrings.Runtime_JsEngineNotLoaded,
149+
EngineName, e.Message), EngineName, EngineVersion, e);
150+
}
151+
});
149152
}
150153

151154
/// <summary>
152-
/// Destructs instance of adapter for the ChakraCore JS engine
155+
/// Destructs an instance of adapter for the ChakraCore JS engine
153156
/// </summary>
154157
~ChakraCoreJsEngine()
155158
{
@@ -159,62 +162,38 @@ public ChakraCoreJsEngine(ChakraCoreSettings settings)
159162

160163
private void InvokeScript(Action action)
161164
{
162-
lock (_executionSynchronizer)
163-
using (new JsScope(_jsContext))
165+
_dispatcher.Invoke(() =>
164166
{
165-
try
166-
{
167-
action();
168-
}
169-
catch (OriginalJsException e)
167+
using (new JsScope(_jsContext))
170168
{
171-
throw ConvertJsExceptionToJsRuntimeException(e);
169+
try
170+
{
171+
action();
172+
}
173+
catch (OriginalJsException e)
174+
{
175+
throw ConvertJsExceptionToJsRuntimeException(e);
176+
}
172177
}
173-
}
178+
});
174179
}
175180

176181
private T InvokeScript<T>(Func<T> func)
177182
{
178-
lock (_executionSynchronizer)
179-
using (new JsScope(_jsContext))
180-
{
181-
try
182-
{
183-
return func();
184-
}
185-
catch (OriginalJsException e)
186-
{
187-
throw ConvertJsExceptionToJsRuntimeException(e);
188-
}
189-
}
190-
}
191-
192-
/// <summary>
193-
/// Destroys object
194-
/// </summary>
195-
/// <param name="disposing">Flag, allowing destruction of
196-
/// managed objects contained in fields of class</param>
197-
private void Dispose(bool disposing)
198-
{
199-
if (_disposedFlag.Set())
183+
return _dispatcher.Invoke(() =>
200184
{
201-
lock (_executionSynchronizer)
185+
using (new JsScope(_jsContext))
202186
{
203-
_jsRuntime.Dispose();
204-
205-
if (_externalObjects != null)
187+
try
206188
{
207-
_externalObjects.Clear();
189+
return func();
208190
}
209-
210-
if (_nativeFunctions != null)
191+
catch (OriginalJsException e)
211192
{
212-
_nativeFunctions.Clear();
193+
throw ConvertJsExceptionToJsRuntimeException(e);
213194
}
214-
215-
_externalObjectFinalizeCallback = null;
216195
}
217-
}
196+
});
218197
}
219198

220199
#region Mapping
@@ -427,12 +406,9 @@ private void ExternalObjectFinalizeCallback(IntPtr data)
427406
return;
428407
}
429408

430-
lock (_executionSynchronizer)
409+
if (_externalObjects != null)
431410
{
432-
if (_externalObjects != null)
433-
{
434-
_externalObjects.Remove(obj);
435-
}
411+
_externalObjects.Remove(obj);
436412
}
437413
}
438414

@@ -1115,10 +1091,7 @@ protected override void InnerEmbedHostType(string itemName, Type type)
11151091

11161092
protected override void InnerCollectGarbage()
11171093
{
1118-
lock (_executionSynchronizer)
1119-
{
1120-
_jsRuntime.CollectGarbage();
1121-
}
1094+
_dispatcher.Invoke(() => _jsRuntime.CollectGarbage());
11221095
}
11231096

11241097
#endregion
@@ -1134,6 +1107,39 @@ public override void Dispose()
11341107
GC.SuppressFinalize(this);
11351108
}
11361109

1110+
1111+
/// <summary>
1112+
/// Destroys object
1113+
/// </summary>
1114+
/// <param name="disposing">Flag, allowing destruction of
1115+
/// managed objects contained in fields of class</param>
1116+
private void Dispose(bool disposing)
1117+
{
1118+
if (_disposedFlag.Set())
1119+
{
1120+
if (_dispatcher != null)
1121+
{
1122+
_dispatcher.Invoke(() => _jsRuntime.Dispose());
1123+
_dispatcher.Dispose();
1124+
}
1125+
1126+
if (disposing)
1127+
{
1128+
if (_externalObjects != null)
1129+
{
1130+
_externalObjects.Clear();
1131+
}
1132+
1133+
if (_nativeFunctions != null)
1134+
{
1135+
_nativeFunctions.Clear();
1136+
}
1137+
1138+
_externalObjectFinalizeCallback = null;
1139+
}
1140+
}
1141+
}
1142+
11371143
#endregion
11381144
}
11391145
}

0 commit comments

Comments
 (0)