1
1
using System ;
2
2
using System . Linq ;
3
3
using System . Reflection ;
4
+ using System . Runtime . CompilerServices ;
4
5
using System . Text . RegularExpressions ;
5
6
6
7
using YantraJS . Core ;
12
13
using OriginalContext = YantraJS . Core . JSContext ;
13
14
using OriginalException = YantraJS . Core . JSException ;
14
15
using OriginalFunction = YantraJS . Core . JSFunction ;
16
+ using OriginalTypeConverter = YantraJS . Utils . TypeConverter ;
15
17
using OriginalUndefined = YantraJS . Core . JSUndefined ;
16
18
using OriginalValue = YantraJS . Core . JSValue ;
17
19
20
22
using JavaScriptEngineSwitcher . Core . Helpers ;
21
23
using JavaScriptEngineSwitcher . Core . Utilities ;
22
24
25
+ using CoreStrings = JavaScriptEngineSwitcher . Core . Resources . Strings ;
23
26
using WrapperCompilationException = JavaScriptEngineSwitcher . Core . JsCompilationException ;
24
27
using WrapperException = JavaScriptEngineSwitcher . Core . JsException ;
25
28
using WrapperRuntimeException = JavaScriptEngineSwitcher . Core . JsRuntimeException ;
@@ -94,7 +97,7 @@ private static OriginalValue MapToScriptType(object value)
94
97
return OriginalUndefined . Value ;
95
98
}
96
99
97
- return value . Marshal ( ) ;
100
+ return OriginalTypeConverter . FromBasic ( value ) ;
98
101
}
99
102
100
103
/// <summary>
@@ -134,7 +137,7 @@ private static object MapToHostType(OriginalValue value)
134
137
}
135
138
else if ( value . IsString )
136
139
{
137
- result = value . AsStringOrDefault ( ) ;
140
+ result = value . ToString ( ) ;
138
141
}
139
142
else
140
143
{
@@ -145,13 +148,51 @@ private static object MapToHostType(OriginalValue value)
145
148
}
146
149
147
150
/// <summary>
148
- /// Makes a mapping of array itemp from the script type to a host type
151
+ /// Makes a mapping of value from the script type to a host type
149
152
/// </summary>
150
- /// <param name="args">The source array</param>
151
- /// <returns>The mapped array</returns>
152
- private static object [ ] MapToHostType ( OriginalValue [ ] args )
153
+ /// <typeparam name="T">The type to convert the value to</typeparam>
154
+ /// <param name="value">The source value</param>
155
+ /// <returns>The mapped value</returns>
156
+ private static T MapToHostType < T > ( OriginalValue value )
153
157
{
154
- return args . Select ( MapToHostType ) . ToArray ( ) ;
158
+ if ( value . IsNull )
159
+ {
160
+ return TypeConverter . ConvertToType < T > ( null ) ;
161
+ }
162
+
163
+ Type targetType = typeof ( T ) ;
164
+
165
+ if ( targetType == typeof ( Undefined ) )
166
+ {
167
+ if ( value . IsUndefined )
168
+ {
169
+ return ( T ) ( object ) Undefined . Value ;
170
+ }
171
+ else
172
+ {
173
+ throw new InvalidOperationException (
174
+ string . Format ( CoreStrings . Common_CannotConvertObjectToType , value . GetType ( ) , targetType )
175
+ ) ;
176
+ }
177
+ }
178
+
179
+ T result ;
180
+
181
+ if ( ! value . ConvertTo < T > ( out result ) )
182
+ {
183
+ if ( targetType == typeof ( string ) )
184
+ {
185
+ result = ( T ) ( object ) value . ToString ( ) ;
186
+ }
187
+ else
188
+ {
189
+ throw new InvalidOperationException (
190
+ string . Format ( CoreStrings . Common_CannotConvertObjectToType , value . GetType ( ) , targetType )
191
+ ) ;
192
+ }
193
+ }
194
+
195
+ return result ;
155
196
}
156
197
157
198
private static OriginalFunction CreateEmbeddedFunction ( Delegate del )
@@ -306,33 +347,56 @@ private WrapperException WrapJsException(OriginalException originalException)
306
347
307
348
#endregion
308
349
309
- #region JsEngineBase overrides
310
-
311
- protected override IPrecompiledScript InnerPrecompile ( string code )
350
+ /// <summary>
351
+ /// Evaluates an expression without converting its result to a host type
352
+ /// </summary>
353
+ /// <param name="expression">JS expression</param>
354
+ /// <param name="documentName">Document name</param>
355
+ /// <returns>Result of the expression not converted to a host type</returns>
356
+ [ MethodImpl ( ( MethodImplOptions ) 256 /* AggressiveInlining */ ) ]
357
+ private OriginalValue InnerEvaluateWithoutResultConversion ( string expression , string documentName )
312
358
{
313
- throw new NotSupportedException ( ) ;
314
- }
359
+ OriginalValue resultValue ;
360
+ string uniqueDocumentName = _documentNameManager . GetUniqueName ( documentName ) ;
315
361
316
- protected override IPrecompiledScript InnerPrecompile ( string code , string documentName )
317
- {
318
- throw new NotSupportedException ( ) ;
319
- }
362
+ try
363
+ {
364
+ lock ( _executionSynchronizer )
365
+ {
366
+ resultValue = _jsContext . Eval ( expression , uniqueDocumentName ) ;
367
+ }
368
+ }
369
+ catch ( OriginalException e )
370
+ {
371
+ throw WrapJsException ( e ) ;
372
+ }
373
+ catch ( Exception e ) when ( ( e is TargetInvocationException || e is WrapperException )
374
+ && e . InnerException != null )
375
+ {
376
+ OriginalException originalException = OriginalException . From ( e . InnerException ) ;
377
+ throw originalException ;
378
+ }
320
379
321
- protected override object InnerEvaluate ( string expression )
322
- {
323
- return InnerEvaluate ( expression , null ) ;
380
+ return resultValue ;
324
381
}
325
382
326
- protected override object InnerEvaluate ( string expression , string documentName )
383
+ /// <summary>
384
+ /// Calls a function without converting its result to a host type
385
+ /// </summary>
386
+ /// <param name="functionName">Function name</param>
387
+ /// <param name="args">Function arguments</param>
388
+ /// <returns>Result of the function execution not converted to a host type</returns>
389
+ [ MethodImpl ( ( MethodImplOptions ) 256 /* AggressiveInlining */ ) ]
390
+ private OriginalValue InnerCallFunctionWithoutResultConversion ( string functionName , params object [ ] args )
327
391
{
328
392
OriginalValue resultValue ;
329
- string uniqueDocumentName = _documentNameManager . GetUniqueName ( documentName ) ;
393
+ OriginalValue [ ] processedArgs = MapToScriptType ( args ) ;
330
394
331
395
try
332
396
{
333
397
lock ( _executionSynchronizer )
334
398
{
335
- resultValue = _jsContext . Eval ( expression , uniqueDocumentName ) ;
399
+ resultValue = _jsContext . InvokeMethod ( functionName , new OriginalArguments ( _jsContext , processedArgs ) ) ;
336
400
}
337
401
}
338
402
catch ( OriginalException e )
@@ -346,6 +410,54 @@ protected override object InnerEvaluate(string expression, string documentName)
346
410
throw originalException ;
347
411
}
348
412
413
+ return resultValue ;
414
+ }
415
+
416
+ /// <summary>
417
+ /// Gets a value of variable without converting it to a host type
418
+ /// </summary>
419
+ /// <param name="variableName">Variable name</param>
420
+ /// <returns>Value of variable not converted to a host type</returns>
421
+ [ MethodImpl ( ( MethodImplOptions ) 256 /* AggressiveInlining */ ) ]
422
+ private OriginalValue InnerGetVariableValueWithoutResultConversion ( string variableName )
423
+ {
424
+ OriginalValue variableValue ;
425
+
426
+ try
427
+ {
428
+ lock ( _executionSynchronizer )
429
+ {
430
+ variableValue = _jsContext [ variableName ] ;
431
+ }
432
+ }
433
+ catch ( OriginalException e )
434
+ {
435
+ throw WrapJsException ( e ) ;
436
+ }
437
+
438
+ return variableValue ;
439
+ }
440
+
441
+ #region JsEngineBase overrides
442
+
443
+ protected override IPrecompiledScript InnerPrecompile ( string code )
444
+ {
445
+ throw new NotSupportedException ( ) ;
446
+ }
447
+
448
+ protected override IPrecompiledScript InnerPrecompile ( string code , string documentName )
449
+ {
450
+ throw new NotSupportedException ( ) ;
451
+ }
452
+
453
+ protected override object InnerEvaluate ( string expression )
454
+ {
455
+ return InnerEvaluate ( expression , null ) ;
456
+ }
457
+
458
+ protected override object InnerEvaluate ( string expression , string documentName )
459
+ {
460
+ OriginalValue resultValue = InnerEvaluateWithoutResultConversion ( expression , documentName ) ;
349
461
object result = MapToHostType ( resultValue ) ;
350
462
351
463
return result ;
@@ -358,9 +470,10 @@ protected override T InnerEvaluate<T>(string expression)
358
470
359
471
protected override T InnerEvaluate < T > ( string expression , string documentName )
360
472
{
361
- object result = InnerEvaluate ( expression , documentName ) ;
473
+ OriginalValue resultValue = InnerEvaluateWithoutResultConversion ( expression , documentName ) ;
474
+ T result = MapToHostType < T > ( resultValue ) ;
362
475
363
- return TypeConverter . ConvertToType < T > ( result ) ;
476
+ return result ;
364
477
}
365
478
366
479
protected override void InnerExecute ( string code )
@@ -398,86 +511,57 @@ protected override void InnerExecute(IPrecompiledScript precompiledScript)
398
511
399
512
protected override object InnerCallFunction ( string functionName , params object [ ] args )
400
513
{
401
- OriginalValue resultValue ;
402
- OriginalValue [ ] processedArgs = MapToScriptType ( args ) ;
403
-
404
- try
405
- {
406
- lock ( _executionSynchronizer )
407
- {
408
- resultValue = _jsContext . InvokeMethod ( functionName , new OriginalArguments ( _jsContext , processedArgs ) ) ;
409
- }
410
- }
411
- catch ( OriginalException e )
412
- {
413
- throw WrapJsException ( e ) ;
414
- }
415
- catch ( Exception e ) when ( ( e is TargetInvocationException || e is WrapperException )
416
- && e . InnerException != null )
417
- {
418
- OriginalException originalException = OriginalException . From ( e . InnerException ) ;
419
- throw originalException ;
420
- }
421
-
514
+ OriginalValue resultValue = InnerCallFunctionWithoutResultConversion ( functionName , args ) ;
422
515
object result = MapToHostType ( resultValue ) ;
423
516
424
517
return result ;
425
518
}
426
519
427
520
protected override T InnerCallFunction < T > ( string functionName , params object [ ] args )
428
521
{
429
- object result = InnerCallFunction ( functionName , args ) ;
522
+ OriginalValue resultValue = InnerCallFunctionWithoutResultConversion ( functionName , args ) ;
523
+ T result = MapToHostType < T > ( resultValue ) ;
430
524
431
- return TypeConverter . ConvertToType < T > ( result ) ;
525
+ return result ;
432
526
}
433
527
434
528
protected override bool InnerHasVariable ( string variableName )
435
529
{
436
530
bool result ;
437
531
438
- lock ( _executionSynchronizer )
532
+ try
439
533
{
440
- try
441
- {
442
- OriginalValue variableValue = _jsContext [ variableName ] ;
534
+ OriginalValue variableValue ;
443
535
444
- result = ! variableValue . IsUndefined ;
445
- }
446
- catch ( OriginalException )
536
+ lock ( _executionSynchronizer )
447
537
{
448
- result = false ;
538
+ variableValue = _jsContext [ variableName ] ;
449
539
}
540
+
541
+ result = ! variableValue . IsUndefined ;
542
+ }
543
+ catch ( OriginalException )
544
+ {
545
+ result = false ;
450
546
}
451
547
452
548
return result ;
453
549
}
454
550
455
551
protected override object InnerGetVariableValue ( string variableName )
456
552
{
457
- OriginalValue variableValue ;
458
-
459
- try
460
- {
461
- lock ( _executionSynchronizer )
462
- {
463
- variableValue = _jsContext [ variableName ] ;
464
- }
465
- }
466
- catch ( OriginalException e )
467
- {
468
- throw WrapJsException ( e ) ;
469
- }
470
-
553
+ OriginalValue variableValue = InnerGetVariableValueWithoutResultConversion ( variableName ) ;
471
554
object result = MapToHostType ( variableValue ) ;
472
555
473
556
return result ;
474
557
}
475
558
476
559
protected override T InnerGetVariableValue < T > ( string variableName )
477
560
{
478
- object result = InnerGetVariableValue ( variableName ) ;
561
+ OriginalValue variableValue = InnerGetVariableValueWithoutResultConversion ( variableName ) ;
562
+ T result = MapToHostType < T > ( variableValue ) ;
479
563
480
- return TypeConverter . ConvertToType < T > ( result ) ;
564
+ return result ;
481
565
}
482
566
483
567
protected override void InnerSetVariableValue ( string variableName , object value )
0 commit comments