getting started with emscripten – transpiling c / c++ to javascript / html5

53
Emscripten - Transpiling C / C+ + to JS / HTML5 Dave Voyles Sr. Tech Evangelist, Philadelphia DaveVoyles.com

Upload: david-voyles

Post on 12-Apr-2017

4.725 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Emscripten - Transpiling C / C++

to JS / HTML5Dave Voyles

Sr. Tech Evangelist, PhiladelphiaDaveVoyles.com

Page 2: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

JavaScript is standards-based and the only language that runs in all web

browsers

You can run only JavaScript in browsers, but you can write in another language - if you compile it to JavaScript

Page 3: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Everything compiles to LLVM bitcode

Which we can then turn into JavaScript

Page 4: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Native code has its perks (performance!)

But so does rapid testing/sharing.

Transpile to JS and just share a URL

Page 5: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

This is nothing new (well, sort of…)

C#, Python, Java, TypescriptAll transpile to JavaScript

• Pyjs – Python• JSIL – C#• Java – Google Web

Toolkit

Page 6: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Why now?

non-standardized approaches (ActiveX, Silverlight, Flash/Alchemy, PNaCl/PPAPI) have had limited

success in the past

Page 7: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Why now?

Plugins outside of HTML5 standards have not received widespread adoption for both technical

and non-technical reasons

Page 8: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Besides, they are on their way out

No plugins for iOS devices, Google nixes NPAPI, etc.

Page 9: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

This is great for the web! Standards!

JavaScript is a standard, so why not compile to that?

Page 10: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Example: gaming on the web

Experience w/ typical games:• Go to platform-specific store, log in, find game,

purchase, download, install, patch, playExperience w/ web games:

• www.DaveVoyles.com (Launches the game!)

Page 11: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

JS then vs JS now

Then: JS began as a slow interpreted language

Page 12: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

JS then vs JS nowImplicit, statically typed code in JS, just like the competition

Page 13: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

JS then vs JS nowNow: Asm.js – highly optimized, performant subset of JS

Page 14: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

asm.js overview

Page 15: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Emscripten overview• Open source (MIT/LLVM) • Began in 2010

Page 16: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Emscripten is built on LLVM• clang C++ frontend• LLVM optimizer• libc++ C++ standard library• libc++abi low-level C++ support

Page 17: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Clang supports nearly all C++ features, so Emscripten does as well

Exception handling takes some work, though

Page 18: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5
Page 19: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Runtime functions

Page 20: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

What about other libraries?

SDL & OpenGL are implemented via Web APIs, same with musl (Linux)

• Bullet • Box2D • Python

• Lua• Ruby• zlib

Page 21: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Not without its limitations• 64-bit integer math will not work

• No multithreading with shared state

• No Direct3D support, only OpenGL

Page 22: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

DebuggingThis is a problem in general with compiling for the web. Source maps can help, but browsers do have more work to do to make debugging compiled code a smoother experience.

Start with your compiled code.

Page 23: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

How does it work?

Page 24: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Numeric types

JS• double

LLVM•i8, i16, i32, float,

double

Page 25: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Performance LLVM

• types & operations map ~1:1 to CPU• RAII offers

Predictability

JS• virtual machine (VM)• just in time (JIT) compilers

w/ type profiling• garbage collection• Etc.

Page 26: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Builds C++

•Need to recompile for each CPU / OS

JS•One build to rule

them all

Page 27: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Variables

LLVM• Local vars have

function scope

JS• Local vars have

function scope

Page 28: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Security concernsJS

• Sandboxed• Cannot see the

machine it is running on

C++•Apps can use system

libs•Access local

filesystem

Page 29: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Security concerns (cont’d)

The JS stack is managed and unobservable/unmodifiable by executing code.

Compiled C++ is immune to some types of buffer overflow attacks

Can be beneficial, though….

Page 30: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

More speedLoads in LLVM IR become reads from typed array (binary data in the browser) in JS, which become reads in machine code.

Page 31: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Why do this?

