SlideShare a Scribd company logo
asm.jsxEmscripten:
Thefoundationofthenextlevelwebgames
MozillaJapanテクニカルマーケティング
清水智公(nshimizu@mozilla-japan.org/@chikoski)
第63回HTML5とか勉強会withhtml5jゲーム部発足記念合同勉強会
N.Shimizu
• Mozilla Japan (L10N, Game, Devtools, Web Animation)
• html5j Web プラットフォーム部、

Firefox OS、Firefox OS コードリーディング、

html5j ゲーム部 (NEW!)
• @chikoski
• プログラミング言語、分類、ベイジアン、サッカー、圏論(NEW!)
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
文字列 実行コード
文字列 実行コード抽象構文木トークン列 中間表現
字句解析 構文解析 意味解析 最適化・コード生成
文字列 実行コード抽象構文木トークン列 中間表現
字句解析 構文解析 意味解析 最適化・コード生成
asm.js x emscripten: The foundation of the next level Web games
文字列 AST バイトコード
字句解析 / 構文解析 生成
実行
* AST: Abstract Syntax Tree / 抽象構文木
function addOne(a){
return a + 1;
}
loc op
----- --
main:
00000: getarg 0
00003: one
00004: add
00005: return
00006: retrval
aのデータ型 a + 1 のデータ型
number number
undefined number
null number
string string
object string
Just In Time Compile
データ型
Data Type
asm.js x emscripten: The foundation of the next level Web games
文字列
字句解析 /
構文解析
実行
バイトコードAST
Baseline
Compiled
Code
MIR
Iron
Compiled
Code
実行と
プロファイル 実行
Bail
生成
Baseline
Compile
Iron Build
Iron
Compile
* AST: Abstract Syntax Tree / 抽象構文木
 MIR: Medium-level Intermediate Representation / 中間表現
* AST: Abstract Syntax Tree / 抽象構文木
 MIR: Medium-level Intermediate Representation / 中間表現
