Preliminary exactly webAssembly series --webAssembly

I. Introduction

Since the beginning of the birth of JavaScript, to now become a popular programming language, behind web development promoted. web applications become more complex, but gradually exposed the problem of JavaScript:

(1) grammar too flexible lead to the development of large-scale web projects difficult;

(2) lack of performance to meet the needs of some of the scenes.

 

Second, why the need WebAssembly

To solve the above problems, JavaScript language there are some in place, such as:

(1) Microsoft TypeScript to improve js loose syntax by JS adding static type checking mechanism to enhance the robustness of the code.

(2) Google's Dart is introducing a new virtual machine for the browser to run directly Dart program to improve performance.

(3) Firefox asm.js is taking a subset of the JS, JS engine for asm.js do performance optimization.

Try more advantages and disadvantages. among them:

(1) TypeScript only solve the problem of loose syntax JS, JS finally needs to be compiled to run into, the performance did not improve.

(2) Dart can run in chrome preview version, no major browsers support Dart much with the development of people.

(3) asm.js grammar too simple, there are very limited, open discovery rate.

Big Three browsers are proposed their own solutions, complementary compatible, contrary to the purpose of the web, is a unified specification allows web go today, so if a new set of norms to solve the problems faced by JS would be great .

So webAssembly appeared, webAssembly is a new bytecode format, the mainstream browsers already support webAssembly . JS and perform different interpretation is required, and the underlying machine code bytecode webassembly very similar fast loading operation, thus the performance with respect to the JS interpreted greatly enhanced. That webAssembly is not a programming language, but a byte code standards, the need to compile the bytecode into webAssembly virtual machine to run high-level language, browser vendors need to do is to implement a virtual machine specification according to webAssembly .

 

Three, webAssembly principle

To find out webAssembly principle, we need to figure out how computers run.

 

By computer electronic components, in order to facilitate processing electronics there are only two states opened and closed, for 1 and 0, which is known only to the computer 1 and 0, and the data represented by logic 1 and 0 need, i.e. directly loaded into the machine code running on a computer. Machine code unreadable, so people through high-level language c, c ++, Java, Go and other written and then compiled into machine code.

 

Because different computer CPU architecture, the machine code standards different, common CPU architectures, including X86, AMD64, ARM, it is necessary to specify the target architecture when programming a high level programming language into a self-code.

 

webassembly erase the bytecode is a machine code different architectures, webassembly bytecode not directly run on any CPU architecture, but due to the very close to the machine code, can very quickly be translated into machine code corresponding to the architecture Therefore webAssembly speed close to the machine code, it sounds very much like java bytecode.

 

With respect JS, webAssembly has the following advantages:

(1) Small size. Since only the loading of the compiled byte code executed on the browser, the same logic is much smaller than the volume of the JS file description string.

(2) load faster. Due to the small file size, coupled with the need to explain the implementation, webAssembly faster to load and instantiate reduce the waiting time before the operation.

(3) fewer compatibility issues. webAssembly is a very low-level byte code specification, developed after little change is good, even if changes occur, just from high-level language compiled into byte code compatible with the process of doing. JS compatibility issues that may arise and webAssembly is bridged JS interface.

 

Each high-level language source code to achieve conversion work machine code to different platforms is repetitive, high-level language only need to generate intermediate language underlying virtual machine (LLVM) know (LLVM IR), LLVM can achieve:

(1) LLVM IR different CPU architectures to generate machine code.

(2) performance and to optimize the size of the machine code compilation.

 

In addition LLVM compiler also achieved LLVM IR function to webAssembly byte code, which means that as long as high-level language can be converted into LLVM IR, webAssembly can be compiled into bytecode, currently compiles bytecode level language webAssembly Have:

(1) AssemblyScript : grammar and TypeScript consistent, low-cost front-end for learning, for the front-end write webAssembly best choice.

(2) c \ c ++: official recommended way to see the detailed document .

(3) Rust : grammar complex, high learning costs, to the front end, it could not meet. For details see the use of the document .

(4) Kotlin : grammar and java, js very similar, low cost language learning, see detailed document .

(5) golang : grammar simple, low-cost learning. But for webAssembly still not officially released in stages, see detailed document .

 

