“使用asm”到底是做啥的?
Posted
技术标签:
【中文标题】“使用asm”到底是做啥的?【英文标题】: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的子集。因此,您告诉引擎(以向后兼容的方式)您正在使用该子集,并且可以遵循稍微不同的规则 【参考方案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 2013 或 official specs。
【讨论】:
【参考方案2】:"use asm" 是一个 pragma,它专门告诉 JavaScript 引擎如何解释它。尽管它是有效的 JavaScript 并且可以在没有编译指示的情况下使用,但 FireFox 可以对 Asm.js 子集执行额外的优化以提高性能。要做到这一点,它必须知道它是Asm.js。
【讨论】:
以上是关于“使用asm”到底是做啥的?的主要内容,如果未能解决你的问题,请参考以下文章