* Warp an exported asynctify function so it can return promise * * @param func The input function * @returns The wrapped async function
(func: (...args: Array<any>) => any)
| 147 | * @returns The wrapped async function |
| 148 | */ |
| 149 | wrapExport(func: (...args: Array<any>) => any): (...args: Array<any>) => Promise<any> { |
| 150 | return async (...args: Array<any>) => { |
| 151 | assert(this.getState() == AsyncifyStateKind.None); |
| 152 | |
| 153 | // call the original function |
| 154 | let result = func(...args); |
| 155 | |
| 156 | // JUMP-PT-UNWIND |
| 157 | // after calling the function |
| 158 | // the caller may hit a unwinding point depending on |
| 159 | // the if (isPromise(value)) condition in wrapImport |
| 160 | while (this.getState() == AsyncifyStateKind.Unwinding) { |
| 161 | this.stopUnwind(); |
| 162 | // try to resolve the promise that the internal requested |
| 163 | // we then store it into the temp value in storedValueBeforeRewind |
| 164 | // which then get passed onto the function(see wrapImport) |
| 165 | // that can return the value |
| 166 | const storedPromiseBeforeUnwind = this.storedPromiseBeforeUnwind; |
| 167 | this.storedPromiseBeforeUnwind = null; |
| 168 | assert(this.storedExceptionBeforeRewind === null); |
| 169 | assert(this.storedValueBeforeRewind == null); |
| 170 | |
| 171 | try { |
| 172 | this.storedValueBeforeRewind = await storedPromiseBeforeUnwind; |
| 173 | } catch (error) { |
| 174 | // the store exception |
| 175 | this.storedExceptionBeforeRewind = error; |
| 176 | } |
| 177 | assert(!isPromise(this.storedValueBeforeRewind)); |
| 178 | // because we called asynctify_stop_unwind,the state is now none |
| 179 | assert(this.getState() == AsyncifyStateKind.None); |
| 180 | |
| 181 | // re-enter the function, jump to JUMP-PT-REWIND in wrapImport |
| 182 | // the value will be passed to that point via storedValueBeforeRewind |
| 183 | // |
| 184 | // NOTE: we guarantee that if exception is throw the asynctify state |
| 185 | // will already be at None, this is because we will goto JUMP-PT-REWIND |
| 186 | // which will call aynctify_stop_rewind |
| 187 | this.startRewind(); |
| 188 | result = func(...args); |
| 189 | } |
| 190 | return result; |
| 191 | }; |
| 192 | } |
| 193 | |
| 194 | private startRewind() : void { |
| 195 | if (this.exports.asyncify_start_rewind === undefined) { |
no test coverage detected