Skip to content

Document tsbindgen in the README - #397

Merged
ASDAlexander77 merged 1 commit into
mainfrom
readme-tsbindgen
Sep 28, 2026
Merged

ASDAlexander77 merged 1 commit into
mainfrom
readme-tsbindgen

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Adds a C bindings with tsbindgen section to the README:

  • the command line and its options, with a simple.c example and its output, and how to include the result (/// <reference path>, named .ts not .d.ts)
  • why nothing can be emitted: declarations from #included headers need --filter; static functions and non-literal macros are skipped
  • extern int f(); is "function without a prototype" before C23 — write (void) or pass -- -std=c23
  • C++ headers: a .h needs -- -x c++; only plain structs, enums and extern "C" functions are emitted, classes / namespace members / C++-linkage functions are dropped without a warning

Every output shown was produced by the current build.

Also adds tslang/tsbindgen to tslang.code-workspace.

🤖 Generated with Claude Code

How to run it, and why it can emit nothing: included declarations
need --filter, static functions and non-literal macros are skipped,
`()` has no prototype before C23, and a C++ header named .h needs
`-- -x c++` (only structs, enums and extern "C" functions are kept).

Adds tsbindgen to the VS Code workspace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit 6cb9eec into main Sep 28, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the readme-tsbindgen branch September 28, 2026 22:24
ASDAlexander77 added a commit that referenced this pull request Sep 28, 2026
Every positive and negative program was dumped under -mm=rc on #397 and the
plan now states what each produces: make() returns +1 with no retain on
either side; a throw out of a try-less function leaks its local in rc too;
the alias test needs `let` (a folded const emits no retain); the unknown
producer is a declared function (.slice needs the default library). Also
the verified call-op names, the --di-only variable name, number-typed
accumulators, and the isHandOver move spelled out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ASDAlexander77 added a commit that referenced this pull request Sep 29, 2026
…ing (#399)

* Design spec for -mm=own, a single-owner memory model

A fourth memory model beside gc, rc and none: ownership inferred at compile
time over the ownership ops MLIRGen already emits, moves and borrows instead
of counts, and a compile error where neither can be proven.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Satisfy markdownlint in the own-model spec

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Written review of the -mm=own spec against main at #397

Six amendments in a new section 10: a lowering error does not fail the
compile today (prerequisite for every model); the phase-0 gate is a pass,
not the lowering; the default library is refused under own; the header
word keeps its store on native targets; expected-error tests reuse the
call-arity ctest pattern; and almost every retain is a birth reference,
so a gate rejecting every retain compiles only heap-free programs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Plan for -mm=own phase 0, with the birth take

Phase 0 accepts a fresh value's single acquisition - rc's count provably
never above one - as a move, and reports every other retain. Seven tasks:
the lowering-error prerequisite (PR #398), the model and flag, the
isRefCounted() audit site by site, destroy-shaped lowering with a retain
backstop, the inference pass, positive/negative/no-counting tests, and a
rebuilt measuring script.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Check every phase-0 test program against rc affine IR

Every positive and negative program was dumped under -mm=rc on #397 and the
plan now states what each produces: make() returns +1 with no retain on
either side; a throw out of a try-less function leaks its local in rc too;
the alias test needs `let` (a folded const emits no retain); the unknown
producer is a declared function (.slice needs the default library). Also
the verified call-op names, the --di-only variable name, number-typed
accumulators, and the isHandOver move spelled out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* The -mm=own memory model exists: flag, name, tracksOwnership()

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Audit isRefCounted(): what own shares with rc is tracksOwnership()

Sixteen of the 21 sites write something a release will read, or emit the ownership ops the inference pass judges, and become tracksOwnership(). Three retain lowerings and the captured-parameter retain are Task 4's; a cell's birth retain stays rc only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Lowering under own: releases destroy without counting; a surviving retain is an error

Under -mm=own emitIfLastReference tests the header against
HEAP_BLOCK_IMMORTAL instead of decrementing it, so a release is one load and
a compare. A retain that reaches LLVM lowering is an error, never erased; a
captured variable holding a heap value is an error (closures are phase 5);
and a type descriptor carries no retain routine, since retainViaDescriptor
is reached only from retain routines. emitIncRef's other callers
(emitRetainCell, buildCaptureBoxRoutine(retaining), buildRetainBody) are all
retain paths. --own-skip-inference (hidden) lets the backstop be tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* OwnershipInferencePass, phase 0: a fresh value's single acquisition is a move; every other retain is an error

Under -mm=own, at the affine level before the verifier: a heap value made by
an allocating op (or marked __owned_result) whose births plus retains total
one has exactly one owner, so its retains are erased and the release rc
already emits becomes the owner's destroy. Any other retain, a RetainCell,
a RetainSlot on a hoisted (initializer-less) variable, and a slot released
without ever being owned are reported. isHandOver moves to OwnershipOps.h,
shared with the ownership verifier.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* The own backstop test writes its .ll to the build tree, not beside the source

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* -mm=own phase-0 tests: positive, negative, and no counting in the output

Six programs run under JIT and ahead of time with -mm=own, each checked to
emit neither __tslang_inc_ref nor __tslang_dec_ref; five are rejected with
the expected error. A literal acquired once is now a birth take too:
`let s = "abc"` and `v: number[] = []` were rejected, and a cast constant is
either the immortal global (its release skips it) or a copy one owner holds.

The "released but never owned" rule is removed: the ownership verifier's
stricter form of it is green over the corpus, so no program reaches it, and
isHandOver goes back into the verifier.

Teeth: with every retain kept, all 15 positive checks fail at the backstop.
With the count check loosened to two, own_err_two_owners.ts compiles and
segfaults under own (rc runs it: 500000, done.) - the count is what stands
between a second owner and a double free. Debug tree: every own test passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* measure.ps1, and the phase-0 numbers for -mm=own

The AOT measuring script, rebuilt: it links the way the test runner does
(read from the generated compile.bat) and reads the peak working set from
the process handle after exit - sampling while it runs read 0.0 MB for
programs that finish in milliseconds. Spec section 11 records the results:
own holds flat exactly where rc does (4.2 MB for 1M strings, none 80.9 MB),
the teeth, and phase 0's known limits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* The lowering-error test uses an input that reports its error in a Debug build too

The array-to-string cast hits llvm_unreachable (CastLogicHelper.h:856) in a Debug build before it reports anything, so the message test failed there. An array literal lowering cannot build as number[] | null reports its error the same way in Release and Debug.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Implement phase 0 ownership rules and error handling for -mm=own; add tests for various ownership violations

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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.

1 participant