Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/wapython
Path: blob/main/core/dylink/src/function-table.ts
1067 views
1
import debug from "debug";
2
import { nonzeroPositions } from "./util";
3
4
const log = debug("dylink:function-table");
5
6
const GROW_THRESH = 50;
7
8
export default class FunctionTable {
9
public readonly table: WebAssembly.Table;
10
11
// indexes into the function table that are null, but
12
// maybe less than nextTablePos.
13
private availableTableIndexes: Set<number> = new Set<number>();
14
15
// next available table position at the very end. Use this if
16
// availableTableIndexes is empty.
17
private nextTablePos: number = 0;
18
19
constructor(table: WebAssembly.Table) {
20
log("constructor");
21
this.table = table;
22
}
23
24
updateAfterImport(): void {
25
this.nextTablePos = Math.max(0, ...nonzeroPositions(this.table)) + 1;
26
}
27
28
prepareForImport(tableSize: number): void {
29
this.nextTablePos += tableSize;
30
if (this.table.length <= this.nextTablePos + GROW_THRESH) {
31
this.table.grow(this.nextTablePos + GROW_THRESH - this.table.length);
32
}
33
}
34
35
getNextTablePos(): number {
36
return this.nextTablePos;
37
}
38
39
// gets the next available index, then marks it
40
// as no longer available, so it can be used.
41
private getNextAvailableIndex(): number {
42
for (const index of this.availableTableIndexes) {
43
this.availableTableIndexes.delete(index);
44
log("getNextAvailableIndex: from availableTableIndexes", index);
45
46
return index;
47
}
48
const index = this.nextTablePos;
49
log("getNextAvailableIndex: from nextTablePos", index);
50
this.nextTablePos += 1;
51
if (this.table.length <= this.nextTablePos + GROW_THRESH) {
52
this.table.grow(this.nextTablePos + GROW_THRESH - this.table.length);
53
}
54
return index;
55
}
56
57
setLater(): { index: number; set: (f: Function) => void } {
58
const index = this.getNextAvailableIndex();
59
return {
60
index,
61
set: (f) => {
62
this.set(f, index);
63
},
64
};
65
}
66
67
set(f: Function, _index?: number): number {
68
const index = _index ?? this.getNextAvailableIndex();
69
if (this.table.get(index) != null) {
70
throw Error("BUG: trying to set a table index that is already set");
71
}
72
this.table.set(index, f);
73
return index;
74
}
75
76
get(index: number): Function | null | undefined {
77
return this.table.get(index);
78
}
79
80
delete(index: number): void {
81
this.table.set(index, null);
82
this.availableTableIndexes.add(index);
83
}
84
}
85
86