Comparing version 0.0.6 to 0.1.0
@@ -96,3 +96,3 @@ var block = exports, | ||
Block.prototype.split = function split(at, root, asyncify) { | ||
Block.prototype.split = function split(at, root, asyncify, marker) { | ||
var index = this.instructions.indexOf(at), | ||
@@ -118,4 +118,5 @@ head = this.instructions.slice(0, index), | ||
fn.name = '__$fn' + next.id; | ||
fn.params = ['__$r']; | ||
fn.params = ['__$e', '__$r']; | ||
fn.isExpression = false; | ||
next.instructions = [this.add('async-test-err')].concat(next.instructions); | ||
@@ -125,3 +126,7 @@ this.ended = false; | ||
if (asyncify) { | ||
at.args.push(this.add('get', [ fn.name ])); | ||
if (marker >= 0) { | ||
at.args[at.args.length - marker].args[0] = fn.name; | ||
} else { | ||
at.args.push(this.add('get', [ fn.name ])); | ||
} | ||
this.instructions.push(at); | ||
@@ -128,0 +133,0 @@ |
@@ -102,3 +102,3 @@ var cfg = exports, | ||
Cfg.prototype.split = function split(at, root, asyncify) { | ||
Cfg.prototype.split = function split(at, root, asyncify, marker) { | ||
var block = at.block; | ||
@@ -109,3 +109,3 @@ | ||
var info = block.split(at, root, asyncify); | ||
var info = block.split(at, root, asyncify, marker); | ||
this.asyncifyState[block.id] = info.fn; | ||
@@ -121,3 +121,3 @@ | ||
info.next.frontier.forEach(function(block) { | ||
var fn = this.split(block.instructions[0], root, false); | ||
var fn = this.split(block.instructions[0], root, false, marker); | ||
@@ -151,2 +151,20 @@ block.predecessors.forEach(function(pred) { | ||
function markerIndex(instr, marker) { | ||
if (!marker) return -1; | ||
var args; | ||
if (instr.type === 'call') { | ||
args = instr.args.slice(1); | ||
} else if (instr.type === 'method') { | ||
args = instr.args.slice(2); | ||
} | ||
if (!args) return -1; | ||
var found = -1; | ||
args.forEach(function(arg, i) { | ||
if (arg.type === 'get' && arg.args[0] === marker) { | ||
found = args.length - i; | ||
} | ||
}); | ||
return found; | ||
} | ||
// Test whether instr matches 'fn' or not | ||
@@ -202,2 +220,7 @@ function match(instr) { | ||
} | ||
if (options.marker && block.fn.root.instr) { | ||
var marker = block.fn.root.instr.params.indexOf(options.marker); | ||
if (marker < 0) return false; | ||
block.fn.root.instr.params[marker] = '__$callback'; | ||
} | ||
@@ -232,6 +255,7 @@ hasDeclaration[block.id] = block; | ||
block.instructions.forEach(function(instr) { | ||
if (!match(instr)) return; | ||
var marker = markerIndex(instr, options.marker); | ||
if (marker < 0 && !match(instr)) return; | ||
// Split graph at instruction | ||
this.split(instr, instr.block.getRoot(), true); | ||
var fn = this.split(instr, instr.block.getRoot(), true, marker); | ||
@@ -1017,3 +1041,3 @@ // Replace all instruction uses by __$r | ||
Cfg.prototype.visitFor = function visitFor(ast) { | ||
this.visit(ast.init); | ||
if (ast.init) this.visit(ast.init); | ||
@@ -1034,3 +1058,3 @@ return this.enterLoop(function(end, loop) { | ||
Cfg.prototype.visitForIn = function visitFor(ast) { | ||
Cfg.prototype.visitForIn = function visitForIn(ast) { | ||
var left = ast.left, | ||
@@ -1125,3 +1149,3 @@ right = ast.right; | ||
Cfg.prototype.visitThrow = function visitTry(ast) { | ||
Cfg.prototype.visitThrow = function visitThrow(ast) { | ||
this.add('throw', ast.argument ? [ this.visit(ast.argument) ] : []); | ||
@@ -1140,3 +1164,3 @@ this.current.end(); | ||
Cfg.prototype.visitSwitch = function visitTry(ast) { | ||
Cfg.prototype.visitSwitch = function visitSwitch(ast) { | ||
throw new TypeError('Switch is not implemented yet'); | ||
@@ -1143,0 +1167,0 @@ var self = this, |
@@ -207,2 +207,4 @@ var renderer = exports, | ||
fn = this.renderAsyncEnd; | ||
} else if (t === 'async-test-err') { | ||
fn = this.renderAsyncTestErr; | ||
} else if (t === 'nop') { | ||
@@ -400,3 +402,3 @@ fn = this.renderNop; | ||
['dot', ['name', '__$callback'], 'call'], | ||
[['name', 'this']].concat(args)]]; | ||
[['name', 'this'],['name', 'null']].concat(args)]]; | ||
}; | ||
@@ -412,4 +414,11 @@ | ||
Renderer.prototype.renderAsyncTestErr = function renderAsyncTestErr(args) { | ||
return ['if', ['name', '__$e'], ['block', | ||
[['return', ['call', | ||
['dot', ['name', '__$callback'], 'call'], | ||
[['name', 'this'],['name', '__$e']]]]]]]; | ||
}; | ||
Renderer.prototype.renderNop = function renderNop() { | ||
return null; | ||
}; |
{ | ||
"name": "spoon", | ||
"version": "0.0.6", | ||
"version": "0.1.0", | ||
"main": "lib/spoon", | ||
@@ -5,0 +5,0 @@ "dependencies": { |
@@ -22,3 +22,4 @@ var spoon = require('..'), | ||
vm.runInNewContext(code + ';\nfn(callback)', { | ||
callback: function(r) { | ||
callback: function(err, r) { | ||
assert.equal(err, null); | ||
if (once) throw new Error('Called twice'); | ||
@@ -39,3 +40,3 @@ once = true; | ||
async: function async(a, callback) { | ||
callback(a); | ||
callback(null, a); | ||
} | ||
@@ -52,3 +53,3 @@ }; | ||
function async(a, callback) { | ||
callback(1); | ||
callback(null, 1); | ||
} | ||
@@ -64,3 +65,3 @@ return 1, async(1), 2; | ||
function async(a, callback) { | ||
callback(a); | ||
callback(null, a); | ||
} | ||
@@ -84,3 +85,3 @@ | ||
function async(a, b, callback) { | ||
callback(a + b); | ||
callback(null, a + b); | ||
} | ||
@@ -102,3 +103,3 @@ | ||
function async(a, b, callback) { | ||
callback(a + b); | ||
callback(null, a + b); | ||
} | ||
@@ -123,3 +124,3 @@ | ||
function async(a, b, callback) { | ||
callback(a + b); | ||
callback(null, a + b); | ||
} | ||
@@ -126,0 +127,0 @@ |
64181
1946