This is a list/overview of the various known sources of technical debt in SpiderMonkey, curated for easy reference. Categorization is inexact, given that issues may span multiple categories.
- Hash table rooting
- Using hash tables mapping different kinds of GC things as keys/values is tricky, in the presence of moving GC. We need to do some work, perhaps with templates, to make it easier to safely create and work with such hash tables.
- Too many rooting mechanisms!
- The story for how to root things in the heap remains more complicated than it should be.
- Parse nodes are large, public unions
ParseNode::pn_uis largely publicly exposed to everyone, and it's easy to use the wrong union arm for the parse node kind. Potentially this should be converted to a more normal C++ inheritance hierarchy. (But note that we mutate parse node kinds in various places, destroying the "static" nature of a ParseNode's instantaneous subclass as would be reflected in a C++ type.) This will become simpler to address (perhaps by making the sub-structs in
pn_ueach private, with friendships to
ParseNodesubclasses) after bug 1130811 is fixed.
- Single-pass parsing intertwined with name analysis
- The JS parser attempts to do name analysis as it goes, with various bits smuggled into bytecode emission and so on. It really should be moved into a separate pass over the constructed AST.
- Emit bytecode in a separate pass, not at the end of each function/script (?).
- SpiderMonkey-specific property lookup APIs don't exist in ES6/etc.
lookupPropertyMOP operation isn't in ES6. It's mostly removed, with the exception of
template <bool> FetchName(...)operation in the interpreter. Property-setting also contains various weird cases, some for SpiderMonkey-specific gunk and other reasons -- although most of this has been removed, courtesy of jorendorff.
- We have both
- These two classes are relatively similar and relatively interconvertible -- it shouldn't be much work to convert all cases to use only one of these, now.
- General API uncleanliness
- Error numbers encoding error type isn't very pleasant: it's not possible to see, at a throw-site, what sort of error is thrown. The number of parameters passed to throw an error is overlarge. There are a bunch of error-reporting methods, rather than a small, constrained set. Generally there should be a much smaller API surface. (It would also be nice if error reporting could be localized, such that localized error messages could appear in the console, although probably not in error messages as observable by scripts.)
- Error reporting mechanisms live in
JSContext, not in
JSRuntime(perhaps in a sub-struct within it)
- Error reporting should be runtime-based, as
JSContextis increasingly irrelevant as a concept.
- Essentially all such functions immediately create a
CallArgsinternally and work only with that, eschewing use of
vp. It would be better to cut out the middlemen, if we can do so respecting ABI in the JITs.
JSContextby moving everything in it into
- Certain places in Gecko want to have different behavior -- different error objects, primarily -- when different contexts are used. (See the item in the Error Reporting section.) Once that's fixed,
JSContextas an independent concept, and part of API, can probably be removed.
- General cleanliness issues
- The shell isn't exactly the most pristine example of JSAPI usage.
- Overlarge files
- Certain files --
js/src/jit/CodeGenerator.cpp, various macro assembler files -- are quite large. It might be better to split some of these up to some degree. There are some bugs on file for this (sunfish's mentored bug?).
- Define the MacroAssembler interface in a single header
- It's very difficult to know what's in platform-specific macro assemblers, and what's in all macro assemblers. Putting the interface for all platforms into a single struct in a single header would greatly aid readability/clarity as to what's usable in what backends.
- Builtin implementations shouldn't reside in
- Builtins should be implemented in
- VM implementation shouldn't reside in
- VM details should be in specific files within
- Object layout (JSFunction stores extra stuff one way, ArrayBuffers another, maybe Servo stuff using a third, SharedArrayBuffer wanting atomic stuffs for a fourth?)
- can we create a unified system for this?
- Move documentation out of MDN, into the tree, in ReadTheDocs formattting
- Our docs are more likely to remain up-to-date if the documentation is immediately adjacent to the relevant code
- Various large-scale things aren't documented at all, even on MDN
- This is particularly a problem for things that don't get driveby attention.
- Kill off the remaining js*.* files
- Generally, we want to make
js/srccontain pretty much only other folders.
- Add a
js/src/README.txtdescribing the overall organization of SpiderMonkey code
- Error reporting is a disaster.
- JS_ReportError is a bad API that doesn't indicate the type of the error thrown, at the location the error's thrown. We need new stuff here. Also, we have two separate manners for tracking errors: exceptions, and error reporting. We should have only one. It would also be nice if error throwing produced a stack even if an error object isn't created/thrown at that spot.