| 66 | * Environment to impelement most of the JS library functions. |
| 67 | */ |
| 68 | export class Environment implements LibraryProvider { |
| 69 | logger: (msg: string) => void; |
| 70 | imports: Record<string, any>; |
| 71 | /** |
| 72 | * Maintains a table of FTVMWasmPackedCFunc that the C part |
| 73 | * can call via TVMWasmPackedCFunc. |
| 74 | * |
| 75 | * We maintain a separate table so that we can have un-limited amount |
| 76 | * of functions that do not maps to the address space. |
| 77 | */ |
| 78 | packedCFuncTable: Array<ctypes.FTVMFFIWasmSafeCallType | undefined> = [ |
| 79 | undefined, |
| 80 | ]; |
| 81 | /** |
| 82 | * Free table index that can be recycled. |
| 83 | */ |
| 84 | packedCFuncTableFreeId: Array<number> = []; |
| 85 | |
| 86 | private libProvider?: LibraryProvider; |
| 87 | |
| 88 | constructor( |
| 89 | importObject: Record<string, any> = {}, |
| 90 | logger: (msg: string) => void = console.log |
| 91 | ) { |
| 92 | this.logger = logger; |
| 93 | this.libProvider = detectLibraryProvider(importObject); |
| 94 | // get imports from the provider |
| 95 | if (this.libProvider !== undefined) { |
| 96 | this.imports = this.libProvider.imports; |
| 97 | } else { |
| 98 | this.imports = importObject; |
| 99 | } |
| 100 | // update with more functions |
| 101 | this.imports.env = this.environment(this.imports.env); |
| 102 | } |
| 103 | |
| 104 | /** Mark the start of the instance. */ |
| 105 | start(inst: WebAssembly.Instance): void { |
| 106 | if (this.libProvider !== undefined) { |
| 107 | this.libProvider.start(inst); |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | private environment(initEnv: Record<string, any>): Record<string, any> { |
| 112 | // default env can be overriden by libraries. |
| 113 | const defaultEnv = { |
| 114 | "__cxa_thread_atexit": (): void => {}, |
| 115 | "emscripten_notify_memory_growth": (index: number): void => {} |
| 116 | }; |
| 117 | const wasmSafeCall: ctypes.FTVMFFIWasmSafeCallType = ( |
| 118 | self: Pointer, |
| 119 | args: Pointer, |
| 120 | num_args: number, |
| 121 | result: Pointer |
| 122 | ): number => { |
| 123 | const cfunc = this.packedCFuncTable[self]; |
| 124 | assert(cfunc !== undefined); |
| 125 | return cfunc(self, args, num_args, result); |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…