We b A s s e m b l y
2 0 1 7 / 0 4 / 1 9 C R E AT O R S M E E T U P # 5 1
• JavaScript web
• C/C++ OSS
• C/C++
• !!!
•
• Hello world
• API
•
•
We b A s s e m b l y
• wasm( )
• (AST : abstract syntax tree)
• React Typescript JavaScript
• asm.js emscripten
• web
We b A s s e m b l y
C/C++
Obj-C
Swift
Compiler .wasm
Browser
Converter .js
JSX
TypeScript
Provider User
• 1byte = 8bit
•
• IEEE 754
• wasm32 / wasm64 (MVP wasm32 )
• API
• http://webassembly.org/docs/portability/
L LV M
• http://llvm.org/
• ( )
•
• clang : C / C++ / Objective-C / swift
Chris Lattner
L LV M
LLVM
Optimizer
Clang
dragon
egg
original
frontend
C/C++
Obj-C
Swift
Fortran
Ada
Go
original
language
x86 backend
ARM
backend
iPhone
Android
Raspberry Pi
PC
...
L LV M + b y n a r y e n
llcclang
C/C++
Obj-C
Swift
.ll .s
s2wasm.wastsexpr-wasm.wasm
LLVM
binaryen
e m s c r i p t e n
• http://emscripten.org/
• C/C++ JavaScript ( )
• C/C++ LLVM IR JavaScript
• C/C++ , POSIX, SDL, OpenGL
• WebAssembly / asm.js / Polyfill
Alon Zakai (kripken)
e m s c r i p t e n
emcc
em++
C/C++
-s -WASM=1
.wasm
.js
.html
LLVM
Bynaryen
H e l l o w o r l d
s e t u p e m s c r i p t e n
• Linux OSX Portable SDK
• https://kripken.github.io/emscripten-site/docs/
getting_started/downloads.html
• renv (clang, node.js,
llvm, binaryen)
$ tar vzxf emsdk-portable.tar.gz
$ cd emsdk-portable
$ ./emsdk install sdk-incoming-64bit binaryen-master-64bit
$ ./emsdk activate sdk-incoming-64bit binaryen-master-64bit
$ source ./emsdk_env.sh
console
H e l l o w o r l d .
#include <stdio.h>
int main(int argc, char* argv[]) {
printf("hello world.”);
return 0;
}
hello.c
$ emcc -s -WASM=1 -o hello.html hello.c
console
hello.html hello.js hello.wasm
• hello.html
•
•
$ emrun --no_browser --port 8080 
<hello.html >
console
< o u t p u t > . h t m l
• emscripten/incoming/src/shell_minimal.html
HTML
• -o <output>.js HTML
$ emcc -s -WASM=1 
--shell-file custom.html 
-o <output>.html <input>.c
console
< o u t p u t > . j s
• emscripten
•
•
• Module WebAssembly.Module
A P I
We b A s s e m b l y. i n s t a n t i a t e
• <script type='module'>
• 1 : wasm ArrayBuffer
• 2 : WebAssembly
•
•
• module(WebAssembly.Module) instance(WebAssembly.Instance)
• https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/
Global_Objects/WebAssembly/instantiate
We b A s s e m b l y. i n s t a n t i a t e
fetch('hello.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
var instance = results.instance;
var module = results.modules;
//
});
JavaScript
We b A s s e m b l y. M o d u l e
• wasm
•
•
WebAssembly.Module
We b A s s e m b l y. I n s t a n c e
• WebAssembly.Module
• new Instance(moduleObject [, importObject])
• instance.exports wasm
instance.exports.< >( );
JavaScript
i m p o r t O b j e c t
var importObject = {
env: {
memory: new WebAssembly.Memory({
initial: 256
}), // Instance
table: new WebAssembly.Table({
initial: 0,
element: 'anyfunc'
}), //
... // WebAssembly.Module
},
global: {
... //
}
};
JavaScript
w a s t
• importObject
(module
....
(import "global" "NaN" (global $import$5 f64))
(import "global" "Infinity" (global $import$6 f64))
....
(import "env" "memory" (memory $0 256 256))
(import "env" "table" (table 10 10 anyfunc))
....
)
wast
i m p o r t
(module
....
(import "env" "_js_hello"
(func $import$13 (param i32 i32) (result i32)))
....
)
wast
extern int js_hello(int arg1, char* arg2);
C/C++
importObject['env']['_js_hello'] =
function(arg1, arg2) {
...
}
JavaScript
e x p o r t
(module
(export "_c_hello" (func $7))
(func $7 (type $8) (param $var$0 i32)
(param $var$1 f64) (result i32)
....
)
)
wast
__attribute__((used))
int c_hello(int arg1, double arg2) {
....
}
C/C++
instance.exports._c_hello(1, 2); JavaScript
Browser
WebAssembly
JavaScript
WebAssembly.instantiate
instance.export._main main
printf
writev[import] env.__syscall146
Module.print
console.logHello world.
run()
int value1 = 1192; // 0x04a8
short value2 = 758; // 0x02f6
char value3 = -1; // 0xff
char value4 = 99; // 0x63
• importObject.env.memory
• wasm
• emscripten Module.HEAPU8 DataView
C/C++
00 00 04 a8 02 f6 ff 63
Memory
…… … …
for (int i = 0; i < 8; i ++) {
console.log(Module.HEAPU8[Module.getptr() + i]);
}
• = OK
•
int value1 = 1192; // 0x04a8
short value2 = 758; // 0x02f6
char value3 = -1; // 0xff
char value4 = 99; // 0x63
// unsigned int getptr();
return (unsigned int)(&value1);
C/C++
a8 04 00 00 f6 02 ff 63
JS(emscripten)
…… … …
for (int i = 0; i < 2; i ++) {
console.log(Module.HEAPU32[Module.getptr() / 4 + i]);
}
for (int i = 0; i < 4; i ++) {
console.log(Module.HEAPU16[Module.getptr() / 2 + i]);
}
i n t s h o r t
00 00 04 a8 63 ff 02 f6
JS(emscripten)
… …
04 a8 00 00 02 f6 63 ff
JS(emscripten)
… …
a8 04 00 00 f6 02 ff 63…… … …
var v = Module.getValue(Module.getptr(), 'i32');
Module.setValue(Module.getptr(), v + 1, 'i32');
• Module.getValue(< >, < >);
• Module.setValue(< >, < >, < >);
• WebAssembly
getValue
JS(emscripten)
console.log(
Module.Pointer_stringify(
Module.getptr()));
• C/C++ JavaScript
• emscripten Pointer_stringify(< >[, < >]);
unsigned int getptr() {
char* str = "hello world!";
return (unsigned int)(&str);
}
C/C++
JS(emscripten)
• http://webassembly.org/
• https://developer.mozilla.org/docs/WebAssembly
• JavaScript API C/C++
wasm
• emscripten
•
• PROCESS WARP
http://www.processwarp.org/
• GitHub llamerada-jp
• facebook ito.yuuji
• blog http://llamerad-jp.hatenablog.com/

