wasmMemoryManager.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. declare function postMessage(message: any, transfer?: any[]): void;
  2. /**
  3. * @hidden
  4. */
  5. export class WASMMemoryManager {
  6. public static LoadBinariesFromCurrentThread = true;
  7. public static InitialMemoryPages = (1 * 1024 * 1024) >> 16; // 1 Mbytes
  8. private static _RequestId = 0;
  9. public static LoadWASM(path: string): Promise<ArrayBuffer> {
  10. if (this.LoadBinariesFromCurrentThread) {
  11. return new Promise((resolve, reject) => {
  12. fetch(path)
  13. .then((response) => {
  14. if (response.ok) {
  15. return response.arrayBuffer();
  16. }
  17. throw new Error(`Could not fetch the wasm component from "${path}": ${response.status} - ${response.statusText}`);
  18. })
  19. .then((wasmBinary) => resolve(wasmBinary))
  20. .catch((reason) => {
  21. reject(reason);
  22. });
  23. });
  24. }
  25. const id = this._RequestId++;
  26. return new Promise((resolve) => {
  27. const wasmLoadedHandler = (msg: any) => {
  28. if (msg.data.action === "wasmLoaded" && msg.data.id === id) {
  29. self.removeEventListener("message", wasmLoadedHandler);
  30. resolve(msg.data.wasmBinary);
  31. }
  32. };
  33. self.addEventListener("message", wasmLoadedHandler);
  34. postMessage({ action: "loadWASM", path: path, id: id });
  35. });
  36. }
  37. private _memory: WebAssembly.Memory;
  38. private _numPages: number;
  39. private _memoryView: Uint8Array;
  40. private _memoryViewByteLength: number;
  41. private _memoryViewOffset: number;
  42. constructor(initialMemoryPages: number = WASMMemoryManager.InitialMemoryPages) {
  43. this._numPages = initialMemoryPages;
  44. this._memory = new WebAssembly.Memory({ initial: this._numPages });
  45. this._memoryViewByteLength = this._numPages << 16;
  46. this._memoryViewOffset = 0;
  47. this._memoryView = new Uint8Array(this._memory.buffer, this._memoryViewOffset, this._memoryViewByteLength);
  48. }
  49. public get wasmMemory(): WebAssembly.Memory {
  50. return this._memory;
  51. }
  52. public getMemoryView(numPages: number, offset: number = 0, byteLength?: number): Uint8Array {
  53. byteLength = byteLength ?? numPages << 16;
  54. if (this._numPages < numPages) {
  55. this._memory.grow(numPages - this._numPages);
  56. this._numPages = numPages;
  57. this._memoryView = new Uint8Array(this._memory.buffer, offset, byteLength);
  58. this._memoryViewByteLength = byteLength;
  59. this._memoryViewOffset = offset;
  60. } else {
  61. this._memoryView = new Uint8Array(this._memory.buffer, offset, byteLength);
  62. this._memoryViewByteLength = byteLength;
  63. this._memoryViewOffset = offset;
  64. }
  65. return this._memoryView;
  66. }
  67. }