@@ -1235,7 +1235,7 @@ private object InvokeHostMember(string name, BindingFlags invokeFlags, object[]
12351235 return DelegateFactory . CreateDelegate ( Engine , args [ 0 ] , specificType ) ;
12361236 }
12371237
1238- return specificType . CreateInstance ( this , AccessContext , DefaultAccess , args , bindArgs ) ;
1238+ return specificType . CreateInstance ( this , Target , args , bindArgs ) ;
12391239 }
12401240 }
12411241
@@ -1255,7 +1255,7 @@ private object InvokeHostMember(string name, BindingFlags invokeFlags, object[]
12551255 return DelegateFactory . CreateDelegate ( Engine , args [ 0 ] , type ) ;
12561256 }
12571257
1258- return type . CreateInstance ( this , AccessContext , DefaultAccess , args , bindArgs ) ;
1258+ return type . CreateInstance ( this , Target , args , bindArgs ) ;
12591259 }
12601260
12611261 if ( TargetDynamicMetaObject != null )
@@ -1386,12 +1386,26 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
13861386 {
13871387 isCacheable = false ;
13881388
1389+ var signature = new BindSignature ( AccessContext , invokeFlags , Target , name , ArrayHelpers . GetEmptyArray < Type > ( ) , bindArgs ) ;
1390+ if ( Engine . TryGetCachedPropertyGetBindResult ( signature , out var boundMember ) )
1391+ {
1392+ if ( boundMember is PropertyInfo boundProperty )
1393+ {
1394+ return GetHostPropertyWorker ( boundProperty , boundProperty . GetMethod , args ) ;
1395+ }
1396+
1397+ if ( boundMember is FieldInfo boundField )
1398+ {
1399+ return GetHostFieldWorker ( boundField , out isCacheable ) ;
1400+ }
1401+ }
1402+
13891403 if ( name == SpecialMemberNames . Default )
13901404 {
13911405 var defaultProperty = Target . Type . GetScriptableDefaultProperty ( invokeFlags , args , bindArgs , AccessContext , DefaultAccess ) ;
13921406 if ( defaultProperty != null )
13931407 {
1394- return GetHostProperty ( defaultProperty , invokeFlags , args ) ;
1408+ return GetHostProperty ( signature , defaultProperty , invokeFlags , args ) ;
13951409 }
13961410
13971411 if ( TargetDynamicMetaObject != null )
@@ -1476,7 +1490,7 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
14761490 var property = Target . Type . GetScriptableProperty ( name , invokeFlags , args , bindArgs , AccessContext , DefaultAccess ) ;
14771491 if ( property != null )
14781492 {
1479- return GetHostProperty ( property , invokeFlags , args ) ;
1493+ return GetHostProperty ( signature , property , invokeFlags , args ) ;
14801494 }
14811495
14821496 if ( args . Length > 0 )
@@ -1494,9 +1508,7 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
14941508 var field = Target . Type . GetScriptableField ( name , invokeFlags , AccessContext , DefaultAccess ) ;
14951509 if ( field != null )
14961510 {
1497- var result = field . GetValue ( Target . InvokeTarget ) ;
1498- isCacheable = ( TargetDynamicMetaObject == null ) && ( field . IsLiteral || field . IsInitOnly ) ;
1499- return Engine . PrepareResult ( result , field . FieldType , field . GetScriptMemberFlags ( ) , false ) ;
1511+ return GetHostField ( signature , field , out isCacheable ) ;
15001512 }
15011513
15021514 if ( includeBoundMembers )
@@ -1539,7 +1551,7 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
15391551 return Nonexistent . Value ;
15401552 }
15411553
1542- private object GetHostProperty ( PropertyInfo property , BindingFlags invokeFlags , object [ ] args )
1554+ private object GetHostProperty ( BindSignature signature , PropertyInfo property , BindingFlags invokeFlags , object [ ] args )
15431555 {
15441556 if ( reflectionProperties . Contains ( property , MemberComparer < PropertyInfo > . Instance ) )
15451557 {
@@ -1569,11 +1581,46 @@ private object GetHostProperty(PropertyInfo property, BindingFlags invokeFlags,
15691581 throw new UnauthorizedAccessException ( "The property get method is unavailable or inaccessible" ) ;
15701582 }
15711583
1584+ var result = GetHostPropertyWorker ( property , getMethod , args ) ;
1585+ Engine . CachePropertyGetBindResult ( signature , property ) ;
1586+ return result ;
1587+ }
1588+
1589+ private object GetHostPropertyWorker ( PropertyInfo property , MethodInfo getMethod , object [ ] args )
1590+ {
15721591 return InvokeHelpers . InvokeMethod ( this , getMethod , Target . InvokeTarget , args , property . GetScriptMemberFlags ( ) ) ;
15731592 }
15741593
1594+ private object GetHostField ( BindSignature signature , FieldInfo field , out bool isCacheable )
1595+ {
1596+ var result = GetHostFieldWorker ( field , out isCacheable ) ;
1597+ Engine . CachePropertyGetBindResult ( signature , field ) ;
1598+ return result ;
1599+ }
1600+
1601+ private object GetHostFieldWorker ( FieldInfo field , out bool isCacheable )
1602+ {
1603+ var result = field . GetValue ( Target . InvokeTarget ) ;
1604+ isCacheable = ( TargetDynamicMetaObject == null ) && ( field . IsLiteral || field . IsInitOnly ) ;
1605+ return Engine . PrepareResult ( result , field . FieldType , field . GetScriptMemberFlags ( ) , false ) ;
1606+ }
1607+
15751608 private object SetHostProperty ( string name , BindingFlags invokeFlags , object [ ] args , object [ ] bindArgs )
15761609 {
1610+ var signature = new BindSignature ( AccessContext , invokeFlags , Target , name , ArrayHelpers . GetEmptyArray < Type > ( ) , bindArgs ) ;
1611+ if ( Engine . TryGetCachedPropertySetBindResult ( signature , out var boundMember ) )
1612+ {
1613+ if ( boundMember is PropertyInfo boundProperty )
1614+ {
1615+ return SetHostPropertyWorker ( boundProperty , boundProperty . SetMethod , args , bindArgs ) ;
1616+ }
1617+
1618+ if ( boundMember is FieldInfo boundField )
1619+ {
1620+ return SetHostFieldWorker ( boundField , args ) ;
1621+ }
1622+ }
1623+
15771624 if ( name == SpecialMemberNames . Default )
15781625 {
15791626 if ( args . Length < 1 )
@@ -1586,7 +1633,7 @@ private object SetHostProperty(string name, BindingFlags invokeFlags, object[] a
15861633 var defaultProperty = Target . Type . GetScriptableDefaultProperty ( invokeFlags , args . Take ( args . Length - 1 ) . ToArray ( ) , bindArgs . Take ( bindArgs . Length - 1 ) . ToArray ( ) , AccessContext , DefaultAccess ) ;
15871634 if ( defaultProperty != null )
15881635 {
1589- return SetHostProperty ( defaultProperty , args , bindArgs ) ;
1636+ return SetHostProperty ( signature , defaultProperty , args , bindArgs ) ;
15901637 }
15911638
15921639 if ( args . Length < 2 )
@@ -1641,36 +1688,19 @@ private object SetHostProperty(string name, BindingFlags invokeFlags, object[] a
16411688 var property = Target . Type . GetScriptableProperty ( name , invokeFlags , args . Take ( args . Length - 1 ) . ToArray ( ) , bindArgs . Take ( bindArgs . Length - 1 ) . ToArray ( ) , AccessContext , DefaultAccess ) ;
16421689 if ( property != null )
16431690 {
1644- return SetHostProperty ( property , args , bindArgs ) ;
1691+ return SetHostProperty ( signature , property , args , bindArgs ) ;
16451692 }
16461693
16471694 var field = Target . Type . GetScriptableField ( name , invokeFlags , AccessContext , DefaultAccess ) ;
16481695 if ( field != null )
16491696 {
1650- if ( args . Length == 1 )
1651- {
1652- if ( field . IsLiteral || field . IsInitOnly || field . IsReadOnlyForScript ( DefaultAccess ) )
1653- {
1654- throw new UnauthorizedAccessException ( "The field is read-only" ) ;
1655- }
1656-
1657- var value = args [ 0 ] ;
1658- if ( field . FieldType . IsAssignableFromValue ( ref value ) )
1659- {
1660- field . SetValue ( Target . InvokeTarget , value ) ;
1661- return value ;
1662- }
1663-
1664- throw new ArgumentException ( "Invalid field assignment" ) ;
1665- }
1666-
1667- throw new InvalidOperationException ( "Invalid argument count" ) ;
1697+ return SetHostField ( signature , field , args ) ;
16681698 }
16691699
16701700 throw new MissingMemberException ( MiscHelpers . FormatInvariant ( "The object has no suitable property or field named '{0}'" , name ) ) ;
16711701 }
16721702
1673- private object SetHostProperty ( PropertyInfo property , object [ ] args , object [ ] bindArgs )
1703+ private object SetHostProperty ( BindSignature signature , PropertyInfo property , object [ ] args , object [ ] bindArgs )
16741704 {
16751705 var scriptAccess = property . GetScriptAccess ( DefaultAccess ) ;
16761706 if ( scriptAccess == ScriptAccess . ReadOnly )
@@ -1684,6 +1714,13 @@ private object SetHostProperty(PropertyInfo property, object[] args, object[] bi
16841714 throw new UnauthorizedAccessException ( "The property set method is unavailable or inaccessible" ) ;
16851715 }
16861716
1717+ var result = SetHostPropertyWorker ( property , setMethod , args , bindArgs ) ;
1718+ Engine . CachePropertySetBindResult ( signature , property ) ;
1719+ return result ;
1720+ }
1721+
1722+ private object SetHostPropertyWorker ( PropertyInfo property , MethodInfo setMethod , object [ ] args , object [ ] bindArgs )
1723+ {
16871724 var value = args [ args . Length - 1 ] ;
16881725
16891726 var argCount = args . Length - 1 ;
@@ -1741,6 +1778,35 @@ private object SetHostProperty(PropertyInfo property, object[] args, object[] bi
17411778 throw new ArgumentException ( "Invalid property assignment" ) ;
17421779 }
17431780
1781+ private object SetHostField ( BindSignature signature , FieldInfo field , object [ ] args )
1782+ {
1783+ if ( args . Length != 1 )
1784+ {
1785+ throw new InvalidOperationException ( "Invalid argument count" ) ;
1786+ }
1787+
1788+ if ( field . IsLiteral || field . IsInitOnly || field . IsReadOnlyForScript ( DefaultAccess ) )
1789+ {
1790+ throw new UnauthorizedAccessException ( "The field is read-only" ) ;
1791+ }
1792+
1793+ var result = SetHostFieldWorker ( field , args ) ;
1794+ Engine . CachePropertySetBindResult ( signature , field ) ;
1795+ return result ;
1796+ }
1797+
1798+ private object SetHostFieldWorker ( FieldInfo field , object [ ] args )
1799+ {
1800+ var value = args [ 0 ] ;
1801+ if ( field . FieldType . IsAssignableFromValue ( ref value ) )
1802+ {
1803+ field . SetValue ( Target . InvokeTarget , value ) ;
1804+ return value ;
1805+ }
1806+
1807+ throw new ArgumentException ( "Invalid field assignment" ) ;
1808+ }
1809+
17441810 private static object CreateScriptableEnumerator < T > ( IEnumerable < T > enumerable )
17451811 {
17461812 return HostObject . Wrap ( new ScriptableEnumeratorOnEnumerator < T > ( enumerable . GetEnumerator ( ) ) , typeof ( IScriptableEnumerator < T > ) ) ;
0 commit comments