PowerPoint 프레젠테이션

Similar documents
PowerPoint 프레젠테이션

C# Programming Guide - Types

PowerPoint 프레젠테이션

1

Interstage5 SOAP서비스 설정 가이드

untitled

Eclipse 와 Firefox 를이용한 Javascript 개발 발표자 : 문경대 11 년 10 월 26 일수요일

playnode.key

Modern Javascript

KT AI MAKERS KIT 사용설명서 (Node JS 편).indd

Mobile Service > IAP > Android SDK [ ] IAP SDK TOAST SDK. IAP SDK. Android Studio IDE Android SDK Version (API Level 10). Name Reference V

11강-힙정렬.ppt

Orcad Capture 9.x

Microsoft Word - FunctionCall

Analytics > Log & Crash Search > Unity ios SDK [Deprecated] Log & Crash Unity ios SDK. TOAST SDK. Log & Crash Unity SDK Log & Crash Search. Log & Cras

PowerPoint 프레젠테이션

02 C h a p t e r Java

example code are examined in this stage The low pressure pressurizer reactor trip module of the Plant Protection System was programmed as subject for

Javascript.pages

Spring Boot/JDBC JdbcTemplate/CRUD 예제

thesis

DE1-SoC Board

PowerPoint 프레젠테이션

05-class.key

untitled

DIY 챗봇 - LangCon

제이쿼리 (JQuery) 정의 자바스크립트함수를쉽게사용하기위해만든자바스크립트라이브러리. 웹페이지를즉석에서변경하는기능에특화된자바스크립트라이브러리. 사용법 $( 제이쿼리객체 ) 혹은 $( 엘리먼트 ) 참고 ) $() 이기호를제이쿼리래퍼라고한다. 즉, 제이쿼리를호출하는기호

6주차.key

Microsoft PowerPoint - web-part03-ch19-node.js기본.pptx

OCaml

AMP는 어떻게 빠른 성능을 내나.key

PowerPoint Template

자바 프로그래밍

chap10.PDF

서현수

- 목차 - - ios 개발환경및유의사항. - 플랫폼 ios Project. - Native Controller와플랫폼화면연동. - 플랫폼 Web(js)-Native 간데이터공유. - 플랫폼확장 WN Interface 함수개발. - Network Manager clas

final_thesis

No Slide Title

2002년 2학기 자료구조

282서비스업관리-마트

4. #include <stdio.h> #include <stdlib.h> int main() { functiona(); } void functiona() { printf("hihi\n"); } warning: conflicting types for functiona

Secure Programming Lecture1 : Introduction

쿠폰형_상품소개서

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

The Self-Managing Database : Automatic Health Monitoring and Alerting

Microsoft Word - ExecutionStack

chap01_time_complexity.key

2007_2_project4

chap 5: Trees

API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Docum

본책- 부속물

MAX+plus II Getting Started - 무작정따라하기

USER GUIDE

rmi_박준용_final.PDF

Microsoft PowerPoint - PL_03-04.pptx

07 자바의 다양한 클래스.key

Special Theme _ 모바일웹과 스마트폰 본 고에서는 모바일웹에서의 단말 API인 W3C DAP (Device API and Policy) 의 표준 개발 현황에 대해서 살펴보고 관 련하여 개발 중인 사례를 통하여 이해를 돕고자 한다. 2. 웹 애플리케이션과 네이

K&R2 Reference Manual 번역본

13주-14주proc.PDF

Design Issues

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

C++ Programming

Deok9_Exploit Technique

Data structure: Assignment 1 Seung-Hoon Na October 1, Assignment 1 Binary search 주어진 정렬된 입력 파일이 있다고 가정하자. 단, 파일내의 숫자는 공백으로 구 분, file내에 숫자들은

2017 년 6 월한국소프트웨어감정평가학회논문지제 13 권제 1 호 Abstract

OOP 소개

신림프로그래머_클린코드.key

PCServerMgmt7

