动态与静态编译器(JavaScript)

Sun*_*987 5 javascript compiler-construction static-analysis dynamic-languages

我目前正在用ANTLR + Java编写一个JavaScript编译器.

我已经在Stack Overflow上阅读了关于如何继续执行的问题 - 而且答案总是很难进行动态语言的静态编译(没有JIT信息) - 但为什么会这样?当然有明显的"类型解析"问题,并且在JavaScript中可能存在eval功能问题- 但还有其他原因吗?(因为它们似乎不太难以静态克服(没有JITS))

我不包括基于JIT的编译,因为我认为这对我来说实施起来太难了.

我在编写带有字节码执行的静态编译器方面有一些经验.

更新:

您的所有答案都非常有助于理解问题.澄清这是否意味着JavaScript比其他动态语言更难实现?

这也意味着我更好地使用基于树的解释器而不是例如字节码(如果我们忘记JS总是在原始源代码中提供的属性 - 因此增加了生成和IR的额外时间,然后执行它) ? - 或者它们应该同样容易/难以做到吗?

(我是新手SOF;不知道这是否是更新问题的首选方式?)

jfr*_*d00 6

这次谈话有很多方法可以实现.这是一个方向.在javascript中,几乎所有东西都是对象,属性或方法可以在运行时添加到任何对象.因此,您在编译时不知道将要或不会将哪些方法或属性附加到对象.因此,必须在运行时查找所有内容.

例如:

var myObj = {};

function configureObject() {
    if (something in the environment) {
        myObj.myfunc = function () {alert("Hi");}
    } else {
        myObj.myfunc = function () {document.write("Hello");}
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,稍后在代码中你调用myObj.myfunc(); 它在编译时不知道它是什么myfunc或者它是否是属性myObj.它必须是运行时查找.

在另一个示例中,请使用以下代码行:

var c = a + b;
Run Code Online (Sandbox Code Playgroud)

他的意思完全取决于a和b的类型,并且这些类型在编译时是未知的.

如果a和b都是数字,那么这是一个加法语句,c将是一个数字.

如果a或b是一个字符串,那么另一个将被强制转换为字符串而c将是一个字符串.

您无法将此类逻辑预编译为本机代码.执行环境必须记录这是对这两个操作数之间的加法运算符的请求,并且必须(在运行时)检查两个操作数的类型并决定做什么.