node.js代码: (function(process){ ......... }); 由此看出,执行完node.js得到的是一个函数 在node.cc中对函数处理: assert(f_value->IsFunction()); Local f = Local::Cast(f_value); 创建函数执行环境,调用函数,把process传入 Local Local args[1] = { Local::New(process_l) }; f->Call(global, 1, args); 执行: uv_run(uv_default_loop(), UV_RUN_DEFAULT);
启动入口函数代码参考: int Start(int argc, char *argv[]) { // Hack aroung with the argv pointer. Used for process.title = "blah". argv = uv_setup_args(argc, argv);
// Logic to duplicate argv as Init() modifies arguments // that are passed into it. char **argv_copy = copy_argv(argc, argv);
// This needs to run *before* V8::Initialize() // Use copy here as to not modify the original argv: Init(argc, argv_copy); V8::Initialize(); { Locker locker; HandleScope handle_scope;
// Create the one and only Context. Persistent context = Context::New(); Context::Scope context_scope(context);
// Use original argv, as we're just copying values out of it. Handle v8_typed_array::AttachBindings(context->Global());
// Create all the objects, load modules, do everything. // so your next reading stop should be node::Load()! Load(process_l);
// All our arguments are loaded. We've evaluated all of the scripts. We // might even have created TCP servers. Now we enter the main eventloop. If // there are no watchers on the loop (except for the ones that were // uv_unref'd) then this function exits. As long as there are active // watchers, it blocks. uv_run(uv_default_loop(), UV_RUN_DEFAULT);
if (args.Length() < 2) { Local exception = Exception::Error( String::New("process.dlopen takes exactly 2 arguments.")); return ThrowException(exception); }
Local String::Utf8Value filename(args[1]); // Cast
if (exports_symbol.IsEmpty()) { exports_symbol = NODE_PSYMBOL("exports"); } Local
if (uv_dlopen(*filename, &lib)) { Local errmsg = String::New(uv_dlerror(&lib)); #ifdef _WIN32 // Windows needs to add the filename into the error message errmsg = String::Concat(errmsg, args[1]->ToString()); #endif return ThrowException(Exception::Error(errmsg)); }
String::Utf8Value path(args[1]); base = *path;
/* Find the shared library filename within the full path. */ #ifdef __POSIX__ pos = strrchr(base, '/'); if (pos != NULL) { base = pos + 1; } #else // Windows for (;;) { pos = strpbrk(base, "\\/:"); if (pos == NULL) { break; } base = pos + 1; } #endif
/* Strip the .node extension. */ pos = strrchr(base, '.'); if (pos != NULL) { *pos = '\0'; }
/* Add the `_module` suffix to the extension name. */ r = snprintf(symbol, sizeof symbol, "%s_module", base); if (r <= 0 || static_cast(r) >= sizeof symbol) { Local exception = Exception::Error(String::New("Out of memory.")); return ThrowException(exception); }
/* Replace dashes with underscores. When loading foo-bar.node, * look for foo_bar_module, not foo-bar_module. */ for (pos = symbol; *pos != '\0'; ++pos) { if (*pos == '-') *pos = '_'; }
node_module_struct *mod; if (uv_dlsym(&lib, symbol, reinterpret_cast(&mod))) { char errmsg[1024]; snprintf(errmsg, sizeof(errmsg), "Symbol %s not found.", symbol); return ThrowError(errmsg); }