【问题标题】:What "use asm" does exactly?“使用asm”到底是做什么的?
【发布时间】:2014-05-03 19:21:06
【问题描述】:

据我所知,Asm.js 只是对 JavaScript 的严格规范,它使用了 JavaScript 的特性,并不是一门新语言。

例如,它不使用var a = e;,而是提供var a = e|0;

我的问题是,如果 asm.js 只是一个定义,可以通过改变使用和声明变量和动态类型的方式来实现,那么 "use asm"; 究竟做了什么?是否需要在声明函数体之前放置这个字符串?

【问题讨论】:

  • 这是一个声明,让受支持的 JS 引擎知道您提供 asm.js 优化代码的意图,因此会尝试这些优化。我想我记得听说 V8 在没有声明的情况下实现了这些优化。不过不确定。
  • 您应该在这里阅读 ASM 以更好地理解它。 ejohn.org/blog/asmjs-javascript-compile-target
  • @cookiemonster 我无法通过优化理解你的意思。开发人员创建的这种优化,对吗?看看我在问题中写的按位运算。
  • 不,引擎本身提供的优化。这些优化需要非常具体的语法,需要由开发人员编写(或者更有可能由代码生成器生成)。在不支持此类优化的实现中,代码可能会比以典型方式编写的 JS 代码运行得慢。
  • 就像“使用严格”,严格的JS也是常规JS的子集。因此,您告诉引擎(以向后兼容的方式)您正在使用该子集,并且可以遵循稍微不同的规则

标签: javascript emscripten asm.js


【解决方案1】:

Asm.js 是 JavaScript 的一个非常严格子集,它针对机器而非人类进行了优化。如果您希望您的浏览器将某些代码解释为 asm.js 代码,您需要创建一个适用以下条件的模块:

  • 所有代码都是完全静态类型的,并且仅限于非常严格的 asm.js JavaScript 子集
  • 您的模块以"use asm" pragma 开头

此外,asm.js 模块最多只允许三个可选但非常具体的参数:

  • 标准库对象,提供对 JavaScript 标准库子集的访问
  • 外部函数接口 (FFI),提供对自定义外部 JavaScript 函数的访问
  • 一个堆缓冲区,提供一个 ArrayBuffer 来充当 asm.js 堆

所以,你的模块基本上应该是这样的:

function MyAsmModule(stdlib, foreign, heap) {
    "use asm";

    // module body...

    return {
        export1: f1,
        export2: f2,
        // ...
    };
}

模块的函数参数允许 asm.js 调用外部 JavaScript 并与“普通” JavaScript 共享其堆缓冲区。从模块返回的导出对象允许外部 JavaScript 调用 asm.js。

省略"use asm",您的浏览器将不知道它应该将您的代码解释为 asm.js 模块。它会将您的代码视为“普通”JavaScript。但是,仅使用 "use asm" 不足以让您的代码被解释为 asm.js。不符合上述任何其他标准,您的代码也将被解释为“普通”JavaScript:

有关 asm.js 的更多信息,请参见例如。 John Resig's article from 2013official specs

【讨论】:

    【解决方案2】:

    "use asm" 是一个 pragma,它专门告诉 JavaScript 引擎如何解释它。尽管它是有效的 JavaScript 并且可以在没有编译指示的情况下使用,但 FireFox 可以对 Asm.js 子集执行额外的优化以提高性能。要做到这一点,它必须知道它是Asm.js。

    【讨论】:

      猜你喜欢
      • 2016-04-22
      • 2013-02-05
      • 1970-01-01
      • 1970-01-01
      • 2015-08-06
      • 2013-09-02
      • 2014-01-02
      • 2013-10-10
      • 2017-05-08
      相关资源
      最近更新 更多