feat: free memory automatically (#5225)
This commit is contained in:
parent
b12009a746
commit
cd603fa981
9 changed files with 163 additions and 0 deletions
8
lib/binding_web/src/finalization_registry.ts
Normal file
8
lib/binding_web/src/finalization_registry.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export function newFinalizer<T>(handler: (value: T) => void): FinalizationRegistry<T> | undefined {
|
||||
try {
|
||||
return new FinalizationRegistry(handler);
|
||||
} catch(e) {
|
||||
console.error('Unsupported FinalizationRegistry:', e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
import { C, Internal, assertInternal } from './constants';
|
||||
import { Language } from './language';
|
||||
import { newFinalizer } from './finalization_registry';
|
||||
|
||||
const finalizer = newFinalizer((address: number) => {
|
||||
C._ts_lookahead_iterator_delete(address);
|
||||
});
|
||||
|
||||
export class LookaheadIterator implements Iterable<string> {
|
||||
/** @internal */
|
||||
|
|
@ -13,6 +18,7 @@ export class LookaheadIterator implements Iterable<string> {
|
|||
assertInternal(internal);
|
||||
this[0] = address;
|
||||
this.language = language;
|
||||
finalizer?.register(this, address, this);
|
||||
}
|
||||
|
||||
/** Get the current symbol of the lookahead iterator. */
|
||||
|
|
@ -27,6 +33,7 @@ export class LookaheadIterator implements Iterable<string> {
|
|||
|
||||
/** Delete the lookahead iterator, freeing its resources. */
|
||||
delete(): void {
|
||||
finalizer?.unregister(this);
|
||||
C._ts_lookahead_iterator_delete(this[0]);
|
||||
this[0] = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { Language } from './language';
|
|||
import { marshalRange, unmarshalRange } from './marshal';
|
||||
import { checkModule, initializeBinding } from './bindings';
|
||||
import { Tree } from './tree';
|
||||
import { newFinalizer } from './finalization_registry';
|
||||
|
||||
/**
|
||||
* Options for parsing
|
||||
|
|
@ -82,6 +83,11 @@ export let LANGUAGE_VERSION: number;
|
|||
*/
|
||||
export let MIN_COMPATIBLE_VERSION: number;
|
||||
|
||||
const finalizer = newFinalizer((addresses: number[]) => {
|
||||
C._ts_parser_delete(addresses[0]);
|
||||
C._free(addresses[1]);
|
||||
});
|
||||
|
||||
/**
|
||||
* A stateful object that is used to produce a {@link Tree} based on some
|
||||
* source code.
|
||||
|
|
@ -117,6 +123,7 @@ export class Parser {
|
|||
*/
|
||||
constructor() {
|
||||
this.initialize();
|
||||
finalizer?.register(this, [this[0], this[1]], this);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
|
@ -131,6 +138,7 @@ export class Parser {
|
|||
|
||||
/** Delete the parser, freeing its resources. */
|
||||
delete() {
|
||||
finalizer?.unregister(this);
|
||||
C._ts_parser_delete(this[0]);
|
||||
C._free(this[1]);
|
||||
this[0] = 0;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { Node } from './node';
|
|||
import { marshalNode, unmarshalCaptures } from './marshal';
|
||||
import { TRANSFER_BUFFER } from './parser';
|
||||
import { Language } from './language';
|
||||
import { newFinalizer } from './finalization_registry';
|
||||
|
||||
const PREDICATE_STEP_TYPE_CAPTURE = 1;
|
||||
|
||||
|
|
@ -506,6 +507,10 @@ function parsePattern(
|
|||
}
|
||||
}
|
||||
|
||||
const finalizer = newFinalizer((address: number) => {
|
||||
C._ts_query_delete(address);
|
||||
});
|
||||
|
||||
export class Query {
|
||||
/** @internal */
|
||||
private [0] = 0; // Internal handle for Wasm
|
||||
|
|
@ -687,10 +692,12 @@ export class Query {
|
|||
this.assertedProperties = assertedProperties;
|
||||
this.refutedProperties = refutedProperties;
|
||||
this.exceededMatchLimit = false;
|
||||
finalizer?.register(this, address, this);
|
||||
}
|
||||
|
||||
/** Delete the query, freeing its resources. */
|
||||
delete(): void {
|
||||
finalizer?.unregister(this);
|
||||
C._ts_query_delete(this[0]);
|
||||
this[0] = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { TreeCursor } from './tree_cursor';
|
|||
import { marshalEdit, marshalPoint, unmarshalNode, unmarshalRange } from './marshal';
|
||||
import { TRANSFER_BUFFER } from './parser';
|
||||
import { Edit } from './edit';
|
||||
import { newFinalizer } from './finalization_registry';
|
||||
|
||||
/** @internal */
|
||||
export function getText(tree: Tree, startIndex: number, endIndex: number, startPosition: Point): string {
|
||||
|
|
@ -28,6 +29,10 @@ export function getText(tree: Tree, startIndex: number, endIndex: number, startP
|
|||
return result ?? '';
|
||||
}
|
||||
|
||||
const finalizer = newFinalizer((address: number) => {
|
||||
C._ts_tree_delete(address);
|
||||
});
|
||||
|
||||
/** A tree that represents the syntactic structure of a source code file. */
|
||||
export class Tree {
|
||||
/** @internal */
|
||||
|
|
@ -45,6 +50,7 @@ export class Tree {
|
|||
this[0] = address;
|
||||
this.language = language;
|
||||
this.textCallback = textCallback;
|
||||
finalizer?.register(this, address, this);
|
||||
}
|
||||
|
||||
/** Create a shallow copy of the syntax tree. This is very fast. */
|
||||
|
|
@ -55,6 +61,7 @@ export class Tree {
|
|||
|
||||
/** Delete the syntax tree, freeing its resources. */
|
||||
delete(): void {
|
||||
finalizer?.unregister(this);
|
||||
C._ts_tree_delete(this[0]);
|
||||
this[0] = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@ import { marshalNode, marshalPoint, marshalTreeCursor, unmarshalNode, unmarshalP
|
|||
import { Node } from './node';
|
||||
import { TRANSFER_BUFFER } from './parser';
|
||||
import { getText, Tree } from './tree';
|
||||
import { newFinalizer } from './finalization_registry';
|
||||
|
||||
const finalizer = newFinalizer((address: number) => {
|
||||
C._ts_tree_cursor_delete_wasm(address);
|
||||
});
|
||||
|
||||
/** A stateful object for walking a syntax {@link Tree} efficiently. */
|
||||
export class TreeCursor {
|
||||
|
|
@ -30,6 +35,7 @@ export class TreeCursor {
|
|||
assertInternal(internal);
|
||||
this.tree = tree;
|
||||
unmarshalTreeCursor(this);
|
||||
finalizer?.register(this, this.tree[0], this);
|
||||
}
|
||||
|
||||
/** Creates a deep copy of the tree cursor. This allocates new memory. */
|
||||
|
|
@ -42,6 +48,7 @@ export class TreeCursor {
|
|||
|
||||
/** Delete the tree cursor, freeing its resources. */
|
||||
delete(): void {
|
||||
finalizer?.unregister(this);
|
||||
marshalTreeCursor(this);
|
||||
C._ts_tree_cursor_delete_wasm(this.tree[0]);
|
||||
this[0] = this[1] = this[2] = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue