From 7e57cf70378025230305ee43d98b9b81f4e45d82 Mon Sep 17 00:00:00 2001 From: Dimi Racordon Date: Sat, 19 Aug 2023 20:19:05 -0400 Subject: [PATCH 1/9] Add a core umbreally trait for linear values --- Library/Hylo/Core/Linear.hylo | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Library/Hylo/Core/Linear.hylo diff --git a/Library/Hylo/Core/Linear.hylo b/Library/Hylo/Core/Linear.hylo new file mode 100644 index 000000000..7ea97adb3 --- /dev/null +++ b/Library/Hylo/Core/Linear.hylo @@ -0,0 +1,2 @@ +/// A type whose instances are movable and deinitializable. +public trait Linear: Deinitializable, Movable {} From efdc25817871d5dc17d51776534bfcc25af106c7 Mon Sep 17 00:00:00 2001 From: Dimi Racordon Date: Sat, 19 Aug 2023 20:19:37 -0400 Subject: [PATCH 2/9] Implement equality operators for 'MutableRawPointer' --- Library/Hylo/Core/MutableRawPointer.hylo | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Library/Hylo/Core/MutableRawPointer.hylo b/Library/Hylo/Core/MutableRawPointer.hylo index 91354b3ad..2e32dee57 100644 --- a/Library/Hylo/Core/MutableRawPointer.hylo +++ b/Library/Hylo/Core/MutableRawPointer.hylo @@ -15,6 +15,16 @@ public type MutableRawPointer { .new(value: Builtin.zeroinitializer_ptr()) } + /// Returns `true` if `self` is equal to `other`. Otherwise, returns `false`. + public fun infix== (_ other: Self) -> Bool { + Bool(value: Builtin.icmp_eq_ptr(value, other.value)) + } + + /// Returns `true` if `self` is not equal to `other`. Otherwise, returns `false`. + public fun infix!= (_ other: Self) -> Bool { + Bool(value: Builtin.icmp_ne_ptr(value, other.value)) + } + } public conformance MutableRawPointer: Deinitializable {} From 61649cfbbca92823df0701c214437448a1393b25 Mon Sep 17 00:00:00 2001 From: Dimi Racordon Date: Sat, 19 Aug 2023 20:20:17 -0400 Subject: [PATCH 3/9] Fix 'DynamicBuffer.capacity' --- Library/Hylo/DynamicBuffer.hylo | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Library/Hylo/DynamicBuffer.hylo b/Library/Hylo/DynamicBuffer.hylo index 353957b08..4a5613802 100644 --- a/Library/Hylo/DynamicBuffer.hylo +++ b/Library/Hylo/DynamicBuffer.hylo @@ -51,6 +51,10 @@ public type DynamicBuffer: Deinitializable { /// The number of elements that can be stored in `self`. public fun capacity() -> Int { + if storage == MutableRawPointer.null() { + return 0 + } + let p = Pointer(storage) return p.with_pointee(fun (_ h: BufferHeader) -> Int { h.0.copy() From eb1bf3fa3706e1bfae79e92a8f486804ef64679f Mon Sep 17 00:00:00 2001 From: Dimi Racordon Date: Sat, 19 Aug 2023 20:20:28 -0400 Subject: [PATCH 4/9] Improve docs --- Library/Hylo/DynamicBuffer.hylo | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Library/Hylo/DynamicBuffer.hylo b/Library/Hylo/DynamicBuffer.hylo index 4a5613802..be5b347a5 100644 --- a/Library/Hylo/DynamicBuffer.hylo +++ b/Library/Hylo/DynamicBuffer.hylo @@ -1,5 +1,9 @@ /// A buffer of elements stored in a contiguous region of memory, whose size is determined at /// instance creation. +/// +/// - Warning: The deinitializer of `DynamicBuffer` does not deinitialize the elements that may +/// be stored in its payload. You must ensure that they are propertly deinitialized before +/// `deinit` is called. public type DynamicBuffer: Deinitializable { /// The description of payloads in `DynamicBuffer`s. @@ -45,6 +49,8 @@ public type DynamicBuffer: Deinitializable { } /// Deinitializes `self`. + /// + /// - Requires: No element is stored in `self`. public fun deinit() sink { storage.deallocate() } From a69f98b456bfb51a3d5c9d5700a9a195afd9e210 Mon Sep 17 00:00:00 2001 From: Dimi Racordon Date: Sat, 19 Aug 2023 20:24:06 -0400 Subject: [PATCH 5/9] Add tests for 'Hylo.DynamicBuffer' --- .../TestCases/DynamicBufferTests.hylo | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Tests/LibraryTests/TestCases/DynamicBufferTests.hylo diff --git a/Tests/LibraryTests/TestCases/DynamicBufferTests.hylo b/Tests/LibraryTests/TestCases/DynamicBufferTests.hylo new file mode 100644 index 000000000..73b0a7809 --- /dev/null +++ b/Tests/LibraryTests/TestCases/DynamicBufferTests.hylo @@ -0,0 +1,18 @@ +//- compileAndRun expecting: success + +fun test_init_empty() { + var d = DynamicBuffer() + precondition(d.capacity() == 0) +} + +fun test_init_with_capacity() { + var d = DynamicBuffer( + capacity: 5, + initializing_header_with: fun(_ h: set Int) -> Void { &h = 0 }) + precondition(d.capacity() == 5) +} + +public fun main() { + test_init_empty() + test_init_with_capacity() +} From eb6e692ac0ed5b05c1d52ca774e41999f1c52fa4 Mon Sep 17 00:00:00 2001 From: Dimi Racordon Date: Thu, 7 Sep 2023 11:47:02 +0200 Subject: [PATCH 6/9] Track specialization of infix operators --- Sources/IR/Emitter.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Sources/IR/Emitter.swift b/Sources/IR/Emitter.swift index dad974751..d5c949aab 100644 --- a/Sources/IR/Emitter.swift +++ b/Sources/IR/Emitter.swift @@ -1260,8 +1260,13 @@ struct Emitter { let l = emit(infixOperand: lhs, passed: ParameterType(calleeType.inputs[0].type)!.access) // The callee must be a reference to member function. - guard case .member(let d, _, _) = program[callee.expr].referredDecl else { unreachable() } - let f = Operand.constant(FunctionReference(to: FunctionDecl.ID(d)!, in: &module)) + guard case .member(let d, let a, _) = program[callee.expr].referredDecl else { + unreachable() + } + + let o = FunctionReference( + to: FunctionDecl.ID(d)!, in: &module, specializedBy: a, in: insertionScope!) + let f = Operand.constant(o) // Emit the call. let site = ast.site(of: e) From 0e4d86f743af8adb993b57ee8c04dfb08f46a501 Mon Sep 17 00:00:00 2001 From: Dimi Racordon Date: Thu, 7 Sep 2023 11:47:25 +0200 Subject: [PATCH 7/9] Omit needless local binding --- Sources/IR/Analysis/Module+Depolymorphize.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/IR/Analysis/Module+Depolymorphize.swift b/Sources/IR/Analysis/Module+Depolymorphize.swift index 3dbdd7d8f..c66c331f2 100644 --- a/Sources/IR/Analysis/Module+Depolymorphize.swift +++ b/Sources/IR/Analysis/Module+Depolymorphize.swift @@ -6,8 +6,7 @@ extension Module { /// Generates the non-parametric resilient API of `self`, reading definitions from `ir`. public mutating func depolymorphize(in ir: IR.Program) { - let work = functions.keys - for k in work { + for k in functions.keys { let f = functions[k]! // Ignore declarations without definition. From 5aef85ae145e728b622fba09454345d7e905439e Mon Sep 17 00:00:00 2001 From: Dimi Racordon Date: Thu, 7 Sep 2023 11:49:08 +0200 Subject: [PATCH 8/9] Restore the initialization of dynamic buffers' headers --- Library/Hylo/DynamicBuffer.hylo | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Library/Hylo/DynamicBuffer.hylo b/Library/Hylo/DynamicBuffer.hylo index 04f9d85e6..5e90c729d 100644 --- a/Library/Hylo/DynamicBuffer.hylo +++ b/Library/Hylo/DynamicBuffer.hylo @@ -40,6 +40,12 @@ public type DynamicBuffer: Deinitializable { &storage = .allocate_bytes( count: Self.payload_offset() + capacity * MemoryLayout.stride(), aligned_at: MemoryLayout.alignment()) + + let p = PointerToMutable(type_punning: storage) + p.unsafe_initialize_pointee(fun (_ h: set BufferHeader) -> Void { + &h.0 = capacity.copy() + init_header(&h.1) + }) } /// Deinitializes `self`. From e708dfe6abc9b01cffdf8dab00cf8d31ec712c9a Mon Sep 17 00:00:00 2001 From: Dimi Racordon Date: Thu, 7 Sep 2023 15:06:56 +0200 Subject: [PATCH 9/9] Spell check --- Library/Hylo/DynamicBuffer.hylo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Hylo/DynamicBuffer.hylo b/Library/Hylo/DynamicBuffer.hylo index 5e90c729d..aec6fa54f 100644 --- a/Library/Hylo/DynamicBuffer.hylo +++ b/Library/Hylo/DynamicBuffer.hylo @@ -2,7 +2,7 @@ /// instance creation. /// /// - Warning: The deinitializer of `DynamicBuffer` does not deinitialize the elements that may -/// be stored in its payload. You must ensure that they are propertly deinitialized before +/// be stored in its payload. You must ensure that they are properly deinitialized before /// `deinit` is called. public type DynamicBuffer: Deinitializable {