V8 엔진이 JS를 기계 코드로 바꾸는 방법

y0ung·2020년 12월 17일
0

모든 시스템은 마이크로프로세서(CPU)를 포함한다.

마이크로프로세서는 전자적인 신호로 동작하는 작은 기계이다. 궁극적으로는 일을 수행한다.우리는 마이크로프로세서에게 지시(instruction)를 주는데 여기서 지시란 것은 마이크로프로세서가 해석할수 있는 언어로 되어 있는 것을 의미한다. 다른 마이크로프로세서들은 다른 언어로 말하는데 가장 일반적인 언어로는 IA-32, x86-64, MIPS 그리고 ARM이 다. 이러한 언어들은 직접 하드웨어와 소통한다. 그래서 거기에 쓰여진 코드는 기계어라고 부른다. 우리가 컴퓨터에 쓴 코드는 변형되거나 컴파일 되어 기계어가 된다.

기계어는 다음과 같이 생겼다.

위 코드는 시스템에서 낮은 레벨의 어떤 메모리 위에 올려져 동작하는 지시가 들어있다.

고 수준의 언어는 기계어에서 많은 추상화가 이루어져 있다. 아래 추상화의 수준에서, 자바스크립트가 기계어로부터 얼마나 추상화가 됐는지 알수 있다.

C/C++는 상대적으로 하드웨어 언어에 가깝고 다른 고수준 언어들보다 훨씬 빠르다.

V8엔진


V8은 구글이 제공하는 강력한 오픈소스 자바스크립트 엔진이다.

자바스크립트 엔진이란?
자바스크립트 코드를 마이크로프로세서가 이해할 수 있는 더 낮은 수준의 언어 혹은 기계어로 변환해주는 역할을 한다.

Rhino, JavaScriptCore, SpiderMonkey와 같은 다양한 종류의 자바스크립트 엔진이 존재하는데, 이 엔진들은 ECMAScript 표준을 따른다. ECMAScript는 스크립팅 언어를 위한 표준을 정의한다. 자바스크립트는 ECMAScript 표준을 기반으로 한다. 이러한 표준은 언어가 어떻게 동작할지 그리고 어떤 특성을 가져야 하는지를 정의한다.

ECMAScript

크롬 V8엔진의 특성

  • C++로 작성됐고 Chrome과 Nodejs에서 사용된다.
  • ECMA-262에 기재된 ECMAScript를 구현했다.
  • 독립(standalone)적으로 동작할 수 있어서 자바스크립트 엔진을 C++ 프로그램에 내장시킬 수 있다.

마지막 항목을 더 깊게 이해해보자. V8엔진은 독립적으로 동작할 수 있고 동시에 C++로 구현된 함수를 자바스크립트의 새로운 특성으로 넣을 수 있다.

예를 들면, print('hello world')는 Node.js에서 유효한 구문이 아니여서, 컴파일하면 에러를 송출할 것이다. 하지만 깃허브에 오픈소스로 제공된 V8엔진의 맨 위에 프린트 문을 추가할수 있다. 그래서 print함수가 native로 동작하게 만들 수 있다. 이러한 행위는 자바스크립트가 ECMAScript 표준이 정의하는 자바스크립트 동작보다 더 많은 동작을 하도록 허용해준다.

C++은 하드 드라이브에 있는 파일과 폴더를 다룰 때 하드웨어와 훨씬 더 가까이 있다. C++로 된 코드를 작성하도록 허용하고 자바스크립트에서 동작 가능하게 만드는 것이 가능하고 그래서 자바스크립트에 더 많은 특성을 추가할 수 있다.

Node.js 자체는 V8엔진, C++ 구현이다. C++로 구현된 V8엔진은 서버사이드 프로그래밍과 네트워킹 어플리케이션을 다룰 수 있게 해준다.

아래에서, Print함수의 구현을 볼 수 있다. print()가 Node.js에서 호출될 때마다, 이 함수는 콜백을 만들고 그 함수가 실행된다.

// 자바스크립트에서 'print' 함수가 호출될 때마다, v8엔진에 의해 콜백이 호출.
// 스페이스와 새로운 라인을 기준으로 분리된 stdout에 있는 인자들을 프린트.
void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
  bool first = true;
  for (int i=0; i<args.length(); i++) {
    v8::HandleScope handle_scope(args.GetIsolate());
    if (first) {
      first = false;
    } else {
      print(" ");
    }
    v8::String::Utf8Value str(args.GetIsolate(), args[i]);
    const char* cstr = ToCString(str);
    printf("%s", cstr);
  }
  printf("\n");
  fflush(stdout);
}

비슷하게, 우리도 C++ 내부에 다른 함수를 추가적으로 구현하여 Node.js에서 인식되도록 할 수 있다.


참고

profile
어제보다는 오늘 더 나은

0개의 댓글