@@ -1235,7 +1235,7 @@ private object InvokeHostMember(string name, BindingFlags invokeFlags, object[]
1235
1235
return DelegateFactory . CreateDelegate ( Engine , args [ 0 ] , specificType ) ;
1236
1236
}
1237
1237
1238
- return specificType . CreateInstance ( this , AccessContext , DefaultAccess , args , bindArgs ) ;
1238
+ return specificType . CreateInstance ( this , Target , args , bindArgs ) ;
1239
1239
}
1240
1240
}
1241
1241
@@ -1255,7 +1255,7 @@ private object InvokeHostMember(string name, BindingFlags invokeFlags, object[]
1255
1255
return DelegateFactory . CreateDelegate ( Engine , args [ 0 ] , type ) ;
1256
1256
}
1257
1257
1258
- return type . CreateInstance ( this , AccessContext , DefaultAccess , args , bindArgs ) ;
1258
+ return type . CreateInstance ( this , Target , args , bindArgs ) ;
1259
1259
}
1260
1260
1261
1261
if ( TargetDynamicMetaObject != null )
@@ -1386,12 +1386,26 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
1386
1386
{
1387
1387
isCacheable = false ;
1388
1388
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
+
1389
1403
if ( name == SpecialMemberNames . Default )
1390
1404
{
1391
1405
var defaultProperty = Target . Type . GetScriptableDefaultProperty ( invokeFlags , args , bindArgs , AccessContext , DefaultAccess ) ;
1392
1406
if ( defaultProperty != null )
1393
1407
{
1394
- return GetHostProperty ( defaultProperty , invokeFlags , args ) ;
1408
+ return GetHostProperty ( signature , defaultProperty , invokeFlags , args ) ;
1395
1409
}
1396
1410
1397
1411
if ( TargetDynamicMetaObject != null )
@@ -1476,7 +1490,7 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
1476
1490
var property = Target . Type . GetScriptableProperty ( name , invokeFlags , args , bindArgs , AccessContext , DefaultAccess ) ;
1477
1491
if ( property != null )
1478
1492
{
1479
- return GetHostProperty ( property , invokeFlags , args ) ;
1493
+ return GetHostProperty ( signature , property , invokeFlags , args ) ;
1480
1494
}
1481
1495
1482
1496
if ( args . Length > 0 )
@@ -1494,9 +1508,7 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
1494
1508
var field = Target . Type . GetScriptableField ( name , invokeFlags , AccessContext , DefaultAccess ) ;
1495
1509
if ( field != null )
1496
1510
{
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 ) ;
1500
1512
}
1501
1513
1502
1514
if ( includeBoundMembers )
@@ -1539,7 +1551,7 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
1539
1551
return Nonexistent . Value ;
1540
1552
}
1541
1553
1542
- private object GetHostProperty ( PropertyInfo property , BindingFlags invokeFlags , object [ ] args )
1554
+ private object GetHostProperty ( BindSignature signature , PropertyInfo property , BindingFlags invokeFlags , object [ ] args )
1543
1555
{
1544
1556
if ( reflectionProperties . Contains ( property , MemberComparer < PropertyInfo > . Instance ) )
1545
1557
{
@@ -1569,11 +1581,46 @@ private object GetHostProperty(PropertyInfo property, BindingFlags invokeFlags,
1569
1581
throw new UnauthorizedAccessException ( "The property get method is unavailable or inaccessible" ) ;
1570
1582
}
1571
1583
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
+ {
1572
1591
return InvokeHelpers . InvokeMethod ( this , getMethod , Target . InvokeTarget , args , property . GetScriptMemberFlags ( ) ) ;
1573
1592
}
1574
1593
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
+
1575
1608
private object SetHostProperty ( string name , BindingFlags invokeFlags , object [ ] args , object [ ] bindArgs )
1576
1609
{
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
+
1577
1624
if ( name == SpecialMemberNames . Default )
1578
1625
{
1579
1626
if ( args . Length < 1 )
@@ -1586,7 +1633,7 @@ private object SetHostProperty(string name, BindingFlags invokeFlags, object[] a
1586
1633
var defaultProperty = Target . Type . GetScriptableDefaultProperty ( invokeFlags , args . Take ( args . Length - 1 ) . ToArray ( ) , bindArgs . Take ( bindArgs . Length - 1 ) . ToArray ( ) , AccessContext , DefaultAccess ) ;
1587
1634
if ( defaultProperty != null )
1588
1635
{
1589
- return SetHostProperty ( defaultProperty , args , bindArgs ) ;
1636
+ return SetHostProperty ( signature , defaultProperty , args , bindArgs ) ;
1590
1637
}
1591
1638
1592
1639
if ( args . Length < 2 )
@@ -1641,36 +1688,19 @@ private object SetHostProperty(string name, BindingFlags invokeFlags, object[] a
1641
1688
var property = Target . Type . GetScriptableProperty ( name , invokeFlags , args . Take ( args . Length - 1 ) . ToArray ( ) , bindArgs . Take ( bindArgs . Length - 1 ) . ToArray ( ) , AccessContext , DefaultAccess ) ;
1642
1689
if ( property != null )
1643
1690
{
1644
- return SetHostProperty ( property , args , bindArgs ) ;
1691
+ return SetHostProperty ( signature , property , args , bindArgs ) ;
1645
1692
}
1646
1693
1647
1694
var field = Target . Type . GetScriptableField ( name , invokeFlags , AccessContext , DefaultAccess ) ;
1648
1695
if ( field != null )
1649
1696
{
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 ) ;
1668
1698
}
1669
1699
1670
1700
throw new MissingMemberException ( MiscHelpers . FormatInvariant ( "The object has no suitable property or field named '{0}'" , name ) ) ;
1671
1701
}
1672
1702
1673
- private object SetHostProperty ( PropertyInfo property , object [ ] args , object [ ] bindArgs )
1703
+ private object SetHostProperty ( BindSignature signature , PropertyInfo property , object [ ] args , object [ ] bindArgs )
1674
1704
{
1675
1705
var scriptAccess = property . GetScriptAccess ( DefaultAccess ) ;
1676
1706
if ( scriptAccess == ScriptAccess . ReadOnly )
@@ -1684,6 +1714,13 @@ private object SetHostProperty(PropertyInfo property, object[] args, object[] bi
1684
1714
throw new UnauthorizedAccessException ( "The property set method is unavailable or inaccessible" ) ;
1685
1715
}
1686
1716
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
+ {
1687
1724
var value = args [ args . Length - 1 ] ;
1688
1725
1689
1726
var argCount = args . Length - 1 ;
@@ -1741,6 +1778,35 @@ private object SetHostProperty(PropertyInfo property, object[] args, object[] bi
1741
1778
throw new ArgumentException ( "Invalid property assignment" ) ;
1742
1779
}
1743
1780
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
+
1744
1810
private static object CreateScriptableEnumerator < T > ( IEnumerable < T > enumerable )
1745
1811
{
1746
1812
return HostObject . Wrap ( new ScriptableEnumeratorOnEnumerator < T > ( enumerable . GetEnumerator ( ) ) , typeof ( IScriptableEnumerator < T > ) ) ;
0 commit comments