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 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)
12. e m s c r i p t e n
emcc
em++
C/C++
-s -WASM=1
.wasm
.js
.html
LLVM
Bynaryen
14. 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
15. 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
18. < 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
19. < o u t p u t > . j s
• emscripten
•
•
• Module WebAssembly.Module
21. 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
22. 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
23. We b A s s e m b l y. M o d u l e
• wasm
•
•
WebAssembly.Module
24. 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
25. 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
26. 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
27. 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
28. 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
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)