<31332DB9E9C6AEB7A2C7D8C5B72D3131C0E528BACEB7CF292E687770>

Something that can be seen, touched or otherwise sensed

1217 WebTrafMon II

1. 안드로이드개발환경설정 안드로이드개발을위해선툴체인을비롯한다양한소프트웨어패키지가필요합니다 툴체인 (Cross-Compiler) 설치 안드로이드 2.2 프로요부터는소스에기본툴체인이 prebuilt 라는이름으로포함되어있지만, 리눅스 나부트로더 (U-boot)

DocsPin_Korean.pages

09-interface.key

JAVA PROGRAMMING 실습 08.다형성

BACK TO THE BASIC C++ 버그 헌팅: 버그를 예방하는 11가지 코딩 습관

HTML5* Web Development to the next level HTML5 ~= HTML + CSS + JS API

DataBinding

thesis

[Brochure] KOR_TunA

Observational Determinism for Concurrent Program Security

PowerPoint 프레젠테이션

5장.key

HTML5가 웹 환경에 미치는 영향 고 있어 웹 플랫폼 환경과는 차이가 있다. HTML5는 기존 HTML 기반 웹 브라우저와의 호환성을 유지하면서도, 구조적인 마크업(mark-up) 및 편리한 웹 폼(web form) 기능을 제공하고, 리치웹 애플리케이 션(RIA)을

11 템플릿적용 - Java Program Performance Tuning (김명호기술이사)

Chap 6: Graphs

MasoJava4_Dongbin.PDF

HW5 Exercise 1 (60pts) M interpreter with a simple type system M. M. M.., M (simple type system). M, M. M., M.

3장

Chap7.PDF

FreeBSD Handbook

유니티 변수-함수.key

JVM 메모리구조

중간고사

Microsoft PowerPoint - Java7.pptx

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout << " 양수입력 : "; cin >> *p; if (*p <= 0) cout << " 양수를입력해야합니다 " << endl; return; 동적할


Week13

Spring Data JPA Many To Many 양방향 관계 예제

PowerPoint 프레젠테이션

Transcription:

Bacardi Project: Node.js 네이티브모듈을위한 오픈소스바인딩제네레이터 방진호 (zino@chromium.org) 2017.10.26

Bacardi Project 란?

Bacardi Project 란..

Node.js 에서 Native Module 을바인딩하는방법에대한오픈소스이다.

그런데이미기존 Node.js 에는바인딩을위한방법들이제공되고있다.

그러나그방법이아름답지않았다.

Bacardi Project 는그러한문제를분석하고

아름답게해결하는방안을모색한다.

다음과같은순서로진행됩니다. JS에서왜 Native Module을사용하는가? 예제를통해알아보는기존의 Native Module 연동방식기존의문제점파헤치기 Chromium에서 Blink와 V8은어떻게연결되나? Node.js에서 Native Module과 V8은어떻게연결되나? WebIDL Auto Binding 구현하기 (Bacardi의구현원리 ) Bacardi Project 활용하기 01 02 03 04 05 06 07

JS 에서왜 Native Module 을 사용하는가?

성능 (Performance)

Low Level APIs

기존에잘만들어진코드가 Native 일때

어쨌든 Node.js 를사용한다면사용중인패키지의 30% 는 Native 이다.

예제를통해알아보는 기존의 Native Module 연동방식

sum() 함수를구현해보자 (JS 호출 ) JS let s = sum([1, 2, 3, 4, 5, 6, 7, 8, 9]); JS function sum(elements) { let s = 0; elements.foreach(element => { s += element; }); return s; }

sum() 함수를구현해보자 (Native 호출 ) JS let s = sum([1, 2, 3, 4, 5, 6, 7, 8, 9]); Native int sum(std::vector<int> elements) { int s = 0; for (int i = 0; i < elements.size(); i++) s += elements[i]; return s; }?

그런데 Javascript 에서어떻게호출할까?

기존의 Native Module 연동방식 아마우리가원했던게이런것은아니지말입니다.. var spawn = require('child_process').spawn; var sum = spawn('sum', [...]); sum.stdout.on('data', result => { process(result);... });

