1. 程式人生 > >深度理解nodejs[1]-node底層機制

深度理解nodejs[1]-node底層機制

nodejs作為javascript在後端執行的環境,原始碼由js與C完成。本質上,nodejs是藉助於谷歌V8引擎來執行javascript程式碼。使用了C的libuv庫來處理網路,訪問檔案系統等操作。

nodejs的作用

1、提供一種介面,僅僅書寫javascript的程式碼,就可以讓他們正確執行,不用書寫C++程式碼。
2、豐富的api。http、fs、path、crypto …modules

nodejs原始碼

nodejs原始碼:

https://github.com/nodejs/node

lib:nodejs庫函式
src:庫函式的C++實現。

pbkdf2中js程式碼

pbkdf2函式的實現:node/lib/internal/crypto/pbkdf2.js

1
2
3
4
5
6
7
8
9
10
11
12
function pbkdf2(password, salt, iterations, keylen, digest, callback) {
 ...

 handleError(keybuf, password, salt, iterations, digest, wrap);
}

呼叫了:

const rc = _pbkdf2(keybuf, password, salt, iterations, digest, wrap);


_pbkdf2綁定了C++函式的實現。
const { pbkdf2: _pbkdf2 } = internalBinding('crypto');

internalBinding連結javascript程式碼與C++程式碼。

pbkdf2中c++程式碼

crypto庫原始碼實現:node/src/node_crypto.cc

1
2
3
4
5
6
7
8
9
10
11
12
13
繫結
env->SetMethod(target, "pbkdf2", PBKDF2);
inline void PBKDF2(const FunctionCallbackInfo<Value>& args)
{

   ...
  job->iteration_count = args[3].As<Uint32>()->Value();
  Utf8Value digest_name(args.GetIsolate(), args[4]);
  job->digest = EVP_get_digestbyname(*digest_name);
  if (job->digest == nullptr) return rv.Set(-1);
  if (args[5]->IsObject()) return PBKDF2Job::Run(std::move(job), args[5]);
  env->PrintSyncTrace();
  job->DoThreadPoolWork();
  rv.Set(job->ToResult());
}

v8

node/src/node_crypto.cc中我們還會看到很多的v8,將javascript型別轉換為c++型別

1
2
3
4
5
6
 using v8::Array;
using v8::Boolean;
using v8::ConstructorBehavior;
using v8::Context;
using v8::DontDelete;
...

libuv

node/src/node_crypto.cc中我們還會看到很多的libuv,處理併發操作。

1
2
3
...
static uv_once_t init_once = UV_ONCE_INIT;
uv_once(&init_once, InitCryptoOnce);