From 21b45667f12d73a03aced51a49274fd5e14f5e50 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sun, 17 Jul 2016 21:30:32 +0300 Subject: [PATCH] Add control flow checker to gen-thread.js --- index.js | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index e30d648..62212f4 100644 --- a/index.js +++ b/index.js @@ -14,11 +14,11 @@ function finishq() i--; } } - while (pending.length > 0 && q.length < pending[0][1]) + while (pending.length > 0 && q.length < pending[0][2]) { var t = pending.shift(); q.push(t[0]); - t[0](); + process.nextTick(t[1]); } } @@ -29,19 +29,22 @@ function runThread(main, arg, done) { // pass parameters as yield result var pass = Array.prototype.slice.call(arguments, 0); + var v; try { v = thread.gen.next(pass); } catch (e) { - v = { done: 1 }; + v = { done: 1, error: e }; } if (v.done) { thread._done = true; - finishq(); + process.nextTick(finishq); } + if (v.error) + throw v.error; if (v.done && done) done(v.value); }; @@ -53,13 +56,31 @@ function runThread(main, arg, done) if (q.length < count) { q.push(thread); - setTimeout(thread, 1); + process.nextTick(thread.cb()); } else { - pending.push([ thread, count ]); + pending.push([ thread, thread.cb(), count ]); } }; + thread.cb = function() + { + var fn = function() + { + if (thread._current != fn) + { + throw new Error('Broken control flow! Callback'+ + thread._current._stack.replace(/^\s*Error\s*at Function\.thread\.cb\s*\([^)]*\)/, '')+ + '\nmust be called to resume thread, but this one is called instead:'+ + fn._stack.replace(/^\s*Error\s*at Function\.thread\.cb\s*\([^)]*\)/, '')+'\n--' + ); + } + return thread.apply(thread, arguments); + }; + fn._stack = new Error().stack; + thread._current = fn; + return fn; + }; thread(); }