기존의 Native Module 연동방식 Node.js C++ Addon https://nodejs.org/dist/latest-v8.x/docs/api/addons.html NAN(Native Abstraction for Node) Node.js C++ Addon 이 V8 Public API 를사용하기때문에 V8 변화에민감하다. Node.js 를업데이트할때마다문제가발생하는것을해결. https://github.com/nodejs/nan N-API Latest! Node.js 8.0 이후부터지원, 8.6 에서 Stable Release NAN 과유사한방식이지만, ABI-Stable 을보장. ( 즉, 재컴파일불필요 ) V8 Public API 가아닌 Node.js 에서한번 Wrapping 하여제공하므로다른엔진으로교체도가능. https://nodejs.org/dist/latest-v8.x/docs/api/n-api.html

N-API 에이르기까지많은개선이있었지만, Binding 코드를작성하는것을위한개선은없었다.

N-API 를사용하여 Binding 해보자 다음의예제는 N-API 를사용하여 Native Binding 을하고있다. napi_value Sum(napi_env, napi_callback_info info) { napi_status status; size_t args = 1; napi_value args[1]; napi_status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); if (argc < 1) { napi_throw_type_error(env, nullptr, " "); return nullptr; } uint32_t length = 0; napi_get_array_length(env, args[0], &length); double sum = 0; for (int i = 0; i < length; i++) { napi_value element; napi_get_element(env, i, &element); napi_valuetype valuetype; napi_typeof(env, element, &valuetype); if (napi_valuetype!= napi_number) { napi_throw_type_error(env, nullptr, " "); return nullptr; } 그러나.. 6 줄짜리 sum() 함수가 35 줄이된다. double value; napi_get_value_double(env, element, &value); sum += value; } napi_value js_sum; napi_create_double(env, sum, &js_sum); return js_sum; }

N-API 를사용하여 Binding 해보자 N-API 를사용하여 Binding 을하면 Javascript 에서호출할수있다. const sum = require( sum ); let s = sum([1, 2, 3, 4, 5, 6, 7, 8, 9]);

기존의문제점파헤치기

지금부터코드가많이나오는데.. 굳이그코드들을이해하실필요는없습니다!

문제점 1: Argument Check napi_value Sum(napi_env, napi_callback_info info) { napi_status status; size_t args = 1; napi_value args[1]; napi_status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); // 문제점1. JS argument는 Runtime에결정되므로개발자가직접체크해야한다. if (argc < 1) { napi_throw_type_error(env, nullptr, " "); return nullptr; }

문제점 2: Type Checking for (int i = 0; i < length; i++) { napi_value element; napi_get_element(env, i, &element); // 문제점2. 각 Array Element의 Type Checking도직접해야한다. napi_valuetype valuetype; napi_typeof(env, element, &valuetype); if (napi_valuetype!= napi_number) { napi_throw_type_error(env, nullptr, " "); return nullptr; }

문제점 3: Type Converting } // 문제점3. JS에서 Native Type Converting을직접해야한다. double value; napi_get_value_double(env, element, &value); sum += value; // 문제점3. Native에서 JS Type Converting을직접해야한다. napi_value js_sum; napi_create_double(env, sum, &js_sum); return js_sum;

문제점 4: Memory Management uint32_t length = 10000; for (int i = 0; i < length; i++) { napi_value element; napi_get_element(env, i, &element); Push 내가아는 Stack napi_value length }... Pop...

