Repository navigation
Data class for Patch data - #35
Merged
Merged
Conversation
The Differ built each DOM update as an Array (`[:replace, new, old]`, `[:keep, old_index, new_index, patches]`, `[index, patches]`) and the Patcher read it by position in 21 places. Such an Array has no element types a type inference can hold, so every value the Patcher took out of a patch was untyped, and the whole VDOM update path stayed off the AOT compiler's typed path. VDOM::Patch is a Data (mruby-data on mruby; each member is one method, two patches with the same members are ==, and a patch cannot change after it is built). `op` names the step and the members a step does not use are nil, or NONE for a list; one constructor per step builds it (Patch.replace, .remove, .text, .props, .child, .keep, .insert, .keyed_children, .update_and_rebind). The Differ emits them, the Patcher reads the members, and patch_t is Patch in the RBS, with the member types declared. Two things the rewrite ran into are fixed with it: `patches += child_patches` and the sort of the removes by a block are loops now, since both boxed the Array for the inference; and the text handed to createTextNode and nodeValue is a copy, since the content String is shared with the VNode and the JS boundary takes a copy of its own. The differ and patcher tests compare Patch values; the whole suite passes on the wasm build.
@event_listeners (the Integer ids addEventListener answers, removed on cleanup) and @child_components (Array[Component]) had no declaration, so a reader of them was untyped. The inline notes on the assignments say Array[Integer] now, as the declaration does.
hasumikin
added a commit
to picoruby/picoruby
that referenced
this pull request
Oct 21, 2026
…ver untyped A call on a receiver Spinel holds as a box took every def of its name, in the dependencies too, so `patches.each` on an `Array[Patch]` parameter reached IndexedDB::Store#each and kept its caller in the irep, and so did `msgs.each` over the values of a Hash[Symbol, Array[String]]. RbsIndex reads the gem's and its dependencies' RBS; when Spinel typed a receiver poly or not at all, resolve_receiver asks the declaration of the slot: a positional parameter of the def, an instance variable (an attr counts), a block parameter of an iteration over a declared Array or Hash (the element, or the key and the value by position), or the value of a method or attr of a declared class. The declared type maps to the scopes a call can reach as Spinel's own kinds do; a union settles only when every member does. Trusting the declaration is what Spinel does with the same file under --rbs and what steep checks against the CRuby run. On funicular, with its patches as a Data (picoruby/funicular#35), the compiled defs go from 127 / 254 to 159 / 407 of 756, the Differ to 9 of 9 and vdom.rb to 23 of 35; the declared gems' counts move by one (net-websocket widened 35 -> 36). Host twin SAME (103), twin32 SAME (87). architecture.md states the rule; aot-plan 1.6 names what still waits on the VDOM path (receivers behind an is_a? guard) and the next two steps. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WA5cW6UWZ6UVReAknDAnxj
hasumikin
added a commit
to picoruby/picoruby
that referenced
this pull request
Oct 21, 2026
The submodule takes picoruby/funicular#35: VDOM::Patch, a Data the Differ emits and the Patcher reads by member, with mruby-data as a dependency, and the RBS of the event listener ids and the child components. The gem builds on the wasm test target with mruby-data in place of picoruby-data (the previous commit) and its picotest suite passes there (1535, 0 failures). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WA5cW6UWZ6UVReAknDAnxj
hasumikin
added a commit
to picoruby/picoruby
that referenced
this pull request
Oct 24, 2026
…ver untyped A call on a receiver Spinel holds as a box took every def of its name, in the dependencies too, so `patches.each` on an `Array[Patch]` parameter reached IndexedDB::Store#each and kept its caller in the irep, and so did `msgs.each` over the values of a Hash[Symbol, Array[String]]. RbsIndex reads the gem's and its dependencies' RBS; when Spinel typed a receiver poly or not at all, resolve_receiver asks the declaration of the slot: a positional parameter of the def, an instance variable (an attr counts), a block parameter of an iteration over a declared Array or Hash (the element, or the key and the value by position), or the value of a method or attr of a declared class. The declared type maps to the scopes a call can reach as Spinel's own kinds do; a union settles only when every member does. Trusting the declaration is what Spinel does with the same file under --rbs and what steep checks against the CRuby run. On funicular, with its patches as a Data (picoruby/funicular#35), the compiled defs go from 127 / 254 to 159 / 407 of 756, the Differ to 9 of 9 and vdom.rb to 23 of 35; the declared gems' counts move by one (net-websocket widened 35 -> 36). Host twin SAME (103), twin32 SAME (87). architecture.md states the rule; aot-plan 1.6 names what still waits on the VDOM path (receivers behind an is_a? guard) and the next two steps. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WA5cW6UWZ6UVReAknDAnxj
hasumikin
added a commit
to picoruby/picoruby
that referenced
this pull request
Oct 25, 2026
…ver untyped A call on a receiver Spinel holds as a box took every def of its name, in the dependencies too, so `patches.each` on an `Array[Patch]` parameter reached IndexedDB::Store#each and kept its caller in the irep, and so did `msgs.each` over the values of a Hash[Symbol, Array[String]]. RbsIndex reads the gem's and its dependencies' RBS; when Spinel typed a receiver poly or not at all, resolve_receiver asks the declaration of the slot: a positional parameter of the def, an instance variable (an attr counts), a block parameter of an iteration over a declared Array or Hash (the element, or the key and the value by position), or the value of a method or attr of a declared class. The declared type maps to the scopes a call can reach as Spinel's own kinds do; a union settles only when every member does. Trusting the declaration is what Spinel does with the same file under --rbs and what steep checks against the CRuby run. On funicular, with its patches as a Data (picoruby/funicular#35), the compiled defs go from 127 / 254 to 159 / 407 of 756, the Differ to 9 of 9 and vdom.rb to 23 of 35; the declared gems' counts move by one (net-websocket widened 35 -> 36). Host twin SAME (103), twin32 SAME (87). architecture.md states the rule; aot-plan 1.6 names what still waits on the VDOM path (receivers behind an is_a? guard) and the next two steps. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WA5cW6UWZ6UVReAknDAnxj
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.
Along with fixing RBS