Usually responsible for high-level language to translate portions of LLVM IR is called a compiler front-end, the LLVM IR compiled into machine code corresponding to the portion of each CPU architecture is called a compiler back end; now more and more high-level programming language selection LLVM as a backend, high-level language just focus on how to provide greater development efficiency while maintaining the grammar translation into LLVM IR program execution performance.

 

Fourth, write webAssembly

4.1 Why AssemblyScript as webAssembly development language

AssemblyScript compared to other languages ​​C, rust, etc. to write webAssembly, the advantage is: For front-end for no additional cost to learn a new language, and does not support webAssembly browser can be compiled by TypeScript compiler can perform normal for JS code. Thereby to achieve a smooth transition from webAssembly of JS.

 

4.2 Construction of access webpack

Any new web development technologies and ultimately, to build, in order to provide a smooth webAssembly development process, then began to introduce webpack concrete steps.

1, the installation-dependent, so that TS AssemblyScript source is compiled into webAssembly.

{
  "devDependencies": {
    "assemblyscript": "github:AssemblyScript/assemblyscript",
    "assemblyscript-typescript-loader": "^1.3.2",
    "typescript": "^2.8.1",
    "webpack": "^3.10.0",
    "webpack-dev-server": "^2.10.1"
  }
}

 

2, modify webpack.config.js, join loader.

module.exports = {
    module: {
        rules: [
            {
                test: /\.ts$/,
                loader: 'assemblyscript-typescript-loader',
                options: {
                    sourceMap: true,
                }
            }
        ]
    },
};

 

3, modify typeScript compiler configuration tsconfig.json, so that the compiler can support AssemblyScript typeScript introduced built-in types and functions.

{
  "extends": "../../node_modules/assemblyscript/std/portable.json",
  "include": [
    "./**/*.ts"
  ]
}

 

4, configuration directly inherited from AssemblyScript built-in configuration file.

 

Five, webAssembly tools

In addition to the above-mentioned webAssembly binary toolbox , webAssembly community as well as the frequently used tools:

(. 1) Emscripten : Can c, c ++ code into wasm, asm.js.

(2) Binaryen : providing a simpler IR, IR converted into WASM, and provides WASM when optimizing compiler, the virtual machine WASM, WASM compression capabilities, the aforementioned AssemblyScript is based on his.

 

六、webAssembly  JS API

Currently webAssembly only through js to load and execute, but the future may be as a browser to load and execute webAssembly load by as JS, JS Here's how to call webAssembly.

JS tone WebAssembly divided into 3 major step: loading bytecode> bytecode compiler> instantiated , acquired by JS WebAssembly instance to call after the above step 3 specific operation is:

1, for the browser to request the network loading bytecode , the bytecode for nodejs can read files fs module;

2, after obtaining the byte code needs to be compiled after conversion into ArrayBuffer, by webAssembly API by JS  webAssembly.compile will be a Promise resolve compiled by webAssembly.module , this module is required can not be called directly.

3, after obtaining module need webAssembly.instance  the API module to instantiate, acquired instance after JS module can be used like a call.

 

One of the steps 2 and 3 can be combined in one step, the previously mentioned  WebAssembly.instantiate  to do both of these things.

WebAssembly.instantiate(bytes).then(mod=>{
  mod.instance.f(50);
})

 

Seven, webAssembly call JS

The previous example is to use JS to call WebAssembly module, but may need to call in WebAssembly browser API module under some scenarios, the following describes how to call the JS in WebAssembly.

WebAssembly.instantiate function supports a second argument WebAssembly.instantiate (bytes, importObject), this effect importObject parameter is passed WebAssembly you need to call JS JS JS module of the WebAssembly. By way of specific example, the foregoing transformation computing Fibonacci sequence is invoked Web window.alert function in the calculated result in WebAssembly pop, which requires loading WebAssembly JS code transformation module:

WebAssembly.instantiate(bytes,{
  window:{
    alert:window.alert
  }
}).then(mod=>{
  mod.instance.f(50);
})

Corresponding also need to modify the source code written in AssemblyScript:

// 声明从外部导入的模块类型
declare namespace window {
    export function alert(v: number): void;
}
 
function _f(x: number): number {
    if (x == 1 || x == 2) {
        return 1;
    }
    return _f(x - 1) + _f(x - 2)
}
 
