Asm.js的简单介绍


Asm.js简介

早前流行的JavaScript将会统治世界这个梗,很好的说明了JavaScript的将来,能用JavaScript书写的都会用JavaScript来进行书写,不过JavaScript的弱类型是其被黑性能的很大不一部分,而为了解决由其他强类型语言【c++、Java】等转换为JavaScript的困扰时,各大浏览器尝试进行了不同的尝试,其中Mozilla的Asm.js最为突出,
Asm.js 来自于 JavaScript 应用的一个新领域: 编译成JavaScript的C/C++应用. 它是 JavaScript 应用的一个全新流派,由 Mozilla 的 Emscripten项目催生而来。
Emscripten 将 C/C++ 代码传入 LLVM, 并将 LLVM生成的字节码转换成 JavaScript (具体的,
Asm.js, 是 JavaScript 的一个子集).
asm.js不是一种新的语言,而是JS语法的一个子集,也就是说所有用asm.js写的程序都是合法的JS程序,asm.js与JS语言的关系有点类似C与C++的关系。因此,不支持asm.js的浏览器或JS引擎也可以无误地执行asm.js的代码。asm.js顾名思义是作为JS的汇编语言来设计的,它的语法手写起来非常困难,且难以阅读。首先,asm.js的语法利用了一些标注让JS的变量成为强类型的,这些标注与Emscripten生成的代码如出一辙,实际上asm.js的产生就是为了提高Emscripten转换后的代码执行效率的。

Asm.js实践

准确的来说,目前我们还无法来完整的使用这个功能,因为仅仅https://www.mozilla.org/zh-CN… 只有他支持asm.js,当然前文也说了,即使不支持的浏览器也可以执行,因为本质上Asm.js就是JavaScript,只不过这样书写的js的性能和可读性都不如正常书写的JavaScript,所以没有意义,asm.js本来也是不希望程序员去书写,而是JavaScript扩展到其他领域的可能,通过将c/c++的应用程序转换为Asm.js的程序,就可以在web平台跑了,
至于怎么运行的,官网上有一张图片:
Asm.js的简单介绍
由于asm.js相当于支持了强类型,因此可以直接对应编译成机器指令执行。asm.js的代码采用另外一套AOT(Ahead Of Time)编译器,将asm.js代码预先编译成机器指令,在编译过程或运行过程中,一旦发现语法错误或违反类型标记的情况出现,便重新将代码交予JS引擎解析执行。

Asm.js的本质

从本质上来说Asm.js不是新的语言,是一种新的JavaScript的使用场景、领域,他的语法都是JavaScript的语法,实现的过程就是:

  1. 使用各种黑白膜法【位运算、注解、检测】来实现了强类型;

  2. 通过各类工具【Emscripten】来将其他语言转换为asm.js格式的js,可在web平台执行;

  3. 通过浏览器的js引擎的支持,将asm.js编译成更为底层的机器码来加提高js的性能;

  4. 同时也要兼容,变异的机器码需要动态检测是引擎否能够支持这种机器码,不能就转到js执行,这样的话性能并没有提高。
    准确的说Asm.js都是编译而来的机器码,但是可以根据web平台的js引擎来进行【机器码–JavaScript】的切换动作,从而兼容其他web平台。

最后列一段真是的编译后的Asm.js模块代码:

function GeometricMean(stdlib, foreign, buffer) {
  "use asm";

  var exp = stdlib.Math.exp;
  var log = stdlib.Math.log;
  var values = new stdlib.Float64Array(buffer);

  function logSum(start, end) {
    start = start|0;
    end = end|0;

    var sum = 0.0, p = 0, q = 0;

    // asm.js forces byte addressing of the heap by requiring shifting by 3
    for (p = start << 3, q = end << 3; (p|0) < (q|0); p = (p + 8)|0) {
      sum = sum + +log(values[p>>3]);
    }

    return +sum;
  }

  function geometricMean(start, end) {
    start = start|0;
    end = end|0;

    return +exp(+logSum(start, end) / +((end - start)|0));
  }

  return { geometricMean: geometricMean };
}

参考:网友解读:https://software.intel.com/zh…
官网:http://asmjs.org/spec/latest/
githu地址 https://github.com/dherman/as…
很赞的文章 http://www.oschina.net/transl…


发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>