diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp index 6cdecc8d..22b95809 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp @@ -243,6 +243,7 @@ void OGTupleWithBuffer(OGTupleType tuple_type, size_t count, const void (* funct if (buffer_size <= 0x1000) { char buffer[buffer_size]; bzero(buffer, buffer_size); + tuple.value = buffer; // NOTE: If you use buffer out of the scope, the stack may be malformed. // So we need to call function in this scope. function(tuple, context); diff --git a/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeCompatibilityTests.swift b/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeCompatibilityTests.swift index 838d0707..ad81905c 100644 --- a/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeCompatibilityTests.swift +++ b/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeCompatibilityTests.swift @@ -151,7 +151,8 @@ struct UnsafeMutableTupleCompatibilityTests { } @Test - func buffer() { + func stackBuffer() { + // size <= 0x1000 withUnsafeTuple(of: TupleType([T1.self, T2.self]), count: 1) { mutableTuple in let ref = T1() ref.a = 1 @@ -162,6 +163,26 @@ struct UnsafeMutableTupleCompatibilityTests { let t1 = tuple[0] as T1 let t2 = tuple[1] as T2 + #expect(t1 === ref) + #expect(t1.a == 1) + #expect(t2.a == 2) + } + + } + + @Test + func heapBuffer() { + // size > 0x1000 + withUnsafeTuple(of: TupleType([T1.self, T2.self]), count: 512) { mutableTuple in + let ref = T1() + ref.a = 1 + mutableTuple.initialize(at: 0, to: ref) + mutableTuple.initialize(at: 1, to: T2(a: 2)) + + let tuple = UnsafeTuple(type: mutableTuple.type, value: mutableTuple.value) + let t1 = tuple[0] as T1 + let t2 = tuple[1] as T2 + #expect(t1 === ref) #expect(t1.a == 1) #expect(t2.a == 2)