@@ -21,6 +21,11 @@ namespace JavaScriptEngineSwitcher.ChakraCore.JsRt
21
21
/// </summary>
22
22
internal sealed class TypeMapper : IDisposable
23
23
{
24
+ /// <summary>
25
+ /// Name of property to store the external object
26
+ /// </summary>
27
+ private const string ExternalObjectPropertyName = "_JavaScriptEngineSwitcher_externalObject" ;
28
+
24
29
/// <summary>
25
30
/// Storage for lazy-initialized embedded objects
26
31
/// </summary>
@@ -200,7 +205,7 @@ public JsValue[] MapToScriptType(object[] args)
200
205
public object MapToHostType ( JsValue value )
201
206
{
202
207
JsValueType valueType = value . ValueType ;
203
- object result ;
208
+ object result = null ;
204
209
205
210
switch ( valueType )
206
211
{
@@ -219,8 +224,18 @@ public object MapToHostType(JsValue value)
219
224
case JsValueType . String :
220
225
result = value . ToString ( ) ;
221
226
break ;
222
- case JsValueType . Object :
223
227
case JsValueType . Function :
228
+ JsPropertyId externalObjectPropertyId = JsPropertyId . FromString ( ExternalObjectPropertyName ) ;
229
+ if ( value . HasProperty ( externalObjectPropertyId ) )
230
+ {
231
+ JsValue externalObjectValue = value . GetProperty ( externalObjectPropertyId ) ;
232
+ result = externalObjectValue . HasExternalData ?
233
+ GCHandle . FromIntPtr ( externalObjectValue . ExternalData ) . Target : null ;
234
+ }
235
+
236
+ result = result ?? value . ConvertToObject ( ) ;
237
+ break ;
238
+ case JsValueType . Object :
224
239
case JsValueType . Error :
225
240
case JsValueType . Array :
226
241
case JsValueType . Symbol :
@@ -311,10 +326,10 @@ private EmbeddedObject CreateEmbeddedFunction(Delegate del)
311
326
312
327
GCHandle delHandle = GCHandle . Alloc ( del ) ;
313
328
IntPtr delPtr = GCHandle . ToIntPtr ( delHandle ) ;
314
- JsValue prototypeValue = JsValue . CreateExternalObject ( delPtr , _embeddedObjectFinalizeCallback ) ;
329
+ JsValue objValue = JsValue . CreateExternalObject ( delPtr , _embeddedObjectFinalizeCallback ) ;
315
330
316
331
JsValue functionValue = JsValue . CreateFunction ( nativeFunction ) ;
317
- functionValue . Prototype = prototypeValue ;
332
+ SetNonEnumerableProperty ( functionValue , ExternalObjectPropertyName , objValue ) ;
318
333
319
334
var embeddedObject = new EmbeddedObject ( del , functionValue ,
320
335
new List < JsNativeFunction > { nativeFunction } ) ;
@@ -415,14 +430,12 @@ private EmbeddedType CreateEmbeddedType(Type type)
415
430
return resultValue ;
416
431
} ;
417
432
418
- string embeddedTypeKey = type . AssemblyQualifiedName ;
419
- GCHandle embeddedTypeKeyHandle = GCHandle . Alloc ( embeddedTypeKey ) ;
420
- IntPtr embeddedTypeKeyPtr = GCHandle . ToIntPtr ( embeddedTypeKeyHandle ) ;
421
- JsValue prototypeValue = JsValue . CreateExternalObject ( embeddedTypeKeyPtr ,
422
- _embeddedTypeFinalizeCallback ) ;
433
+ GCHandle embeddedTypeHandle = GCHandle . Alloc ( type ) ;
434
+ IntPtr embeddedTypePtr = GCHandle . ToIntPtr ( embeddedTypeHandle ) ;
435
+ JsValue objValue = JsValue . CreateExternalObject ( embeddedTypePtr , _embeddedTypeFinalizeCallback ) ;
423
436
424
437
JsValue typeValue = JsValue . CreateFunction ( nativeConstructorFunction ) ;
425
- typeValue . Prototype = prototypeValue ;
438
+ SetNonEnumerableProperty ( typeValue , ExternalObjectPropertyName , objValue ) ;
426
439
427
440
var embeddedType = new EmbeddedType ( type , typeValue ,
428
441
new List < JsNativeFunction > { nativeConstructorFunction } ) ;
@@ -442,8 +455,9 @@ private void EmbeddedTypeFinalizeCallback(IntPtr ptr)
442
455
return ;
443
456
}
444
457
445
- GCHandle embeddedTypeKeyHandle = GCHandle . FromIntPtr ( ptr ) ;
446
- var embeddedTypeKey = ( string ) embeddedTypeKeyHandle . Target ;
458
+ GCHandle embeddedTypeHandle = GCHandle . FromIntPtr ( ptr ) ;
459
+ var type = ( Type ) embeddedTypeHandle . Target ;
460
+ string embeddedTypeKey = type . AssemblyQualifiedName ;
447
461
var lazyEmbeddedTypes = _lazyEmbeddedTypes ;
448
462
449
463
if ( ! string . IsNullOrEmpty ( embeddedTypeKey ) && lazyEmbeddedTypes != null )
@@ -456,7 +470,7 @@ private void EmbeddedTypeFinalizeCallback(IntPtr ptr)
456
470
}
457
471
}
458
472
459
- embeddedTypeKeyHandle . Free ( ) ;
473
+ embeddedTypeHandle . Free ( ) ;
460
474
}
461
475
462
476
private void ProjectFields ( EmbeddedItem externalItem )
@@ -772,7 +786,7 @@ private object[] GetHostItemMemberArguments(JsValue[] args)
772
786
}
773
787
774
788
[ MethodImpl ( ( MethodImplOptions ) 256 /* AggressiveInlining */ ) ]
775
- private void FreezeObject ( JsValue objValue )
789
+ private static void FreezeObject ( JsValue objValue )
776
790
{
777
791
JsValue freezeMethodValue = JsValue . GlobalObject
778
792
. GetProperty ( "Object" )
@@ -781,6 +795,18 @@ private void FreezeObject(JsValue objValue)
781
795
freezeMethodValue . CallFunction ( objValue ) ;
782
796
}
783
797
798
+ [ MethodImpl ( ( MethodImplOptions ) 256 /* AggressiveInlining */ ) ]
799
+ private static void SetNonEnumerableProperty ( JsValue objValue , string name , JsValue value )
800
+ {
801
+ JsValue descriptorValue = JsValue . CreateObject ( ) ;
802
+ descriptorValue . SetProperty ( "enumerable" , JsValue . False , true ) ;
803
+ descriptorValue . SetProperty ( "writable" , JsValue . True , true ) ;
804
+
805
+ JsPropertyId id = JsPropertyId . FromString ( name ) ;
806
+ objValue . DefineProperty ( id , descriptorValue ) ;
807
+ objValue . SetProperty ( id , value , true ) ;
808
+ }
809
+
784
810
#region IDisposable implementation
785
811
786
812
/// <summary>
0 commit comments