最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • WebAssembly 初探

    正文概述 掘金(xfz)   2020-12-29   908

    wasm 现状

    • 目前主要应用在对性能要求较高的应用中、VR、游戏
    • 从前端角度来看,并没有广泛使用,但各大厂对wasm比较积极,相信不远的将来wasm将得以广泛应用,
      • 因此学一门后端语言非常重要,C/C++/go/python,建议学习python或go,python较其他语言较容易入门,不过本人更倾向go,不想干前端了就去做后端~
    • wasm体验

    wasm 特点

    • 标准
      • WebAssembly 在 web 中被设计成无版本、特性可测试、向后兼容,
      • wasm可以被js调用,进入js上下文,也可以像Web API 一样调用浏览器功能
      • wasm即可以运行在浏览器也可以诶运行在非web环境
    • 高效
      • WebAssembly 有一套完整的语义,wasm 是体积小且加载快的二进制格式,其目标就是充分发挥硬件能力已达到原生的执行效率
    • 安全
      • wasm 运行在一个沙箱化的执行环境中,甚至可以在现有的js虚拟机中实现
      • 在web环境中,wasm 严格遵守同源策略和浏览器安全策略
    • 开放
      • wasm 设计了一个非常规整的文本格式,可以以这种文本格式在web页面上查看wasm模块的源码

    WebAssembly 初探

    wasm vs js

    WebAssembly 初探

    • wasm 在开发过程中就将 Parse 前置了
    • wasm 没有GC,wasm GC与V8 GC 不是一回事,它有独立的内存空间,由代码进行管理,因此开发要注意内存问题

    性能问题

    例如:递归Fibonacci 函数,wasm vs js WebAssembly 初探

    wasm 开发工具

    环境准备

    • 安装 gcc 编译环境
    • 安装 g++ 编译环境
    • 安装 xcode
    • 安装 cmake
    • emscripten:wasm 的灵魂工具,将其他高级语言编译成 wasm,针对后端语言
    • AssemblyScript: 支持直接将 Typescript 编译成 wasm。类似ts语法,但它可不是typescript,不建议使用(可选)
    • WABT: 将wasm在字节码和文本格式相互转换的一个工具,方便开发时理解wasm底层(可选)

    Javascript API

    • 方法

    -- WebAssembly.compile() 将 wasm 编译成 v8可以执行的代码 -- WebAssembly.instantiate() 实例化 -- WebAssembly.validate() 验证包含 wasm 二进制码的一个 typed array 是否合法

      • WebAssembly.Module 模块
      • WebAssembly.Instance 实例
      • WebAssembly.Memory 内存空间
      • WebAssembly.Table 是JavaScript包装器对象-一种表示WebAssembly表的类似数组的结构,该表存储函数引用。由JavaScript或WebAssembly代码创建的表将可以从JavaScript和WebAssembly访问并可变
      • WebAssembly.CompileError 编译时错误
      • WebAssembly.LinkError 实例化时错误
      • WebAssembly.RuntimeError 运行时错误

    C 编写 wasm

    实现一个 Hello world

    /**
     * 编译可执行文件
     * gcc hello.c -o hello
     * 执行可执行程序
     * ./hello
     * 输出 hello world!
     */
    
    /**
     * 编译成wasm
     * emcc hello.c -o hello.js,生成 hello.js 和 hello.wasm
     * 执行wasm
     * node hello.js
     * 输出 hello world!
     */
    
    #include <stdio.h> // 引入标准输入输出库
    
    int main()
    {
      printf("hello world!\n");
      return 0;
    }
    

    生成可在浏览器中运行的 wasm

    /**
     * 编译命令 按照wasm的模式以模块的形式输出 math.wasm
     * emcc math.c -Os -s WASM=1 -s SIDE_MODULE=1 -o math.wasm
     */
    
    int add(int x, int y)
    {
      return x + y;
    }
    
    int square(int x)
    {
      return x * x;
    }
    

    创建 index.html 页面在浏览器中调用 wasm对象

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
    </head>
    
    <body>
      <script>
        /**
          * @param {String} path wasm 文件路径
          * @param {Object} imports 传递到 wasm 代码中的变量
        */
        function loadWebAssembly(path, imports = {}) {
          return fetch(path) // 加载文件
            .then(response => response.arrayBuffer()) // 转成 ArrayBuffer
            .then(buffer => WebAssembly.compile(buffer))
            .then(module => {
              imports.env = imports.env || {}
    
              // 开辟内存空间
              imports.env.memoryBase = imports.env.memoryBase || 0
              if (!imports.env.memory) {
                imports.env.memory = new WebAssembly.Memory({ initial: 256 })
              }
    
              // 创建变量映射表
              imports.env.tableBase = imports.env.tableBase || 0
              if (!imports.env.table) {
                // 在 MVP 版本中 element 只能是 "anyfunc"
                imports.env.table = new WebAssembly.Table({ initial: 0, element: 'anyfunc' })
              }
    
              // 创建 WebAssembly 实例
              return new WebAssembly.Instance(module, imports)
            })
        }
        //调用
        loadWebAssembly('./math.wasm')
          .then(instance => {
            const add = instance.exports.add //取出c里面的方法
            const square = instance.exports.square //取出c里面的方法
    
            console.log('10 + 20 =', add(10, 20))
            console.log('3*3 =', square(3))
            console.log('(2 + 5)*2 =', square(add(2 + 5)))
          })
      </script>
    </body>
    
    </html>
    

    控制台输出:

    WebAssembly 初探

    ❤️ 加入我们

    字节跳动 · 幸福里团队

    Nice Leader:高级技术专家、掘金知名专栏作者、Flutter中文网社区创办者、Flutter中文社区开源项目发起人、Github社区知名开发者,是dio、fly、dsBridge等多个知名开源项目作者

    期待您的加入,一起用技术改变生活!!!

    招聘链接: job.toutiao.com/s/JHjRX8B


    起源地下载网 » WebAssembly 初探

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元