Files
vectorcraft/crates/js
dotCooCoo 3ca5a75d87 Scripts: namespace scopes and edits count against the heap limit
The namespace list that inScopeNamespaces(), namespace(),
namespaceDeclarations(), the XPath namespace axis, XPath prefixes and
XPath name() collect from a node and its ancestors was built in Rust
buffers the heap limit did not see, so a node with many namespaces in
scope let a script grow past its limit.

The scope now holds the bytes of its list and prefix table until it is
dropped, and namespaceDeclarations() also holds its ancestor table and
the declarations it returns. The queried node stays rooted while the
scope is built, and each declaration is read in place instead of
copying every node's namespace list.

Other copies in the same files are held against the limit too:
- addNamespace(), setNamespace(), setName() and removeNamespace() read
  an element's attributes one at a time instead of copying the list,
  and removeNamespace() holds its walk stack.
- child(index), comments(), text(), elements(), processingInstructions()
  and normalize() on an XMLList hold the copy of its items, and
  replace() holds the copy of the children it matched.
- XPath name() holds the units of a prefixed name it builds.
- The XML, XMLList, Namespace and QName constructors, isXMLName(),
  attribute(), namespace(), propertyIsEnumerable(), setName(),
  setLocalName(), addNamespace(), removeNamespace() and setNamespace()
  reserve the bytes of the flat copy of a long (rope) string argument
  before they make it, and attribute() reserves the copy of a name
  without its leading @.
- QName.prototype.toString() reserves its result before it builds it.
2026-11-13 05:55:22 -08:00
..