diff --git a/lib/domain.js b/lib/domain.js index 300d9cd050d..7d4067b3c10 100644 --- a/lib/domain.js +++ b/lib/domain.js @@ -149,16 +149,15 @@ Domain.prototype.bind = function(cb, interceptError) { var b = function() { // disposing turns functions into no-ops if (self._disposed) return; - var args = Array.prototype.slice.call(arguments); if (this instanceof Domain) { - return cb.apply(this, args); + return cb.apply(this, arguments); } // only intercept first-arg errors if explicitly requested. - if (interceptError && args[0] && - (args[0] instanceof Error)) { - var er = args[0]; + if (interceptError && arguments[0] && + (arguments[0] instanceof Error)) { + var er = arguments[0]; decorate(er, { domain_bound: cb, domain_thrown: false, @@ -167,11 +166,37 @@ Domain.prototype.bind = function(cb, interceptError) { self.emit('error', er); return; } + // remove first-arg if intercept as assumed to be the error-arg - if (interceptError && args.length) args.shift(); + if (interceptError) + var len = arguments.length; + var args; + switch (len) { + case 0: + case 1: + // no args that we care about. + args = []; + break; + case 2: + // optimization for most common case: cb(er, data) + args = [arguments[1]]; + break; + default: + // slower for less common case: cb(er, foo, bar, baz, ...) + args = new Array(len - 1); + for (var i = 1; i < len; i++) { + args[i] = arguments[i - 1]; + } + break; + } + self.enter(); + var ret = cb.apply(this, args); + self.exit(); + return ret; + } self.enter(); - var ret = cb.apply(this, args); + var ret = cb.apply(this, arguments); self.exit(); return ret; };