Research on compiling NODEJS and its source code

Source: Internet
Author: User
Tags git client joyent

This article will study the principle and essence of Nodejs from the source code, discuss the application scenarios of Nodejs and the practical guide of high performance development.

Directory:

Section First: Compiling node. js

Section II: Source Code Analysis


Enter the topic: The following is done under Win7 64, other platform compilation, please see the official website.

first section: compiling node. js, the process is simple

1, download the source code. git clone https://github.com/joyent/node

If you do not have a GIT client installed, you can download it by clicking Download ZIP in the open Https://github.com/joyent/node

2. Install Python 2.6 or 2.7 and Visual Studio or 2012, I am here python 2.7.8 and Visual Studio

3. Enter node directory to execute VCBUILD release


The compilation succeeds in about more than 10 minutes, and Node.exe is generated in the release directory. Here is a diagram of my successful compilation.



section II: Source Code Analysis

We open the node directory in the IDE, so that we can see the source code. I'm here to view the idea.


Benchmark: Some Nodejs performance test code

Build: Compile Nodejs Build Directory

Debug: compile Nodejs build directory

Release: compile Nodejs build directory

Deps:nodejs-dependent toolkit, including V8, Http_parser, Opensslzlib, zlib, UV ...

Doc: Documentation

Lib: contains JavaScript source code

SRC: Contains C + + source code

Test: Testing the Code

Tools: A tool for compiling

Here we only need to focus on the SRC and Lib folders.


1, from the node.cc file to see the node process startup process