• Download just parts of the app, stream the rest• Ex: Star Citizen: 100GB+ Vs. Age of Ascent: 50Mb

• Circumvent app stores• Want to push updates? Just update your web app• No more 1 week waiting period, iOS

• Distribution through sources other than curated app stores• Release apps on your website

Page 32: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Browser support

Page 33: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

native executable

Page 34: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Compiling with Emscripten

Page 35: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Generating codeThe target file name extension defines the output type to be generated:

<name> .js : JavaScript.

<name> .html : HTML + separate JavaScript file (<name>.js). (Having the separate JavaScript file improves page load time.)

<name> .bc : LLVM bitcode (default).

Page 36: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Porting processemcc is a drop-in replacement for gcc or clang

In many cases, you can use your normal build system, plug in emcc

Page 37: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Porting processemcc is a drop-in replacement for gcc or clang

In many cases, you can use your normal build system, plug in emcc

Page 38: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Connecting C / C++ and JS

Call compiled C++ classes from JavaScript using bindings created with:• Embind or WebIDL-Binder

Call compiled C functions from normal JavaScript:• Using ccall or cwrap.• Using direct function calls (faster but more complicated).

Call JavaScript functions from C/C++:• Using emscripten_run_script().• Using EM_ASM() (faster).• Using a C API implemented in JavaScript.• As function pointers from C.• Using the Embind val class.

Page 39: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Why not just turn your JavaScript code into asm.js?

Run-time type checking takes time.

Page 40: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Why not just turn your JavaScript code into asm.js?

In statically typed languages, such as C, the compiler knows the type of each

object when it is being compiled.

Page 41: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Offline experience

• IndexedDB• Local database of records, holding simple values

and hierarchical objects

• AppCache• Offline browsing, stores content on the disk

instead of network

• Service Workers• Coming soon

Page 42: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Performance

Page 43: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Unity WebGL benchmark

Page 44: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

(Higher is better)

Unity WebGL Benchmarks

Page 45: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Unity WebGL Benchmarks• In benchmarks which stress WebGL rendering performance

(Particles, Asteroid Field), Edge performs best of all tested browsers.

• When you are mostly GPU-bound, you can expect WebGL to perform very similar to native code.

• In some areas, WebGL will actually outperform native code significantly. (Mandlebrot & Cryptohash)

• Native code can still be several times faster than WebGL for areas heavily optimized to use multi-threading and/or SIMD, such as the 3D physics tests.

Page 46: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Case study: Owlchemy Labs• 200+ levels

• 300 assets can be spawned a runtime

• 38 full length songs

• 1 million lines of JavaScript

• WebGL build (With Unity engine!) = 68.8Mb

• PC build = 192 Mb

Page 47: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5
Page 48: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Exporting with Unity

Page 49: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

What goes in must come out

When you build a WebGL project, Unity will create a folder with the following files:

•  index.html file that embeds your content in a web page.

• JavaScript file containing the code for your player.

• .mem file containing a binary image to initialize the heap memory for your player.

• .data file containing the asset data and scenes.• some supporting JavaScript files to initialize and

load the player.

Page 50: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

Some missing features• Networking other than WWW class (a WebSockets

plug-in is available)

• Support for WebCam and Microphone access

• Threads

• Any .NET features requiring dynamic code generation

• Runtime generation of Substance textures

Page 51: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

ConclusionThe advantages of porting C/C++ to JavaScript are clear:

• Often a smaller package size• Easily demo or share projects on the

web• Reuse existing code

Page 52: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5
Page 53: Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5

ReferencesThank you to Alon Zakai (@Kripken)and his wonderful work on the project!• http://twvideo01.ubm-us.net/o1/vault/gdconline12/Presentations/Emscript

en%20(pt%201).pdf

• https://www.reddit.com/r/programming/comments/2k3b4j/alon_zakai_emscripten_and_asmjs_cs_role_in_the/http://llvm.org/devmtg/2013-11/slides/Zakai-Emscripten.pdf

• http://llvm.org/devmtg/2013-11/slides/Zakai-Emscripten.pdf