summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-lower-generics.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2020-06-18 15:05:58 -0700
committerGitHub <noreply@github.com>2020-06-18 15:05:58 -0700
commitaa6aca498cd1f7fbbdb143e72dd48b1d714c8fbb (patch)
treea2361c042e6a03ff957bd4a921f73efbb89dc1b7 /source/slang/slang-ir-lower-generics.cpp
parent5952e3b3d7f505a7e6d71ecd0793911224f5bac3 (diff)
parent82ba914db9c3823ad7a0834d46b7fccedfe0acee (diff)
Merge pull request #1400 from csyonghe/dyndispatch
Dynamic dispatch non-static functions.
Diffstat (limited to 'source/slang/slang-ir-lower-generics.cpp')
-rw-r--r--source/slang/slang-ir-lower-generics.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp
index 4378d396f..f6340a633 100644
--- a/source/slang/slang-ir-lower-generics.cpp
+++ b/source/slang/slang-ir-lower-generics.cpp
@@ -79,6 +79,14 @@ namespace Slang
block->addParam(as<IRParam>(param));
}
loweredGenericFunctions[genericValue] = loweredFunc;
+ // Turn generic parameters into void pointers.
+ for (auto param : cast<IRFunc>(loweredFunc)->getParams())
+ {
+ if (param->findDecoration<IRPolymorphicDecoration>())
+ {
+ param->setFullType(builder.getPtrType(builder.getVoidType()));
+ }
+ }
addToWorkList(loweredFunc);
return loweredFunc;
}
@@ -103,8 +111,29 @@ namespace Slang
builder->sharedBuilder = &sharedBuilderStorage;
builder->setInsertBefore(inst);
List<IRInst*> args;
+ auto pp = as<IRFunc>(loweredFunc)->getParams().begin();
+ auto voidPtrType = builder->getPtrType(builder->getVoidType());
for (UInt i = 0; i < callInst->getArgCount(); i++)
- args.add(callInst->getArg(i));
+ {
+ auto arg = callInst->getArg(i);
+ if ((*pp)->getDataType() == voidPtrType &&
+ arg->getDataType() != voidPtrType)
+ {
+ // We are calling a generic function that with an argument of
+ // concrete type. We need to convert this argument o void*.
+
+ // Ideally this should just be a GetElementAddress inst.
+ // However the current code emitting logic for this instruction
+ // doesn't truly respect the pointerness and does not produce
+ // what we needed. For now we use another instruction here
+ // to keep changes minimal.
+ arg = builder->emitGetAddress(
+ voidPtrType,
+ arg);
+ }
+ args.add(arg);
+ ++pp;
+ }
for (UInt i = 0; i < specializeInst->getArgCount(); i++)
args.add(specializeInst->getArg(i));
auto newCall = builder->emitCallInst(callInst->getFullType(), loweredFunc, args);