@@ -438,7 +438,6 @@ public override bool VisitClassDecl(Class @class)
438
438
var dict = $@ "global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, {
439
439
printedClass } >" ;
440
440
WriteLine ( "internal static readonly {0} NativeToManagedMap = new {0}();" , dict ) ;
441
- WriteLine ( "protected internal void*[] __OriginalVTables;" ) ;
442
441
}
443
442
PopBlock ( NewLineKind . BeforeNextBlock ) ;
444
443
}
@@ -1521,6 +1520,11 @@ public void GenerateVTable(Class @class)
1521
1520
if ( wrappedEntries . Any ( e => e . Method . IsDestructor ) )
1522
1521
WriteLine ( "private static void*[] __ManagedVTablesDtorOnly;" ) ;
1523
1522
WriteLine ( "private static void*[] _Thunks;" ) ;
1523
+ WriteLine ( "private static void*[] __originalVTables;" ) ;
1524
+ bool hasDynamicBase = @class . NeedsBase && @class . BaseClass . IsDynamic ;
1525
+ Write ( $@ "protected internal { ( hasDynamicBase ? "override" : "virtual"
1526
+ ) } void*[] __OriginalVTables => __originalVTables ?? " ) ;
1527
+ SaveOriginalVTablePointers ( @class ) ;
1524
1528
NewLine ( ) ;
1525
1529
1526
1530
GenerateVTableClassSetup ( @class , wrappedEntries ) ;
@@ -1535,21 +1539,13 @@ private void GenerateVTableClassSetup(Class @class, IList<VTableComponent> wrapp
1535
1539
WriteLine ( "private void SetupVTables(bool {0} = false)" , destructorOnly ) ;
1536
1540
WriteOpenBraceAndIndent ( ) ;
1537
1541
1538
- WriteLine ( "if (__OriginalVTables != null)" ) ;
1539
- WriteLineIndent ( "return;" ) ;
1540
-
1541
- SaveOriginalVTablePointers ( @class ) ;
1542
-
1543
- NewLine ( ) ;
1544
-
1545
1542
var hasVirtualDtor = wrappedEntries . Any ( e => e . Method . IsDestructor ) ;
1546
1543
if ( ! hasVirtualDtor )
1547
1544
{
1548
1545
WriteLine ( "if ({0})" , destructorOnly ) ;
1549
1546
WriteLineIndent ( "return;" ) ;
1550
1547
}
1551
1548
1552
- // Get the _Thunks
1553
1549
WriteLine ( "if (_Thunks == null)" ) ;
1554
1550
WriteOpenBraceAndIndent ( ) ;
1555
1551
WriteLine ( "_Thunks = new void*[{0}];" , wrappedEntries . Count ) ;
@@ -1567,30 +1563,34 @@ private void GenerateVTableClassSetup(Class @class, IList<VTableComponent> wrapp
1567
1563
WriteLine ( "_Thunks[{0}] = Marshal.GetFunctionPointerForDelegate({1}).ToPointer();" ,
1568
1564
i , instance ) ;
1569
1565
}
1570
- UnindentAndWriteCloseBrace ( ) ;
1571
1566
1572
1567
NewLine ( ) ;
1573
1568
1574
1569
if ( hasVirtualDtor )
1575
- {
1576
- WriteLine ( "if ({0})" , destructorOnly ) ;
1577
- WriteOpenBraceAndIndent ( ) ;
1578
- WriteLine ( "if (__ManagedVTablesDtorOnly == null)" ) ;
1579
- WriteOpenBraceAndIndent ( ) ;
1570
+ AllocateNewVTables ( @class , wrappedEntries , destructorOnly : true ) ;
1580
1571
1581
- AllocateNewVTables ( @class , wrappedEntries , true ) ;
1572
+ AllocateNewVTables ( @class , wrappedEntries , destructorOnly : false ) ;
1582
1573
1574
+ Write ( "__originalVTables = " ) ;
1575
+ SaveOriginalVTablePointers ( @class ) ;
1576
+ UnindentAndWriteCloseBrace ( ) ;
1577
+
1578
+ NewLine ( ) ;
1579
+ if ( hasVirtualDtor )
1580
+ {
1581
+ WriteLine ( $ "if ({ destructorOnly } )") ;
1582
+ WriteOpenBraceAndIndent ( ) ;
1583
+ AssignNewVTableEntries ( @class , "__ManagedVTablesDtorOnly" ) ;
1583
1584
UnindentAndWriteCloseBrace ( ) ;
1584
1585
WriteLine ( "else" ) ;
1585
1586
WriteOpenBraceAndIndent ( ) ;
1586
- }
1587
- WriteLine ( "if (__ManagedVTables == null)" ) ;
1588
- WriteOpenBraceAndIndent ( ) ;
1589
-
1590
- AllocateNewVTables ( @class , wrappedEntries , false ) ;
1591
-
1592
- if ( hasVirtualDtor )
1587
+ AssignNewVTableEntries ( @class , "__ManagedVTables" ) ;
1593
1588
UnindentAndWriteCloseBrace ( ) ;
1589
+ }
1590
+ else
1591
+ {
1592
+ AssignNewVTableEntries ( @class , "__ManagedVTables" ) ;
1593
+ }
1594
1594
1595
1595
UnindentAndWriteCloseBrace ( ) ;
1596
1596
NewLine ( ) ;
@@ -1603,73 +1603,76 @@ private void AllocateNewVTables(Class @class, IList<VTableComponent> wrappedEntr
1603
1603
AllocateNewVTablesMS ( @class , wrappedEntries , destructorOnly ) ;
1604
1604
else
1605
1605
AllocateNewVTablesItanium ( @class , wrappedEntries , destructorOnly ) ;
1606
+
1607
+ NewLine ( ) ;
1608
+ }
1609
+
1610
+ private void AssignNewVTableEntries ( Class @class , string table )
1611
+ {
1612
+ int size = Context . ParserOptions . IsMicrosoftAbi ?
1613
+ @class . Layout . VTablePointers . Count : 1 ;
1614
+
1615
+ for ( int i = 0 ; i < size ; i ++ )
1616
+ {
1617
+ var offset = @class . Layout . VTablePointers [ i ] . Offset ;
1618
+ WriteLine ( $ "*(void**) ({ Helpers . InstanceIdentifier } + { offset } ) = { table } [{ i } ];") ;
1619
+ }
1606
1620
}
1607
1621
1608
1622
private void SaveOriginalVTablePointers ( Class @class )
1609
1623
{
1610
1624
if ( @class . IsDependent )
1611
1625
@class = @class . Specializations [ 0 ] ;
1612
1626
1627
+ Write ( "new void*[] { " ) ;
1628
+
1613
1629
if ( Context . ParserOptions . IsMicrosoftAbi )
1614
- WriteLine ( "__OriginalVTables = new void*[] {{ {0} }};" ,
1615
- string . Join ( ", " ,
1616
- @class . Layout . VTablePointers . Select ( v =>
1617
- $ "*(void**) ({ Helpers . InstanceIdentifier } + { v . Offset } )") ) ) ;
1630
+ Write ( string . Join ( ", " , @class . Layout . VTablePointers . Select (
1631
+ v => $ "*(void**) ({ Helpers . InstanceIdentifier } + { v . Offset } )") ) ) ;
1618
1632
else
1619
- WriteLine (
1620
- $@ "__OriginalVTables = new void*[] {{ *(void**) ({
1621
- Helpers . InstanceIdentifier } + { @class . Layout . VTablePointers [ 0 ] . Offset } ) }};" ) ;
1633
+ Write ( $@ "*(void**) ({ Helpers . InstanceIdentifier } + {
1634
+ @class . Layout . VTablePointers [ 0 ] . Offset } )" ) ;
1635
+
1636
+ WriteLine ( " };" ) ;
1622
1637
}
1623
1638
1624
1639
private void AllocateNewVTablesMS ( Class @class , IList < VTableComponent > wrappedEntries ,
1625
1640
bool destructorOnly )
1626
1641
{
1627
1642
var managedVTables = destructorOnly ? "__ManagedVTablesDtorOnly" : "__ManagedVTables" ;
1628
- WriteLine ( "{0 } = new void*[{1}];" , managedVTables , @class . Layout . VFTables . Count ) ;
1643
+ WriteLine ( $ " { managedVTables } = new void*[{ @class . Layout . VFTables . Count } ];" ) ;
1629
1644
1630
1645
for ( int i = 0 ; i < @class . Layout . VFTables . Count ; i ++ )
1631
1646
{
1632
- var vfptr = @class . Layout . VFTables [ i ] ;
1633
- var size = vfptr . Layout . Components . Count ;
1634
- WriteLine ( "var vfptr{0} = Marshal.AllocHGlobal({1} * {2});" ,
1635
- i , size , Context . TargetInfo . PointerWidth / 8 ) ;
1636
- WriteLine ( "{0}[{1}] = vfptr{1}.ToPointer();" , managedVTables , i ) ;
1647
+ VFTableInfo vftable = @class . Layout . VFTables [ i ] ;
1648
+ int size = vftable . Layout . Components . Count ;
1649
+ string vfptr = $ "vfptr{ ( destructorOnly ? "_dtor" : string . Empty ) } { i } ";
1650
+ WriteLine ( $@ "var { vfptr } = Marshal.AllocHGlobal({ size } * {
1651
+ Context . TargetInfo . PointerWidth / 8 } );" ) ;
1652
+ WriteLine ( $ "{ managedVTables } [{ i } ] = { vfptr } .ToPointer();") ;
1637
1653
1638
- AllocateNewVTableEntries ( vfptr . Layout . Components , wrappedEntries ,
1654
+ AllocateNewVTableEntries ( vftable . Layout . Components , wrappedEntries ,
1639
1655
@class . Layout . VTablePointers [ i ] . Offset , i , destructorOnly ) ;
1640
1656
}
1641
-
1642
- UnindentAndWriteCloseBrace ( ) ;
1643
- NewLine ( ) ;
1644
-
1645
- for ( int i = 0 ; i < @class . Layout . VTablePointers . Count ; i ++ )
1646
- {
1647
- var offset = @class . Layout . VTablePointers [ i ] . Offset ;
1648
- WriteLine ( $ "*(void**) ({ Helpers . InstanceIdentifier } + { offset } ) = { managedVTables } [{ i } ];") ;
1649
- }
1650
1657
}
1651
1658
1652
1659
private void AllocateNewVTablesItanium ( Class @class , IList < VTableComponent > wrappedEntries ,
1653
1660
bool destructorOnly )
1654
1661
{
1655
1662
var managedVTables = destructorOnly ? "__ManagedVTablesDtorOnly" : "__ManagedVTables" ;
1656
- WriteLine ( "{0 } = new void*[1];", managedVTables ) ;
1663
+ WriteLine ( $ " { managedVTables } = new void*[1];") ;
1657
1664
1658
- var size = @class . Layout . Layout . Components . Count ;
1659
- var pointerSize = Context . TargetInfo . PointerWidth / 8 ;
1660
- WriteLine ( "var vtptr = Marshal.AllocHGlobal({0} * {1});" , size , pointerSize ) ;
1665
+ string suffix = destructorOnly ? "_dtor" : string . Empty ;
1666
+ int size = @class . Layout . Layout . Components . Count ;
1667
+ uint pointerSize = Context . TargetInfo . PointerWidth / 8 ;
1668
+ WriteLine ( $ "var vtptr{ suffix } = Marshal.AllocHGlobal({ size } * { pointerSize } );") ;
1661
1669
1662
- WriteLine ( "var vfptr0 = vtptr + {0} * {1};" , VTables . ItaniumOffsetToTopAndRTTI , pointerSize ) ;
1663
- WriteLine ( "{0}[0] = vfptr0.ToPointer();" , managedVTables ) ;
1670
+ WriteLine ( $@ "var vfptr{ suffix } 0 = vtptr{ suffix } + {
1671
+ VTables . ItaniumOffsetToTopAndRTTI } * { pointerSize } ;" ) ;
1672
+ WriteLine ( $ "{ managedVTables } [0] = vfptr{ suffix } 0.ToPointer();") ;
1664
1673
1665
1674
AllocateNewVTableEntries ( @class . Layout . Layout . Components ,
1666
1675
wrappedEntries , @class . Layout . VTablePointers [ 0 ] . Offset , 0 , destructorOnly ) ;
1667
-
1668
- UnindentAndWriteCloseBrace ( ) ;
1669
- NewLine ( ) ;
1670
-
1671
- var offset = @class . Layout . VTablePointers [ 0 ] . Offset ;
1672
- WriteLine ( $ "*(void**) ({ Helpers . InstanceIdentifier } + { offset } ) = { managedVTables } [0];") ;
1673
1676
}
1674
1677
1675
1678
private void AllocateNewVTableEntries ( IList < VTableComponent > entries ,
@@ -1684,7 +1687,8 @@ private void AllocateNewVTableEntries(IList<VTableComponent> entries,
1684
1687
1685
1688
var nativeVftableEntry = $@ "*(void**) (new IntPtr(*(void**) {
1686
1689
Helpers . InstanceIdentifier } ) + { vptrOffset } + { offset } )" ;
1687
- var managedVftableEntry = $ "*(void**) (vfptr{ tableIndex } + { offset } )";
1690
+ string vfptr = $ "vfptr{ ( destructorOnly ? "_dtor" : string . Empty ) } { tableIndex } ";
1691
+ var managedVftableEntry = $ "*(void**) ({ vfptr } + { offset } )";
1688
1692
1689
1693
if ( ( entry . Kind == VTableComponentKind . FunctionPointer ||
1690
1694
entry . Kind == VTableComponentKind . DeletingDtorPointer ) &&
@@ -2207,17 +2211,7 @@ private void GenerateNativeConstructor(Class @class)
2207
2211
var setupVTables = ! @class . IsAbstractImpl && hasVTables && dtor ? . IsVirtual == true ;
2208
2212
if ( setupVTables )
2209
2213
{
2210
- WriteLine ( "if (skipVTables)" ) ;
2211
- Indent ( ) ;
2212
- }
2213
-
2214
- if ( @class . IsAbstractImpl || hasVTables )
2215
- SaveOriginalVTablePointers ( @class ) ;
2216
-
2217
- if ( setupVTables )
2218
- {
2219
- Unindent ( ) ;
2220
- WriteLine ( "else" ) ;
2214
+ WriteLine ( "if (!skipVTables)" ) ;
2221
2215
Indent ( ) ;
2222
2216
GenerateVTableClassSetupCall ( @class , destructorOnly : true ) ;
2223
2217
Unindent ( ) ;
0 commit comments