【问题标题】:Is it possible to transform LLVM bytecode into Java bytecode?是否可以将 LLVM 字节码转换为 Java 字节码?
【发布时间】:2019-09-18 11:33:55
【问题描述】:

我听说 google 应用引擎可以运行任何可以通过 JVM 转换为 Java 字节码的编程语言。我想知道是否可以将 LLVM 字节码转换为 Java 字节码,因为在 Google App Engine JVM 中运行 LLVM 支持的语言会很有趣。

【问题讨论】:

  • AFAIK LLVM 是一个硬件/操作系统抽象分层库,而不是字节码虚拟机。它提供了一些相同的优点,但需要针对每个目标平台从源代码编译。
  • @Peter:不,您可以解释它并 JIT 编译它 (lli)。但是,是的,这些指令更底层,与其他虚拟机并不真正相似。
  • @Ben,请根据我在stackoverflow.com/a/13540256/304330 中提到的内容重新考虑接受的答案,谢谢。

标签: java compiler-construction llvm


【解决方案1】:

现在似乎可以使用 LLJVM interpreter 将 LLVM IR 字节码转换为 Java 字节码。

kraytracing.com 的 Grzegorz 提供了一个有趣的 Disqus comment (21/03/11),连同代码一起解释了他如何修改 LLJVM 的 Java 类输出例程以发出数量一致的非单片 Java 类与输入 C/C++ 模块。他建议他的技术似乎避免了通常由 LLJVM 生成的过长的“复合”Java Constructor 方法参数签名,并且他提供了指向他的修改和示例的链接。

虽然 LLJVM 看起来已经有几年的积极开发了,但它仍然托管在 Github 上,并且仍然可以在其以前的 GoogleCode 存储库中找到一些文档:

LLJVM @ Github
LLJVM documentation @ GoogleCode

我还遇到了“Proteuscc”项目,该项目也利用 LLVM 输出 Java 字节代码(它表明这是专门针对 C/C++ 的,尽管我认为该项目可以修改或提供 LLVM 中间表示(IR ))。来自http://proteuscc.sourceforge.net

然后使用 Proteus 生成 Java 可执行文件的一般过程 可以总结如下。

  1. 生成 LLVM 中间体的人类可读表示 表示(ll 文件)
  2. 将此 ll 文件作为参数传递给 proteus编译系统
  3. 上面会产生一个Java jar文件 可以作为库执行或使用

我扩展了a bash script to compile the latest versions of LLVM and Clang on Ubuntu,可以找到Github Gist,here

[UPDATE 31/03/14] - LLJVM 似乎已经死了一段时间,但是 Howard Chu (https://github.com/hyc) 看起来已经使 LLJVM 与最新版本兼容LLVM (3.3) 版本。见Howard's LLJVM-LLVM3.3 branch at Github, here

【讨论】:

    【解决方案2】:

    我怀疑你可以,至少在没有大量工作和运行时抽象的情况下不能(例如,构建半个冯诺依曼机器来执行某些操作码)。 LLVM 位码允许全方位的低级不安全“做你想做的,但我们不会清理混乱”的特性,从直接、原始、无构造函数的内存分配到完全未经检查的强制转换——真正的强制转换,而不是转换——如果您愿意,您可以将i32bitcast 带到%stuff *。此外,JVM 主要面向对象和方法,而 LLVM 人很幸运,他们有函数指针和结构。

    另一方面,C can be compiled to Java bytecodeLLVM bitcode can be compiled to Javascript 似乎(虽然缺少许多功能,例如动态加载和 stdlib 函数),所以只要付出足够的努力,它应该是可能的。

    【讨论】:

    • 所以基本上 LLVM 位码比 Java 字节码更接近汇编,所以如果我想,当程序转换为较低级别的表示时,我必须以某种方式“回收”所有“丢失”的信息在JVM中运行它。我想这是不可能的。
    • @Ben:是的,它几乎是可移植的(嗯,有点)汇编......以比 C 更底层的方式。不仅你必须做很多在逆向工程时工作,例如使用llvm-gcc 编译的 Ada 代码,至少 C 和 C++ 可以做许多 Java 字节码根本不允许的事情(无论好坏)。同样,LLVM 允许这些事情,但 JVM 不允许。
    • 我去的经典例子:char *vga = (char *) 0xB8000。 LLVM 可以处理得很好。很确定 JVM 字节码不能。
    【解决方案3】:

    讨论晚了:Sulong 在 JVM 上执行 LLVM IR。它从 LLVM IR 创建可执行节点(它们是 Java 对象),而不是将 LLVM IR 转换为 Java 字节码。这些可执行节点构成了一个 AST 解释器。您可以在https://github.com/graalvm/sulong 查看该项目,或在http://dl.acm.org/citation.cfm?id=2998416 阅读有关它的论文。免责声明:我正在做这个项目。

    【讨论】:

      【解决方案4】:

      阅读:http://vmkit.llvm.org/。我不确定它是否会对您有所帮助,但它似乎是相关的。

      注意:此项目不再维护。

      【讨论】:

      • 正好相反(允许构建基于 LLVM 的 VM,在 LLVM 上运行例如 Java/JVM 语言;OP 希望在 JVM 上运行 LLVM 语言)。
      • Fwiw,点击该链接:“VMKit 项目已退役。”
      猜你喜欢
      • 2019-01-02
      • 1970-01-01
      • 1970-01-01
      • 2014-08-02
      • 2017-09-24
      • 1970-01-01
      • 1970-01-01
      • 2013-03-07
      • 2018-06-24
      相关资源
      最近更新 更多