Commit Graph
6 Commits
Author SHA1 Message Date
dotCooCoo 49c8a380a1 Scripts: flattening a rope keeps it rooted while its copy is reserved
flat_charged and the property-key path now root the rope itself, so a string held only by
native code (a getter's result for ++o.x, a valueOf result, a toString key) still counts
what it holds when the reservation collects. The per-call roots for these cases are removed.
2026-11-11 23:02:45 -08:00
dotCooCoo 46efc4a651 Scripts: a String object counts its rope's copy when a character is read
- wrapping a string no longer flattens it, so Object(s).length and new String(s) on a large concatenated string make no copy and cannot collect while a call's operands are off the stack
- reading a String object's character by index, `in` and hasOwnProperty count the flattened copy at the next limit check, and the run ends before the copy when the fuel for it is not left
- unary plus on an object whose valueOf returns a concatenated string, and a property key from toString, keep that string rooted while its copy is reserved
- the unshift comment cites step 6 of section 15.4.4.13
2026-11-11 22:39:04 -08:00
dotCooCoo 3dc597f259 Scripts: a call and new String keep their operands rooted while a rope is flattened
Boxing the string receiver of a non-strict function flattens it, and reserving the copy can
collect. The callee, receiver and arguments are already off the stack at that point, so they
stay in the temporary roots until the frame holds them; before, an argument object could be
freed and its cell reused by the wrapper. new String(value) roots the converted string the
same way, so what the rope holds is still counted while its copy is reserved.
2026-11-11 21:53:50 -08:00
dotCooCoo 44eb3be713 Scripts: a flattened string stays counted while the next copy is made
- the relational operators root both strings while flattening them, so the first copy still counts when the second one starts a collection
- join roots its separator for the whole join and each element while it is written, and JSON.stringify roots a string while it writes it
- a String object flattens its string when it is made, with the copy counted, so reading one of its characters copies nothing
2026-11-11 21:21:45 -08:00
dotCooCoo cea958b782 JavaScript: text built-ins hold their working memory against the heap limit
Native code now holds the Rust memory it works in against the heap limit
until it is done with it: a matcher's capture state and stack, a pattern
being compiled, the matches and pieces of a replacement, and the text
Date.parse reads. A collection counts these bytes as live while they are
held.

- replace reads its replacement pattern once into parts that refer to
  ranges of the pattern, so literal text is not copied for each match.
  Each piece takes fuel for its units, and the result's length is
  checked against the heap as each piece is added.
- The regular expression compiler charges heap through its callback as
  it builds, including the ranges of a character class, and each class
  atom and range takes fuel. A compiled form counts the capacity of its
  lists.
- Clearing the groups inside a quantifier and clearing the matcher's
  state before each attempt take fuel.
- Flattening a rope in a String, RegExp or Date method reserves the
  flat copy on the heap and takes fuel for it.
- A RegExp object's bytes are reserved together with its compiled form,
  so a collection between the two does not drop the compiled form from
  the heap count.
2026-11-07 19:29:53 -08:00
dotCooCoo 02fffcd00c JavaScript: String, Number, RegExp and Date built-ins
A realm now has String, Number, RegExp and Date as ECMAScript 5.1
sections 15.5, 15.7, 15.9 and 15.10 define them, with Annex B's substr,
getYear, setYear and toGMTString.

- String: every ES5 prototype method; split, replace, match and search
  take strings and RegExps. Each new string's length is checked against
  the heap limit before it is built, and scans take fuel.
- Number: toString(radix), toFixed, toExponential and toPrecision
  format from the number's exact decimal value.
- RegExp: a backtracking matcher keeps its choice points and capture
  state on the heap, within the heap room left, and takes fuel for every
  step, so a catastrophic pattern stops at the fuel limit. Patterns
  nested past Options::max_depth give a SyntaxError. Flags g, i and m,
  lastIndex, exec, test and toString.
- Date: chrono converts days to calendar dates, shifting by whole
  400-year cycles past its years. Realm::set_clock and
  Realm::set_time_zone set the clock and local time (UTC by default).
  Without a hint, a Date converts to a primitive as a string.

cargo xtask test262 also runs the suite's built-ins tests for the four
and prints their counts.
2026-11-07 18:24:27 -08:00