diff --git a/src/node.cc b/src/node.cc index 84af978f22..890ea6355d 100644 --- a/src/node.cc +++ b/src/node.cc @@ -100,6 +100,7 @@ Persistent process_symbol; Persistent domain_symbol; static Persistent process; +static Persistent process_tickCallback; static Persistent exports_symbol; @@ -114,7 +115,9 @@ static Persistent heap_used_symbol; static Persistent fatal_exception_symbol; -static Persistent process_makeCallback; +static Persistent enter_symbol; +static Persistent exit_symbol; +static Persistent disposed_symbol; static bool print_eval = false; @@ -926,11 +929,6 @@ 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); @@ -945,27 +943,60 @@ MakeCallback(const Handle object, TryCatch try_catch; - if (process_makeCallback.IsEmpty()) { - Local cb_v = process->Get(String::New("_makeCallback")); - if (!cb_v->IsFunction()) { - fprintf(stderr, "process._makeCallback assigned to non-function\n"); - abort(); + if (enter_symbol.IsEmpty()) { + enter_symbol = NODE_PSYMBOL("enter"); + exit_symbol = NODE_PSYMBOL("exit"); + disposed_symbol = NODE_PSYMBOL("_disposed"); + } + + Local domain_v = object->Get(domain_symbol); + Local domain; + Local enter; + Local exit; + if (!domain_v->IsUndefined()) { + domain = domain_v->ToObject(); + if (domain->Get(disposed_symbol)->BooleanValue()) { + // domain has been disposed of. + return Undefined(node_isolate); } - Local cb = cb_v.As(); - process_makeCallback = Persistent::New(cb); + enter = Local::Cast(domain->Get(enter_symbol)); + enter->Call(domain, 0, NULL); } - Local argArray = Array::New(argc); - for (int i = 0; i < argc; i++) { - argArray->Set(Integer::New(i, node_isolate), argv[i]); + if (try_catch.HasCaught()) { + FatalException(try_catch); + return Undefined(node_isolate); } - Local object_l = Local::New(node_isolate, object); - Local symbol_l = Local::New(node_isolate, symbol); + Local callback = Local::Cast(callback_v); + Local ret = callback->Call(object, argc, argv); - Local args[3] = { object_l, symbol_l, argArray }; + if (try_catch.HasCaught()) { + FatalException(try_catch); + return Undefined(node_isolate); + } - Local ret = process_makeCallback->Call(process, ARRAY_SIZE(args), args); + if (!domain_v->IsUndefined()) { + exit = Local::Cast(domain->Get(exit_symbol)); + exit->Call(domain, 0, NULL); + } + + if (try_catch.HasCaught()) { + FatalException(try_catch); + return Undefined(node_isolate); + } + + // process nextTicks after every time we get called. + if (process_tickCallback.IsEmpty()) { + Local cb_v = process->Get(String::New("_tickCallback")); + if (!cb_v->IsFunction()) { + fprintf(stderr, "process._tickCallback assigned to non-function\n"); + abort(); + } + Local cb = cb_v.As(); + process_tickCallback = Persistent::New(cb); + } + process_tickCallback->Call(process, NULL, 0); if (try_catch.HasCaught()) { FatalException(try_catch); diff --git a/src/node.js b/src/node.js index 62f5fa8ea6..a9e795acdd 100644 --- a/src/node.js +++ b/src/node.js @@ -48,7 +48,6 @@ startup.processAssert(); startup.processConfig(); startup.processNextTick(); - startup.processMakeCallback(); startup.processStdio(); startup.processKillAndExit(); startup.processSignalHandlers(); @@ -297,57 +296,6 @@ }); }; - 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) { - if (domain._disposed) return; - domain.enter(); - } - - // 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(); - - // process the nextTicks after each time we get called. - process._tickCallback(); - return ret; - }; - }; - startup.processNextTick = function() { var nextTickQueue = []; var nextTickIndex = 0; diff --git a/test/message/stdin_messages.out b/test/message/stdin_messages.out index b0ad45bda4..cd7c12a7b9 100644 --- a/test/message/stdin_messages.out +++ b/test/message/stdin_messages.out @@ -11,7 +11,6 @@ SyntaxError: Strict mode code may not include a with statement at Socket.EventEmitter.emit (events.js:*:*) at _stream_readable.js:*:* at process._tickCallback (node.js:*:*) - at process._makeCallback (node.js:*:*) 42 42 @@ -27,7 +26,6 @@ Error: hello at Socket.EventEmitter.emit (events.js:*:*) at _stream_readable.js:*:* at process._tickCallback (node.js:*:*) - at process._makeCallback (node.js:*:*) [stdin]:1 throw new Error("hello") @@ -41,7 +39,6 @@ Error: hello at Socket.EventEmitter.emit (events.js:*:*) at _stream_readable.js:*:* at process._tickCallback (node.js:*:*) - at process._makeCallback (node.js:*:*) 100 [stdin]:1 @@ -56,7 +53,6 @@ ReferenceError: y is not defined at Socket.EventEmitter.emit (events.js:*:*) at _stream_readable.js:*:* at process._tickCallback (node.js:*:*) - at process._makeCallback (node.js:*:*) [stdin]:1 var ______________________________________________; throw 10 diff --git a/test/message/timeout_throw.out b/test/message/timeout_throw.out index de8ce51a5b..f6e207e382 100644 --- a/test/message/timeout_throw.out +++ b/test/message/timeout_throw.out @@ -4,4 +4,3 @@ ReferenceError: undefined_reference_error_maker is not defined at null._onTimeout (*test*message*timeout_throw.js:*:*) at Timer.listOnTimeout [as ontimeout] (timers.js:*:*) - at process._makeCallback (node.js:*:*)