export function f(x: number): void {
    // 直接调用 JS 模块
    window.alert(_f(x));
}

AssemblyScript above modified source code re-use by wast asc asc f.ts command file to compile more than a few lines of output than before:

(import "window" "alert" (func $src/asm/module/window.alert (type 0)))
 
(func $src/asm/module/f (type 0) (param f64)
    get_local 0
    call $src/asm/module/_f
    call $src/asm/module/window.alert)

This extra logic is part of code wast JS in the incoming call AssemblyScript the module.

In addition to these common API, WebAssembly also provide some API, you can use this  d.ts file to see all the details of WebAssembly JS API.

 

Eight, more than just a browser

webAssembly bytecode as an underlayer, in addition to outer running in a browser, but also in other operating environments.

1, direct execution wasm binary file

The aforementioned Binaryen provides the tools to perform wasm binaries directly on the command line, after at Mac systems brew install binaryen successful installation, you can run directly by wasm-shell f.wasm file

2, running in nodejs

Currently V8 JS engine has added support for the WebAssembly, Chrome, and Node.js are used as a V8 engine, so WebAssembly can also run in Node.js environment;

V8 JS engine, WebAssembly and JS is executed when WebAssembly run in the same virtual machine, rather than WebAssembly runs in a separate virtual machine, so easy to achieve mutual calls between JS and WebAssembly.

The above examples make running Node.js can use the following code:

const fs = require('fs');
 
function toUint8Array(buf) {
    var u = new Uint8Array(buf.length);
    for (var i = 0; i < buf.length; ++i) {
        u[i] = buf[i];
    }
    return u;
}
 
function loadWebAssembly(filename, imports) {
    // 读取 wasm 文件,并转换成 byte 数组
    const buffer = toUint8Array(fs.readFileSync(filename));
    // 编译 wasm 字节码到机器码
    return WebAssembly.compile(buffer)
        .then(module => {
            // 实例化模块
            return new WebAssembly.Instance(module, imports)
        })
}
 
loadWebAssembly('../temp/assembly/module.wasm')
    .then(instance => {
        // 调用 f 函数计算
        console.log(instance.exports.f(10))
    });

Meaning WebAssembly run in Nodejs environment will be negligible, because Nodejs support native module to run, while the native module performance is better than WebAssembly . If you are by C, Rust to write WebAssembly, you can be compiled directly into native module Nodejs can call.

 

Nine, webAssembly outlook

The above content is visible from WebAssembly mainly to solve the performance bottleneck JS, that is suitable for applications that require WebAssembly scene compute-intensive , such as:

(1) processing of audio and video in the browser, flv.js  after use WebAssembly rewrite performance will be greatly improved;

(2) react dom diff a large number of calculations involved, react with the core module webAssembly rewriting can improve performance. JS engine JavaScriptCore safari browser has also been used to support webAssembly, RN can also enhance application performance.

(3) major breakthrough in 3D web game performance bottlenecks, egrets engines have begun to explore the use webassembly .

 

X. summary

Although the standard has been finalized and WebAssembly been achieved mainstream browsers, but there are the following problems:

(1) browser compatibility is not good, only the latest version of browser support, and different browsers JS webAssembly mutually inconsistent tone API support.

(2) the ecological imperfect tool immature, you can not find a smooth writing experience webAssembly language, are still in a preliminary stage.

(3) learning little information, but also need more people to explore mining pit.

In short WebAssembly not too mature now, if your team is not performance issues intolerable, now use WebAssembly into the product is not the time, because this may affect the efficiency of the development team, or come across the pit can not be easily resolved blocked development.

 

XI reference

1、http://www.ruanyifeng.com/blog/2017/09/asmjs_emscripten.html

2、https://www.ibm.com/developerworks/cn/opensource/os-cn-clang/index.html

3、https://developer.mozilla.org/zh-CN/docs/WebAssembly/Understanding_the_text_format

4、https://developer.mozilla.org/zh-CN/docs/WebAssembly/Using_the_JavaScript_API

 

[Thank reading and subsequent starting new articles: sau exchange learning communities: https://www.mwcxs.top/ ]

Guess you like

Origin blog.csdn.net/saucxs/article/details/91967925