詳説WebAssembly

  • 1.
    We b As s e m b l y 2 0 1 7 / 0 4 / 1 9 C R E AT O R S M E E T U P # 5 1
  • 2.
    • JavaScript web •C/C++ OSS • C/C++ • !!!
  • 3.
  • 5.
    We b As s e m b l y • wasm( ) • (AST : abstract syntax tree) • React Typescript JavaScript • asm.js emscripten • web
  • 6.
    We b As s e m b l y C/C++ Obj-C Swift Compiler .wasm Browser Converter .js JSX TypeScript Provider User
  • 7.
    • 1byte =8bit • • IEEE 754 • wasm32 / wasm64 (MVP wasm32 ) • API • http://webassembly.org/docs/portability/
  • 8.
    L LV M •http://llvm.org/ • ( ) • • clang : C / C++ / Objective-C / swift Chris Lattner
  • 9.
  • 10.
    L LV M+ b y n a r y e n llcclang C/C++ Obj-C Swift .ll .s s2wasm.wastsexpr-wasm.wasm LLVM binaryen
  • 11.
    e m sc r i p t e n • http://emscripten.org/ • C/C++ JavaScript ( ) • C/C++ LLVM IR JavaScript • C/C++ , POSIX, SDL, OpenGL • WebAssembly / asm.js / Polyfill Alon Zakai (kripken)
  • 12.
    e m sc r i p t e n emcc em++ C/C++ -s -WASM=1 .wasm .js .html LLVM Bynaryen
  • 13.
    H e ll o w o r l d
  • 14.
    s e tu p e m s c r i p t e n • Linux OSX Portable SDK • https://kripken.github.io/emscripten-site/docs/ getting_started/downloads.html • renv (clang, node.js, llvm, binaryen) $ tar vzxf emsdk-portable.tar.gz $ cd emsdk-portable $ ./emsdk install sdk-incoming-64bit binaryen-master-64bit $ ./emsdk activate sdk-incoming-64bit binaryen-master-64bit $ source ./emsdk_env.sh console
  • 15.
    H e ll o w o r l d . #include <stdio.h> int main(int argc, char* argv[]) { printf("hello world.”); return 0; } hello.c $ emcc -s -WASM=1 -o hello.html hello.c console hello.html hello.js hello.wasm
  • 16.
    • hello.html • • $ emrun--no_browser --port 8080 <hello.html > console
  • 18.
    < o ut p u t > . h t m l • emscripten/incoming/src/shell_minimal.html HTML • -o <output>.js HTML $ emcc -s -WASM=1 --shell-file custom.html -o <output>.html <input>.c console
  • 19.
    < o ut p u t > . j s • emscripten • • • Module WebAssembly.Module
  • 20.
  • 21.
    We b As s e m b l y. i n s t a n t i a t e • <script type='module'> • 1 : wasm ArrayBuffer • 2 : WebAssembly • • • module(WebAssembly.Module) instance(WebAssembly.Instance) • https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/ Global_Objects/WebAssembly/instantiate
  • 22.
    We b As s e m b l y. i n s t a n t i a t e fetch('hello.wasm').then(response => response.arrayBuffer() ).then(bytes => WebAssembly.instantiate(bytes, importObject) ).then(results => { var instance = results.instance; var module = results.modules; // }); JavaScript
  • 23.
    We b As s e m b l y. M o d u l e • wasm • • WebAssembly.Module
  • 24.
    We b As s e m b l y. I n s t a n c e • WebAssembly.Module • new Instance(moduleObject [, importObject]) • instance.exports wasm instance.exports.< >( ); JavaScript
  • 25.
    i m po r t O b j e c t var importObject = { env: { memory: new WebAssembly.Memory({ initial: 256 }), // Instance table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' }), // ... // WebAssembly.Module }, global: { ... // } }; JavaScript
  • 26.
    w a st • importObject (module .... (import "global" "NaN" (global $import$5 f64)) (import "global" "Infinity" (global $import$6 f64)) .... (import "env" "memory" (memory $0 256 256)) (import "env" "table" (table 10 10 anyfunc)) .... ) wast
  • 27.
    i m po r t (module .... (import "env" "_js_hello" (func $import$13 (param i32 i32) (result i32))) .... ) wast extern int js_hello(int arg1, char* arg2); C/C++ importObject['env']['_js_hello'] = function(arg1, arg2) { ... } JavaScript
  • 28.
    e x po r t (module (export "_c_hello" (func $7)) (func $7 (type $8) (param $var$0 i32) (param $var$1 f64) (result i32) .... ) ) wast __attribute__((used)) int c_hello(int arg1, double arg2) { .... } C/C++ instance.exports._c_hello(1, 2); JavaScript
  • 29.
  • 31.
    int value1 =1192; // 0x04a8 short value2 = 758; // 0x02f6 char value3 = -1; // 0xff char value4 = 99; // 0x63 • importObject.env.memory • wasm • emscripten Module.HEAPU8 DataView C/C++ 00 00 04 a8 02 f6 ff 63 Memory …… … …
  • 32.
    for (int i= 0; i < 8; i ++) { console.log(Module.HEAPU8[Module.getptr() + i]); } • = OK • int value1 = 1192; // 0x04a8 short value2 = 758; // 0x02f6 char value3 = -1; // 0xff char value4 = 99; // 0x63 // unsigned int getptr(); return (unsigned int)(&value1); C/C++ a8 04 00 00 f6 02 ff 63 JS(emscripten) …… … …
  • 33.
    for (int i= 0; i < 2; i ++) { console.log(Module.HEAPU32[Module.getptr() / 4 + i]); } for (int i = 0; i < 4; i ++) { console.log(Module.HEAPU16[Module.getptr() / 2 + i]); } i n t s h o r t 00 00 04 a8 63 ff 02 f6 JS(emscripten) … … 04 a8 00 00 02 f6 63 ff JS(emscripten) … … a8 04 00 00 f6 02 ff 63…… … …
  • 34.
    var v =Module.getValue(Module.getptr(), 'i32'); Module.setValue(Module.getptr(), v + 1, 'i32'); • Module.getValue(< >, < >); • Module.setValue(< >, < >, < >); • WebAssembly getValue JS(emscripten)
  • 35.
    console.log( Module.Pointer_stringify( Module.getptr())); • C/C++ JavaScript •emscripten Pointer_stringify(< >[, < >]); unsigned int getptr() { char* str = "hello world!"; return (unsigned int)(&str); } C/C++ JS(emscripten)
  • 37.
  • 38.
    • JavaScript APIC/C++ wasm • emscripten
  • 39.
    • • PROCESS WARP http://www.processwarp.org/ •GitHub llamerada-jp • facebook ito.yuuji • blog http://llamerad-jp.hatenablog.com/