Java Primer: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
Combuster (talk | contribs)
Add the rest of the code.
m Bot: Replace deprecated source tag with syntaxhighlight
 
(3 intermediate revisions by 3 users not shown)
Line 40:
The fact that getting the number of arguments is convoluted to perform on the caller's side, we do callee-cleanup using <tt>RET imm</tt> instead of the regular <tt>RET</tt>. Locals is a convoluted issue as well, so we just reserve room for 8 because you're not meant to copy this code anyway.
 
<sourcesyntaxhighlight lang="java">
// File: compiler/nl/combuster/minijava/Compiler.java
package nl.combuster.minijava;
Line 299:
}
 
</syntaxhighlight>
</source>
 
Yes, that's a compiler in a magic 256 lines of code. The result is Intel syntax assembly, because there already are decent tools for assembly out there that deal with object formats out there. Of course you can write your own later as well.
Line 306:
Almost no programming language has standard constructs for all the things a processor can do, in particular not languages that were designed to be portable and memory-safe. For that reason we are required to add support for that outside of the language. Fortunately, Java does come with one construct specifically design to wrap the language to platform specifics: <tt>native</tt>
 
<sourcesyntaxhighlight lang="java">
// File: os/nl/combuster/minijavaos/Hal.java
package nl.combuster.minijavaos;
Line 314:
public static native void poke(int address, byte data);
}
</syntaxhighlight>
</source>
At some point the OS needs to access memory unsafely, and this is the method we'll use. The native keyword also implies that there is no implementation in java and that it'll come from elsewhere.
 
There are more things that might be difficult to do in straight Java: this example omits memory management in its entirety, but there is still a quirk: Every object subclasses from java.lang.Object. To make matters more complicated, the compiler does not allow us to write java.lang classes in Java. In this case it's a particular chicken-and-egg problem: how would we even compile a class that extends itself? We are in some way forced to treat java.lang.Object special, and basically use its constructor as a terminator for a constructor chain. At a later stage, we might even want to do something more in there, but for now we don't need to. The first piece of native support code deals with these problems:
 
<sourcesyntaxhighlight lang="asm">
; File: os/hal.asm
section .text
Line 335:
ret 2
 
</syntaxhighlight>
</source>
 
== A primitive kernel ==
"Hello world!" is a very overrated thing. Or is it? Strings are a full-blown object in Java, and passing objects safely is one of the things skipped in the compiler itself. Instead, we can count our numbers to show what we have actually works:
 
<sourcesyntaxhighlight lang="java">
package nl.combuster.minijavaos;
 
Line 359:
}
}
</syntaxhighlight>
</source>
This is little more than some simple VGA code, but it demonstrates that we can call Java code, do some calculations, and then call our hardware abstraction layer to complete the little bits Java just couldn't do.
 
Line 367:
==== Multiboot ====
We use GRUB as a bootloader, so the mechanics are the same. The only real difference is that we have to cope with the name mangling and be unable to call something kmain.
<sourcesyntaxhighlight lang="asm">
; File: os/multiboot.asm
 
Line 404:
;hlt
jmp .hang
</syntaxhighlight>
</source>
 
====Linker script====
Linking also happens with the same script as [[Bare Bones]]
 
<sourcesyntaxhighlight lang="c">
/* File: os/linker.ld */
/* The bootloader will look at this image and start execution at the symbol
Line 455:
a segment with the same name. Simply add stuff here as needed. */
}
</syntaxhighlight>
</source>
 
==== GRUB ====
Some configuration files for GRUB legacy. Doing this with a CD is the easiest way, really:
<sourcesyntaxhighlight lang="bash">
#
# File: os/grub.cfg
Line 470:
root (cd)
kernel (cd)/kernel
</syntaxhighlight>
</source>
 
==== Build instructions ====
Line 476:
 
In this example, GRUB is assumed to be preinstalled in /boot where it resides by default on a linux system that has it installed. We also need mkisofs and the binutils step from the [[GCC Cross-Compiler]]. Of course, at some point in time you can decide to write these tools in Java as well
<sourcesyntaxhighlight lang="make">
 
COMPILER_J=$(shell find -L compiler -iname '*.java')
Line 527:
mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $@ build/iso
 
</syntaxhighlight>
</source>
 
If you paid attention, you'll notice that the JAR step requires a manifest at <tt>compiler/compiler.manifest</tt>. It only really marks it as runnable so that we can use it easily:
<sourcesyntaxhighlight lang="bash">
Main-Class: nl.combuster.minijava.Compiler
</syntaxhighlight>
</source>
 
Lastly, the [http://forge.ow2.org/project/download.php?group_id=23&file_id=20549 one library] our compiler uses to do most of its magic. You can just copy the source into the compiler folder and the build script will pick it up.
 
[[Category:Tutorials]] [[Category:Compilers]] [[Category:Languages]]
[[Category:Compilers]]
[[Category:Languages]]
[[Category:Java]]