Add some test cases and asserts for new pretty printing - we were not
properly handing the case when print formatter was not at the start of
the buffer.
A simple fix is to add a lookback_barrier, which is an index into the
buffer that backtracking print formatter can't go past. This ensures
that, whatever newlines are replace with spaces, we don't mess with any
explicit newlines that should be printed.
Also some tweaks to logic to try an make invariants more obvious and
simplify looping and indexing.
kqueue-based filewatch is more limited than inotify, but is still
useful in many cases. Notably absent is any ability to monitor
directories automatically without wasting a lot of file descriptors.
Prevent redefining bindings by accident. There are
a few cases where we want to allow this, such as the `default` macro, so
we allow a keyword :shadow to be included in the `def` expression to
turn off this lint.
TODO:
* Clean up test suite to remove binding shadowing
* Make sure that we don't get lints with *redef* turned on
* Add positive and negative tests for lint messages.
* Add location of shadowed binding in message
Indentation levels are not sufficiently clear for deeply nested
data structures. Instead, align items in a collection
with its opening bracket, also known as hanging indentation.
To avoid guessing the length of a "short" collection to print it
on one line, items are now always printed on separate lines.
Still fallback to blocking connect with WSAConnect when ConnectEx is not
available or applicable, but ConnectEx is preferred and recommended by
Microsoft.
Also make some changes to our use of OVERLAPPED in various places in the
ev code, replacing all uses with JanetOverlapped. This also let's us
avoid reusing internal fields for OVERLAPPED which may or may not be
used in various places.
For unclosable files, no need to dup, but for closable files we can get
a resource leak. Valgrind and similar tools won't catch this but IO will
unexpectedly start going to the wrong descriptor if a file was
transferred to a new thread, closed, and then a new file was created.
janet_collect() marks janet_vm.root_fiber but not janet_vm.fiber.
When janet_pcall (or janet_continue) is called from a C function,
the inner fiber becomes janet_vm.fiber while root_fiber still points
to the outer fiber. If GC triggers inside the inner fiber's execution,
the inner fiber is not in any GC root set and can be collected —
including its stack memory — while actively running.
This also affects deeply nested cases: F1 -> C func -> janet_pcall ->
F2 -> C func -> janet_pcall -> F3, where F2 is saved only in a C
stack local (tstate.vm_fiber), invisible to GC.
Fix: in janet_continue_no_check, root the fiber with janet_gcroot
when this is a nested call (root_fiber already set). Each nesting
level roots its own fiber, handling arbitrary depth. Top-level calls
(event loop, REPL) skip the root/unroot entirely since root_fiber
is NULL.
Add test/test-gc-pcall.c: standalone C test covering both single
and deep nesting cases.
Co-authored-by: Brett Adams <brett@bletia-9.local>
Macro expansion as done by `macex1` was incorrectly losing the semantic
tuple information inside the `set` form. Since macro expansion is
usually done by the compiler, and `macex1` is mainly used for debugging
and deep transformations inside other macros, this only surfaced with
certain usage of short-fn macro.
The buffer overflow happened because we were creating many upvalue
slots in the compiler without using them, along with some faulty logic
that used the wrong length to check for the bitmap's bounds.
This does create a lot of warnings, especially in the test suite, but
should improve code and point out real issues.
To disable individual messages, either disable linting, add the metadata :unused to a
binding, or add the prefix "_" to a symbol.
An optimization to ellude creation of intermediate tuples was
erroneously flagging a splice as invalid, even though it was valid.
Instead, if we see splice on the rhs, bail out of the optimization.