문제점 4: Memory Management uint32_t length = 10000; HandleScopeStack Heap for (int i = 0; i < length; i++) { // napi_get_element() 를호출할때마다 // 새로운 object를생성하고 HandleScope에 // 쌓이게됨. napi_value element; napi_get_element(env, i, &element);... } i = 9999 i = 9998 i = 4 i = 3 i = 2 i = 1 i = 0 napi_value napi_value napi_value napi_value napi_value napi_value napi_value

문제점 4: Memory Management for (int i = 0; i < length; i++) { napi_handle_scope scope; napi_status status = napi_open_handle_scope(env, &scope); napi_value element; napi_get_element(env, i, &element);... } napi_close_handle_scope(env, scope);

문제점 5: Readability // 문제점5. Binding 코드가많이삽입되면서가독성이떨어진다. int sum(std::vector<int> elements) { int s = 0; for (int i = 0; i < elements.size(); i++) s += elements[i]; return s; } napi_value Sum(napi_env, napi_callback_info info) { napi_status status; size_t args = 1; napi_value args[1]; napi_status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); if (argc < 1) { napi_throw_type_error(env, nullptr, " "); return nullptr; } uint32_t length = 0; napi_get_array_length(env, args[0], &length); double sum = 0; for (int i = 0; i < length; i++) { napi_value element; napi_get_element(env, i, &element); napi_valuetype valuetype; napi_typeof(env, element, &valuetype); if (napi_valuetype!= napi_number) { napi_throw_type_error(env, nullptr, " "); return nullptr; } double value; napi_get_value_double(env, element, &value); sum += value; } napi_value js_sum; napi_create_double(env, sum, &js_sum); return js_sum; }

요약 기존의방법은 TypeChecking/Converting 과같은노가다를반복해야한다. Memory 관리 Mechanism 이다르고 Binding 을위해사용되는 API 를다룰줄알아야하므로 V8, N-API, JS, C++ 과같은지식모두를필요로한다. 전체적인코드의복잡도가증가한다.

Chromium 에서 Blink 와 V8 은 어떻게연결되나?

왜 Chromium 을살펴보나?

Chromium 은 V8 의또다른 Embedder 이다.

V8 (Javascript Engine) Blink (Rendering Engine) V8 (Javascript Engine) Node.js Native Module

document.getelementbyid();

<div id="hello"></div> <script> let div = document.getelementbyid( hello ); </script>

V8 Engine 과 Blink Engine 의관계 <div id="hello"></div> <script> let div = document.getelementbyid( hello ); </script> Chromium V8 Loader Engine

V8 Engine 과 Blink Engine 의관계 <div id="hello"></div> <script> let div = document.getelementbyid( hello ); </script> Chromium V8 Loader Engine DOM Parsing V8 Engine Blink Engine

V8 Engine 과 Blink Engine 의관계 <div id="hello"></div> <script> let div = document.getelementbyid( hello ); </script> Chromium V8 Loader Engine V8 Engine JS Evaluate <script> document.getelementbyid( hello ); </script> DOM Parsing V8 Engine Blink Engine

V8 Engine 과 Blink Engine 의관계 <div id="hello"></div> <script> let div = document.getelementbyid( hello ); </script> Chromium V8 Loader Engine V8 Engine JS Evaluate <script> document.getelementbyid( hello ); </script> DOM Parsing V8 Engine Blink Engine Actually, called document.getelementbyid();

V8 Engine 과 Blink Engine 의관계 <div id="hello"></div> <script> let div = document.getelementbyid( hello ); </script> Chromium V8 Loader Engine V8 Engine JS Evaluate <script> document.getelementbyid( hello ); </script> DOM Parsing V8 Engine Blink Engine Return JS Wrapper Object let div = document.getelementbyid( hello ); Actually, called document.getelementbyid();

V8 Engine 과 Blink Engine 의관계 <div id="hello"></div> <script> let div = document.getelementbyid( hello ); </script> Chromium V8 Loader Engine V8 Engine JS Evaluate <script> document.getelementbyid( hello ); </script> V8 Binding DOM Parsing V8 Engine Blink Engine Return JS Wrapper Object let div = document.getelementbyid( hello ); Type Checking/Converting Manage Isolate and Context Actually, called document.getelementbyid();

V8 Engine 과 Blink Engine 의관계 <div id="hello"></div> <script> let div = document.getelementbyid( hello ); </script> Chromium V8 Loader Engine V8 Engine JS Evaluate <script> document.getelementbyid( hello ); </script> WebIDL Binding DOM Parsing V8 Engine Blink Engine Return JS Wrapper Object let div = document.getelementbyid( hello ); Auto-generated!! Actually, called document.getelementbyid();

V8 Binding 이란? Chromium에서 V8과 Blink를연결하는코드이다. 사용자가직접짜지않고 WebIDL으로부터자동생성 (auto-generation) 된다. WebIDL은 JS Engine과 Web Engine을연결하는 Web 표준에의해정의된다. https://heycam.github.io/webidl/ https://www.w3.org/tr/api-design/

코드레벨로살펴보는 WebIDL // WebIDL [Constructor] interface Calculator { double sum(sequence<long> elements); };

코드레벨로살펴보는 WebIDL // WebIDL [Constructor] interface Calculator { double sum(sequence<long> elements); }; VS napi_value Sum(napi_env, napi_callback_info info) { napi_status status; size_t args = 1; napi_value args[1]; napi_status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); if (argc < 1) { napi_throw_type_error(env, nullptr, " "); return nullptr; } uint32_t length = 0; napi_get_array_length(env, args[0], &length); double sum = 0; for (int i = 0; i < length; i++) { napi_value element; napi_get_element(env, i, &element); napi_valuetype valuetype; napi_typeof(env, element, &valuetype); if (napi_valuetype!= napi_number) { napi_throw_type_error(env, nullptr, " "); return nullptr; } double value; napi_get_value_double(env, element, &value); sum += value; } napi_value js_sum; napi_create_double(env, sum, &js_sum); return js_sum; }

코드레벨로살펴보는 WebIDL // User s Native Code class Calculator { public: double Sum(std::vector<int> elements) { int sum = 0; for (int i = 0; i < elements.size(); i++) sum += elements[i]; return sum; } };

코드레벨로살펴보는 WebIDL // User s JS code var calculator = new Calculator(); console.log(calculator.sum([1, 2, 3, 4, 5, 6, 7, 8, 9]));

요약 Chromium 에서 V8 과 Blink 의관계는 Node.js 에서 V8 과 Native Module 의관계와동등하다. V8 과 Blink 를연결하는 Layer 를 V8 Binding(WebIDL Binding) 이라고부른다. V8 Binding(WebIDL Binding) 은 WebIDL 을이용해 Auto-generated 된다.

Node.js Native Module 과 V8 은어떻게연결되나?

const fs = require('fs'); let contents = fs.readfilesync('temp.txt', 'utf8');

V8 Engine 과 Native Module 의관계 Node Runtime const fs = require('fs'); let contents = fs.readfilesync('temp.txt', 'utf8'); V8 Engine

V8 Engine 과 Native Module 의관계 Node Runtime const fs = require('fs'); let contents = fs.readfilesync('temp.txt', 'utf8'); V8 Engine JS Evaluate V8 Engine

V8 Engine 과 Native Module 의관계 Node Runtime const fs = require('fs'); let contents = fs.readfilesync('temp.txt', 'utf8'); V8 Engine JS Evaluate V8 Engine V8 Engine Native Module Actually, called open() and read()

V8 Engine 과 Native Module 의관계 Node Runtime const fs = require('fs'); let contents = fs.readfilesync('temp.txt', 'utf8'); V8 Engine JS Evaluate V8 Engine V8 Engine Native Module Return JS Wrapper Object Actually, called open() and read()

V8 Engine 과 Native Module 의관계 Node Runtime const fs = require('fs'); let contents = fs.readfilesync('temp.txt', 'utf8'); V8 Engine JS Evaluate V8 Engine V8 Binding V8 Engine Native Module Return JS Wrapper Object Type Checking/Converting Manage Isolate and Context Actually, called open() and read()

복습 : N-API 를사용하여 Binding 해보자 이미우리가여러번말했듯이이러한과정을반복한다. napi_value Sum(napi_env, napi_callback_info info) { napi_status status; size_t args = 1; napi_value args[1]; napi_status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); if (argc < 1) { napi_throw_type_error(env, nullptr, " "); return nullptr; } uint32_t length = 0; napi_get_array_length(env, args[0], &length); double sum = 0; for (int i = 0; i < length; i++) { napi_value element; napi_get_element(env, i, &element); napi_valuetype valuetype; napi_typeof(env, element, &valuetype); if (napi_valuetype!= napi_number) { napi_throw_type_error(env, nullptr, " "); return nullptr; } 이런식으로장인정신을발휘하면 잘만들수있다! double value; napi_get_value_double(env, element, &value); sum += value; } napi_value js_sum; napi_create_double(env, sum, &js_sum); return js_sum; }

