WebAssembly JavaScript API ã®ä½¿ç¨
ããã¾ã§ã« Emscripten ãªã©ã®ãã¼ã«ã使ç¨ãã¦ä»ã®è¨èªããã¢ã¸ã¥ã¼ã«ãã³ã³ãã¤ã«ããããèªåèªèº«ã®ã³ã¼ããèªã¿è¾¼ãã§ãã¦å®è¡ããããã¾ãããæ¬¡ã®ã¹ãããã¯ä»ã® WebAssembly JavaScript API ã®ä½¿ãæ¹ã«ã¤ãã¦å¦ã¶ãã¨ã§ãããã®è¨äºã§ã¯ç¥ãå¿ è¦ããããã¨ã説æãã¾ãã
ã¡ã¢: ããããã®è¨äºã§èª¬æãã¦ããåºæ¬çãªæ¦å¿µãããããããªãå ´åã WebAssembly ã®æ¦è¦ãå ã«èªãã§ãããã®è¨äºã«æ»ã£ã¦ãã¦ãã ããã
ããã¤ãã®ä¾
WebAssembly JavaScript API ã®ä½¿ç¨æ¹æ³ã¨ãWasm ã¢ã¸ã¥ã¼ã«ãèªã¿è¾¼ãã§ã¦ã§ããã¼ã¸å ã§ä½¿ç¨ããæ¹æ³ããã¹ããããã¤ã¹ãããã®ä¾ãéãã¦å®è¡ãã¦ã¿ã¾ãããã
ã¡ã¢: ãµã³ãã«ã³ã¼ã㯠webassembly-examples GitHub ãªãã¸ããªã¼ããåç §ãã¦ãã ããã
ä¾ã®æºå
-
ã¾ãã¯ã Wasm ã¢ã¸ã¥ã¼ã«ãå¿ è¦ã§ã!
simple.wasmãã³ãã¼ãã¦ãã¼ã«ã«ãã·ã³ã®æ°ãããã£ã¬ã¯ããªã¼ã®ä¸ã«ä¿åãã¦ãã ããã -
次ã«ã Wasm ãã¡ã¤ã«ã¨åããã£ã¬ã¯ããªã¼ã«
index.htmlã¨ããååã§ã·ã³ãã«ãª HTML ãã¡ã¤ã«ã使ãã¾ãããï¼ç°¡åã«å©ç¨ã§ãããã³ãã¬ã¼ããæã£ã¦ããªãã®ã§ããã°ãåç´ãªãã³ãã¬ã¼ããå©ç¨ã§ãã¾ãï¼ã -
ããã§ãä½ãèµ·ãã£ã¦ããã®ãçè§£ããããããããã«ã Wasm ã¢ã¸ã¥ã¼ã«ã®ããã¹ã表ç¾ãè¦ã¦ã¿ã¾ãããï¼WebAssembly å½¢å¼ãã Wasm ã¸ã®å¤æãåç §ãã¦ãã ããï¼ã
wat(module (func $i (import "my_namespace" "imported_func") (param i32)) (func (export "exported_func") i32.const 42 call $i)) -
2 è¡ç®ã§ 2 é層ã®åå空éãæã¤ã¤ã³ãã¼ãã®å®£è¨ãããã¾ãã â å é¨é¢æ°
$iã¯my_namespace.imported_funcããã¤ã³ãã¼ãããã¦ãã¾ããwasm ã¢ã¸ã¥ã¼ã«ã«ã¤ã³ãã¼ããããªãã¸ã§ã¯ããè¨è¿°ããã¨ãã«ããã® 2 é層ã®åå空éã JavaScript ã«åæ ãããå¿ è¦ãããã¾ãã<script></script>è¦ç´ ã HTML å ã«ä½æãã¦ã次ã®ã³ã¼ãã追å ãã¦ãã ãããjsconst importObject = { my_namespace: { imported_func: (arg) => console.log(arg) }, };
WebAssembly ã¢ã¸ã¥ã¼ã«ãã¹ããªã¼ãã³ã°ãã
Firefox 58 ã®æ°æ©è½ã¨ãã¦ã WebAssembly ã¢ã¸ã¥ã¼ã«ãåºç¤ã¨ãªãã½ã¼ã¹ããç´æ¥ã³ã³ãã¤ã«ããã³ã¤ã³ã¹ã¿ã³ã¹åããæ©è½ãããã¾ãããã㯠WebAssembly.compileStreaming() 㨠WebAssembly.instantiateStreaming() ã¡ã½ããã使ç¨ãã¦å®ç¾ãã¾ãããããã®ã¡ã½ããã¯ããã¤ãã³ã¼ããç´æ¥ Module/Instance ã¤ã³ã¹ã¿ã³ã¹ã«å¤æãããã¨ãã§ããã®ã§ãResponse ã ArrayBuffer ã«å¥éæ ¼ç´ããå¿
è¦ããªããããã¹ããªã¼ãã³ã°ã§ã¯ãªã対å¿ããã¡ã½ãããããç°¡åã«ãªã£ã¦ãã¾ãã
ãã®ä¾ï¼GitHub ã® instantiate-streaming.html ãã¢ããã©ã¤ãçãåç
§ãã¦ãã ããï¼ã§ã¯ã instantiateStreaming() ã使ã£ã¦ Wasm ã¢ã¸ã¥ã¼ã«ãåå¾ããããã« JavaScript 颿°ãã¤ã³ãã¼ããã¦ã³ã³ãã¤ã«ãã¦ã¤ã³ã¹ã¿ã³ã¹åãããã®ã¨ã¯ã¹ãã¼ã颿°ã«ã¢ã¯ã»ã¹ããã¾ã§ããã¹ã¦ä¸åº¦ã«è¡ã£ã¦ãã¾ãã
ã¹ã¯ãªããã«ä»¥ä¸ã® 1 ãããã¯ãå ãã¦ãã ããã
WebAssembly.instantiateStreaming(fetch("simple.wasm"), importObject).then(
(obj) => obj.instance.exports.exported_func(),
);
ãã®çµæãã¨ã¯ã¹ãã¼ããã WebAssembly ã® exported_func 颿°ãå¼ã³åºããã¤ã³ãã¼ããã JavaScript ã® imported_func 颿°ãå¼ã³åºããWebAssembly ã¤ã³ã¹ã¿ã³ã¹ã®ä¸ã§æä¾ããå¤ (42) ãã³ã³ã½ã¼ã«ã«è¨é²ãããã¨ã«ãªãã¾ããããµã³ãã«ã®ã³ã¼ããä¿åãã¦ãWebAssembly ã«å¯¾å¿ãã¦ãããã©ã¦ã¶ã¼ã§èªã¿è¾¼ãã¨ããããå®éã«åä½ãã¦ããã®ããããã¾ãã
ã¡ã¢: ããã¯è¤éã§é·ãä¾ã®ã»ãã®ä¸é¨ã§ãããã¦ã§ãã¢ããªã±ã¼ã·ã§ã³å ã§ WebAssembly ãã©ã®ããã« JavaScript ã¨çµã¿åããã¦åä½ããããã¨ãã§ãããã説æãã¦ãã¾ããå¥ã®å ´æã§ãè¨åãã¦ãã¾ããã WebAssembly 㯠JavaScript ã®ç½®ãæããç®æãã¦ããããã§ã¯ããã¾ããã両æ¹ãååãã¦ããäºãã®å¼·ã¿ãæ´»ãããã¨ãã§ãã¾ãã
ã¹ããªã¼ãã³ã°ããã« Wasm ã¢ã¸ã¥ã¼ã«ãèªã¿è¾¼ã
ä¸è¨ã®ãããªã¹ããªã¼ãã³ã°ã¡ã½ããã使ç¨ã§ããªããã¾ãã¯ä½¿ç¨ããããªãå ´åã¯ã代ããã«ã¹ããªã¼ãã³ã°ã¡ã½ããã§ã¯ãªã WebAssembly.compile() / WebAssembly.instantiate() ã使ç¨ãããã¨ãã§ãã¾ãã
ãããã®ã¡ã½ããã¯ãã¤ãã³ã¼ãã«ç´æ¥ã¢ã¯ã»ã¹ããªãã®ã§ã Wasm ã¢ã¸ã¥ã¼ã«ãã³ã³ãã¤ã«/ã¤ã³ã¹ã¿ã³ã¹åããåã«ã¬ã¹ãã³ã¹ã ArrayBuffer ã«å¤æããä½åãªæé ãå¿
è¦ã«ãªãã¾ãã
åçã®ã³ã¼ãã¯æ¬¡ã®ããã«ãªãã¾ãã
fetch("simple.wasm")
.then((response) => response.arrayBuffer())
.then((bytes) => WebAssembly.instantiate(bytes, importObject))
.then((results) => {
results.instance.exports.exported_func();
});
éçºè ãã¼ã«ã§ Wasm ãè¦ã
Firefox 54 以éã§ã¯ãéçºè ãã¼ã«ã®ãããã¬ã¼ããã«ã§ã¦ã§ããã¼ã¸ã«å«ã¾ãã Wasm ã³ã¼ãã®ããã¹ã表ç¾ã表示ããæ©è½ãããã¾ããããã表示ããããã«ã¯ããããã¬ã¼ããã«ã«ç§»åãã¦ã "wasm://" é ç®ãã¯ãªãã¯ãã¦ãã ããã

