Skip to content

Add intial jtl and rework runtime objects #313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 60 commits into from
Apr 28, 2025
Merged

Add intial jtl and rework runtime objects #313

merged 60 commits into from
Apr 28, 2025

Conversation

jeaye
Copy link
Member

@jeaye jeaye commented Mar 31, 2025

Part 1

We're introducing jtl, which is the start of a replacement for the C++ stdlib. This will grow to contain functionality as we remove more and more stdlib headers. The purpose of this is to optimize both our compile times and our run times. The jtl will aim to be closer to Rust than the C++ stdlib, but it's a replacement nonetheless.

  • Add jtl::ptr
  • Add jtl::ref
  • Add jtl::storage
  • Add jank_assert and jank_debug_assert
  • Add jtl::panic
  • Move option into jtl
  • Move result into jtl
  • Move native_persistent_string into jtl::immutable_string
  • Move type_name into jtl
  • Replace native_box usage for errors and analysis
    • The largest user, the runtime, still remains

Part 2

With the start of the jtl in place, we also took some steps to improve how we represent objects. Previously, we have a native_box<T> type which was a GC'd smart pointer with assertions against nullptr derefs. Now, we have jtl::ptr which does the same, but accepts nullptr as a valid state. We also have jtl::ref, which can never hold nullptr. We also have oref<T>, which is only for jank runtime objects. oref<T> cannot hold nullptr, but it can hold nil. This is analogous to the JVM's null, since derefing it can now throw an exception, rather than be UB. Juggling both nil and T in one box requires some type erasure dancing.

We also introduce sequence_range as a bridge from the Clojure sequence world into the C++ iterator world. Another benefit it adds is that we don't need to worry about next vs next_in_place anymore. We delegate all of that to sequence_range, which allows us to make next_in_place optional for some types. This solves some long-standing issues with sequence-related crashes.

Finally, the entire compiler/runtime has been updated to use jtl's fixed-width primitive types. This also follows Rust's design.

  • Add oref to deal with runtime objects
  • Replace native_box usages with oref for runtime
  • Clean up duplication in sequence equality
  • Add sequence_range and make next_in_place optional for conj and lazy_sequence -- this fixes Segmentation fault on for list comprehension at certain size #87
  • Add jank_nil, jank_true, and jank_false constants for easy use -- the C API fns have been renamed
  • Replace native_bool, native_integer, native_real, and native_hash with jtl primitives

@jeaye jeaye requested review from frenchy64 and removed request for frenchy64 March 31, 2025 20:06
@jeaye jeaye changed the title Add intial jtl Add intial jtl and rework runtime objects Apr 18, 2025
@jeaye jeaye merged commit a7a517e into main Apr 28, 2025
7 checks passed
@jeaye jeaye deleted the jtl branch April 28, 2025 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Segmentation fault on for list comprehension at certain size
1 participant