<h2>WebAssembly与asm.js</h2>
<p>首先,让我们看看,原则上,<em>WebAssembly</em>与<em>asm.js</em>有何不同,以及是否有可能重用现有的知识和工具。以下是很好的概述:</p>
<ul>
<li><a href="http://webassembly.org/docs/faq/#why-create-a-new-standard-when-there-is-already-asmjs" rel="noreferrer">Why create a new standard when there is already asm.js?</a></li>
<li><a href="https://stackoverflow.com/q/31502563/2072035">What is the difference between asm.js and web assembly?</a></li>
<li><a href="https://hacks.mozilla.org/2017/03/why-webassembly-is-faster-than-asm-js/" rel="noreferrer">Why WebAssembly is Faster Than asm.js</a></li>
</ul>
<p>让我们概括一下,WebAssembly(MVP,因为有更多关于<a href="https://github.com/WebAssembly/design/blob/master/FutureFeatures.md" rel="noreferrer">its roadmap</a>的内容,大致如下):</p>
<ul>
<li>是具有静态类型的AST二进制格式,可以由现有的JavaScript引擎执行(因此可以使用JIT或编译AOT)</li>
<li>它比JavaScript紧凑10-20%(gzip比较),解析速度快一个数量级</li>
<li>它可以表示更多不符合JavaScript语法的低级操作,读取asm.js(例如64位整数、特殊CPU指令、SIMD等)</li>
<li>可以(在某种程度上)转换到/从asm.js。</li>
</ul>
<P>因此,目前WebAssembly是As.js上的迭代,而目标仅是C/C++。</p>
<h2>网络上的Python</h2>
<p>看起来GC并不是阻止Python代码瞄准WebAssembly/asm.js的唯一方法。两者都表示低级静态类型的代码,其中Python代码不能(实际地)表示。由于当前WebAssembly/asm.js的工具链是基于LLVM的,因此可以将一种易于编译为LLVM-IR的语言转换为WebAssembly/asm.js。但遗憾的是,Python的动态性太强,无法容纳它,PyPy的<a href="https://en.wikipedia.org/wiki/CPython#Unladen_Swallow" rel="noreferrer">Unladen Swallow</a>和<a href="http://rpython.readthedocs.io/en/latest/faq.html#could-we-use-llvm" rel="noreferrer">several attempts</a>证明了这一点。</p>
<p>这个asm.js演示文稿有<a href="http://kripken.github.io/mloc_emscripten_talk/" rel="noreferrer">slides about the state of dynamic languages</a>。它的意思是,目前只有将VM(语言实现在C/C++中)编译成WebSasMals/as.js,并用可能的JIT解释原始源。对于Python,有几个现有项目:</p>
<ol>
<li>PyPy:<a href="https://github.com/pypyjs/pypyjs" rel="noreferrer">PyPy.js</a>(作者的<a href="https://youtu.be/PiBfOFqDIAI" rel="noreferrer">talk at PyCon</a>)。这是<a href="https://github.com/pypyjs/pypyjs-release" rel="noreferrer">release repo</a>。JS主文件<code>pypyjs.vm.js</code>是13mb(在<code>gzip -6</code>之后是2MB)+Python stdlib+其他东西。</li>
<li>CPython:<a href="https://github.com/iodide-project/pyodide" rel="noreferrer">pyodide</a>,<a href="https://github.com/aidanhs/empython" rel="noreferrer">EmPython</a>,<a href="https://github.com/dgym/cpython-emscripten" rel="noreferrer">CPython-Emscripten</a>,<a href="https://github.com/PeachPy/EmCPython" rel="noreferrer">EmCPython</a>等,<code>empython.js</code>是5.8mb(在<code>gzip -6</code>之后是2.1MB),没有stdlib。</li>
<li><p>微蟒:<a href="https://github.com/matthewelse/micropython/tree/emscripten/emscripten" rel="noreferrer">this fork</a>。</p>
<p>那里没有生成的JS文件,所以我可以用<a href="https://hub.docker.com/r/trzeci/emscripten/" rel="noreferrer">^{<cd5>}</a>来生成它,这是一个现成的Emscripten工具链。类似于:</p>
<pre><code>git clone https://github.com/matthewelse/micropython.git
cd micropython
docker run --rm -it -v $(pwd):/src trzeci/emscripten bash
apt-get update && apt-get install -y python3
cd emscripten
make -j
# to run REPL: npm install && nodejs server.js
</code></pre>
<p>它产生1.1 MB的<code>micropython.js</code>(在<code>gzip -d</code>之后225 KB)。如果您只需要非常兼容的实现而不需要stdlib,那么后者已经是需要考虑的了。</p>
<p>要生成WebAssembly构建,可以将<code>Makefile</code>的第13行更改为</p>
<pre><code>CC = emcc -s RESERVED_FUNCTION_POINTERS=20 -s WASM=1
</code></pre>
<p>然后<code>make -j</code>产生:</p>
<pre><code>113 KB micropython.js
240 KB micropython.wasm
</code></pre>
<p>您可以查看<code>emcc hello.c -s WASM=1 -o hello.html</code>的HTML输出,了解如何使用这些文件。</p>
<p>这样,您还可以在WebAssembly中构建PyPy和CPython,以便在兼容的浏览器中解释Python应用程序。</p></li>
</ol>
<P>另一个潜在有趣的事情是<a href="http://nuitka.net/" rel="noreferrer">Nuitka</a>,一个Python到C++编译器。潜在地,可以将您的Python应用程序构建到C++,然后与Emscripten一起使用CPython编译它。但实际上我不知道该怎么做。</p>
<h2>解决方案</h2>
<p>目前,如果您正在构建一个传统的web站点或web应用程序,而下载几个兆字节的JS文件几乎不是一个选项,那么看看Python到JavaScript的transpiler(例如<a href="https://github.com/qquick/Transcrypt" rel="noreferrer">Transcrypt</a>)或JavaScript-Python实现(例如<a href="https://github.com/brython-dev/brython" rel="noreferrer">Brython</a>)。或者和<a href="https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS#python" rel="noreferrer">list of languages that compile to JavaScript</a>的其他人碰碰运气。</p>
<p>否则,如果下载大小不是问题,并且您已经准备好处理许多粗糙的边,请在以上三者之间进行选择。</p>