diff options
| author | Yong He <yonghe@outlook.com> | 2020-06-18 15:05:58 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-18 15:05:58 -0700 |
| commit | aa6aca498cd1f7fbbdb143e72dd48b1d714c8fbb (patch) | |
| tree | a2361c042e6a03ff957bd4a921f73efbb89dc1b7 /source/slang/slang-ir-lower-generics.cpp | |
| parent | 5952e3b3d7f505a7e6d71ecd0793911224f5bac3 (diff) | |
| parent | 82ba914db9c3823ad7a0834d46b7fccedfe0acee (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.cpp | 31 |
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); |
