Repository navigation
@linkname: a second name for @dllname, and one C symbol for many declarations - #366
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r lookup, C string open issue Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es and enhancing function declaration handling
…oject declaration
--emit=jit refused any main with parameters or a result ("expected 'main' to
have 0 inputs and 0 results"), because the JIT called the entry as void(*)().
It now calls a generated `i32 __tslang_jit_main(i32, ptr)` thunk, built in
LLVM IR after the optimizer, that adapts to main's lowered signature:
argc as an integer or number, argv as a string[] (data, length) or a
Ref<string> (the C char ** itself), and the result (void, integer or number)
as the process exit code.
- LowerToAffineLoops: the JIT gate is now a shape check for
main(argc?: i32 | number, argv?: string[] | Ref<string>): void | i32 | number
- tslang: trailing positionals are program arguments for --emit=jit
(argv[0] is the input file, '--' before dash-prefixed ones); an error in
every other mode, as a second positional was before
- tslang: --emit=jit turns --opt on (level 3 by default) unless --opt is given
explicitly, --opt_level=0, or --di (--opt strips the debug info)
- tests: 00main_argc_argv (JIT and compiled), 00main_number_result (JIT only:
a compiled number-typed main gets an int argc and returns no exit code)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LLVM's setName made a taken name unique, so a second declaration of strlen called strlen.1 and linked to nothing. A function with @dllname/@Linkname is now public: it defines a symbol that is bound by that name, and as a private function --opt inlined its callers and SymbolDCE erased it before the rename, leaving the declaration of that name with no definition. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cross-module test of an imported `export declare` binding is registered DISABLED: importing one crashes (null symbol lookup), as it did with @dllname before this branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tically A function renamed to a name another @dllname/@Linkname function is renamed away from was accepted or rejected depending on which came first in the file. Every vacated name is now recorded before the renames run. The static-link multi-file pairs for @Linkname and for an imported `export declare` binding were passing but not registered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR 1 of the plan in
docs/superpowers/specs/2026-09-25-tsbindgen-linkname-design.md. It adds@linkname("sym")as a second spelling of@dllname("sym"). It also fixes two bugs that stop a C function being bound under another TS name. tsbindgen (the stacked PR) needs these fixes for its--namespaceoutput.Changes
@linknameis an alias of@dllname. Both spellings map to the sameDLL_NAMEattribute initerateDecorators, so everything that already reads@dllnameaccepts@linkname, including__decls, which still prints@dllname(...). Using both on one declaration with different symbols is an error. Using both with the same symbol is allowed.Several declarations of one C symbol now bind it together. The rename used to happen in LLVM (
ExportFixPass). When the name was already taken,setNamequietly made it unique:@strlen,@strlen.1and@strlen.2. The JIT failed withSymbols not found: [ strlen.1, strlen.2 ]and the exe withLNK2019: unresolved external symbol strlen.1.strlen, both linked and under the JIT (declare_linkname_shared_symbol.ts).The rename now happens in MLIR (
LowerToLLVM.cpp, beside the existing global rename). Declarations of one symbol are merged. Everything else is an error instead of a silent.1:The error cases are the
test-compile-linkname-*tests.export declareno longer marks the C functiondllexport. A declaration without a body stops getting theexportattribute. Whether it is re-printed into__declsis unchanged.test-compile-linkname-declare-not-exportedchecks the IR has nodeclare dllexport.export declaresstrlenstill writes a.lib/.exp. Those come from the module's own__decls/__tsmmdllexport globals, which are exported on purpose.strlenitself was not exported before this change and is not exported after it. The spec said the exe "re-exports strlen" and blamed it for the.lib; that was wrong, and the spec has been corrected.Existing bug found while testing: a function carrying
@dllname/@linknamewas private. Under--opt, inlining plus SymbolDCE deleted it before it could be renamed. That is why@dllnamedefinitions went missing under--opt. Such functions are now public.Also on this branch
docs/superpowers/).--emit=jitnow runs amain(argc, argv)that takes parameters and returns a result, and defaults to-O3. Test:00main_argc_argv.ts,00main_number_result.ts. Two AOT problems are still open:argv.lengthreadsenvp;mainreturningnumberdoesn't give a proper exit code.Tests
Full Release suite on Windows: all pass, with one test disabled.
The disabled test is
test-compile-shared-export-import-declare-linkname. Importing a-sharedmodule'sexport declarebinding of a C runtime function crashes: the importer looksstrlenup in the loaded tslang libraries, which never contain it. A build from before this branch crashes the same way with@dllname, so this is an existing bug: #368. Its static-link twin,test-compile-export-import-declare-linkname, passes and guards the same path.Known gaps
'strlen') rather than the TS name.@linknametarget is a function gives an internal "failed to legalize" error instead of a clear one.@dllnamealready behaved this way.🤖 Generated with Claude Code