webassembly
WebAssembly is a very cool topic nowadays.
WebAssembly是当今一个非常酷的话题。
WebAssembly is a new low-level binary format for the web. It’s not a programming language you are going to write, but instead other higher level languages (at the moment C, Rust and C++) are going to be compiled to WebAssembly to have the opportunity to run in the browser.
WebAssembly是Web的一种新的低级二进制格式。 它不是您要编写的编程语言,而是将其他高级语言(目前为C,Rust和C ++)编译为WebAssembly,以便有机会在浏览器中运行。
It’s designed to be fast, memory-safe, and open.
它被设计为快速,内存安全和开放的。
You’ll never write code in WebAssembly (also called WASM) but instead WebAssembly is the low level format to which other languages are compiled to.
您永远不会在WebAssembly(也称为WASM)中编写代码,而WebAssembly是将其他语言编译成的低级格式。
It’s the second language ever to be understandable by Web Browsers, after the JavaScript introduction in the 90’s.
这是90年代JavaScript引入之后,Web浏览器可以理解的第二种语言。
WebAssembly is a standard developed by the W3C WebAssembly Working Group. Today all modern browsers (Chrome, Firefox, Safari, Edge, mobile browsers) and Node.js support it.
WebAssembly是W3C WebAssembly工作组开发的标准。 如今,所有现代浏览器(Chrome,Firefox,Safari,Edge,移动浏览器)和Node.js都支持它。
Did I say Node.js? Yes, because WebAssembly was born in the browser, but Node already supports it since version 8 and you can build parts of a Node.js application in any language other than JavaScript.
我是说Node.js吗? 是的,因为WebAssembly诞生于浏览器中,但是Node从版本8开始已经支持它,并且您可以使用JavaScript以外的任何语言来构建Node.js应用程序的一部分。
People that dislike JavaScript, or prefer writing in other languages, thanks to WebAssembly will now have the option to write parts of their applications for the Web in languages different than JavaScript.
借助WebAssembly,不喜欢JavaScript或更喜欢用其他语言编写的人现在可以选择使用不同于JavaScript的语言为Web编写应用程序的一部分。
Be aware though: WebAssembly is not meant to replace JavaScript, but it’s a way to port programs written in other languages to the browser, to power parts of the application that are either better created in those languages, or pre-existing.
但是请注意: WebAssembly并不是要替换JavaScript ,而是将用其他语言编写的程序移植到浏览器的一种方法,以增强应用程序中那些用这些语言创建或已存在的部分。
JavaScript and WebAssembly code interoperate to provide great user experiences on the Web.
JavaScript和WebAssembly代码可以互操作,以在Web上提供出色的用户体验。
It’s a win-win for the web, since we can use the flexibility and ease of use of JavaScript and complement it with the power and performance of WebAssembly.
这是Web上的双赢,因为我们可以利用JavaScript的灵活性和易用性,并通过WebAssembly的功能和性能对其进行补充。
WebAssembly code runs in a sandboxed environment, with the same security policy that JavaScript has, and the browser will ensure same-origin and permissions policies.
WebAssembly代码在沙盒环境中运行,具有与JavaScript相同的安全策略,浏览器将确保同源策略和权限策略。
If you are interested in the subject I recommend to read Memory in WebAssembly and the Security docs of webassembly.org.
如果您对该主题感兴趣,建议阅读WebAssembly中的Memory和webassembly.org的安全性文档 。
WebAssembly was designed for speed. Its main goal is to be really, really fast. It’s a compiled language, which means programs are going to be transformed to binaries before being executed.
WebAssembly专为提高速度而设计。 它的主要目标是真正,非常快。 这是一种编译语言,这意味着程序将在执行之前转换为二进制文件。
It can reach performance that can closely match natively compiled languages like C.
它可以达到可以与本地编译语言(如C)紧密匹配的性能。
Compared to JavaScript, which is a dynamic and interpreted programming language, speed cannot be compared. WebAssembly is always going to beat JavaScript performance, because when executing JavaScript the browser must interpret the instructions and perform any optimization it can on the fly.
与JavaScript(一种动态的解释型编程语言)相比,速度是无法比较的。 WebAssembly总是会击败JavaScript性能,因为执行JavaScript时,浏览器必须解释指令并进行动态优化。
Is WebAssembly ready for use? Yes! Many companies are already using it to make their products better on the Web.
WebAssembly可以使用了吗? 是! 许多公司已经在使用它来改善他们在Web上的产品。
A great example you probably already used is Figma, a design application which I also use to create some of the graphics I use in the day-to-day work. This application runs inside the browser, and it’s really fast.
您可能已经使用的一个很好的例子是Figma ,这是一个设计应用程序,我还使用它来创建我在日常工作中使用的一些图形。 该应用程序在浏览器中运行,并且速度非常快。
The app is built using React, but the main part of the app, the graphics editor, is a C++ application compiled to WebAssembly, rendered in a Canvas using WebGL.
该应用程序是使用React构建的,但该应用程序的主要部分(图形编辑器)是编译为WebAssembly的C ++应用程序,并使用WebGL在Canvas中呈现。
In early 2018 AutoCAD released its popular design product running inside a Web App, using WebAssembly to render its complex editor, which was built using C++ (and migrated from the desktop client codebase)
在2018年初,AutoCAD发布了其流行的设计产品,该产品在Web App内运行,使用WebAssembly渲染其复杂的编辑器,该编辑器是使用C ++构建的(并从桌面客户端代码库中迁移过来)
The Web is not a limiting technology any more for those products that require a very performant piece to their core.
对于那些需要非常高性能的产品而言,Web不再是一种限制技术。
C and C++ applications can be ported to WebAssembly using Emscripten, a toolchain that can compile your code to two files:
可以使用Emscripten将C和C ++应用程序移植到WebAssembly,该工具链可以将您的代码编译为两个文件:
a .wasm
file
.wasm
文件
a .js
file
.js
文件
where the .wasm
file contains the actual WASM code, and the .js
file contains the glue that will allow the JavaScript code to run the WASM.
其中.wasm
文件包含实际的WASM代码,而.js
文件包含将允许JavaScript代码运行WASM的粘合。
Emscripten will do a lot of work for you, like converting OpenGL calls to WebGL, will provide bindings for the DOM API and other browsers and device APIs, will provide filesystem utilities that you can use inside the browser, and much more. By default those things are not accessible in WebAssembly directly, so it’s a great help.
Emscripten将为您做很多工作,例如将OpenGL调用转换为WebGL,将为DOM API和其他浏览器和设备API提供绑定,将提供可在浏览器内部使用的文件系统实用程序,等等。 默认情况下,这些东西不能直接在WebAssembly中访问,所以这是一个很大的帮助。
Rust code is different, as it can be directly compiled to WebAssembly as its output target, and there’s an https://developer.mozilla.org/en-US/docs/WebAssembly/Rust_to_wasm.
Rust代码有所不同,因为它可以直接编译为WebAssembly作为其输出目标,并且有一个https://developer.mozilla.org/zh-CN/docs/WebAssembly/Rust_to_wasm 。
WebAssembly is now at version 1.0. It currently officially supports only 3 languages (C, Rust, C++) but many more are coming. Go, Java and C# cannot currently be (officially) compiled to WebAssembly because there is no support for garbage collection yet.
WebAssembly现在是1.0版。 目前,它仅正式支持3种语言(C,Rust,C ++),但还会有更多语言支持。 Go,Java和C#当前无法(正式)编译为WebAssembly,因为尚不支持垃圾回收。
When making any call to browser APIs using WebAssembly you currently need to interact with JavaScript first. There is work in progress to make WebAssembly a more first class citizen in the browser and make it able to call DOM, Web Workers or other browser APIs directly.
当前使用WebAssembly调用浏览器API时,您当前首先需要与JavaScript进行交互。 正在使WebAssembly在浏览器中成为更高级的公民,并使其能够直接调用DOM,Web Workers或其他浏览器API的工作正在进行中。
Also, there is work in progress to be able to make JavaScript code being able to load WebAssembly modules, through the ES Modules specification.
另外,正在通过ES模块规范使JavaScript代码能够加载WebAssembly模块的工作正在进行中。
Install Emscripten by cloning the emsdk
GitHub repo:
通过克隆emsdk
GitHub存储库安装Emscripten:
git clone https://github.com/juj/emsdk.git
then
然后
dev cd emsdk
Now, make sure you have an up to date version of Python installed. I had 2.7.10 and this caused a TLS error.
现在,请确保您已安装最新版本的Python。 我有2.7.10,这导致了TLS错误。
I had to download the new one (2.7.15) from https://www.python.org/getit/ install it and then run the Install Certificates.command
program that comes with the installation.
我必须从https://www.python.org/getit/下载新版本(2.7.15),然后运行Install Certificates.command
随附的Install Certificates.command
程序。
Then
然后
./emsdk install latest
let it download and install the packages, then run
让它下载并安装软件包,然后运行
./emsdk activate latest
and add the paths to your shell by running:
并通过运行以下命令将路径添加到您的shell:
source ./emsdk_env.sh
I am going to create a simple C program and I want it to execute inside the browser.
我将创建一个简单的C程序,并希望它在浏览器中执行。
This is a pretty standard “Hello World” program:
这是一个非常标准的“ Hello World”程序:
#include
int main(int argc, char ** argv) {
printf("Hello World\n");
}
You could compile it using:
您可以使用以下命令进行编译:
gcc -o test test.c
and running ./test
would print “Hello World” to the console.
并运行./test
会将“ Hello World”打印到控制台。
Let’s compile this program using Emscripten to run it in the browser:
让我们使用Emscripten编译该程序以在浏览器中运行它:
emcc test.c -s WASM=1 -o test.html
Emscripten gave us a html page that already wraps the WebAssembly program compiled, ready to run. You need to open it from a web server though, not from the local filesystem, so start a local web server, for example the http-server
global npm package (install it using npm install -g http-server
if you don’t have it installed already). Here it is:
Emscripten给了我们一个HTML页面,该页面已经包装了已编译的WebAssembly程序,可以运行了。 不过,您需要从Web服务器而不是本地文件系统中打开它,因此请启动本地Web服务器,例如http-server
全局npm软件包(如果没有,请使用npm install -g http-server
进行安装)它已经安装)。 这里是:
As you can see, the program ran and printed “Hello World” in the console.
如您所见,该程序已运行并在控制台中打印了“ Hello World”。
This was one way to run a program compiled to WebAssembly. Another option is to make a program expose a function you are going to call from JavaScript.
这是运行编译为WebAssembly的程序的一种方法。 另一种选择是使程序公开要从JavaScript调用的函数。
Let’s tweak the Hello World defined previously.
让我们调整之前定义的Hello World。
Include the emscripten
headers:
包括emscripten
标题:
#include
and define an hello
function:
并定义一个hello
函数:
int EMSCRIPTEN_KEEPALIVE hello(int argc, char ** argv) {
printf("Hello!\n");
return 8;
}
EMSCRIPTEN_KEEPALIVE
is needed to preserve the function from being automatically stripped if not called from main()
or other code executed at startup (as the compiler would otherwise optimize the resulting compiled code and remove unused functions - but we’re going to call this dynamically from JS, and the compiler does now know this).
如果不从main()
或启动时执行的其他代码中调用该函数,则需要EMSCRIPTEN_KEEPALIVE
来防止该函数被自动剥离(因为否则编译器会优化生成的编译后的代码并删除未使用的函数-但我们将从JS,并且编译器现在知道这一点)。
This little function prints Hello! and returns the number 8.
这个小功能可以打印Hello! 并返回数字8。
Now if we compile again using emcc
:
现在,如果我们再次使用emcc
编译:
emcc test.c -s WASM=1 -o test.html -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap']"
This time we added a EXTRA_EXPORTED_RUNTIME_METHODS
flag to tell the compiler to leave the ccall
and cwrap
functions on the Module object, which we’ll use in JavaScript.
这次,我们添加了EXTRA_EXPORTED_RUNTIME_METHODS
标志,以告知编译器将ccall
和cwrap
函数保留在Module对象上,这将在JavaScript中使用。
Now we can fire up the Web Server again and once the page is open call Module.ccall('hello', 'number', null, null)
in the console, and it will print “Hello!” and return 8:
现在,我们可以再次启动Web服务器,并在打开页面后在控制台中调用Module.ccall('hello', 'number', null, null)
,它将显示“ Hello!”。 并返回8:
The 4 parameters that Module.ccall
takes are the C function name, the return type, the types of the arguments (an array), and the arguments (also an array).
Module.ccall
接受的4个参数是C函数名称,返回类型,参数的类型(数组)和参数(也是数组)。
If our function accepted 2 strings as parameters, for example, we would have called it like this:
例如,如果我们的函数接受2个字符串作为参数,则我们将这样调用它:
Module.ccall('hello', 'number', ['string', 'string'], ['hello', 'world'])
The types we can use are null
, string
, number
, array
, boolean
.
我们可以使用的类型为null
, string
, number
, array
, boolean
。
We can also create a JavaScript wrapper for the hello
function by using the Module.cwrap
function, so that we can call the function as many times we want by using the JS counterpart:
我们还可以使用Module.cwrap
函数为hello
函数创建一个JavaScript包装器,以便我们可以使用JS对应对象多次调用该函数:
const hello = Module.cwrap('hello', number, null, null)
Here’s the official docs for ccall
and cwrap
.
这是ccall
和cwrap
的官方文档 。
翻译自: https://flaviocopes.com/webassembly/
webassembly