int Start (int argc, char** argv) {const char* replaceinvalid = getenv ("Node_invalid_utf8"); if (Replaceinvalid = = NULL) write_utf8_flags |= String::replace_invalid_utf8; #if!defined (_WIN32)//Try hard don't to L  OSE SIGUSR1 signals during the bootstrap process.  Installearlydebugsignalhandler (); #endif assert (argc > 0); Hack around with the argv pointer.  Used for process.title = "blah".  argv = Uv_setup_args (argc, argv);  This needs to run *before* v8::initialize ().  The const_cast is no//optional, in case you ' re wondering.  int EXEC_ARGC;  Const char** EXEC_ARGV; Init (&AMP;ARGC, Const_cast<const char**> (argv), &AMP;EXEC_ARGC, &exec_argv); #if have_openssl//V8 on Windows Doesn ' t has a good source of entropy.  Seed it from//OpenSSL ' s pool.  V8::setentropysource (crypto::entropysource); #endif int code;  V8::initialize ();    {Locker Locker (node_isolate);    Isolate::scope Isolate_scope (node_isolate);    Handlescope Handle_scope (node_isolate); local&Lt    context> context = context::new (node_isolate);    environment* env = createenvironment (node_isolate, Context, argc, argv, EXEC_ARGC, EXEC_ARGV);      Assign env to the debugger ' s context if (debugger_running) {handlescope scope (env->isolate ());    Env->assigntocontext (V8::D ebug::getdebugcontext ()); }//This context::scope are here and enabledebug () can look up the current//environment with Environment::getcurren    T ().    TODO (Bnoordhuis) Reorder The debugger initialization logic so it can/is removed.      {Context::scope Context_scope (Env->context ());      BOOL more;        do {more = Uv_run (Env->event_loop (), uv_run_once);          if (more = = False) {emitbeforeexit (env);          Emit ' Beforeexit ' If the loop became alive either after emitting//event, or after running some callbacks.          more = Uv_loop_alive (Env->event_loop ()); if (Uv_run (Env->event_loop (), uv_run_nowait)! = 0)           more = true;      }} while (more = = true);      Code = EMITEXIT (env);    Runatexit (env);    } env->dispose ();  env = NULL;  } check_ne (Node_isolate, NULL);  Node_isolate->dispose ();  Node_isolate = NULL;  V8::D ispose ();  Delete[] EXEC_ARGV;  EXEC_ARGV = NULL; return code;}

environment* createenvironment (isolate* Isolate, handle<context> Context, int argc, const char* const* argv, int exec_  ARGC, const char* const* exec_argv) {Handlescope handle_scope (isolate);  Context::scope Context_scope (context);  environment* env = environment::new (context);  Uv_check_init (Env->event_loop (), Env->immediate_check_handle ());  Uv_unref (Reinterpret_cast<uv_handle_t*> (Env->immediate_check_handle ()));  Uv_idle_init (Env->event_loop (), Env->immediate_idle_handle ());  Inform V8 ' s CPU Profiler when we ' re idle. The profiler is sampling-based//And not all samples is created equal;  Mark the wall clock time spent in//epoll_wait () and friends so profiling tools can filter it out.  The samples//still end up in V8.log and with State=idle rather than state=external. TODO (Bnoordhuis) DepEnds on a LIBUV implementation detail then we should//probably fortify in the API contract, namely this last Starte  D Prepare//or check watcher runs first. It ' s not 100% foolproof; If an add-on starts//a prepare or check watcher after us, any samples attributed to its callback/'ll be recorded W  ITH State=idle.  Uv_prepare_init (Env->event_loop (), Env->idle_prepare_handle ());  Uv_check_init (Env->event_loop (), Env->idle_check_handle ());  Uv_unref (Reinterpret_cast<uv_handle_t*> (Env->idle_prepare_handle ()));  Uv_unref (Reinterpret_cast<uv_handle_t*> (Env->idle_check_handle ()));  if (v8_is_profiling) {startprofileridlenotifier (env);  } local<functiontemplate> process_template = functiontemplate::new (isolate);  Process_template->setclassname (fixed_one_byte_string (Isolate, "process"));  local<object> process_object = process_template->getfunction ()->newinstance ();  Env->set_process_object (Process_object); SetupprocessobJect (env, argc, argv, EXEC_ARGC, EXEC_ARGV);  Load (env); return env;}

void Setupprocessobject (environment* env, int argc, const char* const* argv, int EXEC_ARGC, const char* const* exec_argv) {handlescope scope (env->i  Solate ());  local<object> process = Env->process_object (); Process->setaccessor (Env->title_string (), Processtitlegetter, Processtit  Lesetter); Process.version Readonly_property (Process, "version", Fixed_one_byte_string (env-  >isolate (), node_version)); Process.moduleloadlist Readonly_property (Process, "moduleloadlist", Env->modu  Le_load_list_array ());  Process.versions local<object> versions = Object::new (Env->isolate ());  Readonly_property (Process, "versions", versions); const char http_parser_version[] = node_stringify (http_parser_version_major) "."                                    Node_stringify (Http_parser_version_minor); Readonly_property (versions, "Http_parser", Fixed_one_byte_string (Env->isolate (),  http_parser_version)); +1 to get rid of the leading ' V ' readonly_property (versions, "Node", Onebytestri  Ng (Env->isolate (), node_version + 1)); Readonly_property (versions, "V8", Onebytestring (Env->isolate (), v8::getversion ())  ); Readonly_property (versions, "UV", onebytestring (Env->isolate (), uv_version_string  ())); Readonly_property (versions, "Zlib", Fixed_one_byte_string (Env->isolate (), Zlib_ve  rsion));  const char node_modules_version[] = node_stringify (node_module_version); Readonly_property (versions, "Modules", Fixed_one_byte_string (Env->isolate (), node_modules_version));

void Load (environment* env) {Handlescope handle_scope (env->isolate ()); Compile, execute the src/node.js file. (which is included as static C//string in Node_natives.h.  ' Natve_node ' is the string containing that//source code.)  The node. js file returns a function ' F ' atexit (atexit);  TryCatch Try_catch; Disable verbose mode to stop fatalexception () handler from trying//to handle the exception.  Errors this early in the start-up phase//is not safe to ignore. Try_catch.  Setverbose (FALSE);  local<string> script_name = fixed_one_byte_string (Env->isolate (), "node. js");  local<value> F_value = executestring (env, MainSource (env), script_name); if (Try_catch.    Hascaught ()) {reportexception (env, try_catch);  Exit (10);  } assert (F_value->isfunction ());  local<function> f = local<function>::cast (F_value); Now we call ' F ' with the ' process ' variable, that we ' ve built up with//all of our bindings. Inside node. js we ' ll take care of assigning things to//their places. We start the process this on order to is more modular. Developers//Who does not like how ' src/node.js ' setups the module system but does like//node ' s I/O bindings may want to  Replace ' F ' with their own function. ADD a reference to the global object local<object> global = Env->context ()->global ();


The general process is this:

Load V8, OpenSSL ...

Create a environment environment

Set up the process progress object

Execute node. js file


2, from the node. js file to see the global configuration process, spit trough a bit, nodejs source write too, C language born style?

This file is roughly a configuration of global variables, configuration process, and Module object definition.


The following will delve into the file of node. js and the C + + class in conjunction with SRC, explaining nodejs with the JS code under LIB.

We can draw a conclusion: Nodejs = node API + V8;




Research on compiling NODEJS and its source code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.