1

In most cases, it is possible to create both a native compiler and an interpreter for a programming language. The compiler would simply convert the source code to machine code, and the interpreter would simply execute the source code (or some IL produced by a compiler).

However, I'm not sure about languages with garbage collection. Let's take Java for example.

When Java was designed, it was clear that Java programs were always going to be run on the JVM. And the JVM was supposed to feature a garbage collection mechanism. So while designing the Java language itself, there was no need for destructors and such.

If one was going to implement a native Java compiler, that would mean the Java source code would be compiled to machine code to be run on the machine itself, not on a VM. And the machine itself doesn't feature a mechanism for garbage collection.

How would someone implementing a native Java compiler deal with this situation? Is it possible to create a native compiler for Java, since the Java design 'counts' on automatic garbage collection? (And possibly on some additional things the VM does for the program?)

2

2 Answers 2

10

Since native compilers for Java, C# etc. exist, it is obviously possible.

Whether or not a language is "managed" is a question of language semantics, not the implementation. It doesn't matter whether it's a compiler, an interpreter or a mixed-mode implementation. Every language can be implemented with a compiler and every language can be implemented with an interpreter. After all, most real-world implementations of Java are static compilers anyway.

Even C and C++ need a runtime library. For a Java-to-x86 compiler, that runtime library would need to include a little bit more than it would for a C-to-x86 compiler (the GC, reflection system, but also the dynamic linker and dynamic loader because Java code can be added to the program at any time), but the principle is the same.

By the way, you should be careful with terms like "native code" or "native compiler": there are CPUs that execute JVM byte code, and there are x86 interpreters for the JVM. So, imagine a JVM program running on a JVM CPU, and an x86 program running on an interpreter running on a JVM running on a Sparc CPU emulated via QEmu running on a PowerPC. Which one is "native"?

4
  • Do you mean that there are physical CPUs that can execute Java Bytecode?
    – Aviv Cohn
    Commented Apr 23, 2014 at 12:33
  • 2
    Yes, there are, or at least there were. In the early 90s, Java CPUs were a big thing, many of the big CPU vendors plus some startups worked on them, because it was thought that this was the most promising way to make Java fast. It turns out, though, that dynamic adaptive JIT compilation is much better. Commented Apr 23, 2014 at 14:05
  • 1
    Even C and C++ need a runtime library. I don't know about C++, but I have written at least one C program that did not link with any run-time library. The "executable" output at the end of my tool-chain was a Motorola S-record file that I "ran" by burning it into an EPROM, and then plugging that into the circuit board. That being said, I can no longer remember whether there was any language feature (e.g., passing structs by value) that I might have disabled and had to work around because of my not using the vendor-supplied CRT0 library. Commented Jan 25, 2016 at 19:28
  • 1
    @jameslarge: Yes, you are right, that is an over-simplification. I also remember reading an article about the early init code in the LinuxBIOS project, which is written in C, but runs before the stack pointer is initialized and without any form of memory allocator present. However, typically, even in a freestanding implementation, you will have some sort of runtime library – you just have to write it yourself. (See e.g. kmalloc and friends in the Linux kernel.) Commented Jan 26, 2016 at 0:59
2

Sure, it's possible. It just means that to keep the full semantics of java as it is specified, you have to include part of the code that constitutes the JVM into each binary you create.

In particular, the reference-counting, the garbage collecting, the run-time type information code etc. have to be included (unless maybe you have a very smart compiler that can prove certain features aren't going to be used by this program). Overall you save some of the JIT and byte code interpretation code in the JVM, but you pay for that by increasing the size of each natively compiled program.

This is usually not a good trade-off, which is why it's rarely done, but there is no fundamental technical reason why things the JVM does for you can't be done by a standalone application for itself. It's no different from bundling e.g. a Perl interpreter with a cool script to spare people the necessity of installing Perl itself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.