Skip to content

Instantly share code, notes, and snippets.

@jlongster
Last active January 1, 2016 17:29
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlongster/8177833 to your computer and use it in GitHub Desktop.
Save jlongster/8177833 to your computer and use it in GitHub Desktop.
working debugger with pure JavaScript state machine transform
# will suspend on every function call (very proof of concept,
# it will be really easy to get access to local variables, a
# full stack, and even live evaluate within any closure)
% node test.out.js
[suspended] foo()
> c
[suspended] bar(x)
> c
[suspended] bar(i - 1)
> c
[suspended] bar(i - 1)
> c
[suspended] bar(i - 1)
> c
[suspended] bar(i - 1)
> c
[suspended] bar(i - 1)
> stack
*** stack:
bar
bar
bar
bar
bar
bar
foo
root
> c
[suspended] foo()()
> c
15
function bar(i) {
if(i > 0) {
return i + bar(i - 1);
}
return 0;
}
function foo() {
var x = 5;
var y = bar(x);
return function() { return y; };
}
console.log(foo()());
__debug_sourceURL="test.js";
var __debug = {
"1": {
"5": {
"start": {
"line": 16,
"column": 12
},
"end": {
"line": 16,
"column": 17
}
},
"7": {
"start": {
"line": 16,
"column": 12
},
"end": {
"line": 16,
"column": 19
}
},
"8": {
"start": {
"line": 16,
"column": 0
},
"end": {
"line": 16,
"column": 20
}
}
},
"2": {
"3": {
"start": {
"line": 11,
"column": 12
},
"end": {
"line": 11,
"column": 18
}
}
},
"3": {},
"4": {
"3": {
"start": {
"line": 4,
"column": 19
},
"end": {
"line": 4,
"column": 29
}
}
}
}
invokeRoot(function() {
var bar, foo;
return invokeFunction("\u003Canon\u003E", 1, function($ctx) {
while (1) switch ($ctx.next) {
case 0:
foo = function foo() {
var x, y;
return invokeFunction("foo", 2, function foo$($ctx) {
while (1) switch ($ctx.next) {
case 0:
x = 5;
$ctx.next = 3;
return bar(x);
case 3:
y = $ctx.returned;
$ctx.rval = function() { return invokeFunction("\u003Canon\u003E", 3, function($ctx) {
while (1) switch ($ctx.next) {
case 0:
$ctx.rval = y;
delete $ctx.thrown;
$ctx.next = 4;
break;
case 4:
case "end":
return $ctx.stop();
}
}, this) };
delete $ctx.thrown;
$ctx.next = 8;
break;
case 8:
case "end":
return $ctx.stop();
}
}, this);
};
bar = function bar(i) {
return invokeFunction("bar", 4, function bar$($ctx) {
while (1) switch ($ctx.next) {
case 0:
if (!(i > 0)) {
$ctx.next = 7;
break;
}
$ctx.next = 3;
return bar(i - 1);
case 3:
$ctx.rval = i + $ctx.returned;
delete $ctx.thrown;
$ctx.next = 11;
break;
case 7:
$ctx.rval = 0;
delete $ctx.thrown;
$ctx.next = 11;
break;
case 11:
case "end":
return $ctx.stop();
}
}, this);
};
$ctx.next = 8;
$ctx.next = 5;
return foo();
case 5:
$ctx.next = 7;
return (0, $ctx.returned)();
case 7:
return console.log($ctx.returned);
case 8:
case "end":
return $ctx.stop();
}
}, this);
}, this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment