Repository navigation
@value T | null fixes, interfaces print their fields, C string from an imported .d.ts - #761
Merged
Merged
Conversation
…rint Three failures of a @value type that may be missing, all on main before #760: - rc: `d < 0 ? null : { at: d, owner: new Owner(d) }` returned as `Mark | null`. The branch released the new object before the result's retain after the join, which then retained freed memory. consumeConditionalResults' producerOf looks through a tuple cast to the @value type it is laid out as, so yieldsLiteralOfBranchTemporary sees the literal and the branch retains first. - `h ?? find(3)` was typed `Hit | (Hit | null)` and did not compile: an optional member of a union gave its element as one member. processUnionTypeItem now processes the element like any other member, so a union in it gives its members. - print / string conversion: an undefined `T | undefined` printed as null or as a zeroed T (the optional went through ValueOrDefault); it is "undefined" now. A null `T | null` stored without a tag (#760) printed T's fields; castNullableToString takes a @value base too and prints "null". Test value/value_missing_ops (gc, rc, none; own cannot yet tell which branch of a `?:` owns a literal it merges). ctest 6546/6546; fuzz seeds 83000-83599 clean; DefaultLib compiles under own and rc. Printing a @value value holding an interface still crashes, as printing any interface does - not changed here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Printing an interface value, or putting it into a string, crashed at run time, whatever object was behind it - a class, an object literal, or one a @value value holds. USER RULING: print its fields. castInterfaceToString: - its `toString` when the interface has one, as a class's is; - else its fields, read through the interface, those of the interfaces it extends first, in an object literal's format (`{ n: 3, name: 'b' }`, fieldsToString, which castTupleToString now shares); - null as "null"; - a field of an interface type already being printed is `[Object]`: the text is made inline, and `interface Chain { next: Chain }` nests without end. Test tests/00interface_print (every model). ctest 6552/6552; fuzz seeds 84000-84599 clean; DefaultLib compiles under all four models. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…first TSLANG_ISSUES 21. The string a C function returns is copied into a string of the program's own (#575), but not when the `.d.ts` declaring it was first reached through a module this file imports: `declaredFunctions` kept the module of that earlier pass, and isForeignCall wanted the one being generated. The raw `char*` was taken as it was - stored strerror() results showed the buffer's last text, and under -mm=rc the count was written into C's memory and the release freed it (native_ts_graphics on Android: "Scudo ERROR: misaligned pointer when deallocating"). A top-level body-less `declare function` is C whichever module's pass loaded its `.d.ts`: isForeignCall now asks that, and that this module's function has no body. Test c-string-import/ (gc, rc, none, own; compiled and JIT), whose `.d.ts` is outside tests/, where *.d.ts are build output and ignored. ctest 6560/6560; fuzz seeds 85000-85599 clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Three failures of a
@valuetype that may be missing (T | null,T | undefined), all on main before #760, plus printing of interface values. Found while working on #760.@value T | null(98e92da)return d < 0 ? null : { at: d, owner: new Owner(d) }in a function returningMark | nullread freed memory. The branch released the newOwnerbefore the retain after the?:ran.consumeConditionalResults'producerOfnow sees through the cast from a tuple to the@valuetype it is laid out as. SoyieldsLiteralOfBranchTemporaryrecognizes the literal, and the branch retains first. 2,000,000 calls peak at 4.7 MB, so nothing leaks.??:find(-1) ?? find(3)withfind(): Hit | nullwas typedHit | (Hit | null)and did not compile. An optional member of a union contributed its whole element type as one member.processUnionTypeItemnow processes the element like any other member, so a union inside it contributes its members.T | undefinedprintednull, or a zeroedT; it now printsundefined;T | nullstored without a tag (@value T | null without a tag when T holds an interface or a class; null tested by descriptor kind #760) printedT's fields; it now printsnull.castNullableToStringnow accepts a@valuebase.The new test
value/value_missing_ops.tsruns under gc, rc and none, for aTholding a class (no tag) and aTof numbers only (tagged). Own rejects it: it can't yet tell which branch of a?:owns a literal it merges.Printing an interface (7fa8c15)
Printing an interface value, or putting one into a string, crashed at run time, whatever object was behind it: a class instance, an object literal, or an interface held by a
@value. Per your ruling, an interface now prints its fields, as an object literal does ({ n: 3, name: 'b' }), with fields of the interfaces it extends first.toStringcalls it, as a class does.null.[Object], becauseinterface Chain { next: Chain }would otherwise expand forever.castTupleToStringand the newcastInterfaceToStringshare one formatter,fieldsToString. The new testtests/00interface_printruns under every model.A C string result from a .d.ts an imported module loaded first (2da1465, TSLANG_ISSUES 21)
The string a C function returns is copied (#575), except when the
.d.tsdeclaring it was first reached through a module this file imports.declaredFunctionskept that earlier pass's module, andisForeignCallrequired the current one, so the rawchar*was used as is. Storedstrerrorresults then all showed the buffer's last text, and under-mm=rcthe reference count was written into C's memory and the release freed it. Now a top-leveldeclare functionwith no body counts as C whichever module loaded its.d.ts. The new test is inc-string-import/, under gc, rc, none and own, compiled and JIT. Its.d.tslives outsidetests/becausetests/*.d.tsare build output and git ignores them.Testing
🤖 Generated with Claude Code