diff options
| -rw-r--r-- | source/slang/slang-emit-vm.cpp | 11 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-existential.cpp | 8 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-generics.cpp | 6 | ||||
| -rw-r--r-- | tests/language-feature/types/optional-ifoo.slang | 26 |
4 files changed, 45 insertions, 6 deletions
diff --git a/source/slang/slang-emit-vm.cpp b/source/slang/slang-emit-vm.cpp index 1602fbfb8..80d3762aa 100644 --- a/source/slang/slang-emit-vm.cpp +++ b/source/slang/slang-emit-vm.cpp @@ -247,6 +247,17 @@ public: operand = addConstantValue(constantInst); mapInstToOperand[inst] = operand; } + else if (auto constantVector = as<IRMakeVector>(inst)) + { + SLANG_ASSERT(constantVector->getOperandCount() > 0); + operand = ensureInst(constantVector->getOperand(0)); + for (UInt i = 1; i < constantVector->getOperandCount(); i++) + { + ensureInst(constantVector->getOperand(i)); + } + operand.size *= (uint32_t)constantVector->getOperandCount(); + mapInstToOperand[inst] = operand; + } else { SLANG_UNEXPECTED("unsupported global inst for vm bytecode emit"); diff --git a/source/slang/slang-ir-lower-existential.cpp b/source/slang/slang-ir-lower-existential.cpp index 076ed57bd..ea7f906a9 100644 --- a/source/slang/slang-ir-lower-existential.cpp +++ b/source/slang/slang-ir-lower-existential.cpp @@ -68,13 +68,15 @@ struct ExistentialLoweringContext auto witnessTableIdType = cast<IRWitnessTableIDType>(tupleType->getOperand(1)); auto anyValueType = cast<IRAnyValueType>(tupleType->getOperand(2)); - // Create a null value for `rttiObject` for now since it will not be used. + // Create a standin value for `rttiObject` for now since it will not be used + // other than test for null in the case of `Optional<IFoo>`. auto uint2Type = builder->getVectorType( builder->getUIntType(), builder->getIntValue(builder->getIntType(), 2)); + IRInst* standinVal = builder->getIntValue(builder->getUIntType(), 0xFFFFFFFF); IRInst* zero = builder->getIntValue(builder->getUIntType(), 0); - IRInst* zeroVectorArgs[] = {zero, zero}; - IRInst* rttiObject = builder->emitMakeVector(uint2Type, 2, zeroVectorArgs); + IRInst* standinRTTIVectorArgs[] = {standinVal, zero}; + IRInst* rttiObject = builder->emitMakeVector(uint2Type, 2, standinRTTIVectorArgs); // Pack the user provided value into `AnyValue`. IRInst* packedValue = inst->getValue(); diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp index be21a66ba..8677973f5 100644 --- a/source/slang/slang-ir-lower-generics.cpp +++ b/source/slang/slang-ir-lower-generics.cpp @@ -23,11 +23,11 @@ namespace Slang { // Replace all uses of RTTI objects with its sequential ID. -// Currently we don't use RTTI objects at all, so all of them -// are 0. +// Currently we don't use RTTI objects other than check for null/invalid value, +// so all of them are 0xFFFFFFFF. void specializeRTTIObjectReferences(SharedGenericsLoweringContext* sharedContext) { - uint32_t id = 0; + uint32_t id = 0xFFFFFFFF; for (auto rtti : sharedContext->mapTypeToRTTIObject) { IRBuilder builder(sharedContext->module); diff --git a/tests/language-feature/types/optional-ifoo.slang b/tests/language-feature/types/optional-ifoo.slang new file mode 100644 index 000000000..d2c9b6a50 --- /dev/null +++ b/tests/language-feature/types/optional-ifoo.slang @@ -0,0 +1,26 @@ +//TEST:INTERPRET(filecheck=CHECK): + +interface IFoo +{ + int get_result(); +} + +struct FooImpl : IFoo +{ + int get_result() { return data; } + int data; +} + +Optional<IFoo> generate_foo(int i) +{ + FooImpl result = {}; + result.data = i; + return { result }; +} + +void main() +{ + // CHECK: hasValue: 1 + let result_foo = generate_foo(100); + printf("hasValue: %d\n", (int)result_foo.hasValue); +} |
