(command, ctx)
| 2134 | // Core execution engine |
| 2135 | // ================================================================= |
| 2136 | unifiedExec(command, ctx) { |
| 2137 | while (true) { |
| 2138 | try { |
| 2139 | var next = this.unifiedEval(command, ctx); |
| 2140 | } catch (e) { |
| 2141 | if (ctx.meta.handlingFinally) { |
| 2142 | console.error(" Exception in finally block: ", e); |
| 2143 | next = _Runtime.HALT; |
| 2144 | } else { |
| 2145 | this.registerHyperTrace(ctx, e); |
| 2146 | if (ctx.meta.errorHandler && !ctx.meta.handlingError) { |
| 2147 | ctx.meta.handlingError = true; |
| 2148 | ctx.locals[ctx.meta.errorSymbol] = e; |
| 2149 | command = ctx.meta.errorHandler; |
| 2150 | continue; |
| 2151 | } else { |
| 2152 | ctx.meta.currentException = e; |
| 2153 | next = _Runtime.HALT; |
| 2154 | } |
| 2155 | } |
| 2156 | } |
| 2157 | if (next == null) { |
| 2158 | throw new Error("Command " + (command.type || "unknown") + " did not return a next element to execute"); |
| 2159 | } else if (next.then) { |
| 2160 | next.then((resolvedNext) => { |
| 2161 | this.unifiedExec(resolvedNext, ctx); |
| 2162 | }).catch((reason) => { |
| 2163 | this.unifiedExec({ |
| 2164 | resolve: function() { |
| 2165 | throw reason; |
| 2166 | } |
| 2167 | }, ctx); |
| 2168 | }); |
| 2169 | return; |
| 2170 | } else if (next === _Runtime.HALT) { |
| 2171 | if (ctx.meta.finallyHandler && !ctx.meta.handlingFinally) { |
| 2172 | ctx.meta.handlingFinally = true; |
| 2173 | command = ctx.meta.finallyHandler; |
| 2174 | } else { |
| 2175 | if (ctx.meta.onHalt) { |
| 2176 | ctx.meta.onHalt(); |
| 2177 | } |
| 2178 | if (ctx.meta.currentException) { |
| 2179 | if (ctx.meta.reject) { |
| 2180 | ctx.meta.reject(ctx.meta.currentException); |
| 2181 | return; |
| 2182 | } else { |
| 2183 | throw ctx.meta.currentException; |
| 2184 | } |
| 2185 | } else { |
| 2186 | return; |
| 2187 | } |
| 2188 | } |
| 2189 | } else { |
| 2190 | command = next; |
| 2191 | } |
| 2192 | } |
| 2193 | } |
no test coverage detected