@@ -297,8 +297,11 @@ public virtual string GetInitJavaScript()
297
297
}
298
298
299
299
/// <summary>
300
- /// Attempts to execute the provided JavaScript code using the current engine. If an
301
- /// exception is thrown, retries the execution using a new thread (and hence a new engine)
300
+ /// Attempts to execute the provided JavaScript code using a non-pooled JavaScript engine (ie.
301
+ /// creates a new JS engine per-thread). This is because Babel uses a LOT of memory, so we
302
+ /// should completely dispose any engines that have loaded Babel in order to conserve memory.
303
+ ///
304
+ /// If an exception is thrown, retries the execution using a new thread (and hence a new engine)
302
305
/// with a larger maximum stack size.
303
306
/// This is required because JSXTransformer uses a huge stack which ends up being larger
304
307
/// than what ASP.NET allows by default (256 KB).
@@ -307,18 +310,14 @@ public virtual string GetInitJavaScript()
307
310
/// <param name="function">JavaScript function to execute</param>
308
311
/// <param name="args">Arguments to pass to function</param>
309
312
/// <returns>Result returned from JavaScript code</returns>
310
- public virtual T ExecuteWithLargerStackIfRequired < T > ( string function , params object [ ] args )
313
+ public virtual T ExecuteWithBabel < T > ( string function , params object [ ] args )
311
314
{
312
- // This hack is not required when pooling JavaScript engines, since pooled MSIE
313
- // engines already execute on their own thread with a larger stack.
314
- if ( _config . ReuseJavaScriptEngines )
315
- {
316
- return Execute < T > ( function , args ) ;
317
- }
315
+ var engine = _engineFactory . GetEngineForCurrentThread ( ) ;
316
+ EnsureBabelLoaded ( engine ) ;
318
317
319
318
try
320
319
{
321
- return Execute < T > ( function , args ) ;
320
+ return engine . CallFunctionReturningJson < T > ( function , args ) ;
322
321
}
323
322
catch ( Exception )
324
323
{
@@ -330,10 +329,11 @@ public virtual T ExecuteWithLargerStackIfRequired<T>(string function, params obj
330
329
var thread = new Thread ( ( ) =>
331
330
{
332
331
// New engine will be created here (as this is a new thread)
333
- var engine = _engineFactory . GetEngineForCurrentThread ( ) ;
332
+ var threadEngine = _engineFactory . GetEngineForCurrentThread ( ) ;
333
+ EnsureBabelLoaded ( threadEngine ) ;
334
334
try
335
335
{
336
- result = engine . CallFunctionReturningJson < T > ( function , args ) ;
336
+ result = threadEngine . CallFunctionReturningJson < T > ( function , args ) ;
337
337
}
338
338
catch ( Exception threadEx )
339
339
{
@@ -417,18 +417,18 @@ public virtual IReactSiteConfiguration Configuration
417
417
/// <summary>
418
418
/// Ensures that Babel has been loaded into the JavaScript engine.
419
419
/// </summary>
420
- public void EnsureBabelLoaded ( )
420
+ private void EnsureBabelLoaded ( IJsEngine engine )
421
421
{
422
422
// If Babel is disabled in the config, don't even try loading it
423
423
if ( ! _config . LoadBabel )
424
424
{
425
425
throw new BabelNotLoadedException ( ) ;
426
426
}
427
427
428
- var babelLoaded = Engine . Evaluate < bool > ( "typeof global.Babel !== 'undefined'" ) ;
428
+ var babelLoaded = engine . Evaluate < bool > ( "typeof global.Babel !== 'undefined'" ) ;
429
429
if ( ! babelLoaded )
430
430
{
431
- Engine . ExecuteResource ( "React.node_modules.babel_core.browser.js" , typeof ( ReactEnvironment ) . Assembly ) ;
431
+ engine . ExecuteResource ( "React.node_modules.babel_core.browser.js" , typeof ( ReactEnvironment ) . Assembly ) ;
432
432
}
433
433
}
434
434
}
0 commit comments