fixed list iterator destoying list
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 17 Apr 2021 22:27:13 +0000 (17:27 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 17 Apr 2021 22:27:13 +0000 (17:27 -0500)
core/list.onyx
src/onyxwasm.c

index 81c14727832d1bf697624bb5c3510fdd7616c9f2..d4bd0658e3daf8691fbe07544ae23255e9aae0a8 100644 (file)
@@ -72,20 +72,31 @@ contains :: (list: ^List($T), x: T) -> bool {
 }
 
 get_iterator :: (list: ^List($T)) -> Iterator(T) {
-    iterator_impl :: ($T: type_expr, data: rawptr) -> (T, bool) {
-        elem_ptr := cast(^^ListElem(T)) data;
-        elem := *elem_ptr;
+    iterator_next :: ($T: type_expr, data: rawptr) -> (T, bool) {
+        list_iter := cast(^ListIterator(T)) data;
 
         use package core.intrinsics.onyx { __zero_value }
-        if elem == null do return __zero_value(T), false;
+        if list_iter.current == null do return __zero_value(T), false;
 
-        *elem_ptr = elem.next;
-        return elem.data, true;
+        defer list_iter.current = list_iter.current.next;
+        return list_iter.current.data, true;
     }
 
+    iterator_close :: (data: rawptr) {
+        cfree(data);
+    }
+
+    ListIterator :: struct (T: type_expr) {
+        current: ^ListElem(T);
+    }
+
+    list_iterator := new(#type ListIterator(T));
+    list_iterator.current = list.first;
+
     return .{
-        data = ^list.first,
-        next = #solidify iterator_impl { T = T },
+        data = list_iterator,
+        next = #solidify iterator_next { T = T },
+        close = iterator_close,
     };
 }
 
index 582f6aede452de770b2e9b83d018feb7362bdc7a..0975b55a2362c3e721724579acbab897522523f9 100644 (file)
@@ -6,9 +6,8 @@
 //      by the WASM outputter.
 //  [x] remove the need to have "allocate_exprs" on blocks and in functions. This will
 //      be easy once the above is done.
-//  [ ] there should be a better way to emit pending deferred statements because there
+//  [x] there should be a better way to emit pending deferred statements because there
 //      is some code duplication between emit_return and emit_structured_jump.
-//
 //  [ ] Change the calling convention so it is easier to use from both JS and in the compiler.