WebAssembly ãããã¹ãã¨ãã¦è¡¨ç¤ºããã ãã§ãªãã WebAssembly ã®ããã¹ã表ç¾ã使ç¨ãã¦ããã«ãããã°ãéå§ãããã¨ãã§ãã¾ãï¼ãã¬ã¼ã¯ãã¤ã³ããã³ã¼ã«ã¹ã¿ãã¯ã®æ¤æ»ãã¹ãããå®è¡ãªã©ï¼ã
ã¡ã¢ãªã¼
WebAssembly ã®ä½ã¬ãã«ã®ã¡ã¢ãªã¼ã¢ãã«ã§ã¯ãã¡ã¢ãªã¼ã¯ç·å½¢ã¡ã¢ãªã¼ã¨å¼ã°ããåã®ãªãé£ç¶ãããã¤ãåã¨ãã¦è¡¨ç¾ãããã¢ã¸ã¥ã¼ã«å ã®ãã¼ããã¹ãã¢å½ä»¤ã使ç¨ãã¦èªã¿æ¸ãããã¾ãããã®ã¡ã¢ãªã¼ã¢ãã«ã§ã¯ãä»»æã®ãã¼ããã¹ãã¢å½ä»¤ã¯ç·å½¢ã¡ã¢ãªã¼å ¨ä½ã®ä»»æã®ãã¤ãã«ã¢ã¯ã»ã¹ãããã¨ãã§ãã¾ããããã¯ãã¤ã³ã¿ã¼ãªã©ã® C/C++ ã®æ¦å¿µãå¿ å®ã«è¡¨ç¾ããããã«å¿ è¦ãªãã®ã§ãã
ããããå©ç¨å¯è½ãªã¡ã¢ãªã¼ç¯å²ãããã»ã¹å
¨ä½ã«åã¶ãã¤ãã£ãã® C/C++ ããã°ã©ã ã¨ã¯ç°ãªããç¹å®ã® WebAssembly ã¤ã³ã¹ã¿ã³ã¹ãã¢ã¯ã»ã¹ã§ããã¡ã¢ãªã¼ã¯ã WebAssembly Memory ãªãã¸ã§ã¯ããå«ãç¹å®ã®ï¼æ½å¨çã«é常ã«å°ããªï¼ç¯å²ã«å¶éããã¦ãã¾ããããã«ãããåä¸ã®ã¦ã§ãã¢ããªã§è¤æ°ã®ç¬ç«ããã©ã¤ãã©ãªã¼ï¼ãããããå
é¨ã§ WebAssembly ã使ç¨ãã¦ããï¼ã使ç¨ããäºãã«å®å
¨ã«åé¢ãããåå¥ã®ã¡ã¢ãªã¼ãæã¤ãã¨ãã§ãã¾ããããã«ãæ°ããå®è£
ã§ã¯å
±æã¡ã¢ãªã¼ã使ãããã¨ãã§ãããã㯠postMessage() ã«ãã£ã¦ã¦ã£ã³ãã¦ã¨ã¯ã¼ã«ã¼ã³ã³ããã¹ãéã§è»¢éãã¦è¤æ°ã®å ´æã§ä½¿ç¨ãããã¨ãå¯è½ã§ãã
JavaScript ã§ã¯ãMemory ã¤ã³ã¹ã¿ã³ã¹ã¯ãªãµã¤ãºå¯è½ãª ArrayBuffer (ã¾ãã¯å
±æã¡ã¢ãªã¼ã®å ´å㯠SharedArrayBuffer) ã¨ã¿ãªããã¨ãã§ãã¾ããArrayBuffer ã¨åæ§ã«ãåä¸ã®ã¦ã§ãã¢ããªã±ã¼ã·ã§ã³ã§å¤ãã®ç¬ç«ãã Memory ãªãã¸ã§ã¯ãã使ãããã¨ãã§ãã¾ããMemory ãªãã¸ã§ã¯ãã¯åæãµã¤ãºã¨æå¤§ãµã¤ãº (çç¥å¯) ãæå®ãã¦ãWebAssembly.Memory() ã³ã³ã¹ãã©ã¯ã¿ã¼ãã使ãããã¨ãã§ãã¾ãã
ç°¡åãªä¾ãè¦ãªãããæ¢ç´¢ãå§ãã¾ãããã
-
ãã 1 ã¤ã®ã·ã³ãã«ãª HTML ãã¼ã¸ãï¼åç´ãªãã³ãã¬ã¼ããã³ãã¼ãã¦ï¼ä½æãã
memory.htmlã¨ããååãä»ãã¦ãã ããããã®ãã¼ã¸ã«<script></script>è¦ç´ ã追å ãã¦ãã ããã -
ã¡ã¢ãªã¼ã¤ã³ã¹ã¿ã³ã¹ã使ããããã«ã次ã®è¡ãã¹ã¯ãªããã«è¿½å ãã¾ãã
jsconst memory = new WebAssembly.Memory({ initial: 10, maximum: 100 });initialã¨maximumã®åä½ã¯ WebAssembly ãã¼ã¸ã§ããããã㯠64KB ã«åºå®ããã¦ãã¾ããä¸ã®ä¾ã§ã¯ãã¡ã¢ãªã¼ã¤ã³ã¹ã¿ã³ã¹ã¯åæãµã¤ãºã 640KBãæå¤§ãµã¤ãºã 6.4MB ã§ãããã¨ãæå³ãã¦ãã¾ããWebAssembly ã¡ã¢ãªã¼ãæã¤ãã¤ãå㯠ArrayBuffer ã¨ã㦠buffer ã²ãã¿ã¼/ã»ãã¿ã¼ããå ¬éããã¦ãã¾ããä¾ãã°ãç·å½¢ã¡ã¢ãªã¼ã®å é ã¯ã¼ãã«ç´æ¥ã 42 ãæ¸ãè¾¼ãã«ã¯æ¬¡ã®ããã«ãã¾ãã
jsconst data = new DataView(memory.buffer); data.setUint32(0, 42, true);WebAssembly ã®ã¡ã¢ãªã¼ã¯å¸¸ã«ãªãã«ã¨ã³ãã£ã¢ã³ã§ããããããªãã«ã¨ã³ãã£ã¢ã³ã§ã®èªã¿æ¸ããå¼·å¶ãã
trueã®ä½¿ç¨ã«æ³¨æãã¦ãã ãããæ¬¡ã«ã以ä¸ã使ç¨ãã¦åãå¤ãè¿ããã¨ãã§ãã¾ããjsdata.getUint32(0, true); -
ãã¢ã§è©¦ãã¦ã¿ã¾ããããããã¾ã§ã«è¿½å ããå 容ãä¿åãã¦ãã©ã¦ã¶ã¼ã§èªã¿è¾¼ãã å¾ãJavaScript ã³ã³ã½ã¼ã«ã§ä¸ã® 2 è¡ãå ¥åãã¦ã¿ã¦ãã ããã
ã¡ã¢ãªã¼ã®æ¡å¼µ
ã¡ã¢ãªã¼ã¤ã³ã¹ã¿ã³ã¹ã¯ Memory.prototype.grow() ãå¼ã³åºããã¨ã§æ¡å¼µãããã¨ãã§ãã¾ãã弿°ã¯ WebAssembly ãã¼ã¸åä½ã§æå®ãã¾ãã
memory.grow(1);
Memory ã¤ã³ã¹ã¿ã³ã¹ã®ä½ææã«æå¤§å¤ãæå®ãã¦ãã¦ããã®æå¤§å¤ãè¶
ãã¦æ¡å¼µãããã¨ãã㨠RangeError ä¾å¤ãçºçãã¾ããã¨ã³ã¸ã³ã¯æä¾ãããä¸éãå©ç¨ãã¦ã¡ã¢ãªã¼ãäºåã«ç¢ºä¿ãã¦ãããã¨ã§ãããå¹ççãªãªãµã¤ãºãå¯è½ã«ãªãã¾ãã
ã¡ã¢: ArrayBuffer ã® byteLength ã¯å¤æ´ä¸å¯ã§ããããã Memory.prototype.grow() æä½ãæåããå¾ãbuffer ã²ãã¿ã¼ã¯æ°ãã (æ°ãã byteLength ã§) ArrayBufferãè¿ãã¾ããããã¦ãåã® ArrayBuffer ã¯ãåãé¢ãããç¶æ
ãã«ãªãããã¡ã¢ãªã¼ããåãé¢ããã¾ãã
颿°ã¨åæ§ã«ãç·å½¢ã¡ã¢ãªã¼ã¯ã¢ã¸ã¥ã¼ã«å
ã§å®ç¾©ãããã¨ãã¤ã³ãã¼ããããã¨ãã§ãã¾ããåãããã«ã¢ã¸ã¥ã¼ã«ã¯ä»»æã§ã¡ã¢ãªã¼ãã¨ã¯ã¹ãã¼ããããã¨ãå¯è½ã§ãããã㯠JavaScript ã WebAssembly ã¤ã³ã¹ã¿ã³ã¹ã«å¯¾ãã¦æ°ãã使ãã WebAssembly.Memory ãã¤ã³ãã¼ãã§æ¸¡ããããMemory ã®ã¨ã¯ã¹ãã¼ãããï¼Instance.prototype.exports ãä»ãã¦ï¼åãåãããã¨ãæå³ãã¦ãã¾ãã
ããè¤éãªã¡ã¢ãªã¼ã®ä¾
ããè¤éãªã¡ã¢ãªã¼ã®ä¾ãè¦ã¦ãä¸è¨ã®ãã¨ãæç¢ºã«ãã¾ããããå ã«å®ç¾©ããã¡ã¢ãªã¼ã¤ã³ã¹ã¿ã³ã¹ãã¤ã³ãã¼ããããããæ´æ°ã®é åã§åãè¾¼ãã§ãããããåè¨ãã WebAssembly ã¢ã¸ã¥ã¼ã«ã§ãããã㯠memory.wasm ã§è¦ããã¨ãã§ãã¾ãã
-
memory.wasmã®ãã¼ã«ã«ã³ãã¼ã以åã¨åããã£ã¬ã¯ããªã¼ã«ä½æãã¾ããã¡ã¢: ã¢ã¸ã¥ã¼ã«ã®ããã¹ã表ç¾ã¯ memory.wat ãåç §ãã¦ãã ããã
-
memory.htmlãµã³ãã«ãã¡ã¤ã«ã«æ»ã£ã¦ã以åã¨åãããã« Wasm ã¢ã¸ã¥ã¼ã«ãèªã¿åããã³ã³ãã¤ã«ãã¤ã³ã¹ã¿ã³ã¹åãã¾ãã以ä¸ã®ãã®ãã¹ã¯ãªããã®æå¾ã«è¿½å ãã¦ãã ãããjsWebAssembly.instantiateStreaming(fetch("memory.wasm"), { js: { mem: memory }, }).then((results) => { // ããã«ã³ã¼ãã追å }); -
ãã®ã¢ã¸ã¥ã¼ã«ã¯ã¢ã¸ã¥ã¼ã«å é¨ã®ã¡ã¢ãªã¼ãã¨ã¯ã¹ãã¼ããã¾ããinstance ã¨ããååã§ã¢ã¸ã¥ã¼ã«ã® Instance ãåå¾ãããã¨ã¯ã¹ãã¼ãããã颿°
accumulate()ã使ç¨ãã¦ã¢ã¸ã¥ã¼ã«ã®ç·å½¢ã¡ã¢ãªã¼ (mem) ã«ç´æ¥å ¥åãããé åãåè¨ããäºãã§ãã¾ããæå®ãããå ´æã«ã次ã®ã³ã¼ãã追å ãã¦ã¿ã¾ããããjsconst summands = new DataView(memory.buffer); for (let i = 0; i < 10; i++) { summands.setUint32(i * 4, i, true); } const sum = results.instance.exports.accumulate(0, 10); console.log(sum);
Memory ãªãã¸ã§ã¯ãèªä½ã§ãªããMemory ãªãã¸ã§ã¯ãã® buffer (Memory.prototype.buffer) ãã Uint32Array ãã¥ã¼ã使ãã¦ãããã¨ã«æ³¨æãã¦ãã ããã
ã¡ã¢ãªã¼ã®ã¤ã³ãã¼ãã¯é¢æ°ã®ã¤ã³ãã¼ãã¨åãããã«æ©è½ãã¾ããJavaScript 颿°ã®ä»£ããã« Memory ãªãã¸ã§ã¯ããæ¸¡ãã ãã§ããã¡ã¢ãªã¼ã®ã¤ã³ãã¼ã㯠2 ã¤ã®çç±ã§å½¹ã«ç«ã¡ã¾ãã
- ã¢ã¸ã¥ã¼ã«ãã³ã³ãã¤ã«ããåããããã¯ä¸¦è¡ãã¦ãã¡ã¢ãªã¼ã®åæã³ã³ãã³ãã JavaScript ã§èªã¿åããã¾ãã¯ä½æãããã¨ãã§ãã¾ãã
- åä¸ã® Memory ãªãã¸ã§ã¯ããè¤æ°ã®ã¢ã¸ã¥ã¼ã«ã¤ã³ã¹ã¿ã³ã¹ã«ã¤ã³ãã¼ããããã¨ãã§ãã¾ãããã㯠WebAssembly ã§åçãªã³ã¯ãå®è£ ããããã®éè¦ãªæ§æè¦ç´ ã§ãã
ã¡ã¢: å®å ¨ãªãã¢ã¯ memory.html (åä½ä¾) ãåç §ãã¦ãã ããã
ãã¼ãã«
WebAssembly Table 㯠JavaScript 㨠WebAssembly ã³ã¼ãã®ä¸¡æ¹ã§ã¢ã¯ã»ã¹ã§ãããªãµã¤ãºå¯è½ãª åç § ã®åä»ãé åã§ããMemory ã¯ãªãµã¤ãºå¯è½ãªçã®ãã¤ãåãæä¾ãã¾ãããåç §ã¯ã¨ã³ã¸ã³ã«ä¿è¨¼ãããå¤ï¼ãã®ãã¤ãåã¯å®å ¨æ§ãç§»æ¤æ§ãå®å®æ§ã®çç±ããã³ã³ãã³ãã«ãã£ã¦ç´æ¥èªã¿æ¸ããã¦ã¯ãããªãï¼ã§ãããããåç §ãæ ¼ç´ããããã«ä½¿ç¨ãããã¨ã¯å®å ¨ã§ã¯ããã¾ããã
ãã¼ãã«ã¯è¦ç´ ã®åãæã¡ããã¼ãã«ã«æ ¼ç´ã§ããåç §ã®åãå¶éããã¾ããWebAssembly ã®ç¾ãã¼ã¸ã§ã³ã§ã¯ WebAssembly ã³ã¼ãå ã§å¿ è¦ãªåç §ã®åã¯é¢æ°åã®1ã¤ã ãã§ããããã¦ããããå¯ä¸ã®æ£ããè¦ç´ ã®åã¨ãªãã¾ããå°æ¥ã®ãã¼ã¸ã§ã³ã§ã¯ãããã«å¤ãã®è¦ç´ ã®åã追å ãããäºå®ã§ãã
颿°åç §ã¯é¢æ°ãã¤ã³ã¿ã¼ãæã¤ C/C++ ã®ãããªè¨èªãã³ã³ãã¤ã«ããããã«å¿ è¦ã§ããC/C++ ã®ãã¤ãã£ãå®è£ ã§ã¯ã颿°ãã¤ã³ã¿ã¼ã¯ããã»ã¹ã®ä»®æ³ã¢ãã¬ã¹ç©ºéå ã®é¢æ°ã®ã³ã¼ãã®çã®ã¢ãã¬ã¹ã§è¡¨ç¾ããããããå®å ¨æ§ã®çç±ããç·å½¢ã¡ã¢ãªã¼ã«ç´æ¥æ ¼ç´ãããã¨ã¯ã§ãã¾ããã代ããã«ã颿°åç §ã¯ãã¼ãã«ã«æ ¼ç´ããã¾ããæ´æ°å¤ã®ã¤ã³ããã¯ã¹ã¯ç·å½¢ã¡ã¢ãªã¼ã«æ ¼ç´ãããã¨ãã§ãã¾ãã
颿°ãã¤ã³ã¿ã¼ãå¼ã³åºãã¨ãã¯ãWebAssembly ãå¼ã³åºãå´ã§ã¤ã³ããã¯ã¹ãæå®ãã¾ããã¤ã³ããã¯ã¹ãä»ããããã¤ã³ããã¯ã¹ä»ãããã颿°åç §ãå¼ã³åºãåã«å®å ¨ãªå¢çã®ãã§ãã¯ããããã¨ãã§ãã¾ãããããã£ã¦ããã¼ãã«ã¯ç¾å¨ãå®å ¨ãã¤ç§»æ¤å¯è½ã«ä½ã¬ãã«ã®ããã°ã©ãã³ã°è¨èªã®æ©è½ãã³ã³ãã¤ã«ããããã«ä½¿ç¨ããããä½ã¬ãã«ã®ããªããã£ãã§ãã
ãã¼ãã«ã¯ Table.prototype.set() ãéãã¦ãã¼ãã«å
ã®å¤ã1ã¤æ´æ°ãããã¨ãã§ãã¾ããããã«ãTable.prototype.grow() ã§ãã¼ãã«ã«æ ¼ç´ã§ããå¤ã®æ°ãå¢ãããã¨ãã§ãã¾ããæéã®çµéã¨ã¨ãã«éæ¥å¼ã³åºãããã颿°ã夿´ãããã¨ã許容ãããã㯠åçãªã³ã¯æè¡ ã®ããã«å¿
è¦ãªãã®ã§ããå¤åããå¤ã«å¯¾ã㦠JavaScript ã§ã¯ Table.prototype.get() ãéãã¦ããã«ã¢ã¯ã»ã¹ã§ãã¾ããwasm ã¢ã¸ã¥ã¼ã«ãããåæ§ã§ãã
ãã¼ãã«ã®ä¾
ãã¼ãã«ã®ã·ã³ãã«ãªä¾ãè¦ã¦ã¿ã¾ããããç´¹ä»ãã WebAssembly ã¢ã¸ã¥ã¼ã«ã¯2ã¤ã®è¦ç´ (è¦ç´ 0ã¯13ãè¦ç´ 1ã¯42ãè¿ãã¾ã) ãæã¤ãã¼ãã«ãã¨ã¯ã¹ãã¼ããããã®ã§ããã¢ã¸ã¥ã¼ã«ã¯ table.wasm ããè¦ã¤ãããã¾ãã
-
table.wasmããã¼ã«ã«ã®æ°ãããã£ã¬ã¯ããªã¼ã«ã³ãã¼ãã¾ããã¡ã¢: ãã®ã¢ã¸ã¥ã¼ã«ã®ããã¹ã表ç¾ã¯ table.wat ãåç §ãã¦ãã ããã
-
HTML template ã
table.htmlã¨ããååã§åããã£ã¬ã¯ããªã¼ã«ã³ãã¼ãã¾ãã -
åã¨åãããã«ãWasm ã¢ã¸ã¥ã¼ã«ãèªã¿åããã³ã³ãã¤ã«ãã¤ã³ã¹ã¿ã³ã¹åãã¾ããæ¬¡ã®ã³ã¼ãã HTML ã® body ã®æ«å°¾ã®
<script>è¦ç´ ã«è¿½å ãã¦ãã ãããjsWebAssembly.instantiateStreaming(fetch("table.wasm")).then((results) => { // add code here }); -
ä»åº¦ã¯ãã¼ãã«å ã®ãã¼ã¿ã«ã¢ã¯ã»ã¹ãã¦ã¿ã¾ããããã³ã¼ãã®æå®ãããå ´æã«æ¬¡ã®è¡ã追å ãã¦ãã ããã
jsconst tbl = results.instance.exports.tbl; console.log(tbl.get(0)()); // 13 console.log(tbl.get(1)()); // 42
ãã®ã³ã¼ãã¯ãã¼ãã«ã«æ ¼ç´ããã¦ããå颿°åç
§ã«é çªã«ã¢ã¯ã»ã¹ããå
å
ããå¤ãã³ã³ã½ã¼ã«ã«æ¸ãåºãããã«ã¤ã³ã¹ã¿ã³ã¹åãã¾ãã Table.prototype.get() ã§å颿°åç
§ãåå¾ããå¾ã颿°ãå®è¡ããããã«ã¯æ¬å¼§ã追å ãããã¨ã«æ³¨æãã¦ãã ããã
ã¡ã¢: å®å ¨ãªãã¢ã¯ table.html (åä½ä¾) ãåç §ãã¦ãã ããã
ã°ãã¼ãã«å¤
WebAssembly ã¯ã°ãã¼ãã«å¤æ°ã®ã¤ã³ã¹ã¿ã³ã¹ã使ããæ©è½ãæã£ã¦ããã JavaScript ã®ä¸¡æ¹ããã¢ã¯ã»ã¹ã§ãã1 ã¤ä»¥ä¸ã® WebAssembly.Module ã¤ã³ã¹ã¿ã³ã¹ã«ããã£ã¦ã¤ã³ãã¼ã/ã¨ã¯ã¹ãã¼ããå¯è½ã§ããããã«ãããè¤æ°ã®ã¢ã¸ã¥ã¼ã«ãåçã«ãªã³ã¯ãããã¨ãã§ããã®ã§ãé常ã«ä¾¿å©ã§ãã
JavaScript ã®å
é¨ãã WebAssembly ã®ã°ãã¼ãã«ã¤ã³ã¹ã¿ã³ã¹ã使ããã«ã¯ã次ã®ãã㪠WebAssembly.Global() ã³ã³ã¹ãã©ã¯ã¿ã¼ã使ç¨ãã¾ãã
const global = new WebAssembly.Global({ value: "i32", mutable: true }, 0);
ãã㯠2 ã¤ã®å¼æ°ãåããã¨ããããã¾ãã
-
ã°ãã¼ãã«å¤æ°ã«ã¤ãã¦è¨è¿°ãã 2 ã¤ã®ããããã£ãå«ããªãã¸ã§ã¯ãã§ãã
value: ãã¼ã¿åã¯ã WebAssembly ã¢ã¸ã¥ã¼ã«ã§åãå ¥ãããããã® (i32,i64,f32,f64) ãªãã°ã©ãã§ãæ§ãã¾ãããmutable: è«çå¤ã§ãå¤ã夿´å¯è½ãã©ãããå®ç¾©ãã¾ãã
-
夿°ã®å®éã®å¤ãå«ãå¤ãããã¯ãæå®ããããã¼ã¿åã¨ä¸è´ãã¦ããéããã©ã®ãããªå¤ã§ãããã
ã§ã¯ããããã©ã使ãã®ã§ãããããæ¬¡ã®ä¾ã§ã¯ãå¤ã 0 ã¨ãã mutable åã® i32 ã¨ãã¦ã°ãã¼ãã«ãå®ç¾©ãã¦ãã¾ãã
次ã«ãã°ãã¼ãã«å¤æ°ã®å¤ã夿´ãã¦ã¿ã¾ããæå㯠Global.value ã使ç¨ã㦠42 ã«è¨å®ãããããã global.wasm ã¢ã¸ã¥ã¼ã«ããã¨ã¯ã¹ãã¼ãããã incGlobal() 颿°ã使ç¨ã㦠43 ã«ãã¾ãï¼ãã®é¢æ°ã¯ãæå®ãããå¤ã«ä½ã§ã 1 ãå ç®ããæ°ããå¤ãè¿ãã¾ãï¼ã
const output = document.getElementById("output");
function assertEq(msg, got, expected) {
const result =
got === expected
? `SUCCESS! Got: ${got}\n`
: `FAIL!\nGot: ${got}\nExpected: ${expected}\n`;
output.innerText += `Testing ${msg}: ${result}`;
}
assertEq("WebAssembly.Global exists", typeof WebAssembly.Global, "function");
const global = new WebAssembly.Global({ value: "i32", mutable: true }, 0);
WebAssembly.instantiateStreaming(fetch("global.wasm"), { js: { global } }).then(
({ instance }) => {
assertEq(
"getting initial value from wasm",
instance.exports.getGlobal(),
0,
);
global.value = 42;
assertEq(
"getting JS-updated value from wasm",
instance.exports.getGlobal(),
42,
);
instance.exports.incGlobal();
assertEq("getting wasm-updated value from JS", global.value, 43);
},
);
ã¡ã¢: GitHub ã®åä½ä¾ ãè¦ããã¨ãã§ãã¾ããã½ã¼ã¹ã³ã¼ããè¦ã¦ãã ããã
å¤éæ§
ããã§ãWebAssembly ã®ä¸»è¦ãªæ§æè¦ç´ ã®ä½¿ç¨æ¹æ³ã説æãã¾ãããããã§ãå¤éæ§ã®æ¦å¿µã«ã¤ãã¦è§¦ãã¦ããã¾ããããããã«ãããWebAssembly ã¯ã¢ã¼ããã¯ãã£ã®å¹çæ§ã«ããã¦å¤ãã®é²æ©ãéãã¾ããã
- 1 ã¤ã®é¢æ°ã N åã®ã¯ãã¼ã¸ã£ãçæããã®ã¨åæ§ã«ã 1 ã¤ã®ã¢ã¸ã¥ã¼ã«ã¯ N åã®ã¤ã³ã¹ã¿ã³ã¹ãæã¤ãã¨ãã§ãã¾ãã
- 1 ã¤ã®ã¢ã¸ã¥ã¼ã«ã¤ã³ã¹ã¿ã³ã¹ã¯ 0 ãã 1 ã¤ã®ã¡ã¢ãªã¼ã¤ã³ã¹ã¿ã³ã¹ãæã¤ãã¨ãã§ããããããã¢ãã¬ã¹ç©ºéããæä¾ãã¾ããWebAssembly ã®å°æ¥ã®ãã¼ã¸ã§ã³ã§ã¯ã 1 ã¤ã®ã¢ã¸ã¥ã¼ã«ã 0 ãã N åã®ã¡ã¢ãªã¼ã¤ã³ã¹ã¿ã³ã¹ã許容ããå¯è½æ§ãããã¾ã (Multiple Memories ãåç §) ã
- 1 ã¤ã®ã¢ã¸ã¥ã¼ã«ã¤ã³ã¹ã¿ã³ã¹ã¯ 0 ãã 1 ã¤ã®ãã¼ãã«ã¤ã³ã¹ã¿ã³ã¹ãæã¤ãã¨ãã§ãã¾ããããã¯ã¤ã³ã¹ã¿ã³ã¹ã®ã颿°ã¢ãã¬ã¹ç©ºéãã§ãC è¨èªã®é¢æ°ãã¤ã³ã¿ã¼ãå®è£ ããããã«ä½¿ç¨ããã¾ãã WebAssembly ã®å°æ¥ã®ãã¼ã¸ã§ã³ã§ã¯ 1 ã¤ã®ã¢ã¸ã¥ã¼ã«ã«ã¤ã 0 ãã N åã®ã¡ã¢ãªã¼ã¤ã³ã¹ã¿ã³ã¹ã許容ããå¯è½æ§ãããã¾ãã
- 1 ã¤ã®ã¡ã¢ãªã¼ããã¼ãã«ã 0 ãã N åã®ã¢ã¸ã¥ã¼ã«ãã使ç¨ãããã¨ãã§ãã¾ããè¤æ°ã®ã¤ã³ã¹ã¿ã³ã¹å ¨ã¦ãåãã¢ãã¬ã¹ç©ºéãå ±æã§ããåçãªã³ã¯ ãå¯è½ã§ãã
å¤éæ§ã«ã¤ãã¦ã¯ããWebAssembly ããã¹ãå½¢å¼ã®çè§£ãã®è¨äºã§å¤éæ§ã®åãã«ã¤ãã¦ã¿ããã¨ãã§ãã¾ãããã®ä¸ã®ãã¼ãã«ã®å¤æ´ã¨åçãªã³ã¯ãåç §ãã¦ãã ããã
ã¾ã¨ã
ãã®è¨äºã§ã¯ WebAssembly JavaScript API ã®åºæ¬çãªä½¿ãæ¹ã«ã¤ãã¦èª¬æãã¾ãããWebAssembly ã¢ã¸ã¥ã¼ã«ã JavaScript ã®ã³ã³ããã¹ãã«çµã¿è¾¼ãæ¹æ³ããã®é¢æ°ã使ãããããããã¨ãJavaScript ã§ã®ã¡ã¢ãªã¼ã¨ãã¼ãã«ã®ä½¿ãæ¹ã«ã¤ãã¦ãããã«ãå¤éæ§ã®æ¦å¿µã«ã¤ãã¦ã触ãã¾ããã