文字列
字句解析 /
構文解析
実行
バイトコードAST
Baseline
Compiled
Code
MIR
Iron
Compiled
Code
実行と
プロファイル 実行
Bail
生成
Baseline
Compile
Iron Build
Iron
Compile
• JITは重い
• hot code(よく実行されるコード)しかコンパイルされない
• JITが始まるまでは、遅いまま
• 型推論に失敗するなどして、JITをやり直すことがある
ダウンロード 実行開始 コンパイル
Ahead-Of-Time Compile
AOT ダウンロード コンパイル 実行開始
JIT ダウンロード 実行開始 コンパイル
Native ダウンロードコンパイル 実行開始
データ型
Data Type
asm.js
asm.js:anextraordinarilyoptimizable,low-levelsubsetofJavaScript
• JavaScript として評価可能
• 数値計算、関数の定義と呼び出し、ArrayBufferの操作のみ可能
• その他のことは不可能
• 型アノテーションと、フォーマルな検証プロセス
• FFIを通じたJavaScript との相互呼び出し
• ArrayBuffer の共有によるデータの受け渡し
asm.js x emscripten: The foundation of the next level Web games
function add1(a){
return a + 1;
}
function Peano(stdlib, ffi, heap){
"use asm";
function add1(a){
a = a | 0;
return (a + 1) | 0;
}
return {
suc: add1
}
}
const add1 = Peano(window).suc;
const zero = 0;
const one = add1(zero);
console.log(one); // 1
asm.js で定義したモジュールの利用
function Peano(stdlib, ffi, heap){
"use asm";
// 外部からインポートするシンボルの宣言
// 関数宣言
// 関数表の宣言
// モジュールのエキスポート
}
asm モジュールの構造
#include <stdio.h> // 標準ライブラリのインクルード
#include "log.h"   // その他のライブラリのインクルード
extern void log(int); // 外部からインポートするシンボルの宣言
int add1(int n){ // 関数宣言
log(n);
return n + 1;
}
function Peano(stdlib, ffi, heap){
"use asm";
var abs = stdlib.Math.abs; // 標準ライブラリからのインポート
var z = ffi.zero | 0; // 定数の受け渡し
var log = ffi.log; // JS関数のインポート
外部からインポートするシンボルの宣言
const ffi = {
zero: 0,
log: text => console.log(text)
};
const add1 = Peano(window, ffi).suc;
JS から asm.js へのシンボルの受け渡し
function Peano(stdlib, ffi, heap){
"use asm";
var abs = stdlib.Math.abs; // 標準ライブラリからのインポート
var z = ffi.zero | 0; // 定数の受け渡し
var log = ffi.log; // JS関数のインポート
型アノテーション
変数x のアノテーション 引数 x の型
x = x | 0; int
x = +x; double
x = f(x); float
function addOne(n){
// 引数の型宣言
// 変数宣言
// 関数本体の記述
}
関数宣言の構造
function addOne(n){
n = n | 0; // 引数の型宣言
var one = 1; // 変数宣言
one = (one + n) | 0; // 関数本体
return one | 0;
}
返り値の ret アノテーション 返り値の型
return +ret; double
return ret | 0; int
return 3; double
return f(ret); float
return; void
function addOne(n){
n = n | 0; // 引数の型宣言
var one = 1; // 変数宣言
one = (one + n) | 0; // 関数本体
return one | 0;
}
関数の型: (引数の型) → 返り値の型
function addOne(n){
n = n | 0;
return (n + 1)| 0;
}
function addTwo(n){
n = n | 0;
return (n + 2) | 0;
}
int -> int の関数
var addFunctions = [addOne, addTwo];
関数表宣言(関数ポインタの列)
function Peano(stdlib, ffi, heap){
"use asm";
var abs = stdlib.Math.abs; // 標準ライブラリからのインポート
var z = ffi.zero | 0; // 定数の受け渡し
var log = ffi.log; // JS関数のインポート
標準ライブラリ、外部関数、ヒープ
標準ライブラリ 型
Infinity
NaN
double
Math.acos
Math.asin
Math.atan
Math.cos
Math.sin
Math.tan
Math.exp
(double?) → double
標準ライブラリ 型
Math.ceil
Math.floor
Math.sqrt
(double?) → double ∧
(float?) → float
Math.abs (signed) → signed ∧
(double?) → double ∧
(float?) → float
Math.min
Math.max
(int, int…) → signed ∧
(double, double…) → double
Math.atan2
Math.pow
(double?, double?) → double
標準ライブラリ 型
Math.imul (int, int) → signed
Math.fround fround
Math.E
Math.LN10
Math.LN2
Math.LOG2E
Math.LOG10E
Math.PI
Math.SQRT1_2
Math.SQRT2
double
var log = ffi.log; // 外部関数
log(n | 0);     // これはリンク時にエラー
log((n | 0) >>> 0); // これはリンクできる
外部関数の呼び出しにも配慮が必要
asm.js における型(矢印は継承を表す)
JavaScript の環境と行き来できる型
単項演算子 型
+ (signed) → double ∧

(unsigned) → double ∧
(double?) → double ∧

(float?) → double
- (int) → intish ∧

(double?) → double ∧
(float?) → floatish
~ (intish) → signed
! (int) → int
二項演算子 型
+ (double, double) → double ∧
(float?, float?) → floatish
- (double?, double?) → double ∧
(float?, float?) → floatish
* (double?, double?) → double ∧
(float?, float?) → floatish
/ (signed, signed) → intish ∧
(unsigned, unsigned) → intish ∧
(double?, double?) → double ∧
(float?, float?) → floatish
二項演算子 型
% (signed, signed) → intish ∧
(unsigned, unsigned) → intish ∧
(double?, double?) → double
|, &, ^, <<, >> (intish, intish) → signed
>>> (intish, intish) → unsigned
<, <=, >, >=, ==, != (signed, signed) → int ∧
(unsigned, unsigned) → int ∧
(double, double) → int ∧
(float, float) → int
var memo = new stdlib.Uint32Array(heap);
if(memo[n >> 2] | 0 != 0){
return memo[n >> 2] | 0;
}
if(n >>> 0 > 2){
result = ((fib(n - 1 | 0) | 0) + (fib(n - 2 | 0) | 0)) | 0;
}
return result | 0; heap の利用例
Heap View Type 要素サイズ load type store type
Uint8Array 1 intish intish
Int8Array 1 intish intish
Uint16Array 2 intish intish
Int16Array 2 intish intish
Uint32Array 4 intish intish
Int32Array 4 intish intish
Float32Array 4 float? floatish,
double?
Float64Array 8 double? float?, double?
var memo = new stdlib.Uint32Array(heap);
if(memo[n >> 2] | 0 != 0){
return memo[n >> 2] | 0;
}
if(n >>> 0 > 2){
result = ((fib(n - 1 | 0) | 0) + (fib(n - 2 | 0) | 0)) | 0;
}
return result | 0;log2(要素のバイト数) ぶんだけ右にシフトしなくてはならない
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
• 例外を投げることなく return まで到達すること
• 全ての属性アクセスは、データアクセスとして解決されること
• heap があるなら、それは ArrayBuffer であること
• heap の大きさは [212
, 224
) 、もしくは 224
の倍数であること
• stdlibから取られたシンボルは、

標準ライブラリ中のものを指すこと
リンクに成功する条件
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
% emcc -o hello.js hello.c
% node hello.js
hello world
% emcc -o hello.html hello.c
% open hello.html
-o オプションで html / js へ出力
EmscriptencompilesC/C++intoJavaScriptinasm.jsformat
• ファイル入出力: XHR に書き換え / ファイルを JS に結合
• JavaScript からC/C++コードの呼び出し
• cwrap / ccall を利用
• WebIDL を作成し、binding を生成
• CからJavaScriptコードの呼び出し
• EM_ASMマクロの利用したコード埋め込み
• 外部関数 (extern)として呼び出し、リンク時に解決
ファイルアクセス
% emcc —preload-file hello.txt -o file.html fileio.c
—preload-file オプションをつけると read を XHR に変更
% emcc —preload-file hello.txt -o file.html fileio.c
% emcc --embed-file hello.txt -o hello.html file.c
—embed-file オプションで、ファイルを埋め込む
ccall / cwrap
extern "C" {
unsigned int fib(unsigned int n){
if(n < 3){
return 1;
}
return fib(n - 1) + fib(n - 2);
}
}
C++ での記述: エキスポートする関数名のマングリングを防ぐ
% emcc -o fib.html 
-s EXPORTED_FUNCTIONS="['_fib']" 
fib.cpp
不要なコードの削除を防ぐために EXPORTED_FUNCTIONS を指定
var fib = Module.cwrap("fib", "number", ["number"]);
console.log(fib(30));
var result = Module.ccall("fib",
"number", ["number"],
[30]);
console.log(result);
JavaScriptからの呼び出し: 識別子、型情報の指定が必要
WebIDL
class Peano{
public:
Peano();
int current();
void suc();
};
C++ でクラスを定義
class Peano{
public:
Peano();
int current();
void suc();
};
interface Peano{
void Peano();
long current();
void suc();
};
インタフェースを定義するWebIDLファイルを作成
% python tools/webidl_binder.py peano.webidl peano-glue
グルーコードを生成
#include "peano.cpp"
#include "peano-glue.cpp"
ラッパーを作成
% emcc -o peano.html 
--post-js peano-glue.js 
peano.cpp 
peano-wrapper.cpp
—post-js オプションをつけてemcc コンパイル
p = new Module.Peano();
console.log(p.current()); // 0 を出力
p.next();
console.log(p.current()); // 1 を出力
JavaScriptからはModule オブジェクトの属性として参照できる
CへのJavaScriptの埋め込み
#include <stdio.h>
#include <emscripten.h>
int main(int argc, char **argv){
EM_ASM({
alert("hello!");
});
}
EM_ASM マクロを使って JavaScript コードを埋め込める
x = EM_ASM_INT({
console.log("argument:"+ [$0, $1]);
return Math.pow($0, $1);
}, 2, 24);
printf("x = %dn", x);
引数、返り値のあるコードの埋め込み例
CからJavaScriptコードの呼び出し
#include <stdio.h>
extern "C"{
extern int id(int);
extern void hi();
}
外部関数を宣言
int main(int argc, char **argv){
int x = 10;
printf("id(%d) = %dn", x, id(x));
hi();
return 0;
}
リンクされる前提で呼び出す
mergeInto(LibraryManager.library, {
id: function(n){
return n;
},
hi: function(){
alert("hi");
}
});
library.js に関数を実装
-rw-r--r-- 1 chiko staff 81B 2 17 19:25 hello.c
-rw-r--r-- 1 chiko staff 100K 3 24 18:17 hello.html
-rw-r--r-- 1 chiko staff 466K 3 24 18:17 hello.js
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games

More Related Content

PDF
Goをカンストさせる話
PDF
PDF
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
KEY
今さら始めるCoffeeScript
PPT
python-geohex
PDF
Backbone model collection (jscafe 8)
PDF
速くなければスマフォじゃない - インターンバージョン-
PDF
Common LispでGPGPU
Goをカンストさせる話
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
今さら始めるCoffeeScript
python-geohex
Backbone model collection (jscafe 8)
速くなければスマフォじゃない - インターンバージョン-
Common LispでGPGPU

What's hot (19)

PDF
EmacsとGlossでお絵描きしてみるよ
PDF
private-values
PDF
Spectacular Future with clojure.spec
PDF
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
KEY
Ll xcode
PDF
セミコロンレスc++
PDF
JavaScript入門
PPT
C++でHello worldを書いてみた
ODP
0x300
PDF
第10回 計算機構成
PDF
第12回計算機構成
PPTX
メタプログラミング C#
PDF
Siv3Dで楽しむゲームとメディアアート開発
ODP
みんな大好き! Hello, World
PPTX
How to make Inn-fighting dice
PDF
イニシャライザー Part 2.5 #hakataswift
PDF
Python で munin plugin を書いてみる
PPTX
F#のすすめ
EmacsとGlossでお絵描きしてみるよ
private-values
Spectacular Future with clojure.spec
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
Ll xcode
セミコロンレスc++
JavaScript入門
C++でHello worldを書いてみた
0x300
第10回 計算機構成
第12回計算機構成
メタプログラミング C#
Siv3Dで楽しむゲームとメディアアート開発
みんな大好き! Hello, World
How to make Inn-fighting dice
イニシャライザー Part 2.5 #hakataswift
Python で munin plugin を書いてみる
F#のすすめ
Ad

Viewers also liked (11)

PPTX
MP2011#01
PDF
20160428 html5jwebplat
PDF
20150512 webgl-off-the-main-thread
PDF
20160803 devrel
PDF
20160601 devtools
PDF
20160713 webvr
PDF
Designing Teams for Emerging Challenges
PDF
UX, ethnography and possibilities: for Libraries, Museums and Archives
PDF
Visual Design with Data
PDF
3 Things Every Sales Team Needs to Be Thinking About in 2017
PDF
How to Become a Thought Leader in Your Niche
MP2011#01
20160428 html5jwebplat
20150512 webgl-off-the-main-thread
20160803 devrel
20160601 devtools
20160713 webvr
Designing Teams for Emerging Challenges
UX, ethnography and possibilities: for Libraries, Museums and Archives
Visual Design with Data
3 Things Every Sales Team Needs to Be Thinking About in 2017
How to Become a Thought Leader in Your Niche
Ad

Similar to asm.js x emscripten: The foundation of the next level Web games (20)

PDF
Cookpad Summer Intern 2015 - Programming Paradigm
PPTX
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
PDF
中3女子でもわかる constexpr
PDF
Javaセキュアコーディングセミナー東京第2回講義
PDF
あまぁいRcpp生活
PDF
速習A tour of go
PDF
詳解Dexファイルフォーマット
PDF
これから Haskell を書くにあたって
PDF
これからの「言語」の話をしよう ―― 未来を生きるためのツール
PDF
Adding simpl GVN path into GHC
PDF
Boost Tour 1.50.0 All
ODP
これから Haskell を書くにあたって
PDF
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
PDF
これからのJavaScriptー関数型プログラミングとECMAScript6
PDF
boost tour 1.48.0 all
PDF
超絶技巧プログラミングの世界(FTD2015)
PDF
中3女子が狂える本当に気持ちのいい constexpr
PDF
関数プログラミング入門
PDF
CLRの基礎 - プログラミング .NET Framework 第3版 読書会
PDF
Boost tour 1_40_0
Cookpad Summer Intern 2015 - Programming Paradigm
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
中3女子でもわかる constexpr
Javaセキュアコーディングセミナー東京第2回講義
あまぁいRcpp生活
速習A tour of go
詳解Dexファイルフォーマット
これから Haskell を書くにあたって
これからの「言語」の話をしよう ―― 未来を生きるためのツール
Adding simpl GVN path into GHC
Boost Tour 1.50.0 All
これから Haskell を書くにあたって
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
これからのJavaScriptー関数型プログラミングとECMAScript6
boost tour 1.48.0 all
超絶技巧プログラミングの世界(FTD2015)
中3女子が狂える本当に気持ちのいい constexpr
関数プログラミング入門
CLRの基礎 - プログラミング .NET Framework 第3版 読書会
Boost tour 1_40_0

More from Noritada Shimizu (20)

PDF
Mozilla とブラウザゲーム
PDF
2016 gunma.web games-and-asm.js
PDF
20151224-games
PDF
20151128 firefoxos-handson
PDF
20151117 devtools
PDF
Inspection & Tweak: Firefox を使ったフロント開発
PDF
20150822 osc-shimane
PDF
20150829 firefox-os-handson
PDF
20150829 firefox-os
PDF
20150727 Development tools for Firefox OS apps
PDF
Firefox OS でアプリを作るときに気をつけたい N 個のこと
PDF
Firefox OSアプリ開発ハンズオン(Hello World編)
PDF
WebVR(html5j TV部、WebVRとかVRのUIとか勉強会)
PDF
Application submission, management and manetization in Firefox Marketplace
PDF
つくろう!Firefox OS アプリ
PDF
20150118 firefoxos-handson-helloworld
PDF
20141115 fx os-codereading
PDF
20141030 html5j-firefox os-deviceapi
PDF
20140830 firefox os-sampler
PDF
20140801 webrtc on-firefox
Mozilla とブラウザゲーム
2016 gunma.web games-and-asm.js
20151224-games
20151128 firefoxos-handson
20151117 devtools
Inspection & Tweak: Firefox を使ったフロント開発
20150822 osc-shimane
20150829 firefox-os-handson
20150829 firefox-os
20150727 Development tools for Firefox OS apps
Firefox OS でアプリを作るときに気をつけたい N 個のこと
Firefox OSアプリ開発ハンズオン(Hello World編)
WebVR(html5j TV部、WebVRとかVRのUIとか勉強会)
Application submission, management and manetization in Firefox Marketplace
つくろう!Firefox OS アプリ
20150118 firefoxos-handson-helloworld
20141115 fx os-codereading
20141030 html5j-firefox os-deviceapi
20140830 firefox os-sampler
20140801 webrtc on-firefox

asm.js x emscripten: The foundation of the next level Web games