SlideShare une entreprise Scribd logo
1  sur  21
Télécharger pour lire hors ligne
Extending node.js
using C++
Kenneth Geisshirt
kg@realm.io
Realm Inc.
@realm
http://github.com/Realm/
http://realm.io/
Today’s goal
• Learn
- the basics of V8 internals and API
- how to wrap C++ classes
• Go home and write an extension
Agenda
1.Why write extensions in
C++
2.My demo C++ classes
3.Building extensions
4.Wrapping classes
• Setting up class
• Instantiating objects
• Setters, getters, etc.
• Methods
• Callbacks/anonymous functions
• Exceptions
Why Extensions in C++?
• You get access to system resources
• I/O, peripheral devices, GPUs, etc,
• To get the performance of C++
• Cross-Language
• Common core features in C++, many language bindings
• Legacy code
• Tons of old and useful C/C++/Fortran code
Demo C++ Classes
• Person
• firstname()
• lastname()
• birthday()
• to_str()
• Book
• add(Person* p)
• Person *lookup(string
name)
• operator [size_t index]
• remove(size_t index)
• size_t size()
Gettersandsetters
https://github.com/kneth/DemoNodeExtension
V8 concepts
• Isolate is an isolated instance of V8
• Handles are references to JavaScript objects, and V8’s garbage collector
reclaims them
• Local handles are allocated on the stack; life-time is scope based
• Persistent handles are allocated on the heap; life-time can span multiple
function calls
• You don’t return an object - you set the return value using
GetReturnValue().Set()
• and you cannot return a Local object (I’ll return to it later on)
• V8 has classes to represent JavaScript types (String, Number, Array,
Object, …)
Breaking changes
0.10 →0.12
• V8 API changes in node.js 0.12 (February 2015)
• How to return values from C++ to JavaScript
• Type name for methods’ arguments
• Creating objects require an Isolate
• String encoding is strict (UTF-8 is common)
• Extensions cannot support both 0.10 and 0.12+
• https://strongloop.com/strongblog/node-js-v0-12-c-apis-
breaking/
Building extensions
• Wrapping classes
(person.cpp →
person_wrap.cpp, …)
• Build process described in
bindings.gyp
• node-gyp configure build
{
'targets': [{
'target_name': 'funstuff',
'sources': [ 'person.cpp', 'person_wrap.cpp', 'book.cpp',
'book_wrap.cpp', 'funstuff.cpp' ],
'xcode_settings': {
'OTHER_CFLAGS': [ '-mmacosx-version-min=10.8', '-std=c++11',
'-stdlib=libc++', '-fexceptions', '-frtti' ]
}
}]
}
Name of extension
OS X specific options
#include <node.h>
#include "person_wrap.hpp"
#include "book_wrap.hpp"
using namespace v8;
void InitAll (Handle<Object> exports) {
PersonWrap::Init(exports);
BookWrap::Init(exports);
}
NODE_MODULE(funstuff, InitAll)
Wrapping a class
• Wrapper classes inherent
from node::ObjectWrap
• All methods are static
#include <node.h>
#include <node_object_wrap.h>
#include "book.hpp"
#include "person.hpp"
class BookWrap : public node::ObjectWrap {
public:
static void Init(v8::Handle<v8::Object> exports);
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
BookWrap();
private:
~BookWrap();
Book* m_book;
static v8::Persistent<v8::Function> Constructor;
};
Add class to V8
Helper to create new objects
The class to wrap
Adding a
class to V8
• Calling BookWrap::Init() to register/add the
class
• Sets up constructor, methods, and basic
infrastructure
void BookWrap::Init(Handle<Object> exports) {
Isolate* isolate = exports->GetIsolate();
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, BookWrap::New);
tpl->SetClassName(String::NewFromUtf8(isolate, "Book"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
NODE_SET_PROTOTYPE_METHOD(tpl, “add", Add);
tpl->InstanceTemplate()->SetIndexedPropertyHandler(Getter, Setter,
0, Deleter, Enumerator);
Constructor.Reset(isolate, tpl->GetFunction());
exports->Set(String::NewFromUtf8(isolate, "Book"), tpl->GetFunction());
}
Setting the class name
Adding a method
Getter, setter, etc.
Preparing
constructor
var funstuff = require('./build/Release/funstuff');
Instantiate
an object
void BookWrap::New(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
if (args.IsConstructCall()) {
if (args.Length() == 0) {
BookWrap* bw = new BookWrap();
Book *b = new Book();
bw->m_book = b;
bw->Wrap(args.This());
args.GetReturnValue().Set(args.This());
}
}
Create wrapper and object
Add wrapper to V8 runtime
Return the object
var book = new funstuff.Book();
Methods
• Methods are implemented in C++
• Input validation is important (IsString,
IsNumber, …)
void BookWrap::Length(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope scope(isolate);
BookWrap* bw = ObjectWrap::Unwrap<BookWrap>(args.This());
const int count = bw->m_book->size();
Local<Integer> result = Integer::New(isolate, count);
args.GetReturnValue().Set(result);
}
var book = new funstuff.Book();
console.log('Book: ' + book.length());
Arguments: args.Length(), args[0]
Get this as wrapper object
Create an object to return
Return the new object
Get current scope
Instantiate objects
• Instantiating wrapper object in C++
• Method of one class returns object of other class
• For example: var person = book[4];
Handle<Object> PersonWrap::New(Isolate* isolate, Book* b, uint32_t index) {
EscapableHandleScope scope(isolate);
Handle<Value> argv[] = { Boolean::New(isolate, true) };
Local<Function> cons = Local<Function>::New(isolate, Constructor);
Handle<Object> obj = cons->NewInstance(1, argv);
PersonWrap* pw = PersonWrap::Unwrap<PersonWrap>(obj);
pw->m_person = (*b)[size_t(index)];
return scope.Escape(obj);
}
Dummy argument
Call constructor:
PersonWrap::New(const FunctionCallbackInfo<Value>& args)Add object to current scope
Indexed getters
and setters
book[6] = new Person();
var person = book[4];
void BookWrap::Getter(uint32_t index, const PropertyCallbackInfo<Value>& info) {
Isolate* isolate = info.GetIsolate();
HandleScope scope(isolate);
BookWrap* bw = ObjectWrap::Unwrap<BookWrap>(info.This());
Book* b = bw->m_book;
if (index >= b->size()) {
isolate->ThrowException(Exception::RangeError(String::NewFromUtf8(isolate,
"invalid row index")));
info.GetReturnValue().SetUndefined();
}
else {
Handle<Object> result = PersonWrap::New(isolate, b, index);
info.GetReturnValue().Set(result);
}
}
Instantiate a wrapper object and return it
Unwrap this and get C++ object
Validate input (index is in range)
void BookWrap::Setter(uint32_t index, Local<Value> value,
const PropertyCallbackInfo<Value>& info)
Value to set; remember to validate!
Accessors
• Accessors are useful for known properties
• C++ isn’t dynamic as JavaScript
• Added to V8 during initialisation (PersonWrap::Init())
var person = new funstuff.Person();
person.firstname = “Arthur”;
tpl->InstanceTemplate()->SetAccessor(String::NewFromUtf8(isolate, "firstname"),
PersonWrap::FirstnameGetter, PersonWrap::FirstnameSetter);
void PersonWrap::FirstnameGetter(Local<String> property,
const PropertyCallbackInfo<Value>& info) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
PersonWrap *pw = ObjectWrap::Unwrap<PersonWrap>(info.This());
Person *p = pw->m_person;
info.GetReturnValue().Set(String::NewFromUtf8(isolate, p->firstname().c_str()));
}
Callbacks
• Callbacks and anonymous functions are JavaScript
in a nutshell
• Functions are objects: Function is used in V8
book.each(function (p) {
console.log("Firstname: " + p.firstname);
});
void BookWrap::Each(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope scope(isolate);
Book* book = ObjectWrap::Unwrap<BookWrap>(args.This())->m_book;
if (args.Length() == 1) {
if (args[0]->IsFunction()) {
Local<Function> fun = Local<Function>::Cast(args[0]);
for(uint32_t i = 0; i < book->size(); ++i) {
Local<Object> pw = PersonWrap::New(isolate, book, i);
Local<Value> argv[1] = { pw };
fun->Call(Null(isolate), 1, argv);
}
args.GetReturnValue().SetUndefined();
return;
}
}
}
The anonymous function
Set up arguments
Call the function
Throwing Exceptions
• Throwing a C++ exception is a no-go
• set node.js’ state to “exception”
• when returning to JavaScript an exception is thrown
• V8 has a limited number of exceptions: RangeError,
ReferenceError, SyntaxError, TypeError, Error
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
// …
isolate->ThrowException(Exception::SyntaxError(String::NewFromUtf8(isolate,
"No arguments expected")));
args.GetReturnValue().SetUndefined();
return;
Catching
Exceptions
• Callbacks might throw an exception
• V8 has a TryCatch class to check for it
try {
var s = book.apply(function (b) {
throw { msg: "Error" };
});
console.log(" Length: " + s);
}
catch (e) {
console.log(" Exception caught: " + e.msg);
}
void BookWrap::Apply(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope scope(isolate);
Local<Function> fun = Local<Function>::Cast(args[0]);
Handle<Value> argv[] = { args.This() };
TryCatch trycatch;
Handle<Value> v = fun->Call(Null(isolate), 1, argv);
if (trycatch.HasCaught()) {
trycatch.ReThrow();
}
args.GetReturnValue().Set(v);
}
If HasCaught() is true, an JS exception was thrown
Set the node.s’ “exception” state
NAN
• Native Abstraction for Node (NAN) makes it easier
to write extensions
• Hides breaking changes in the V8 API
- Your extension will support many versions!
• Functions and macros for common tasks
• https://github.com/nodejs/nan
Observations
• Extensions do not have to be a one-to-one mapping
• A lot of code to do input validation
• JavaScript isn’t a strongly typed language
• Unit testing is very important
• C++ has classes - JavaScript doesn’t
• Awkward for JavaScript programmers
• Crossing language barrier during call is hard for debuggers
Learn more
• Check out my demo: https://github.com/kneth/
DemoNodeExtension
• Google’s documentation: https://
developers.google.com/v8/embed?hl=en
• JavaScript - The Good Parts. D. Crockford. O’Reilly
Media, 2008.
• Any modern C++ text book 😱
http://realm
.io
W
e
are
hiring

Contenu connexe

Tendances

Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engineDuoyi Wu
 
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data EcosystemWprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data EcosystemSages
 
連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」matuura_core
 
Node Architecture and Getting Started with Express
Node Architecture and Getting Started with ExpressNode Architecture and Getting Started with Express
Node Architecture and Getting Started with Expressjguerrero999
 
Swift after one week of coding
Swift after one week of codingSwift after one week of coding
Swift after one week of codingSwiftWro
 
Building fast interpreters in Rust
Building fast interpreters in RustBuilding fast interpreters in Rust
Building fast interpreters in RustIngvar Stepanyan
 
ooc - OSDC 2010 - Amos Wenger
ooc - OSDC 2010 - Amos Wengerooc - OSDC 2010 - Amos Wenger
ooc - OSDC 2010 - Amos WengerAmos Wenger
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/OJussi Pohjolainen
 
Advanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScriptAdvanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScriptecker
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architectureJung Kim
 
Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streamsmattpodwysocki
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!Brendan Eich
 
20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting Started20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting StartedTeerawat Issariyakul
 
The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88Mahmoud Samir Fayed
 
A JIT Smalltalk VM written in itself
A JIT Smalltalk VM written in itselfA JIT Smalltalk VM written in itself
A JIT Smalltalk VM written in itselfESUG
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! aleks-f
 
From C++ to Objective-C
From C++ to Objective-CFrom C++ to Objective-C
From C++ to Objective-Ccorehard_by
 

Tendances (20)

Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
 
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data EcosystemWprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
 
連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」
 
Node Architecture and Getting Started with Express
Node Architecture and Getting Started with ExpressNode Architecture and Getting Started with Express
Node Architecture and Getting Started with Express
 
Swift after one week of coding
Swift after one week of codingSwift after one week of coding
Swift after one week of coding
 
Building fast interpreters in Rust
Building fast interpreters in RustBuilding fast interpreters in Rust
Building fast interpreters in Rust
 
ooc - OSDC 2010 - Amos Wenger
ooc - OSDC 2010 - Amos Wengerooc - OSDC 2010 - Amos Wenger
ooc - OSDC 2010 - Amos Wenger
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/O
 
Advanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScriptAdvanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScript
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architecture
 
Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streams
 
Rust ⇋ JavaScript
Rust ⇋ JavaScriptRust ⇋ JavaScript
Rust ⇋ JavaScript
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!
 
20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting Started20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting Started
 
The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88
 
A JIT Smalltalk VM written in itself
A JIT Smalltalk VM written in itselfA JIT Smalltalk VM written in itself
A JIT Smalltalk VM written in itself
 
NS2 Object Construction
NS2 Object ConstructionNS2 Object Construction
NS2 Object Construction
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! 
 
From C++ to Objective-C
From C++ to Objective-CFrom C++ to Objective-C
From C++ to Objective-C
 

Similaire à Node.js extensions in C++

Building High Performance Android Applications in Java and C++
Building High Performance Android Applications in Java and C++Building High Performance Android Applications in Java and C++
Building High Performance Android Applications in Java and C++Kenneth Geisshirt
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele RialdiCodeFest
 
How to Write Node.js Module
How to Write Node.js ModuleHow to Write Node.js Module
How to Write Node.js ModuleFred Chien
 
The Present and Future of the Web Platform
The Present and Future of the Web PlatformThe Present and Future of the Web Platform
The Present and Future of the Web PlatformC4Media
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxDavid Rodenas
 
Look Mommy, No GC! (TechDays NL 2017)
Look Mommy, No GC! (TechDays NL 2017)Look Mommy, No GC! (TechDays NL 2017)
Look Mommy, No GC! (TechDays NL 2017)Dina Goldshtein
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The LandingHaci Murat Yaman
 
JavaScript in 2016
JavaScript in 2016JavaScript in 2016
JavaScript in 2016Codemotion
 
JavaScript in 2016 (Codemotion Rome)
JavaScript in 2016 (Codemotion Rome)JavaScript in 2016 (Codemotion Rome)
JavaScript in 2016 (Codemotion Rome)Eduard Tomàs
 
MFF UK - Introduction to iOS
MFF UK - Introduction to iOSMFF UK - Introduction to iOS
MFF UK - Introduction to iOSPetr Dvorak
 
FI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS BasicsFI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS BasicsPetr Dvorak
 
Objective-C Survives
Objective-C SurvivesObjective-C Survives
Objective-C SurvivesS Akai
 
JSLT: JSON querying and transformation
JSLT: JSON querying and transformationJSLT: JSON querying and transformation
JSLT: JSON querying and transformationLars Marius Garshol
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?Andrey Karpov
 
Objective-C for iOS Application Development
Objective-C for iOS Application DevelopmentObjective-C for iOS Application Development
Objective-C for iOS Application DevelopmentDhaval Kaneria
 

Similaire à Node.js extensions in C++ (20)

Building High Performance Android Applications in Java and C++
Building High Performance Android Applications in Java and C++Building High Performance Android Applications in Java and C++
Building High Performance Android Applications in Java and C++
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele Rialdi
 
How to Write Node.js Module
How to Write Node.js ModuleHow to Write Node.js Module
How to Write Node.js Module
 
The Present and Future of the Web Platform
The Present and Future of the Web PlatformThe Present and Future of the Web Platform
The Present and Future of the Web Platform
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
 
C++ Advanced Features
C++ Advanced FeaturesC++ Advanced Features
C++ Advanced Features
 
Look Mommy, No GC! (TechDays NL 2017)
Look Mommy, No GC! (TechDays NL 2017)Look Mommy, No GC! (TechDays NL 2017)
Look Mommy, No GC! (TechDays NL 2017)
 
C++ Advanced Features
C++ Advanced FeaturesC++ Advanced Features
C++ Advanced Features
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
 
JavaScript in 2016
JavaScript in 2016JavaScript in 2016
JavaScript in 2016
 
JavaScript in 2016 (Codemotion Rome)
JavaScript in 2016 (Codemotion Rome)JavaScript in 2016 (Codemotion Rome)
JavaScript in 2016 (Codemotion Rome)
 
Android ndk
Android ndkAndroid ndk
Android ndk
 
Angular2 for Beginners
Angular2 for BeginnersAngular2 for Beginners
Angular2 for Beginners
 
MFF UK - Introduction to iOS
MFF UK - Introduction to iOSMFF UK - Introduction to iOS
MFF UK - Introduction to iOS
 
FI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS BasicsFI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS Basics
 
Objective-C Survives
Objective-C SurvivesObjective-C Survives
Objective-C Survives
 
Python_Unit_2 OOPS.pptx
Python_Unit_2  OOPS.pptxPython_Unit_2  OOPS.pptx
Python_Unit_2 OOPS.pptx
 
JSLT: JSON querying and transformation
JSLT: JSON querying and transformationJSLT: JSON querying and transformation
JSLT: JSON querying and transformation
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Objective-C for iOS Application Development
Objective-C for iOS Application DevelopmentObjective-C for iOS Application Development
Objective-C for iOS Application Development
 

Plus de Kenneth Geisshirt

Building parsers in JavaScript
Building parsers in JavaScriptBuilding parsers in JavaScript
Building parsers in JavaScriptKenneth Geisshirt
 
Building mobile apps with Realm for React Native
Building mobile apps with Realm for React NativeBuilding mobile apps with Realm for React Native
Building mobile apps with Realm for React NativeKenneth Geisshirt
 
Tales from the dark side: developing SDKs at scale
Tales from the dark side: developing SDKs at scaleTales from the dark side: developing SDKs at scale
Tales from the dark side: developing SDKs at scaleKenneth Geisshirt
 
Is the database a solved problem?
Is the database a solved problem?Is the database a solved problem?
Is the database a solved problem?Kenneth Geisshirt
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboyKenneth Geisshirt
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboyKenneth Geisshirt
 
Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012Kenneth Geisshirt
 
Hadoop - the data scientist's toolbox
Hadoop - the data scientist's toolboxHadoop - the data scientist's toolbox
Hadoop - the data scientist's toolboxKenneth Geisshirt
 
JavaScript/Emacs integration
JavaScript/Emacs integrationJavaScript/Emacs integration
JavaScript/Emacs integrationKenneth Geisshirt
 
Introduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software DevelopmentIntroduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software DevelopmentKenneth Geisshirt
 

Plus de Kenneth Geisshirt (15)

Building parsers in JavaScript
Building parsers in JavaScriptBuilding parsers in JavaScript
Building parsers in JavaScript
 
Open Source in Real Life
Open Source in Real LifeOpen Source in Real Life
Open Source in Real Life
 
Building mobile apps with Realm for React Native
Building mobile apps with Realm for React NativeBuilding mobile apps with Realm for React Native
Building mobile apps with Realm for React Native
 
micro:bit and JavaScript
micro:bit and JavaScriptmicro:bit and JavaScript
micro:bit and JavaScript
 
Tales from the dark side: developing SDKs at scale
Tales from the dark side: developing SDKs at scaleTales from the dark side: developing SDKs at scale
Tales from the dark side: developing SDKs at scale
 
Android things
Android thingsAndroid things
Android things
 
Is the database a solved problem?
Is the database a solved problem?Is the database a solved problem?
Is the database a solved problem?
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Sociale netværk
Sociale netværkSociale netværk
Sociale netværk
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012
 
Hadoop - the data scientist's toolbox
Hadoop - the data scientist's toolboxHadoop - the data scientist's toolbox
Hadoop - the data scientist's toolbox
 
JavaScript/Emacs integration
JavaScript/Emacs integrationJavaScript/Emacs integration
JavaScript/Emacs integration
 
Introduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software DevelopmentIntroduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software Development
 
Kendthed og vigtighed
Kendthed og vigtighedKendthed og vigtighed
Kendthed og vigtighed
 

Dernier

JS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIJS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIIvo Andreev
 
Cybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadCybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadIvo Andreev
 
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Jaydeep Chhasatia
 
Why Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdfWhy Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdfBrain Inventory
 
Generative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilGenerative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilVICTOR MAESTRE RAMIREZ
 
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine HarmonyLeveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmonyelliciumsolutionspun
 
Introduction-to-Software-Development-Outsourcing.pptx
Introduction-to-Software-Development-Outsourcing.pptxIntroduction-to-Software-Development-Outsourcing.pptx
Introduction-to-Software-Development-Outsourcing.pptxIntelliSource Technologies
 
Watermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security ChallengesWatermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security ChallengesShyamsundar Das
 
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLBig Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLAlluxio, Inc.
 
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...OnePlan Solutions
 
OpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorOpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorShane Coughlan
 
Deep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - DatacampDeep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - DatacampVICTOR MAESTRE RAMIREZ
 
ERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptxERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptxAutus Cyber Tech
 
Mastering Kubernetes - Basics and Advanced Concepts using Example Project
Mastering Kubernetes - Basics and Advanced Concepts using Example ProjectMastering Kubernetes - Basics and Advanced Concepts using Example Project
Mastering Kubernetes - Basics and Advanced Concepts using Example Projectwajrcs
 
eAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionseAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionsNirav Modi
 
Kubernetes go-live checklist for your microservices.pptx
Kubernetes go-live checklist for your microservices.pptxKubernetes go-live checklist for your microservices.pptx
Kubernetes go-live checklist for your microservices.pptxPrakarsh -
 
Webinar - IA generativa e grafi Neo4j: RAG time!
Webinar - IA generativa e grafi Neo4j: RAG time!Webinar - IA generativa e grafi Neo4j: RAG time!
Webinar - IA generativa e grafi Neo4j: RAG time!Neo4j
 
About .NET 8 and a first glimpse into .NET9
About .NET 8 and a first glimpse into .NET9About .NET 8 and a first glimpse into .NET9
About .NET 8 and a first glimpse into .NET9Jürgen Gutsch
 
Your Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software TeamsYour Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software TeamsJaydeep Chhasatia
 

Dernier (20)

JS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIJS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AI
 
Cybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadCybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and Bad
 
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
 
Why Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdfWhy Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdf
 
Generative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilGenerative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-Council
 
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine HarmonyLeveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
 
Introduction-to-Software-Development-Outsourcing.pptx
Introduction-to-Software-Development-Outsourcing.pptxIntroduction-to-Software-Development-Outsourcing.pptx
Introduction-to-Software-Development-Outsourcing.pptx
 
Watermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security ChallengesWatermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security Challenges
 
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLBig Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
 
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
 
OpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorOpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS Calculator
 
Deep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - DatacampDeep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - Datacamp
 
Sustainable Web Design - Claire Thornewill
Sustainable Web Design - Claire ThornewillSustainable Web Design - Claire Thornewill
Sustainable Web Design - Claire Thornewill
 
ERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptxERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptx
 
Mastering Kubernetes - Basics and Advanced Concepts using Example Project
Mastering Kubernetes - Basics and Advanced Concepts using Example ProjectMastering Kubernetes - Basics and Advanced Concepts using Example Project
Mastering Kubernetes - Basics and Advanced Concepts using Example Project
 
eAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionseAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspections
 
Kubernetes go-live checklist for your microservices.pptx
Kubernetes go-live checklist for your microservices.pptxKubernetes go-live checklist for your microservices.pptx
Kubernetes go-live checklist for your microservices.pptx
 
Webinar - IA generativa e grafi Neo4j: RAG time!
Webinar - IA generativa e grafi Neo4j: RAG time!Webinar - IA generativa e grafi Neo4j: RAG time!
Webinar - IA generativa e grafi Neo4j: RAG time!
 
About .NET 8 and a first glimpse into .NET9
About .NET 8 and a first glimpse into .NET9About .NET 8 and a first glimpse into .NET9
About .NET 8 and a first glimpse into .NET9
 
Your Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software TeamsYour Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
 

Node.js extensions in C++

  • 1. Extending node.js using C++ Kenneth Geisshirt kg@realm.io Realm Inc. @realm http://github.com/Realm/ http://realm.io/
  • 2. Today’s goal • Learn - the basics of V8 internals and API - how to wrap C++ classes • Go home and write an extension
  • 3. Agenda 1.Why write extensions in C++ 2.My demo C++ classes 3.Building extensions 4.Wrapping classes • Setting up class • Instantiating objects • Setters, getters, etc. • Methods • Callbacks/anonymous functions • Exceptions
  • 4. Why Extensions in C++? • You get access to system resources • I/O, peripheral devices, GPUs, etc, • To get the performance of C++ • Cross-Language • Common core features in C++, many language bindings • Legacy code • Tons of old and useful C/C++/Fortran code
  • 5. Demo C++ Classes • Person • firstname() • lastname() • birthday() • to_str() • Book • add(Person* p) • Person *lookup(string name) • operator [size_t index] • remove(size_t index) • size_t size() Gettersandsetters https://github.com/kneth/DemoNodeExtension
  • 6. V8 concepts • Isolate is an isolated instance of V8 • Handles are references to JavaScript objects, and V8’s garbage collector reclaims them • Local handles are allocated on the stack; life-time is scope based • Persistent handles are allocated on the heap; life-time can span multiple function calls • You don’t return an object - you set the return value using GetReturnValue().Set() • and you cannot return a Local object (I’ll return to it later on) • V8 has classes to represent JavaScript types (String, Number, Array, Object, …)
  • 7. Breaking changes 0.10 →0.12 • V8 API changes in node.js 0.12 (February 2015) • How to return values from C++ to JavaScript • Type name for methods’ arguments • Creating objects require an Isolate • String encoding is strict (UTF-8 is common) • Extensions cannot support both 0.10 and 0.12+ • https://strongloop.com/strongblog/node-js-v0-12-c-apis- breaking/
  • 8. Building extensions • Wrapping classes (person.cpp → person_wrap.cpp, …) • Build process described in bindings.gyp • node-gyp configure build { 'targets': [{ 'target_name': 'funstuff', 'sources': [ 'person.cpp', 'person_wrap.cpp', 'book.cpp', 'book_wrap.cpp', 'funstuff.cpp' ], 'xcode_settings': { 'OTHER_CFLAGS': [ '-mmacosx-version-min=10.8', '-std=c++11', '-stdlib=libc++', '-fexceptions', '-frtti' ] } }] } Name of extension OS X specific options #include <node.h> #include "person_wrap.hpp" #include "book_wrap.hpp" using namespace v8; void InitAll (Handle<Object> exports) { PersonWrap::Init(exports); BookWrap::Init(exports); } NODE_MODULE(funstuff, InitAll)
  • 9. Wrapping a class • Wrapper classes inherent from node::ObjectWrap • All methods are static #include <node.h> #include <node_object_wrap.h> #include "book.hpp" #include "person.hpp" class BookWrap : public node::ObjectWrap { public: static void Init(v8::Handle<v8::Object> exports); static void New(const v8::FunctionCallbackInfo<v8::Value>& args); BookWrap(); private: ~BookWrap(); Book* m_book; static v8::Persistent<v8::Function> Constructor; }; Add class to V8 Helper to create new objects The class to wrap
  • 10. Adding a class to V8 • Calling BookWrap::Init() to register/add the class • Sets up constructor, methods, and basic infrastructure void BookWrap::Init(Handle<Object> exports) { Isolate* isolate = exports->GetIsolate(); Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, BookWrap::New); tpl->SetClassName(String::NewFromUtf8(isolate, "Book")); tpl->InstanceTemplate()->SetInternalFieldCount(1); NODE_SET_PROTOTYPE_METHOD(tpl, “add", Add); tpl->InstanceTemplate()->SetIndexedPropertyHandler(Getter, Setter, 0, Deleter, Enumerator); Constructor.Reset(isolate, tpl->GetFunction()); exports->Set(String::NewFromUtf8(isolate, "Book"), tpl->GetFunction()); } Setting the class name Adding a method Getter, setter, etc. Preparing constructor var funstuff = require('./build/Release/funstuff');
  • 11. Instantiate an object void BookWrap::New(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = Isolate::GetCurrent(); HandleScope scope(isolate); if (args.IsConstructCall()) { if (args.Length() == 0) { BookWrap* bw = new BookWrap(); Book *b = new Book(); bw->m_book = b; bw->Wrap(args.This()); args.GetReturnValue().Set(args.This()); } } Create wrapper and object Add wrapper to V8 runtime Return the object var book = new funstuff.Book();
  • 12. Methods • Methods are implemented in C++ • Input validation is important (IsString, IsNumber, …) void BookWrap::Length(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = args.GetIsolate(); HandleScope scope(isolate); BookWrap* bw = ObjectWrap::Unwrap<BookWrap>(args.This()); const int count = bw->m_book->size(); Local<Integer> result = Integer::New(isolate, count); args.GetReturnValue().Set(result); } var book = new funstuff.Book(); console.log('Book: ' + book.length()); Arguments: args.Length(), args[0] Get this as wrapper object Create an object to return Return the new object Get current scope
  • 13. Instantiate objects • Instantiating wrapper object in C++ • Method of one class returns object of other class • For example: var person = book[4]; Handle<Object> PersonWrap::New(Isolate* isolate, Book* b, uint32_t index) { EscapableHandleScope scope(isolate); Handle<Value> argv[] = { Boolean::New(isolate, true) }; Local<Function> cons = Local<Function>::New(isolate, Constructor); Handle<Object> obj = cons->NewInstance(1, argv); PersonWrap* pw = PersonWrap::Unwrap<PersonWrap>(obj); pw->m_person = (*b)[size_t(index)]; return scope.Escape(obj); } Dummy argument Call constructor: PersonWrap::New(const FunctionCallbackInfo<Value>& args)Add object to current scope
  • 14. Indexed getters and setters book[6] = new Person(); var person = book[4]; void BookWrap::Getter(uint32_t index, const PropertyCallbackInfo<Value>& info) { Isolate* isolate = info.GetIsolate(); HandleScope scope(isolate); BookWrap* bw = ObjectWrap::Unwrap<BookWrap>(info.This()); Book* b = bw->m_book; if (index >= b->size()) { isolate->ThrowException(Exception::RangeError(String::NewFromUtf8(isolate, "invalid row index"))); info.GetReturnValue().SetUndefined(); } else { Handle<Object> result = PersonWrap::New(isolate, b, index); info.GetReturnValue().Set(result); } } Instantiate a wrapper object and return it Unwrap this and get C++ object Validate input (index is in range) void BookWrap::Setter(uint32_t index, Local<Value> value, const PropertyCallbackInfo<Value>& info) Value to set; remember to validate!
  • 15. Accessors • Accessors are useful for known properties • C++ isn’t dynamic as JavaScript • Added to V8 during initialisation (PersonWrap::Init()) var person = new funstuff.Person(); person.firstname = “Arthur”; tpl->InstanceTemplate()->SetAccessor(String::NewFromUtf8(isolate, "firstname"), PersonWrap::FirstnameGetter, PersonWrap::FirstnameSetter); void PersonWrap::FirstnameGetter(Local<String> property, const PropertyCallbackInfo<Value>& info) { Isolate* isolate = Isolate::GetCurrent(); HandleScope scope(isolate); PersonWrap *pw = ObjectWrap::Unwrap<PersonWrap>(info.This()); Person *p = pw->m_person; info.GetReturnValue().Set(String::NewFromUtf8(isolate, p->firstname().c_str())); }
  • 16. Callbacks • Callbacks and anonymous functions are JavaScript in a nutshell • Functions are objects: Function is used in V8 book.each(function (p) { console.log("Firstname: " + p.firstname); }); void BookWrap::Each(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = args.GetIsolate(); HandleScope scope(isolate); Book* book = ObjectWrap::Unwrap<BookWrap>(args.This())->m_book; if (args.Length() == 1) { if (args[0]->IsFunction()) { Local<Function> fun = Local<Function>::Cast(args[0]); for(uint32_t i = 0; i < book->size(); ++i) { Local<Object> pw = PersonWrap::New(isolate, book, i); Local<Value> argv[1] = { pw }; fun->Call(Null(isolate), 1, argv); } args.GetReturnValue().SetUndefined(); return; } } } The anonymous function Set up arguments Call the function
  • 17. Throwing Exceptions • Throwing a C++ exception is a no-go • set node.js’ state to “exception” • when returning to JavaScript an exception is thrown • V8 has a limited number of exceptions: RangeError, ReferenceError, SyntaxError, TypeError, Error Isolate* isolate = Isolate::GetCurrent(); HandleScope scope(isolate); // … isolate->ThrowException(Exception::SyntaxError(String::NewFromUtf8(isolate, "No arguments expected"))); args.GetReturnValue().SetUndefined(); return;
  • 18. Catching Exceptions • Callbacks might throw an exception • V8 has a TryCatch class to check for it try { var s = book.apply(function (b) { throw { msg: "Error" }; }); console.log(" Length: " + s); } catch (e) { console.log(" Exception caught: " + e.msg); } void BookWrap::Apply(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = args.GetIsolate(); HandleScope scope(isolate); Local<Function> fun = Local<Function>::Cast(args[0]); Handle<Value> argv[] = { args.This() }; TryCatch trycatch; Handle<Value> v = fun->Call(Null(isolate), 1, argv); if (trycatch.HasCaught()) { trycatch.ReThrow(); } args.GetReturnValue().Set(v); } If HasCaught() is true, an JS exception was thrown Set the node.s’ “exception” state
  • 19. NAN • Native Abstraction for Node (NAN) makes it easier to write extensions • Hides breaking changes in the V8 API - Your extension will support many versions! • Functions and macros for common tasks • https://github.com/nodejs/nan
  • 20. Observations • Extensions do not have to be a one-to-one mapping • A lot of code to do input validation • JavaScript isn’t a strongly typed language • Unit testing is very important • C++ has classes - JavaScript doesn’t • Awkward for JavaScript programmers • Crossing language barrier during call is hard for debuggers
  • 21. Learn more • Check out my demo: https://github.com/kneth/ DemoNodeExtension • Google’s documentation: https:// developers.google.com/v8/embed?hl=en • JavaScript - The Good Parts. D. Crockford. O’Reilly Media, 2008. • Any modern C++ text book 😱 http://realm .io W e are hiring