In the Wasm version, we allocate CST nodes via bump pointer allocation into linear memory. Currently, we reset the heap before each call to match. This is fine for typical use cases, but there are some languages that require two stages of parsing. For example, in Shopify's liquid-html-grammar, they call match in the process of building the initial intermediate representation (which they also call a "CST").
To support uses like this, we'll need to have a way of explicitly freeing linear memory. My current thought is to make the MatchResult object the main interface for resource management:
const result = grammar.match(sourceCode);
createAst(result);
result.dispose();
If we go this route, we'll probably also want a way of ensuring that users remember to call dispose. A few ideas:
- Use a
FinalizationRegistry, and either (a) automatically free things, and/or (b) print a warning about undisposed MatchResults.
- Automatically call
dispose before match, and/or warn if the previous result was not yet disposed. And then we could have another API to handle the special case.
For example:
const result = grammar.match(sourceCode);
result.beforeDisposing(() => {
grammar.match(somethingElse);
});
or
const result = grammar.match(sourceCode);
result.retain(); // <- We could register with FinalizationRegistry here too.
grammar.match(somethingElse);
result.dispose();
In the Wasm version, we allocate CST nodes via bump pointer allocation into linear memory. Currently, we reset the heap before each call to
match. This is fine for typical use cases, but there are some languages that require two stages of parsing. For example, in Shopify's liquid-html-grammar, they callmatchin the process of building the initial intermediate representation (which they also call a "CST").To support uses like this, we'll need to have a way of explicitly freeing linear memory. My current thought is to make the
MatchResultobject the main interface for resource management:If we go this route, we'll probably also want a way of ensuring that users remember to call
dispose. A few ideas:FinalizationRegistry, and either (a) automatically free things, and/or (b) print a warning about undisposed MatchResults.disposebeforematch, and/or warn if the previous result was not yet disposed. And then we could have another API to handle the special case.For example:
or