diff --git a/src/node.cc b/src/node.cc index fe7d4bcd32e7..b88639f70615 100644 --- a/src/node.cc +++ b/src/node.cc @@ -908,6 +908,11 @@ MakeCallback(const Handle object, Handle argv[]) { HandleScope scope; + if (argc > 6) { + fprintf(stderr, "node::MakeCallback - Too many args (%d)\n", argc); + abort(); + } + Local callback_v = object->Get(symbol); if (!callback_v->IsFunction()) { String::Utf8Value method(symbol); @@ -918,18 +923,6 @@ MakeCallback(const Handle object, abort(); } - Local callback = Local::Cast(callback_v); - - return scope.Close(MakeCallback(object, callback, argc, argv)); -} - -Handle -MakeCallback(const Handle object, - const Handle callback, - int argc, - Handle argv[]) { - HandleScope scope; - // TODO Hook for long stack traces to be made here. TryCatch try_catch; @@ -950,9 +943,9 @@ MakeCallback(const Handle object, } Local object_l = Local::New(node_isolate, object); - Local callback_l = Local::New(node_isolate, callback); + Local symbol_l = Local::New(node_isolate, symbol); - Local args[3] = { object_l, callback_l, argArray }; + Local args[3] = { object_l, symbol_l, argArray }; Local ret = process_makeCallback->Call(process, ARRAY_SIZE(args), args); diff --git a/src/node.js b/src/node.js index f86a95042621..9fc68e4986d8 100644 --- a/src/node.js +++ b/src/node.js @@ -296,6 +296,8 @@ }; startup.processMakeCallback = function() { + // Along with EventEmitter.emit, this is the hottest code in node. + // Everything that comes from C++ into JS passes through here. process._makeCallback = function(obj, fn, args) { var domain = obj.domain; if (domain) { @@ -303,7 +305,38 @@ domain.enter(); } - var ret = fn.apply(obj, args); + // I know what you're thinking, why not just use fn.apply + // Because we hit this function a lot, and really want to make sure + // that V8 can optimize it as well as possible. + var ret; + switch (args.length) { + case 0: + ret = obj[fn](); + break; + case 1: + ret = obj[fn](args[0]); + break; + case 2: + ret = obj[fn](args[0], args[1]); + break; + case 3: + ret = obj[fn](args[0], args[1], args[2]); + break; + case 4: + ret = obj[fn](args[0], args[1], args[2], args[3]); + break; + case 5: + ret = obj[fn](args[0], args[1], args[2], args[3], args[4]); + break; + case 6: + ret = obj[fn](args[0], args[1], args[2], args[3], args[4], args[5]); + break; + + default: + // How did we even get here? This should abort() in C++ land! + throw new Error('too many args to makeCallback'); + break; + } if (domain) domain.exit();