【问题标题】:JVM language interoperabilityJVM 语言互操作性
【发布时间】:2018-07-12 13:02:08
【问题描述】:

最近我一直在为 JVM 编程语言编写编译器,但我意识到了一个问题。

我想从我的编程语言访问一个 Java 方法,并允许 Java 方法访问我的语言中的一个方法。问题是我需要知道 Java 方法签名才能在我生成的字节码中调用它,反之亦然。

我一直在尝试思考 Scala 如何做到这一点的任何方法。这是我的想法。

  1. Scala 访问类路径上的.java 文件并解析它们,从中提取方法签名。
  2. .java 文件被编译为.class 文件。然后使用 Java ASM 库访问 .class 文件并获取方法签名。这种方法的问题是必须先编译.java 文件。
  3. .java 文件是使用反射动态加载的。这个问题是我相信JVM不允许加载编译器类路径之外的类。

查看 Scala 它可以很好地与其他 JVM 语言配合使用,但我无法找到有关它是如何做到这一点的信息。

Scala 如何获取其他 JVM 语言方法的方法签名?

【问题讨论】:

  • 您应该将您希望从您的语言和从 java 访问 java 方法的信息添加到您的方法。 (因为其他答案已被删除)
  • 混合使用 java-yourLanguage 项目是一个非常高级的用例。
  • 它可能是高级的,但 Scala/Java 等语言可以做到这一点。混合使用这两种语言并不少见,我将来必须实现此功能。
  • Reflection 只为您提供 java -> yourLang 互操作性,即:您可以从代码中调用 java 的东西,但不能反过来。为了让它反过来工作,你必须生成 javac 可以使用的东西,即将你的东西编译为 jvm 字节码并将 .class 提供给 javac

标签: java scala compiler-construction programming-languages java-bytecode-asm


【解决方案1】:

我认为您混淆了类路径和源路径:类路径上没有.java.scala 文件,有.class 文件(可能在.jars 内)。所以对于依赖项(在类路径上),你不需要做任何特别的事情。它们可以对您的语言有自己的依赖项,包括项目的早期版本,但它们已经按定义编译。

现在,对于混合项目,您在源路径上有 Java 和您的语言scalac does parse Java with its own parser (i.e. your option 1)

选项 3 的问题不在于“JVM 不允许加载编译器类路径之外的类”,而是反射也仅适用于类,而不适用于源文件。

【讨论】:

  • 有道理!所以这意味着如果制作了一种新的 JVM 语言,Scala 将不得不编写新的解析器来获取信息?这是否也意味着 Java 有 Scala 的解析器能够获取 Scala 方法签名?
  • Java 不需要了解 scala,scala 可以只为自己的类生成存根,所以简单的类只包含用于编译 java 的方法签名。所以如果还不能编译它们,javac 会看到已编译的 scala 类、普通类或存根。
  • @Michael Javac 不允许编译混合项目。 Scalac 也不允许编译包含除 Java 或 Scala 之外的其他语言的项目。
  • 我想我理解@GotoFinal。所以,如果我重复你所说的话。 Scala 将使用存根方法生成.class 文件。那么在 Java 编译完它的类之后,它会运行 Scala 编译器并完全生成方法吗?
  • @Michael 是的,看看 C/Cpp 的编译是如何工作的,你有特殊的头文件,所以你不需要包含完整的代码,因为这可能并不总是可能/容易。或者您需要在文件顶部定义方法,但在较低的地方实现它 - 所以编译器已经知道这个方法。但是在这里你需要生成它们。然后再次编译成正常的完整类。
猜你喜欢
  • 1970-01-01
  • 2014-05-26
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
相关资源
最近更新 更多