1
1
using System ;
2
2
using System . Text ;
3
+ using System . Threading ;
3
4
4
5
using Jint ;
5
6
using IOriginalPrimitiveInstance = Jint . Native . IPrimitiveInstance ;
27
28
28
29
using CoreStrings = JavaScriptEngineSwitcher . Core . Resources . Strings ;
29
30
using WrapperCompilationException = JavaScriptEngineSwitcher . Core . JsCompilationException ;
31
+ using WrapperInterruptedException = JavaScriptEngineSwitcher . Core . JsInterruptedException ;
30
32
using WrapperRuntimeException = JavaScriptEngineSwitcher . Core . JsRuntimeException ;
31
33
using WrapperTimeoutException = JavaScriptEngineSwitcher . Core . JsTimeoutException ;
32
34
using WrapperUsageException = JavaScriptEngineSwitcher . Core . JsUsageException ;
@@ -53,6 +55,16 @@ public sealed class JintJsEngine : JsEngineBase
53
55
/// </summary>
54
56
private OriginalEngine _jsEngine ;
55
57
58
+ /// <summary>
59
+ /// Token source for canceling of script execution
60
+ /// </summary>
61
+ private CancellationTokenSource _cancellationTokenSource ;
62
+
63
+ /// <summary>
64
+ /// Constraint for canceling of script execution
65
+ /// </summary>
66
+ private CustomCancellationConstraint _cancellationConstraint ;
67
+
56
68
/// <summary>
57
69
/// Synchronizer of code execution
58
70
/// </summary>
@@ -78,13 +90,17 @@ public JintJsEngine()
78
90
/// <param name="settings">Settings of the Jint JS engine</param>
79
91
public JintJsEngine ( JintSettings settings )
80
92
{
93
+ _cancellationTokenSource = new CancellationTokenSource ( ) ;
94
+ _cancellationConstraint = new CustomCancellationConstraint ( _cancellationTokenSource . Token ) ;
95
+
81
96
JintSettings jintSettings = settings ?? new JintSettings ( ) ;
82
97
83
98
try
84
99
{
85
100
_jsEngine = new OriginalEngine ( options => {
86
101
options
87
102
. AllowDebuggerStatement ( jintSettings . AllowDebuggerStatement )
103
+ . Constraint ( _cancellationConstraint )
88
104
. DebugMode ( jintSettings . EnableDebugging )
89
105
. LimitMemory ( jintSettings . MemoryLimit )
90
106
. LimitRecursion ( jintSettings . MaxRecursionDepth )
@@ -187,8 +203,9 @@ private static WrapperCompilationException WrapParserException(OriginalParserExc
187
203
return wrapperCompilationException ;
188
204
}
189
205
190
- private static WrapperRuntimeException WrapRuntimeException ( OriginalRuntimeException originalRuntimeException )
206
+ private WrapperRuntimeException WrapRuntimeException ( OriginalRuntimeException originalRuntimeException )
191
207
{
208
+ WrapperRuntimeException wrapperRuntimeException ;
192
209
string message = originalRuntimeException . Message ;
193
210
if ( string . IsNullOrWhiteSpace ( message ) )
194
211
{
@@ -227,11 +244,17 @@ private static WrapperRuntimeException WrapRuntimeException(OriginalRuntimeExcep
227
244
228
245
message = JsErrorHelpers . GenerateScriptErrorMessage ( type , description , documentName , lineNumber ,
229
246
columnNumber ) ;
247
+
248
+ wrapperRuntimeException = new WrapperRuntimeException ( message , EngineName , EngineVersion ,
249
+ originalJavaScriptException ) ;
230
250
}
231
251
else if ( originalRuntimeException is OriginalMemoryLimitExceededException )
232
252
{
233
253
type = JsErrorType . Common ;
234
254
message = JsErrorHelpers . GenerateScriptErrorMessage ( type , description , string . Empty ) ;
255
+
256
+ wrapperRuntimeException = new WrapperRuntimeException ( message , EngineName , EngineVersion ,
257
+ originalRuntimeException ) ;
235
258
}
236
259
else if ( originalRuntimeException is OriginalRecursionDepthOverflowException )
237
260
{
@@ -266,28 +289,45 @@ private static WrapperRuntimeException WrapRuntimeException(OriginalRuntimeExcep
266
289
267
290
type = JsErrorType . Range ;
268
291
message = JsErrorHelpers . GenerateScriptErrorMessage ( type , description , callStack ) ;
292
+
293
+ wrapperRuntimeException = new WrapperRuntimeException ( message , EngineName , EngineVersion ,
294
+ originalRecursionException ) ;
269
295
}
270
296
else if ( originalRuntimeException is OriginalStatementsCountOverflowException )
271
297
{
272
298
type = JsErrorType . Range ;
273
299
message = JsErrorHelpers . GenerateScriptErrorMessage ( type , description , string . Empty ) ;
300
+
301
+ wrapperRuntimeException = new WrapperRuntimeException ( message , EngineName , EngineVersion ,
302
+ originalRuntimeException ) ;
303
+ }
304
+ else if ( originalRuntimeException is ScriptExecutionCanceledException )
305
+ {
306
+ _cancellationTokenSource = new CancellationTokenSource ( ) ;
307
+ _cancellationConstraint . Reset ( _cancellationTokenSource . Token ) ;
308
+
309
+ type = JsErrorType . Common ;
310
+ message = CoreStrings . Runtime_ScriptInterrupted ;
311
+ description = message ;
312
+
313
+ wrapperRuntimeException = new WrapperInterruptedException ( message ,
314
+ EngineName , EngineVersion , originalRuntimeException ) ;
274
315
}
275
316
else
276
317
{
277
318
type = JsErrorType . Common ;
278
319
message = JsErrorHelpers . GenerateScriptErrorMessage ( type , description , string . Empty ) ;
320
+
321
+ wrapperRuntimeException = new WrapperRuntimeException ( message , EngineName , EngineVersion ,
322
+ originalRuntimeException ) ;
279
323
}
280
324
281
- var wrapperRuntimeException = new WrapperRuntimeException ( message , EngineName , EngineVersion ,
282
- originalRuntimeException )
283
- {
284
- Description = description ,
285
- Type = type ,
286
- DocumentName = documentName ,
287
- LineNumber = lineNumber ,
288
- ColumnNumber = columnNumber ,
289
- CallStack = callStack
290
- } ;
325
+ wrapperRuntimeException . Description = description ;
326
+ wrapperRuntimeException . Type = type ;
327
+ wrapperRuntimeException . DocumentName = documentName ;
328
+ wrapperRuntimeException . LineNumber = lineNumber ;
329
+ wrapperRuntimeException . ColumnNumber = columnNumber ;
330
+ wrapperRuntimeException . CallStack = callStack ;
291
331
292
332
return wrapperRuntimeException ;
293
333
}
@@ -602,7 +642,7 @@ protected override void InnerEmbedHostType(string itemName, Type type)
602
642
603
643
protected override void InnerInterrupt ( )
604
644
{
605
- throw new NotSupportedException ( ) ;
645
+ _cancellationTokenSource . Cancel ( ) ;
606
646
}
607
647
608
648
protected override void InnerCollectGarbage ( )
@@ -641,7 +681,7 @@ public override bool SupportsScriptPrecompilation
641
681
/// </summary>
642
682
public override bool SupportsScriptInterruption
643
683
{
644
- get { return false ; }
684
+ get { return true ; }
645
685
}
646
686
647
687
/// <summary>
@@ -663,6 +703,13 @@ public override void Dispose()
663
703
lock ( _executionSynchronizer )
664
704
{
665
705
_jsEngine = null ;
706
+ _cancellationConstraint = null ;
707
+
708
+ if ( _cancellationTokenSource != null )
709
+ {
710
+ _cancellationTokenSource . Dispose ( ) ;
711
+ _cancellationTokenSource = null ;
712
+ }
666
713
}
667
714
}
668
715
}
0 commit comments