복습 : V8 Engine 과 Blink Engine 의관계 <div id="hello"></div> <script> let div = document.getelementbyid( hello ); </script> Chromium V8 Loader Engine V8 Engine JS Evaluate <script> document.getelementbyid( hello ); </script> WebIDL Binding DOM Parsing V8 Engine Blink Engine Return JS Wrapper Object let div = document.getelementbyid( hello ); Auto-generated!! Actually, called document.getelementbyid();

Node.js 에 Auto Binding 을적용한다면.. IDL을제외하고는추가적인 Binding 코드를직접작성하지않아도된다. 바인딩코드와실제 User Implementation이완벽히분리된다. V8( 또는 N-API) 을이해하지않아도된다. 안전하고빠르게바인딩할수있다.

실제사례 : Open CV Binding // Open CV Matrix를생성하는 5개의함수오버로딩.. let m1 = new Matrix(); let m2 = new Matrix(rows, cols); let m3 = new Matrix(10, 20, CV_32F); let m4 = new Matrix(10, 20, CV_32F, [1, 2, 3]); let m5 = new Matrix(m4, 10, 20, 30, 40);

실제사례 : Open CV Binding // 이 Matrix 의실제 Binding 구현은다음과유사하다. // https://github.com/peterbraden/node-opencv/blob/master/src/matrix.cc#l132 Matrix* mat; if (info.length() == 0) { mat = new Matrix; } else if (info.length() == 2 && info[0]->isint32() && info[1]->isint32()) { mat = new Matrix(info[0]->IntegerValue(), info[1]->integervalue()); } else if (info.length() == 3 && info[0]->isint32() && info[1]->isint32() && info[2]->isint32()) { mat = new Matrix(info[0]->IntegerValue(), info[1]->integervalue(), info[2]->integervalue()); } else if (info.length() == 4 && info[0]->isint32() && info[1]->isint32() && info[2]->isint32() && info[3]->isarray()) { mat = new Matrix(info[0]->IntegerValue(), info[1]->integervalue(), info[2]->integervalue(), info[3]->toobject()); else { // if (info.length() == 5) {... }

