@@ -1446,6 +1446,24 @@ UnownedStringSlice CPPSourceEmitter::_getFuncName(const HLSLIntrinsic* specOp)
1446
1446
return m_slicePool.getSlice (handle);
1447
1447
}
1448
1448
1449
+ UnownedStringSlice CPPSourceEmitter::_getWitnessTableWrapperFuncName (IRFunc* func)
1450
+ {
1451
+ StringSlicePool::Handle handle = StringSlicePool::kNullHandle ;
1452
+ if (m_witnessTableWrapperFuncNameMap.TryGetValue (func, handle))
1453
+ {
1454
+ return m_slicePool.getSlice (handle);
1455
+ }
1456
+
1457
+ StringBuilder builder;
1458
+ builder << getName (func) << " _wtwrapper" ;
1459
+
1460
+ handle = m_slicePool.add (builder);
1461
+ m_witnessTableWrapperFuncNameMap.Add (func, handle);
1462
+
1463
+ SLANG_ASSERT (handle != StringSlicePool::kNullHandle );
1464
+ return m_slicePool.getSlice (handle);
1465
+ }
1466
+
1449
1467
SlangResult CPPSourceEmitter::calcFuncName (const HLSLIntrinsic* specOp, StringBuilder& outBuilder)
1450
1468
{
1451
1469
typedef HLSLIntrinsic::Op Op;
@@ -1591,6 +1609,83 @@ void CPPSourceEmitter::emitWitnessTable(IRWitnessTable* witnessTable)
1591
1609
pendingWitnessTableDefinitions.add (witnessTable);
1592
1610
}
1593
1611
1612
+ void CPPSourceEmitter::_emitWitnessTableWrappers ()
1613
+ {
1614
+ for (auto witnessTable : pendingWitnessTableDefinitions)
1615
+ {
1616
+ for (auto child : witnessTable->getChildren ())
1617
+ {
1618
+ if (auto entry = as<IRWitnessTableEntry>(child))
1619
+ {
1620
+ if (auto funcVal = as<IRFunc>(entry->getSatisfyingVal ()))
1621
+ {
1622
+ emitType (funcVal->getResultType ());
1623
+ m_writer->emit (" " );
1624
+ m_writer->emit (_getWitnessTableWrapperFuncName (funcVal));
1625
+ m_writer->emit (" (" );
1626
+ // Emit parameter list.
1627
+ {
1628
+ bool isFirst = true ;
1629
+ for (auto param : funcVal->getParams ())
1630
+ {
1631
+ if (as<IRTypeType>(param->getFullType ()))
1632
+ continue ;
1633
+
1634
+ if (isFirst)
1635
+ isFirst = false ;
1636
+ else
1637
+ m_writer->emit (" ," );
1638
+
1639
+ if (param->findDecoration <IRThisPointerDecoration>())
1640
+ {
1641
+ m_writer->emit (" void* " );
1642
+ m_writer->emit (getName (param));
1643
+ continue ;
1644
+ }
1645
+ emitSimpleFuncParamImpl (param);
1646
+ }
1647
+ }
1648
+ m_writer->emit (" )\n {\n " );
1649
+ m_writer->indent ();
1650
+ m_writer->emit (" return " );
1651
+ m_writer->emit (getName (funcVal));
1652
+ m_writer->emit (" (" );
1653
+ // Emit argument list.
1654
+ {
1655
+ bool isFirst = true ;
1656
+ for (auto param : funcVal->getParams ())
1657
+ {
1658
+ if (as<IRTypeType>(param->getFullType ()))
1659
+ continue ;
1660
+
1661
+ if (isFirst)
1662
+ isFirst = false ;
1663
+ else
1664
+ m_writer->emit (" , " );
1665
+
1666
+ if (param->findDecoration <IRThisPointerDecoration>())
1667
+ {
1668
+ m_writer->emit (" *static_cast<" );
1669
+ emitType (param->getFullType ());
1670
+ m_writer->emit (" *>(" );
1671
+ m_writer->emit (getName (param));
1672
+ m_writer->emit (" )" );
1673
+ }
1674
+ else
1675
+ {
1676
+ m_writer->emit (getName (param));
1677
+ }
1678
+ }
1679
+ }
1680
+ m_writer->emit (" );\n " );
1681
+ m_writer->dedent ();
1682
+ m_writer->emit (" }\n " );
1683
+ }
1684
+ }
1685
+ }
1686
+ }
1687
+ }
1688
+
1594
1689
void CPPSourceEmitter::_emitWitnessTableDefinitions ()
1595
1690
{
1596
1691
for (auto witnessTable : pendingWitnessTableDefinitions)
@@ -1612,8 +1707,9 @@ void CPPSourceEmitter::_emitWitnessTableDefinitions()
1612
1707
m_writer->emit (" ,\n " );
1613
1708
else
1614
1709
isFirstEntry = false ;
1710
+
1615
1711
m_writer->emit (" &KernelContext::" );
1616
- m_writer->emit (getName (funcVal));
1712
+ m_writer->emit (_getWitnessTableWrapperFuncName (funcVal));
1617
1713
}
1618
1714
else
1619
1715
{
@@ -1671,7 +1767,13 @@ void CPPSourceEmitter::_maybeEmitWitnessTableTypeDefinition(
1671
1767
m_writer->emit (" , " );
1672
1768
else
1673
1769
isFirstParam = false ;
1674
- emitParamType (param->getFullType (), getName (param));
1770
+ if (param->findDecoration <IRThisPointerDecoration>())
1771
+ {
1772
+ m_writer->emit (" void* " );
1773
+ m_writer->emit (getName (param));
1774
+ continue ;
1775
+ }
1776
+ emitSimpleFuncParamImpl (param);
1675
1777
}
1676
1778
m_writer->emit (" );\n " );
1677
1779
}
@@ -1681,7 +1783,7 @@ void CPPSourceEmitter::_maybeEmitWitnessTableTypeDefinition(
1681
1783
}
1682
1784
}
1683
1785
m_writer->dedent ();
1684
- m_writer->emit (" \n };\n " );
1786
+ m_writer->emit (" };\n " );
1685
1787
}
1686
1788
1687
1789
bool CPPSourceEmitter::tryEmitGlobalParamImpl (IRGlobalParam* varDecl, IRType* varType)
@@ -1877,6 +1979,31 @@ void CPPSourceEmitter::emitSimpleValueImpl(IRInst* inst)
1877
1979
}
1878
1980
}
1879
1981
1982
+ static bool isVoidPtrType (IRType* type)
1983
+ {
1984
+ auto ptrType = as<IRPtrType>(type);
1985
+ if (!ptrType) return false ;
1986
+ return ptrType->getValueType ()->op == kIROp_VoidType ;
1987
+ }
1988
+
1989
+ void CPPSourceEmitter::emitSimpleFuncParamImpl (IRParam* param)
1990
+ {
1991
+ // Polymorphic types are already translated to void* type in
1992
+ // lower-generics pass. However, the current emitting logic will
1993
+ // emit "void&" instead of "void*" for pointer types.
1994
+ // In the future, we will handle pointer types more properly,
1995
+ // and this override logic will not be necessary.
1996
+ // For now we special-case this scenario.
1997
+ if (param->findDecoration <IRPolymorphicDecoration>() &&
1998
+ isVoidPtrType (param->getDataType ()))
1999
+ {
2000
+ m_writer->emit (" void* " );
2001
+ m_writer->emit (getName (param));
2002
+ return ;
2003
+ }
2004
+ CLikeSourceEmitter::emitSimpleFuncParamImpl (param);
2005
+ }
2006
+
1880
2007
void CPPSourceEmitter::emitVectorTypeNameImpl (IRType* elementType, IRIntegerValue elementCount)
1881
2008
{
1882
2009
emitSimpleType (m_typeSet.addVectorType (elementType, int (elementCount)));
@@ -2102,6 +2229,16 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
2102
2229
m_writer->emit (" )" );
2103
2230
return true ;
2104
2231
}
2232
+ case kIROp_getAddr :
2233
+ {
2234
+ // Once we clean up the pointer emitting logic, we can
2235
+ // just use GetElementAddress instruction in place of
2236
+ // getAddr instruction, and this case can be removed.
2237
+ m_writer->emit (" (&(" );
2238
+ emitInstExpr (inst->getOperand (0 ), EmitOpInfo::get (EmitOp::General));
2239
+ m_writer->emit (" ))" );
2240
+ return true ;
2241
+ }
2105
2242
}
2106
2243
}
2107
2244
@@ -2670,6 +2807,11 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module)
2670
2807
}
2671
2808
}
2672
2809
2810
+ // Emit wrapper functions for each witness table entry.
2811
+ // These wrapper functions takes an abstract type parameter (void*)
2812
+ // in the place of `this` parameter.
2813
+ _emitWitnessTableWrappers ();
2814
+
2673
2815
m_writer->dedent ();
2674
2816
m_writer->emit (" };\n\n " );
2675
2817
}
0 commit comments