summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-emit-vm.cpp11
-rw-r--r--source/slang/slang-ir-lower-existential.cpp8
-rw-r--r--source/slang/slang-ir-lower-generics.cpp6
-rw-r--r--tests/language-feature/types/optional-ifoo.slang26
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);
+}