실제사례 : Open CV Binding // 만약 WebIDL Binding을사용했다면.. [ Constructor(), Constructor(long rows, long cols), Constructor(long rows, long cols, long type), Constructor(long rows, long cols, long type, sequence<long> scalar), Constructor(Matrix m, long x, long y, long z, long w) ] interface Matrix {... };

실제사례 : Open CV Binding // 만약당신이 WebIDL 고수였다면.. [ Constructor(), Constructor(long rows, long cols, optional long type, optional sequence<long> scalar), Constructor(Matrix m, long x, long y, long z, long w) ] interface Matrix {... };

요약 Node.js 에서 V8 과 Native Module 사이의 Binding 은개발자가직접한땀한땀개발해야만했다. Chromium 에서사용되는 WebIDL Binding 을도입한다면, 그러한장인정신을발휘하지않고도쉽고빠르게개발할수있다.

Node.js를위한 WebIDL Auto Binding 구현하기 (Bacardi의구현원리 )

What should we do? WebIDL 을해석한후 N-API 를사용하는적절한 Binding 코드를생성한다.

Blink 에서 WebIDL 이처리되는과정 WebIDL User Native Implementation

Blink 에서 WebIDL 이처리되는과정 WebIDL Input IDL Parser User Native Implementation

Blink 에서 WebIDL 이처리되는과정 WebIDL Input IDL Parser Binding Code Generator User Native Implementation

