タイトル通り。
・canvas への描画が可能なことを確認。
・emscripten_sleep() でその場で停止できることを確認。
・付属の emrun や mongoose などで Local Server を作れば、local だけで
wasm の起動が出来ることを確認。
・mongoose からは、cgi も起動でき、XmlHttpRequest()でローカルファイルを
JSから読み込め、cgi も自由に起動できることを確認。
・ローカル・ファイルアクセス、clipboard の読み書きの他、Local OS の
全ての機能を自由にできる可能性有り。
・これを使えば、Java の JVM に変わる新たなローカル仮想環境ができる。
探検
【wasm】ブラウザでC++。Emscriptenを語ろう
■ このスレッドは過去ログ倉庫に格納されています
1L
2019/01/15(火) 19:50:48.94ID:cXSiB+ud2019/01/19(土) 11:38:40.03ID:P/iwNPAz
【wasm を使う際に難しそうな事柄色々】
・async, await
・yield [ function generator ]
・setjmp(), longjmp()
・sleep() ; emscripten_sleep() で実装されてはいるが、とても複雑な方法で実装。バグ有り。
・Atomics, wait(), notify()
【ヒント】
1. wasm からは、JSの関数を呼び出せる。
2. JS からは、wasmの関数を呼び出せる。
3. JS からは、XmlHttpRequest() で WebServer 経由で外部ファイルを読み出せる。
4. XmlHttpRequest() の代わりに fetch() も使えるらしい。
5. JS では、eval(文字列); によって、文字列の中に書かれているJSコードを実行できる。
6. 1と5を使えば、wasmからJSの任意のコードを実行段階で変化する動的な引数を付けて
呼び出されるように出来る。
7. Emscripten では、EM_ASM(), EM_ASM_INT() 文は、*.ll コードでは、
それぞれに対応した関数を call するコードに置き換わる。
・async, await
・yield [ function generator ]
・setjmp(), longjmp()
・sleep() ; emscripten_sleep() で実装されてはいるが、とても複雑な方法で実装。バグ有り。
・Atomics, wait(), notify()
【ヒント】
1. wasm からは、JSの関数を呼び出せる。
2. JS からは、wasmの関数を呼び出せる。
3. JS からは、XmlHttpRequest() で WebServer 経由で外部ファイルを読み出せる。
4. XmlHttpRequest() の代わりに fetch() も使えるらしい。
5. JS では、eval(文字列); によって、文字列の中に書かれているJSコードを実行できる。
6. 1と5を使えば、wasmからJSの任意のコードを実行段階で変化する動的な引数を付けて
呼び出されるように出来る。
7. Emscripten では、EM_ASM(), EM_ASM_INT() 文は、*.ll コードでは、
それぞれに対応した関数を call するコードに置き換わる。
2019/01/19(土) 12:31:16.19ID:P/iwNPAz
【asm.js】
・asm.js は、JS のサブセット。だから、JS を超えることは出来ないらしい。
・Emscripten は、Em+Script+en という造語らしい。「Em+xxx+en」は「xxx化する」
の意味なので、Emscripten は、「Script 化する」の意味となる。
・Emscripten は元々、C/C++ コードを wasm ではなく、JS コードのサブセットで
あるところの asm.js に変換するシステムだったらしい。
・だから今でも、いったん asm.js に直してから binaryen で wasm に
変換しているらしい(←推定)。
・asm.js の仮想マシンの主記憶は JS の HEAP32[] 配列が対応するらしい。
・仮想マシンのスタックポインタは JS の STACKTOP という名前の変数で、C/C++ の
auto local な変数は、HEAP32[STACKTOP + ofs] の形式で参照されることが多い。
【wasm】
・wasm は、バイナリ形式だがテキスト形式も存在し、wast、wat と呼ばれ、
LISP の S 式に近い人間が可読な形式になっている。
【LLVM】
・LLVM は、*.bc がバイナリ形式。*.ll が人間が可読な形式。Emscriptenでは、
拡張子が bc の代わりに o とされている。
・llvm-as で、*.ll を *.bc に変換できる。
・asm.js は、JS のサブセット。だから、JS を超えることは出来ないらしい。
・Emscripten は、Em+Script+en という造語らしい。「Em+xxx+en」は「xxx化する」
の意味なので、Emscripten は、「Script 化する」の意味となる。
・Emscripten は元々、C/C++ コードを wasm ではなく、JS コードのサブセットで
あるところの asm.js に変換するシステムだったらしい。
・だから今でも、いったん asm.js に直してから binaryen で wasm に
変換しているらしい(←推定)。
・asm.js の仮想マシンの主記憶は JS の HEAP32[] 配列が対応するらしい。
・仮想マシンのスタックポインタは JS の STACKTOP という名前の変数で、C/C++ の
auto local な変数は、HEAP32[STACKTOP + ofs] の形式で参照されることが多い。
【wasm】
・wasm は、バイナリ形式だがテキスト形式も存在し、wast、wat と呼ばれ、
LISP の S 式に近い人間が可読な形式になっている。
【LLVM】
・LLVM は、*.bc がバイナリ形式。*.ll が人間が可読な形式。Emscriptenでは、
拡張子が bc の代わりに o とされている。
・llvm-as で、*.ll を *.bc に変換できる。
2019/01/19(土) 13:02:28.07ID:P/iwNPAz
誤: auto local な変数は、HEAP32[STACKTOP + ofs] の形式で参照されることが多い。
正: auto local な変数は、HEAP32[(STACKTOP<<2) + ofs] の形式で参照されることが多い。
正: auto local な変数は、HEAP32[(STACKTOP<<2) + ofs] の形式で参照されることが多い。
2019/01/19(土) 15:43:48.91ID:P/iwNPAz
【VM (Virtual Machine) としての wasm】
・結論から言うと、wasm は、VM としては、JVM や、flash VMより劣っていると思う。
例としては、「同期オブジェクト(Win32 のWaitForSingleObject()相当)」や、
sleep() もほぼ、wasm でちゃんと実装できそうなのは、Chrome と、FireFoxに限られる事。
・ところが、Platform 会社の「思惑(Mac上の開発環境の使用の強制)」や
「訴訟問題(GoogleとOracleの裁判)」により、上記の二つのVMは除外されて行く
傾向にあり、スマフォでも使えるVMとして残っていくのは、wasm と .NET だけ
になっていきそうな気がする。
・だから、言語のFRONT END開発者としては、スマフォでも使えるVMとしての選択肢は
wasm が有力ではあるが、機能面で(かなりの)問題があるというジレンマが生じる。
・これは、GAFA プラットフォーム支配の問題点の一つ。
------------------
[WHY APPLE WON'T ALLOW ADOBE FLASH ON IPHONE]
https://www.wired.com/2008/11/adobe-flash-on/
・結論から言うと、wasm は、VM としては、JVM や、flash VMより劣っていると思う。
例としては、「同期オブジェクト(Win32 のWaitForSingleObject()相当)」や、
sleep() もほぼ、wasm でちゃんと実装できそうなのは、Chrome と、FireFoxに限られる事。
・ところが、Platform 会社の「思惑(Mac上の開発環境の使用の強制)」や
「訴訟問題(GoogleとOracleの裁判)」により、上記の二つのVMは除外されて行く
傾向にあり、スマフォでも使えるVMとして残っていくのは、wasm と .NET だけ
になっていきそうな気がする。
・だから、言語のFRONT END開発者としては、スマフォでも使えるVMとしての選択肢は
wasm が有力ではあるが、機能面で(かなりの)問題があるというジレンマが生じる。
・これは、GAFA プラットフォーム支配の問題点の一つ。
------------------
[WHY APPLE WON'T ALLOW ADOBE FLASH ON IPHONE]
https://www.wired.com/2008/11/adobe-flash-on/
2019/01/21(月) 19:24:23.00ID:x6DE2oRu
7L
2019/01/22(火) 15:48:18.25ID:6S+2YJAI XmlHttpRequest() は、同期モードにすれば、CGI の動作が完了するまで
待てる気がする。もし、その CGI が、内部で Sleep( 1000 ) 相当の待機を
行えば、JS を、その場で 1秒間 待機させることが出来るかもしれない。
待てる気がする。もし、その CGI が、内部で Sleep( 1000 ) 相当の待機を
行えば、JS を、その場で 1秒間 待機させることが出来るかもしれない。
2019/01/22(火) 17:47:28.65ID:6S+2YJAI
Android の主要言語はJavaだが、VMは、JVM ではなく、Google 製の
ART (旧Dalvik) の VM を使っている。
だから、このVMは残っていくんだ・・・。
Google は、もっぱら wasm 路線だと思っていたんだが・・・。
ART (旧Dalvik) の VM を使っている。
だから、このVMは残っていくんだ・・・。
Google は、もっぱら wasm 路線だと思っていたんだが・・・。
2019/01/24(木) 22:53:00.98ID:/05KE7l4
>>3 >>4
どうやら、STACKTOP、HEAP32[] を使うのは、asm.js 流で、
wasm の stack はまた別系統になっているらしい。
前者は、global 領域に確保された HEAP32 配列を使うので、通常の
CPUアーキテクチャでのスタックの実装法に近い。そのため、CPUで
出来ることは何でも出来るといっても過言ではない。
一方、wasm の stack には、今のところ stack pointer が存在していない
らしい。だから、stack の値を検査したり、独自にコピーして保存して
何らかの効果を得たりすることも出来ないと思われる。
一方で、wasmでの標準的な作法なので、auto 変数もこのやり方
を使うことになっているため、ブラウザでJITなどは、CPUレジスタに
割り付けることによる速度向上が見られるかもしれない。
ここでジレンマが生じる。実は、wasm では、sleep() 機能を使う際には、
-s ASYNCIFY=1 を指定しなくてはならない。すると、前者の実装方に
なるだろう。すると、wasm での標準的な方法ではなくなるために、
CPUレジスタへの割付が行われない可能性がある。
なお、話が複雑になるが、ASYNCIFY=1 の指定は、現在の JS の WebAPI の仕様
と絡むと、emscripten_sleep() だけの問題ではなく、非常に重要と言っても過言ではない。
結論を言ってしまえば、OpenFileDialog() のようなもので、ユーザーがファイル名を
選択するのをその場で「待つ」事や、getch() や bat ファイルの pause 文のように
キー入力を待つことのような、便利な機能がはっきり言って実装不可能になってしまう。
これは長くて深い話なので、ちゃんと説明するのは難しい。
どうやら、STACKTOP、HEAP32[] を使うのは、asm.js 流で、
wasm の stack はまた別系統になっているらしい。
前者は、global 領域に確保された HEAP32 配列を使うので、通常の
CPUアーキテクチャでのスタックの実装法に近い。そのため、CPUで
出来ることは何でも出来るといっても過言ではない。
一方、wasm の stack には、今のところ stack pointer が存在していない
らしい。だから、stack の値を検査したり、独自にコピーして保存して
何らかの効果を得たりすることも出来ないと思われる。
一方で、wasmでの標準的な作法なので、auto 変数もこのやり方
を使うことになっているため、ブラウザでJITなどは、CPUレジスタに
割り付けることによる速度向上が見られるかもしれない。
ここでジレンマが生じる。実は、wasm では、sleep() 機能を使う際には、
-s ASYNCIFY=1 を指定しなくてはならない。すると、前者の実装方に
なるだろう。すると、wasm での標準的な方法ではなくなるために、
CPUレジスタへの割付が行われない可能性がある。
なお、話が複雑になるが、ASYNCIFY=1 の指定は、現在の JS の WebAPI の仕様
と絡むと、emscripten_sleep() だけの問題ではなく、非常に重要と言っても過言ではない。
結論を言ってしまえば、OpenFileDialog() のようなもので、ユーザーがファイル名を
選択するのをその場で「待つ」事や、getch() や bat ファイルの pause 文のように
キー入力を待つことのような、便利な機能がはっきり言って実装不可能になってしまう。
これは長くて深い話なので、ちゃんと説明するのは難しい。
2019/01/24(木) 23:11:44.56ID:/05KE7l4
>>9
正しくは、「WebAPI」ではなく、ブラウザ上の JS で使える EventLoop などの
仕様のこと。
1. JS では、Win32 の GetMessage() や PeekMessage() のような、
Event Queue の現在の中身を直接を調べるような関数が存在しないらしい事。
2. WebWorker で WorkerThread を作っても、結局、DOMには
アクセスできない事。
3. さらに、WorkerThrad では、イベントを受け取ることも出来ない事。
4. Win32 の GetAsyncKeystate() のような、イベントによらないでキーの
On/Off 状態を取得する方法が無いこと。
5. 以上の事は、OpenFileDialog() や getch()、pause() 文の模倣をそのままでは
原理的に不可能にする可能性がとても高い。
[回避策]
a. C/C++ のステートメントの実行を一行実行するたびにイベントループに戻る
ような「インタプリタ的な」実行法を採用する。これは、「Emterpreter」
(「Emscripten」と似ているが違うので注意)なるやり方が相当。
b. 関数のコンパイルの仕方を大幅に変更する方法。これが、ASYNCIFY=1
に相当すると思われる。具体的には、関数で「待つ」必要がある場合には、
イベントループに戻る。このことは、結論的には、JSやwasmの色々な機能不足を
一挙に解決できる。イベントループに戻ることで、キーやマウスのイベントを
受け取ることも出来るようになるし、タイマーイベントが発生するまでCPUを
hlt 状態にすることも出来るようになる。この事は実は似ているが、よく考えると
別の事柄でもあったりするので、説明が難しいが、とにかく、一挙に色々な
事を解決できるようになる。GetAsyncKeyState() 相当の関数が無いことと
Atomics の wait(), wake(), notify() が、限られたブラウザでしか実装されて無い事
の問題も解決する。誤解を招かずに説明するには話が長くなるのが・・・。
正しくは、「WebAPI」ではなく、ブラウザ上の JS で使える EventLoop などの
仕様のこと。
1. JS では、Win32 の GetMessage() や PeekMessage() のような、
Event Queue の現在の中身を直接を調べるような関数が存在しないらしい事。
2. WebWorker で WorkerThread を作っても、結局、DOMには
アクセスできない事。
3. さらに、WorkerThrad では、イベントを受け取ることも出来ない事。
4. Win32 の GetAsyncKeystate() のような、イベントによらないでキーの
On/Off 状態を取得する方法が無いこと。
5. 以上の事は、OpenFileDialog() や getch()、pause() 文の模倣をそのままでは
原理的に不可能にする可能性がとても高い。
[回避策]
a. C/C++ のステートメントの実行を一行実行するたびにイベントループに戻る
ような「インタプリタ的な」実行法を採用する。これは、「Emterpreter」
(「Emscripten」と似ているが違うので注意)なるやり方が相当。
b. 関数のコンパイルの仕方を大幅に変更する方法。これが、ASYNCIFY=1
に相当すると思われる。具体的には、関数で「待つ」必要がある場合には、
イベントループに戻る。このことは、結論的には、JSやwasmの色々な機能不足を
一挙に解決できる。イベントループに戻ることで、キーやマウスのイベントを
受け取ることも出来るようになるし、タイマーイベントが発生するまでCPUを
hlt 状態にすることも出来るようになる。この事は実は似ているが、よく考えると
別の事柄でもあったりするので、説明が難しいが、とにかく、一挙に色々な
事を解決できるようになる。GetAsyncKeyState() 相当の関数が無いことと
Atomics の wait(), wake(), notify() が、限られたブラウザでしか実装されて無い事
の問題も解決する。誤解を招かずに説明するには話が長くなるのが・・・。
2019/01/24(木) 23:42:39.89ID:/05KE7l4
>>10
誤: 3. さらに、WorkerThrad では、イベントを受け取ることも出来ない事。
正: 3. さらに、WorkerThread では、(キーボードやマウスなどからの)
「外部イベント」を受け取ることも出来ない事。
・WorkerThread でも、postMessage() によるソフトウェア的なイベントは受け取ることが
できる。
・ EventTarget の dispatchEvent() を使えば、強制的にイベント・ハンドラを呼び出すことが
できる。この時、ハンドラの実行が開始され、実行が完了するまで呼び出し元には帰って
こないらしい。そのため、この呼び出し方は「同期的呼び出し(Synchronously invoke)」
とされる。
色々考えてみたが、今ある全ての JS の関数、wasm の機能をどんな組み合わせで使っても、
C/C++ の関数を独特な特殊な形式までコンパイルしてやら無いと、getch(), pause(),
OpenFileDialog() のような機能は実現できないと思われる。
それが、「-s ASYNCIFY=1」だと思う。sleep() に関してだけは、Atomics の wait(),
wake() や、>>7 に書いた方法で実装できると思われる。
なお、JS の、async, await, yield などは、使える可能性はあるが、しかし、C/C++ を
wasm に直すことを考えたとき、使うのが難しいか、または、使えても効率はあまりよくない、
または、問題が生じてしまう、と考えている。例えば、wasm に直さずに、asm.js のように
js レベルまでのコンパイルでよいなら、async, await は、何とか利用できる気がする。
それでも、それらの仕様がどうも貧弱なので、それが問題。というのは、2段階以上の
深い関数では、await はエラーになってしまうらしいから、使いたい全ての関数に
async 修飾をしなくてはならない事になりそう。
また、説明するのが難しいが、結局、ASYNCIFY=1 でやっていることと余り変わらないという
か、>>9 のSTACKTOP, HEAP32[] を使うのと、async, await, yield は結局は本質的に同じような気がする。
誤: 3. さらに、WorkerThrad では、イベントを受け取ることも出来ない事。
正: 3. さらに、WorkerThread では、(キーボードやマウスなどからの)
「外部イベント」を受け取ることも出来ない事。
・WorkerThread でも、postMessage() によるソフトウェア的なイベントは受け取ることが
できる。
・ EventTarget の dispatchEvent() を使えば、強制的にイベント・ハンドラを呼び出すことが
できる。この時、ハンドラの実行が開始され、実行が完了するまで呼び出し元には帰って
こないらしい。そのため、この呼び出し方は「同期的呼び出し(Synchronously invoke)」
とされる。
色々考えてみたが、今ある全ての JS の関数、wasm の機能をどんな組み合わせで使っても、
C/C++ の関数を独特な特殊な形式までコンパイルしてやら無いと、getch(), pause(),
OpenFileDialog() のような機能は実現できないと思われる。
それが、「-s ASYNCIFY=1」だと思う。sleep() に関してだけは、Atomics の wait(),
wake() や、>>7 に書いた方法で実装できると思われる。
なお、JS の、async, await, yield などは、使える可能性はあるが、しかし、C/C++ を
wasm に直すことを考えたとき、使うのが難しいか、または、使えても効率はあまりよくない、
または、問題が生じてしまう、と考えている。例えば、wasm に直さずに、asm.js のように
js レベルまでのコンパイルでよいなら、async, await は、何とか利用できる気がする。
それでも、それらの仕様がどうも貧弱なので、それが問題。というのは、2段階以上の
深い関数では、await はエラーになってしまうらしいから、使いたい全ての関数に
async 修飾をしなくてはならない事になりそう。
また、説明するのが難しいが、結局、ASYNCIFY=1 でやっていることと余り変わらないという
か、>>9 のSTACKTOP, HEAP32[] を使うのと、async, await, yield は結局は本質的に同じような気がする。
2019/01/25(金) 00:01:31.69ID:58XK3b4v
>>9
>一方、wasm の stack には、今のところ stack pointer が存在していない
>らしい。
ここは、興味深い話として、
1. LLVM には、C の longjmp(), setjmp() の他、 C++ の throw, catch も、
直接的なサポートがある。
2. LLVM には、仮想レジスタは有っても「CPUレジスタ」的なものは(ある意味では)
「存在しない」が「スタックポインタ」は、一応、存在している。
3. LLVM には、(EIP のような)「命令ポインタ」的なものは存在していない(ハズ)。
関数内には、ラベルを書くことが出来て、br 命令で比較的自由に飛ぶことも出来る。
ところが、全く別の関数への大域的な、jmp 命令のようなものは多分無い。
4. 一番言いたいことは、上記の「2.」のこと。LLVM にはスタックポインタを直接
触ることが出来る。それなのに、wasm では出来ない(らしい)。この事は、
結構理不尽な感じがする。
5. 実CPUでは簡単かつ効率よく出来てしまう事が、wasmではできない。
6. Win32 では簡単に出来てしまうことが JS では出来ない。メッセージ・キューの読み出し。
独自イベントループの記述。while ( GetMessage(&msg ) ) { DispathMessage( &msg); } みたいな。
7. 結果、BASIC でも、35年前の昔から簡単に出来ていた input "a="; a 見たいな事が、JS では出来ない。
>一方、wasm の stack には、今のところ stack pointer が存在していない
>らしい。
ここは、興味深い話として、
1. LLVM には、C の longjmp(), setjmp() の他、 C++ の throw, catch も、
直接的なサポートがある。
2. LLVM には、仮想レジスタは有っても「CPUレジスタ」的なものは(ある意味では)
「存在しない」が「スタックポインタ」は、一応、存在している。
3. LLVM には、(EIP のような)「命令ポインタ」的なものは存在していない(ハズ)。
関数内には、ラベルを書くことが出来て、br 命令で比較的自由に飛ぶことも出来る。
ところが、全く別の関数への大域的な、jmp 命令のようなものは多分無い。
4. 一番言いたいことは、上記の「2.」のこと。LLVM にはスタックポインタを直接
触ることが出来る。それなのに、wasm では出来ない(らしい)。この事は、
結構理不尽な感じがする。
5. 実CPUでは簡単かつ効率よく出来てしまう事が、wasmではできない。
6. Win32 では簡単に出来てしまうことが JS では出来ない。メッセージ・キューの読み出し。
独自イベントループの記述。while ( GetMessage(&msg ) ) { DispathMessage( &msg); } みたいな。
7. 結果、BASIC でも、35年前の昔から簡単に出来ていた input "a="; a 見たいな事が、JS では出来ない。
2019/01/27(日) 02:20:20.81ID:UeSsBKpf
>>9
>どうやら、STACKTOP、HEAP32[] を使うのは、asm.js 流で、
>wasm の stack はまた別系統になっているらしい。
C/C++ の文字列のポインタを JS の関数に渡して、JSで
文字列として扱いたい場合、Emscripten が用意している
Pointer_stringify() という JS の関数を使うことになる。
この関数のソースを見てみたところ、例えば、
writeArrayToMemory: function(array, buffer) {
for (var i = 0; i < array.length; i++) {
HEAP8[ buffer++ ] = array[i];
}
}
のような関数を使っており、HEAP8[] 配列が使われている。
これは、asm.js 流の stack を恐らく「必ず」使っている事を
意味するのだと思う。言いたいことは、wasm の 「nativeな」
stack の仕組みを使わずに、JS の global 変数的に TypedArray
として HEAP8[] を確保して、それを「必ず」使っている、ということ。
そうでなければ、Pointer_stringify() 関数が使えなくなってしまうはずだから。
その結果、wasm の native stack を使って無いので、ブラウザの JIT が働いても、
CPUレジスタが効率よく使われる可能性は低くなる。
ただ、C/C++ と JS 間の文字列の受け渡しは大切で、上記のような実装以外は
現状、多分できそうにない。なら、結論的には、Emscripten がどんなに
改良されても、wasm 側に何らかの改良が施されない限り、wasm の native stack
を使用した wasm コードは根本的に生成できないと思われる。
>どうやら、STACKTOP、HEAP32[] を使うのは、asm.js 流で、
>wasm の stack はまた別系統になっているらしい。
C/C++ の文字列のポインタを JS の関数に渡して、JSで
文字列として扱いたい場合、Emscripten が用意している
Pointer_stringify() という JS の関数を使うことになる。
この関数のソースを見てみたところ、例えば、
writeArrayToMemory: function(array, buffer) {
for (var i = 0; i < array.length; i++) {
HEAP8[ buffer++ ] = array[i];
}
}
のような関数を使っており、HEAP8[] 配列が使われている。
これは、asm.js 流の stack を恐らく「必ず」使っている事を
意味するのだと思う。言いたいことは、wasm の 「nativeな」
stack の仕組みを使わずに、JS の global 変数的に TypedArray
として HEAP8[] を確保して、それを「必ず」使っている、ということ。
そうでなければ、Pointer_stringify() 関数が使えなくなってしまうはずだから。
その結果、wasm の native stack を使って無いので、ブラウザの JIT が働いても、
CPUレジスタが効率よく使われる可能性は低くなる。
ただ、C/C++ と JS 間の文字列の受け渡しは大切で、上記のような実装以外は
現状、多分できそうにない。なら、結論的には、Emscripten がどんなに
改良されても、wasm 側に何らかの改良が施されない限り、wasm の native stack
を使用した wasm コードは根本的に生成できないと思われる。
2019/01/27(日) 02:29:37.09ID:UeSsBKpf
>>13
確認が必要ではあるが、ある意味では「良い」こととして
-s ASYNCIFY=1 を指定しても、指定しなかったときに比べた
速度低下は、native stack を使うかどうかに起因する事は
ない可能性がある。だから、-s ASYNCIFY=1 は、そんなに
気兼ねすることなく使ってもいい可能性が出てくる。
というか、-s ASYNCIFY=1 は、Emscriptenの作者の気持ちは
離れていっているかもしれないが、実際にはこれなしでは、
Windows を模倣したような汎用的な ToolKit は作れない
と思うが・・・。
確認が必要ではあるが、ある意味では「良い」こととして
-s ASYNCIFY=1 を指定しても、指定しなかったときに比べた
速度低下は、native stack を使うかどうかに起因する事は
ない可能性がある。だから、-s ASYNCIFY=1 は、そんなに
気兼ねすることなく使ってもいい可能性が出てくる。
というか、-s ASYNCIFY=1 は、Emscriptenの作者の気持ちは
離れていっているかもしれないが、実際にはこれなしでは、
Windows を模倣したような汎用的な ToolKit は作れない
と思うが・・・。
2019/01/27(日) 02:56:58.37ID:UeSsBKpf
>>14
>というか、-s ASYNCIFY=1 は、Emscriptenの作者の気持ちは
>離れていっているかもしれないが、
実は、さらに効率が悪いと思われる「Emterpreter」という、C/C++
のソースをバイトコードにコンパイルして、インタプリタ的に実行して
しまう方式の方に、Emscripten の作者の心は向いているのかも知れない。
-s ASYNCIFY=1 は、「推奨しない」が、新しい方式として、「Emterpreter」
を挙げているようにも思える書き方がされているようなので。
>というか、-s ASYNCIFY=1 は、Emscriptenの作者の気持ちは
>離れていっているかもしれないが、
実は、さらに効率が悪いと思われる「Emterpreter」という、C/C++
のソースをバイトコードにコンパイルして、インタプリタ的に実行して
しまう方式の方に、Emscripten の作者の心は向いているのかも知れない。
-s ASYNCIFY=1 は、「推奨しない」が、新しい方式として、「Emterpreter」
を挙げているようにも思える書き方がされているようなので。
16L
2019/01/27(日) 14:04:20.14ID:UeSsBKpf LLVM の alloca を wasm の native スタックに対応させずに、
グローバル変数的な、HEAP32[STACKTOP + ofs] の方に対応させた上で工夫すれば、
ASYNCIFY=1 的なものや、yield, async, await, function generator 的なものも
LLVM の LL コード以後の backend 層を修正する事無く実現可能ではないかと思っていた。
でも、LLVM の仮想レジスタ(%10 みたいな) の方も同様に HEAP32[] の方に
移さないと、多分、駄目だろう・・・。一時的に使うものは除いて。
一時的に使っているだけかどうかを最適化層で判定して、一時的ではないもの
だけを HEAP32[] の方に移さないと、アプリの実行速度は下がる。
本当は、LL コードは仮想レジスタに対しては最適化が強く利くはずなので、
なるべく仮想レジスタだけで済むならそれに越したことは無い。
グローバル変数の最適化はかなり難しいのd。
グローバル変数的な、HEAP32[STACKTOP + ofs] の方に対応させた上で工夫すれば、
ASYNCIFY=1 的なものや、yield, async, await, function generator 的なものも
LLVM の LL コード以後の backend 層を修正する事無く実現可能ではないかと思っていた。
でも、LLVM の仮想レジスタ(%10 みたいな) の方も同様に HEAP32[] の方に
移さないと、多分、駄目だろう・・・。一時的に使うものは除いて。
一時的に使っているだけかどうかを最適化層で判定して、一時的ではないもの
だけを HEAP32[] の方に移さないと、アプリの実行速度は下がる。
本当は、LL コードは仮想レジスタに対しては最適化が強く利くはずなので、
なるべく仮想レジスタだけで済むならそれに越したことは無い。
グローバル変数の最適化はかなり難しいのd。
2019/01/27(日) 16:09:38.70ID:UeSsBKpf
Emscriptenの emcc で、ASYNCIFY=1 を指定した場合、1つのイベント・ハンドラ
の処理が完了する前に別のイベント・ハンドラが起動してしまうことがあるらしい。
例えば、Windows でいうところの OnMouseMove() ハンドラの中で少し
時間のかかる処理をしていたとする。例として、ハンドラの中で printf()
を使い、端末のスクロールに時間がかかってしまうとか。その場合、
そのイベント・ハンドラの処理が完了する前に、新しい OnMouseMove()
イベントが生じてしまう事があるらしい。
普通、Windows でも、JS でも、マウス・イベントなどは、イベント・キューの中
に蓄えられ、待ち行列を形成し、今実行中のイベント・ハンドラの処理が
完了するまでは次のイベント・ハンドラが実行されることは無い
(Win32では、ハンドラの中で SendMessage() を行えば話は違ってくるが。)。
ところが、ASYNCIFY=1 を指定した場合、printf() 関数の中で、新しい
マウス・イベントに対しての OnMouseMove() が、また呼び出されることが
あるようだ。これも確定事項ではない。しかし、いくつかの実験が不可解な
挙動をしていたのを、今から考えればでそう思えて来た。
そのときは、ASYNCIFY=1 を指定すると、printf() が「バグる」と思って
いたのだが。そういうカラクリだったのか・・・。
の処理が完了する前に別のイベント・ハンドラが起動してしまうことがあるらしい。
例えば、Windows でいうところの OnMouseMove() ハンドラの中で少し
時間のかかる処理をしていたとする。例として、ハンドラの中で printf()
を使い、端末のスクロールに時間がかかってしまうとか。その場合、
そのイベント・ハンドラの処理が完了する前に、新しい OnMouseMove()
イベントが生じてしまう事があるらしい。
普通、Windows でも、JS でも、マウス・イベントなどは、イベント・キューの中
に蓄えられ、待ち行列を形成し、今実行中のイベント・ハンドラの処理が
完了するまでは次のイベント・ハンドラが実行されることは無い
(Win32では、ハンドラの中で SendMessage() を行えば話は違ってくるが。)。
ところが、ASYNCIFY=1 を指定した場合、printf() 関数の中で、新しい
マウス・イベントに対しての OnMouseMove() が、また呼び出されることが
あるようだ。これも確定事項ではない。しかし、いくつかの実験が不可解な
挙動をしていたのを、今から考えればでそう思えて来た。
そのときは、ASYNCIFY=1 を指定すると、printf() が「バグる」と思って
いたのだが。そういうカラクリだったのか・・・。
18L
2019/01/29(火) 10:27:43.11ID:8rAEnTT8 Emscriptenを使わずに、clang で wasm を出力してみたところ、
C の local auto 変数は、wasm の native stack(shadow stack) ではなく、
グローバル変数(wast において $global$0 という名前 ) を stack pointer
(asmjs における STACKTOP) として、memory なる HEAP8[] 相当の
JS 配列の中に確保されることが分かった。
つまり、asm.js を途中に介さないで直接 wasm を出力した場合でも、
local auto 変数は、wasm の native stack に確保されるわけではなく、
ちゃんと、HEAP8[SATCKTOP + ofs] のような意味でJS の グローバル変数の
HEAP8[] 配列のようなものの中に確保されていると言うこと。
だから、C の local auto 変数の(先頭)アドレスを取得することも出来るし、
C のglobal 変数のアドレスと、全く同じ扱いにすることが出来ている。
wasm において、Cのポインタの中に入っている「アドレス」は、
HEAP8[] 配列の index 番号である。だから、0 に近い小さな値となっている。
ポインタの値が、10 の場合、HEAP8[10] に対応している。
また、この memory は、現状、wasm 側で確保して、それを、JS 側に export
している。JS 側は、それを必要あらば、HEAP8[] 配列に「投影」することが出来る。
HEAP8 という名前は仮のもので、任意の名前をつけることが出来る。
また、同じ memory 領域を HEAP32、HEAP16、HEAP8 として、重ねるように
配列に投影することも出来る。
C の local auto 変数は、wasm の native stack(shadow stack) ではなく、
グローバル変数(wast において $global$0 という名前 ) を stack pointer
(asmjs における STACKTOP) として、memory なる HEAP8[] 相当の
JS 配列の中に確保されることが分かった。
つまり、asm.js を途中に介さないで直接 wasm を出力した場合でも、
local auto 変数は、wasm の native stack に確保されるわけではなく、
ちゃんと、HEAP8[SATCKTOP + ofs] のような意味でJS の グローバル変数の
HEAP8[] 配列のようなものの中に確保されていると言うこと。
だから、C の local auto 変数の(先頭)アドレスを取得することも出来るし、
C のglobal 変数のアドレスと、全く同じ扱いにすることが出来ている。
wasm において、Cのポインタの中に入っている「アドレス」は、
HEAP8[] 配列の index 番号である。だから、0 に近い小さな値となっている。
ポインタの値が、10 の場合、HEAP8[10] に対応している。
また、この memory は、現状、wasm 側で確保して、それを、JS 側に export
している。JS 側は、それを必要あらば、HEAP8[] 配列に「投影」することが出来る。
HEAP8 という名前は仮のもので、任意の名前をつけることが出来る。
また、同じ memory 領域を HEAP32、HEAP16、HEAP8 として、重ねるように
配列に投影することも出来る。
19L
2019/01/30(水) 15:30:21.11ID:vB8508VG ・LLVM は、割と簡単にデバッグ用の行番号情報を入れることが出来る。
・emcc で、-g4 と --source-map-base オプションを使えば、
それを、sourcemap なる JS のデバッグ情報ファイルに出力できる。
・FireFox Debveloper Edition では、普通に C のソースに break point
を指定して、wasm のプログラムをブラウザ上でデバッグできることを
確認した。
・ただし、Web に出ている情報は、少しずつ間違っているか、または、
現状に合ってないので、実験しないと上手くいく方法は分からなかった。
[emcc を使わないで、wasm-ld.exe を使って debug 情報を入れる方法]
・wasm-ld.exe は、wasm 用のリンカであり、入力は elf 形式似た *.o 。
出力は、*.wasm 形式。wast が見たい場合は、wasm-dis.exe で変換する。
・この *.o は、emcc の *.o とは別。emcc の *.o は、単に拡張子が
変わっているだけで、中身は *.bc と同じ。
・この elf 的な方の *.o は、clang で、*.bc を入力して作ることが出来る。
・wasm-ld.exe は、実験してみると、多分。この elf 的な *.o しか入力として受け付けない。
・wasm-ld.exe は、今のところ、直接的には、sourcemap を出力できないらしい。
・しかし、*.wasm の中には、既に dwarf 形式でデバッグ情報が入っているかもしれない。
・なぜなら、wast に変換してみてみると、ファイルの最後の方に ; ・・・ のコメントとして、
それらしき記述があるから。
・この wasm の中の dwarf 情報は、wasm-dwarf なるプログラムで、sourcemap に変換
することが出来るらしい。ところが、このプログラムは、「Rust言語」を使って書かれている
らしい。
・だから、emcc を使わなくても、デバッグ情報を最後まで出力できる道は一応は、存在している
かも知れない。
・最大の問題は、wasm-dwarf が Rust 言語で書かれていること。exe に直す方法があれば
便利になると思う。
・emcc で、-g4 と --source-map-base オプションを使えば、
それを、sourcemap なる JS のデバッグ情報ファイルに出力できる。
・FireFox Debveloper Edition では、普通に C のソースに break point
を指定して、wasm のプログラムをブラウザ上でデバッグできることを
確認した。
・ただし、Web に出ている情報は、少しずつ間違っているか、または、
現状に合ってないので、実験しないと上手くいく方法は分からなかった。
[emcc を使わないで、wasm-ld.exe を使って debug 情報を入れる方法]
・wasm-ld.exe は、wasm 用のリンカであり、入力は elf 形式似た *.o 。
出力は、*.wasm 形式。wast が見たい場合は、wasm-dis.exe で変換する。
・この *.o は、emcc の *.o とは別。emcc の *.o は、単に拡張子が
変わっているだけで、中身は *.bc と同じ。
・この elf 的な方の *.o は、clang で、*.bc を入力して作ることが出来る。
・wasm-ld.exe は、実験してみると、多分。この elf 的な *.o しか入力として受け付けない。
・wasm-ld.exe は、今のところ、直接的には、sourcemap を出力できないらしい。
・しかし、*.wasm の中には、既に dwarf 形式でデバッグ情報が入っているかもしれない。
・なぜなら、wast に変換してみてみると、ファイルの最後の方に ; ・・・ のコメントとして、
それらしき記述があるから。
・この wasm の中の dwarf 情報は、wasm-dwarf なるプログラムで、sourcemap に変換
することが出来るらしい。ところが、このプログラムは、「Rust言語」を使って書かれている
らしい。
・だから、emcc を使わなくても、デバッグ情報を最後まで出力できる道は一応は、存在している
かも知れない。
・最大の問題は、wasm-dwarf が Rust 言語で書かれていること。exe に直す方法があれば
便利になると思う。
2019/01/30(水) 15:49:47.96ID:vB8508VG
Rust は、コンパイル言語なので、rustc コマンドでコンパイルすれば良いだけ
だったかも。
だったかも。
2019/01/30(水) 22:10:26.01ID:GmcWmER+
・wasm-dwarf を試してみたて、ちゃんと、sourcemap 形式のものを出力
することはできた。
・FireFox Dev Ed. でCソースの行番号レベルのソースレベル・デバッグっぽい
ことが出来る寸前まではいけた。ブレイクポイントは設定できる。
しかし、実際にそこで停止することは出来なかった。
・もしかすると、wasm-dwarf の出力する sourcemap ファイルの mapping 部分は
正しくないかもしれない。
・llvm-dwarfdump なるコマンドがあり、exeバイナリも容易に入手できる。
そのコマンドを -all オプションを指定して使うと、*.wasm の中のデバッグ情報を
全部見ることができるらしい。
・LLVM 公式サイトには、LLVM の操作ライブラリもおいてあるが、llvm-dwarfdump.exe
や、wasm-emscripten-finalize.exe などのツール類は、そのライブラリを使って
作られている気がする。サイズがどのコマンドも大きいくなっているのはそのせいかもしれない。
たくさんの機能を持った汎用のライブラリがそのまま exe の中に入っているためにそう
なっている気がするから。
することはできた。
・FireFox Dev Ed. でCソースの行番号レベルのソースレベル・デバッグっぽい
ことが出来る寸前まではいけた。ブレイクポイントは設定できる。
しかし、実際にそこで停止することは出来なかった。
・もしかすると、wasm-dwarf の出力する sourcemap ファイルの mapping 部分は
正しくないかもしれない。
・llvm-dwarfdump なるコマンドがあり、exeバイナリも容易に入手できる。
そのコマンドを -all オプションを指定して使うと、*.wasm の中のデバッグ情報を
全部見ることができるらしい。
・LLVM 公式サイトには、LLVM の操作ライブラリもおいてあるが、llvm-dwarfdump.exe
や、wasm-emscripten-finalize.exe などのツール類は、そのライブラリを使って
作られている気がする。サイズがどのコマンドも大きいくなっているのはそのせいかもしれない。
たくさんの機能を持った汎用のライブラリがそのまま exe の中に入っているためにそう
なっている気がするから。
2019/01/30(水) 23:38:06.00ID:YAuiBXnQ
もしかして、ここまですべて同じ人?
2019/01/30(水) 23:56:12.42ID:GmcWmER+
[エンタープライズ号、航海日誌 第5016日]
emcc を使わずに wasm をソースレベルデバッグしたい場合、
JSファイルではなくて、wasm そのものの中に、その事をマークしなければならない。
そしてそれは、「 custom section "sourceMappingURL"」なるものの中に、
JSファイルで、//# sourceMappingURL=xxxx と書く場合の xxxx の部分
の文字列を入れることで行えるらしい。
ただし今のところ、この section だけを上手く書き換える方法が良く分かってない。
wasm-emscripten-finalize.exe を使えば、書き換えることは可能ではあるが、
wasm 本体のコード部分のバイナリも変わってしまうらしいので、アドレス値が
ずれてしまうので、結局、sourcemap が狂ってしまう。
だから、何とかして、この section だけに文字列を追加する方法を見出さなくて
はならない。
emcc を使わずに wasm をソースレベルデバッグしたい場合、
JSファイルではなくて、wasm そのものの中に、その事をマークしなければならない。
そしてそれは、「 custom section "sourceMappingURL"」なるものの中に、
JSファイルで、//# sourceMappingURL=xxxx と書く場合の xxxx の部分
の文字列を入れることで行えるらしい。
ただし今のところ、この section だけを上手く書き換える方法が良く分かってない。
wasm-emscripten-finalize.exe を使えば、書き換えることは可能ではあるが、
wasm 本体のコード部分のバイナリも変わってしまうらしいので、アドレス値が
ずれてしまうので、結局、sourcemap が狂ってしまう。
だから、何とかして、この section だけに文字列を追加する方法を見出さなくて
はならない。
2019/01/31(木) 00:30:00.40ID:OGxiQZdZ
結論的に言えば、
・custom section は、id=0 の section で、割と簡単に作ることが出来る。
known section は、id >=1 になっているので、区別が付く。
custom section は、文字列で、好きな名前をつけることが出来る。
・wasm ファイル自体が、section を chunk 方式のように羅列している
だけなので、意外と簡単に section の追加が出来るかもしれない。
section は、入れ子になることはなく、単に global level で1次元配列のように
直線的に羅列されているだけらしい。ただし、それぞれのsectionのサイズは
可変長なので、配列ではなく、「chunk」である。
・ただし、text format の wast では、custom section を定義する方法が
用意されていないようなので、binary 形式の wasm を直接修正する
必要があると思う。
・custom section は、id=0 の section で、割と簡単に作ることが出来る。
known section は、id >=1 になっているので、区別が付く。
custom section は、文字列で、好きな名前をつけることが出来る。
・wasm ファイル自体が、section を chunk 方式のように羅列している
だけなので、意外と簡単に section の追加が出来るかもしれない。
section は、入れ子になることはなく、単に global level で1次元配列のように
直線的に羅列されているだけらしい。ただし、それぞれのsectionのサイズは
可変長なので、配列ではなく、「chunk」である。
・ただし、text format の wast では、custom section を定義する方法が
用意されていないようなので、binary 形式の wasm を直接修正する
必要があると思う。
2019/01/31(木) 09:53:09.92ID:OGxiQZdZ
Emscripten を使わなくても、ブラウザ上の wasm で、Cソース上の break point
で停止させることに成功した。
なお、海外のサイトを検索しても、その報告例は見つからなかった。
で停止させることに成功した。
なお、海外のサイトを検索しても、その報告例は見つからなかった。
2019/02/01(金) 17:28:19.91ID:WOdIBupf
wasm は、JS の WebAssembly.instantiate() 系の関数を上手く使うと、既に、
WebWorker スレッドのコンテキストにおいても実行する事が出来るらしい。
また、実験的な確認は取れてないが、JS の WebAssembly 関連の関数の仕様と
先日から調査した HEAP8[] などによる memoy の扱い方やグローバル変数や
スタック変数の確保の仕方、ポインタ変数の中身の意味などから総合的に判断すると、
別ファイルの*.wasm を複数 instance 化できてもおかしくない仕様になっている
と思う。
ちなみに、C の関数ポインタは、wasm でも使用できることを実験して確認した。
そして、wasm においては、「関数アドレス」ではなく、「関数番号」となる。
番号に対応した関数の「関数名(関数オブジェクト)」は、table なる wasm
内の section に配列的に並べられている。
そして、JSコードからも、そのテーブルの読み書き、追加が可能。
だから、動的に関数を追加して、動的リンクなども出来てもおかしくない仕様に
なっている。
WebWorker スレッドのコンテキストにおいても実行する事が出来るらしい。
また、実験的な確認は取れてないが、JS の WebAssembly 関連の関数の仕様と
先日から調査した HEAP8[] などによる memoy の扱い方やグローバル変数や
スタック変数の確保の仕方、ポインタ変数の中身の意味などから総合的に判断すると、
別ファイルの*.wasm を複数 instance 化できてもおかしくない仕様になっている
と思う。
ちなみに、C の関数ポインタは、wasm でも使用できることを実験して確認した。
そして、wasm においては、「関数アドレス」ではなく、「関数番号」となる。
番号に対応した関数の「関数名(関数オブジェクト)」は、table なる wasm
内の section に配列的に並べられている。
そして、JSコードからも、そのテーブルの読み書き、追加が可能。
だから、動的に関数を追加して、動的リンクなども出来てもおかしくない仕様に
なっている。
2019/02/01(金) 17:38:50.44ID:WOdIBupf
wasm, wast において:
・call_indirect の引数は、関数アドレスではなく、関数番号となる。
この番号は、table section のエントリへの index 番号となっている。
・store アドレス, 値
・load アドレス
の「アドレス」部分は、memory section の先頭からの offset 値に
なっている。memory section は、JS コードからも参照する事が出来て、
8, 16, 32 BIT の配列としてアクセスする事が出来る。名前は任意に
ついけられるが、HEAP8[], HEAP16[], HEA32[] という配列に「投影」
してアクセスする事が出来る。型が決まった配列に投影するやり方は、
TypedArray への投影として行う。一方、32BIT値などを、アラインを
気にせずに中途半端なアドレスを指定してアクセスするには、
DataView が便利である。なお、TypedArray へ投影する場合でも、
アラインがずれている変なアドレスを先頭アドレスにして 32BIT 値の
配列にすることも可能らしい。
なお、普通のJSでは、数値は、全て 64BIT double 型の不動小数点型である。
TypedArray では、ちゃんとBIT 数を指定した整数型としての配列を作る
ことが出来る。ただし、上の例では配列を作っているのではなく、配列へ
「投影」している。
・call_indirect の引数は、関数アドレスではなく、関数番号となる。
この番号は、table section のエントリへの index 番号となっている。
・store アドレス, 値
・load アドレス
の「アドレス」部分は、memory section の先頭からの offset 値に
なっている。memory section は、JS コードからも参照する事が出来て、
8, 16, 32 BIT の配列としてアクセスする事が出来る。名前は任意に
ついけられるが、HEAP8[], HEAP16[], HEA32[] という配列に「投影」
してアクセスする事が出来る。型が決まった配列に投影するやり方は、
TypedArray への投影として行う。一方、32BIT値などを、アラインを
気にせずに中途半端なアドレスを指定してアクセスするには、
DataView が便利である。なお、TypedArray へ投影する場合でも、
アラインがずれている変なアドレスを先頭アドレスにして 32BIT 値の
配列にすることも可能らしい。
なお、普通のJSでは、数値は、全て 64BIT double 型の不動小数点型である。
TypedArray では、ちゃんとBIT 数を指定した整数型としての配列を作る
ことが出来る。ただし、上の例では配列を作っているのではなく、配列へ
「投影」している。
2019/02/01(金) 22:39:58.03ID:q39qofSl
[用語解説]
エントリ = アセンブリレベルのデータにおいて時々使われる言葉。
同じサイズのデータが並んでいるような場合に、各データが
入っている「箱」、のような意味。
C言語の配列における各要素が入っている小さな箱のようなイメージ。
「room」「folder」などの言葉も大体同じ意味かもしれない。
エントリ = アセンブリレベルのデータにおいて時々使われる言葉。
同じサイズのデータが並んでいるような場合に、各データが
入っている「箱」、のような意味。
C言語の配列における各要素が入っている小さな箱のようなイメージ。
「room」「folder」などの言葉も大体同じ意味かもしれない。
29L
2019/02/01(金) 22:54:21.57ID:q39qofSl [独断と偏見の見解]
辞書に置いては、英語版でも日本語版でも、「エントリ」や「インデックス」
の意味がはっきり言って「間違っている」。自分が読んできたコンピュータ系の
技術文書に置いては、
インデックス = 「index number」のように使われて、配列の「要素番号」
配列の添え字の意味であり、それ以外の意味で使われることは
まずない。BYTE a[256]; に対して、a[idx] の idx がそれ。
変数名としては、大体 idx か index。一方、id は、identifier の
場合が多くて、識別子。意味も少し似ていて混同してもそんなに
問題ないかも知れないが。英語圏に置いて、配列の添え字は、大体
index number という言葉が使われる。subscript も使われる
こともたまにある気もするが、そっちは「下付き文字」の意味で、
ニュアンスが結構違うと思う。
エントリ = ネットの辞書にあるような、「データ入力」や「エントリ・モデル」の
意味ではほぼ絶対に使われない。配列や行列やテーブルの要素の
入っている箱のような意味。「データ入力」は、多分、「data input」
ということが多いと思う、なんとなくだが。
辞書に置いては、英語版でも日本語版でも、「エントリ」や「インデックス」
の意味がはっきり言って「間違っている」。自分が読んできたコンピュータ系の
技術文書に置いては、
インデックス = 「index number」のように使われて、配列の「要素番号」
配列の添え字の意味であり、それ以外の意味で使われることは
まずない。BYTE a[256]; に対して、a[idx] の idx がそれ。
変数名としては、大体 idx か index。一方、id は、identifier の
場合が多くて、識別子。意味も少し似ていて混同してもそんなに
問題ないかも知れないが。英語圏に置いて、配列の添え字は、大体
index number という言葉が使われる。subscript も使われる
こともたまにある気もするが、そっちは「下付き文字」の意味で、
ニュアンスが結構違うと思う。
エントリ = ネットの辞書にあるような、「データ入力」や「エントリ・モデル」の
意味ではほぼ絶対に使われない。配列や行列やテーブルの要素の
入っている箱のような意味。「データ入力」は、多分、「data input」
ということが多いと思う、なんとなくだが。
2019/02/03(日) 18:21:17.31ID:gzQofkZX
Emscripten や、その付属ライブラリなしで malloc(), free() ( <--- dlmalloc ) を
使うことに成功した。dlmalloc と 自分のアプリで wasm 分けずに、 リンクして
単一のwasm で行ける。 wasm の起動処理も必要なビルトイン的なJS関数の準備も、
全部自前で書いた JS で行っている。
使うことに成功した。dlmalloc と 自分のアプリで wasm 分けずに、 リンクして
単一のwasm で行ける。 wasm の起動処理も必要なビルトイン的なJS関数の準備も、
全部自前で書いた JS で行っている。
>>29
>それ以外の意味で使われることはまずない
「まずない」というのはちょっと極端ですね…
今思いついたところでは、インデックスレジスター絡みのアドレッシングとか命令とか、はありうると思いますね
あと index には「指標」という意味がありますから、OS 等の動きや効率を計算して振る舞いを変えるための状況指示関数みたいなものを index と呼ぶ可能性もあります
>それ以外の意味で使われることはまずない
「まずない」というのはちょっと極端ですね…
今思いついたところでは、インデックスレジスター絡みのアドレッシングとか命令とか、はありうると思いますね
あと index には「指標」という意味がありますから、OS 等の動きや効率を計算して振る舞いを変えるための状況指示関数みたいなものを index と呼ぶ可能性もあります
32L
2019/02/04(月) 11:11:39.60ID:fEV2g5eo >>31
結論から先に言っておくと、とても言いにくいことだけど、あなたの意見はおいらの見解とは合わない。
>今思いついたところでは、インデックスレジスター絡みのアドレッシングとか命令とか、
>はありうると思いますね
Intel CPU の IA32 の「アドレッシングモード」は、Mod/RM で指定する。メモリから
データを読み書きする場合には「間接アドレッシングモード」を使い、元々の意図
としては次のようになっている。ただし、アセンブリ言語の使い方はとても自由で、
絶対この意味で使わなくてはいけないというわけではなく、元々、Intel も別の意味での
使い方も想定している。だから、言葉の意味とは違った使い方がされていることとがある。
そしてそれは悪いことではない。だから注意が必要:
[base + index * scale + offset]
base = ベースレジスタ(配列の先頭アドレスに当たる)。base は基盤。だから、先頭アドレスの意味になる。
index = インデックスレジスタ(配列の添え字に当たる)
scale = 1,2,4,8 ; スケールファクタ(配列の要素のバイト数にあたる)
offset = オフセットアドレス(ベースアドレスを少しずらす目的か、または、逆にこっちをベースアドレスにする使い方がある)
C 言語で、TYPE arr[N]; と宣言すると、TYPE 型を要素が N 個集まった配列が定義できる。
上記の間接アドレスで、scale は、sizeof(TYPE) とする事が想定されている。つまり、
arr[index] ---> [&arr + index * sizeof(TYPE)] のように置き換わり、
scale = sizeof(TYPE); の場合に相当する。だから、この場合も、index は紛れもなく配列の添え字である。
ただし、scale=1 に設定することで、index の部分にベースアドレスを指定することも出来るように
なるので、実際のアセンブリ言語では、index が添え字であるという元々の意味を超え、さまざまな使われ
方がされている。しかし、それは、index の言葉の意味が「添え字」である、という事を否定すること
にはならない。
結論から先に言っておくと、とても言いにくいことだけど、あなたの意見はおいらの見解とは合わない。
>今思いついたところでは、インデックスレジスター絡みのアドレッシングとか命令とか、
>はありうると思いますね
Intel CPU の IA32 の「アドレッシングモード」は、Mod/RM で指定する。メモリから
データを読み書きする場合には「間接アドレッシングモード」を使い、元々の意図
としては次のようになっている。ただし、アセンブリ言語の使い方はとても自由で、
絶対この意味で使わなくてはいけないというわけではなく、元々、Intel も別の意味での
使い方も想定している。だから、言葉の意味とは違った使い方がされていることとがある。
そしてそれは悪いことではない。だから注意が必要:
[base + index * scale + offset]
base = ベースレジスタ(配列の先頭アドレスに当たる)。base は基盤。だから、先頭アドレスの意味になる。
index = インデックスレジスタ(配列の添え字に当たる)
scale = 1,2,4,8 ; スケールファクタ(配列の要素のバイト数にあたる)
offset = オフセットアドレス(ベースアドレスを少しずらす目的か、または、逆にこっちをベースアドレスにする使い方がある)
C 言語で、TYPE arr[N]; と宣言すると、TYPE 型を要素が N 個集まった配列が定義できる。
上記の間接アドレスで、scale は、sizeof(TYPE) とする事が想定されている。つまり、
arr[index] ---> [&arr + index * sizeof(TYPE)] のように置き換わり、
scale = sizeof(TYPE); の場合に相当する。だから、この場合も、index は紛れもなく配列の添え字である。
ただし、scale=1 に設定することで、index の部分にベースアドレスを指定することも出来るように
なるので、実際のアセンブリ言語では、index が添え字であるという元々の意味を超え、さまざまな使われ
方がされている。しかし、それは、index の言葉の意味が「添え字」である、という事を否定すること
にはならない。
33L
2019/02/04(月) 11:25:05.10ID:fEV2g5eo Z80 には、IX、IY という16BITレジスタがあり、
LD A,(IX + 4)
使い方が出来た。4 の部分は、8BIT の定数を指定する。
Z80のアドレス幅は16BITだったので、8BIT 値では、ベースアドレス
を指定することは出来ない。その意味では、IX は、配列の添え字ではなく、
先頭アドレスを指定するのがほぼ必須となっていた。
でもこれは、いまからずっと古い話で、どういう経緯かは分からないが、
index は、今では、99.9 % 位は、配列の添え字(文字の位置もここでは同義と
考える)という意味で使われるようになってきている。例えば、言語としては
C/C++ よりは新しい JS においても、indexOf() がある。これも文字の位置を
返す関数なので、配列の添え字と同一視する事が出来、index という言葉が、
やはり配列の添え字として使われていることが分かる。
最近では、配列とリンクリストの違いが分かってない人が増えているので、
index の意味を誤解する人が出てきているかもしれない。
LD A,(IX + 4)
使い方が出来た。4 の部分は、8BIT の定数を指定する。
Z80のアドレス幅は16BITだったので、8BIT 値では、ベースアドレス
を指定することは出来ない。その意味では、IX は、配列の添え字ではなく、
先頭アドレスを指定するのがほぼ必須となっていた。
でもこれは、いまからずっと古い話で、どういう経緯かは分からないが、
index は、今では、99.9 % 位は、配列の添え字(文字の位置もここでは同義と
考える)という意味で使われるようになってきている。例えば、言語としては
C/C++ よりは新しい JS においても、indexOf() がある。これも文字の位置を
返す関数なので、配列の添え字と同一視する事が出来、index という言葉が、
やはり配列の添え字として使われていることが分かる。
最近では、配列とリンクリストの違いが分かってない人が増えているので、
index の意味を誤解する人が出てきているかもしれない。
34L
2019/02/04(月) 11:34:20.94ID:fEV2g5eo >>1
>あと index には「指標」という意味がありますから、OS 等の動きや効率を計算して
>振る舞いを変えるための状況指示関数みたいなものを index と呼ぶ可能性もあります
Intel Manual や、Microsoft (MSDN Libydary など), JavaScript, Java, Ruby, Perl
などではそのような使い方がされることはないといっても過言ではない。
>あと index には「指標」という意味がありますから、OS 等の動きや効率を計算して
>振る舞いを変えるための状況指示関数みたいなものを index と呼ぶ可能性もあります
Intel Manual や、Microsoft (MSDN Libydary など), JavaScript, Java, Ruby, Perl
などではそのような使い方がされることはないといっても過言ではない。
35L
2019/02/04(月) 11:36:44.96ID:fEV2g5eo なお、誤解を与える前に書いておくと、これは、99%位、記憶に頼って書いている。
Mod/RM の部分は、100%脳内の記憶から書いた。
Mod/RM の部分は、100%脳内の記憶から書いた。
36L
2019/02/05(火) 01:17:05.71ID:1Lt6uOg9 >>6
[Wasm & Windows 共通 GUI Toolkit, with NWSC used]
http://nowsmartsoft.atwebpages.com/
↑ 別の無料サーバー(海外のもの) に置き直してみた。
[事情]
・>>6 で借りてる無料サーバーは、サーバー(Xrea)自体が
BitDefender Traffinc Light の BlackList に入ってしまっていて、「黄色」ランプ
になっていたので気になっていた。過去に この Xrea サーバーのバナー広告がトロイ
の木馬に感染してしまっていたらしい(当然だが、オイラとは全く関係ない)。
・新しいサーバーは、BitDefender Traffinc Light の BlackList に入ってないので
緑色のランプになっている。
[Wasm & Windows 共通 GUI Toolkit, with NWSC used]
http://nowsmartsoft.atwebpages.com/
↑ 別の無料サーバー(海外のもの) に置き直してみた。
[事情]
・>>6 で借りてる無料サーバーは、サーバー(Xrea)自体が
BitDefender Traffinc Light の BlackList に入ってしまっていて、「黄色」ランプ
になっていたので気になっていた。過去に この Xrea サーバーのバナー広告がトロイ
の木馬に感染してしまっていたらしい(当然だが、オイラとは全く関係ない)。
・新しいサーバーは、BitDefender Traffinc Light の BlackList に入ってないので
緑色のランプになっている。
2019/02/05(火) 15:47:24.76ID:1Lt6uOg9
Emscripten を使わずに、>>36 のビルドに成功。
分割コンパイル時の最後のリンク時間が速くならずに困っていたのが、
激速になった。また、出力される wasm、ランタイムの js、html のサイズが
小さくなり、ランタイムがシンプルになって何をやってるのかとても分かり
易くなった。ライブラリも何をやってるのか分かり易くなったしサイズも
激減したので、配布も楽になりそう。処理系もほぼ全てバイナリになったので
Python や node.js、Java などの処理系の配布も不要になった。
分割コンパイル時の最後のリンク時間が速くならずに困っていたのが、
激速になった。また、出力される wasm、ランタイムの js、html のサイズが
小さくなり、ランタイムがシンプルになって何をやってるのかとても分かり
易くなった。ライブラリも何をやってるのか分かり易くなったしサイズも
激減したので、配布も楽になりそう。処理系もほぼ全てバイナリになったので
Python や node.js、Java などの処理系の配布も不要になった。
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 小野田紀美・経済安保担当相「何か気に入らないことがあればすぐに経済的威圧をする国への依存はリスク」 ★2 [Hitzeschleier★]
- 【中国局長】両国関係に「深刻な影響」 首相発言の撤回要求 [蚤の市★]
- 日本行き空路49万件キャンセル 中国自粛呼びかけ 日本行きチケット予約の約32%に相当 ★2 [ぐれ★]
- 【インバウンド】中国人観光客の日本での消費額は年間約2兆円超…中国政府は公務員の出張取り消し [1ゲットロボ★]
- 外務省局長は無言で厳しい表情…日中の高官協議終了か 高市首相“台湾”発言で中国が強硬対応 発言撤回求めたか…★3 [BFU★]
- 【維新】吉村知事「中国人観光客だけに頼るビジネスモデル変えていかないといけない」「高市総理の発言は撤回する必要はない」 [Hitzeschleier★]
- 【高市速報】日本人の3割「中国への武力行使に踏み切る必要がある」ANN世論調査 [931948549]
- 高市「発言は撤回しない。謝罪もするな。外務省局長!任せたぞ。」👈なにをさせたかったの?😲 [826239858]
- 【実況】博衣こよりのえちえち歌枠🧪
- 外務省局長、よくわからないまま帰国へ [834922174]
- ぶっちゃけ普通の日本人は台湾とかどうでもよくて、野蛮な反日国中国が偉そうにするのがムカつく!という感情論だけだよね… [452836546]
- 自分に自信がない女の子、陽キャ美容室で80cmのエクステを付けた結果wwwwwwwwwwwwwwwwwww [329329848]