Blink 에서 WebIDL 이처리되는과정 WebIDL Input IDL Parser Binding Code Generator Input Code Template User Native Implementation

Blink 에서 WebIDL 이처리되는과정 WebIDL Input IDL Parser Binding Code Generator Input Code Template Build User Native Implementation Generated Code Based on V8

Blink 에서 WebIDL 이처리되는과정 WebIDL Input IDL Parser Binding Code Generator Input Code Template Build User Native Implementation Reference Generated Code Based on V8

Blink 에서 WebIDL 이처리되는과정 WebIDL Input IDL Parser Binding Code Generator Input Code Template Build User Native Implementation Reference Generated Code Based on V8 Build Build Output Binary

What should we do? IDL Parser 를구현한다. (Front End) Code Generator 를구현한다. (Back End)

How to implement IDL Parser 를구현한다. (Front End) 이미잘구현된 WebIDL Parser 가있다 : https://github.com/w3c/webidl2.js 우리는 AST(Abstract Syntax Tree) 를 IDL Definitions 로만들어주는것만하면된다. Code Generator 를구현한다. (Back End)

How to implement IDL Parser 를구현한다. (Front End) 이미잘구현된 WebIDL Parser 가있다 : https://github.com/w3c/webidl2.js 우리는 AST(Abstract Syntax Tree) 를 IDL Definitions 로만들어주는것만하면된다. Code Generator 를구현한다. (Back End) Python 의 Jinja2 를 JS 로포팅한 Nunjucks 가있다 : https://github.com/mozilla/nunjucks 우리는 C++ Binding Code (N-API 를사용한 ) 를잘생성해주는로직을짜기만하면된다.

IDL Parser (Front End) Compiler의 FrontEnd의역할. IR(Intermediate Representation) 을생성. Constructing 단계에서다음의두가지요소가추가적으로필요함. Extended attribute validation Dependency resolution. IDL Tokens AST (Abstract Syntax Tree) IR (IDL Definitions) Lexing Parsing Constructing

IDL Parser (Front End) [Constructor] interface Hello { double test(world world); }; [{ type: 'interface', name: 'Hello', partial: false, members: [ [...] ], inheritance: null, extattrs: [ [...] ] }] Parsing Dependency Resolution [{... name: 'Hello', members: [ [{ idltype: 'World,... }] ], }] Constructing [Constructor] interface World { readonly attribute value; };

Code Generator (Back End) Compiler 의 BackEnd 의역할. IR 을 Input 으로최종결과물 (binding code) 생성. 코드생성을위해 Nunjucks Template Engine 을사용. Code Template IR (IDL Definitions) Contexts Native Binding Code V8 Engine Logic Processing Template Processing

Code Generator (Back End) {% for argument in member.arguments %} auto {{argument.name}} = NativeTypeTraits<IDL{{argument.type camelcase-}} >::NativeValue(info.Env(), info[{{loop.index - 1}}]); {% endfor %} {% if member.type!= "void" %}auto return_value = {% endif %} {% if member.is_static -%} {{name}}::{% else %} impl_->{% endif %} {{member.name camelcase}}({{-member.arguments[0].name-}} {%- for i in range(1, member.arguments.length) -%}, {{member.arguments[i].name-}} {% endfor %}); return JSTypeTraits(info.Env(), return_value);

Code Generator (Back End) {% for argument in member.arguments %} auto {{argument.name}} = NativeTypeTraits<IDL{{argument.type camelcase-}} >::NativeValue(info.Env(), info[{{loop.index - 1}}]); {% endfor %} {% if member.type!= "void" %}auto return_value = {% endif %} {% if member.is_static -%} {{name}}::{% else %} impl_->{% endif %} {{member.name camelcase}}({{-member.arguments[0].name-}} {%- for i in range(1, member.arguments.length) -%}, {{member.arguments[i].name-}} {% endfor %}); return JSTypeTraits(info.Env(), return_value);

Code Generator (Back End) if (info.length()!= 2) { Napi::RangeError::New(info.Env(), "Invalid").ThrowAsJavaScriptException(); return Napi::Value(); } // 복잡한 Type Mapping 및 Converting 은개발자에게노출하지않는다. double number1 = NativeTypeTraits<IDLDouble>::NativeValue(info.Env(), info[0]); double number2 = NativeTypeTraits<IDLDouble>::NativeValue(info.Env(), info[1]); // 사용자가작성한 User Native Implementation 을여기서호출한다. auto return_value = impl_->add(number1, number2); return JSTypeTraits(info.Env(), return_value);

Code Generator (Back End) class Calculator { public: Calculator() {} } // 개발자는 JS Engine의 public API가어떻게동작하는지알필요가없다. // WebIDL Spec에따라 IDL type이정확한 platform object type과 mapping된다. double Add(double number1, double number2) { return number1 + number2; }

요약 Node.js 에 WebIDL Binding 을구현하기위해서는 IDL Parser 와 Code Generator 두가지를구현해야한다.

Bacardi Project 활용하기

Introduce Bacardi Project Node.js 에서 Chromium 이사용하는 WebIDL Auto Binding 을적용하기위한오픈소스프로젝트입니다. https://github.com/lunchclass/bacardi Chromium Committer 들이주축으로만들어갑니다.

How to test Bacardi # Git clone repository $ git clone https://github.com/lunchclass/bacardi

How to test Bacardi # Git clone repository $ git clone https://github.com/lunchclass/bacardi # If you are using MacOS $ xcode-select install # If you are using Linux $ sudo apt-get install g++ git make python wget

How to test Bacardi # Git clone repository $ git clone https://github.com/lunchclass/bacardi # If you are using MacOS $ xcode-select install # If you are using Linux $ sudo apt-get install g++ git make python wget # Build & Test $./bacardi build &&./bacardi test

Details 자세한것은 Repository 를참조. https://github.com/lunchclass/bacardi 테스트가아닌간단한예제는 examples 디렉토리를참조. https://github.com/lunchclass/bacardi/tree/master/examples

Bacardi with Electron # Build for Electron & Run Electron app $./bacardi build_electron &&./bacardi electron

Bacardi with Electron - SimRank 두객체의유사도를구하는알고리즘.

Bacardi with Electron - SimRank 만약여러분이사용하고싶은구현이 Node.js 에존재하지않는다면..

Bacardi with Electron - SimRank 구글링 (Googling) 을해보니 SimRank 의 C++ 구현은존재한다. https://github.com/roukaour/simrank

Bacardi with Electron - SimRank

Bacardi with Electron - SimRank 이것을그대로 Javascript 로 binding 하여 Electron app 에출력해보자. https://github.com/lunchclass/bacardi/pull/135 [ Constructor(), Constructor(long k, double c) ] interface ElectronNative { void addedge(string head, string tail); void calculatesimrank(); double similarity(string node1, string node2); };

Bacardi with Electron - SimRank

Bacardi with Electron - SimRank

Bacardi 의향후계획 2017년 4분기까지 C++ Binding 구현완료 - NPM 배포 OpenCV & Tensor Flow Binding Bacardi로옮기기 Cross Platform Build 지원 Welcome to contribution (https://github.com/lunchclass/bacardi)

요약 Node.js 에 WebIDL Binding 을구현하기위해서는 IDL Parser 와 Code Generator 두가지를구현해야한다. 모두가같은노력을할필요없으므로오픈소스프로젝트 (Bacardi Project) 로진행중이며, 이를 Node.js Native Module 개발에활용할수있다.

Q & A zino@chromium.org

THANK YOU Copyright c 2017 SAMSUNG ELECTRONICS. ALL RIGHTS RESERVED