Next: The ``Defined'' Example with Up: First Approach Direct Compilation Previous: Data Type Support   Contents

Putting It Together with B

The final step to achieve the JVM port is to support the OP-codes in the IR. In this area, the B module is most useful. The B::JVM::Jasmin module that generates the Jasmin assembler from perl's IR is written as a subclass of B. It descends the syntax tree provided by the IR, in a depth-first fashion. For each node in the OP-tree, the module processes that node using the emitter to generate Jasmin code. The emitted Jasmin code utilizes the various data type classes to perform the task the OP-code would have performed had it been run on the PVM.

Figure: B::JVM::Jasmin Code for handling ``gvsv'' SVOP
sub B::SVOP::JVMJasmin {
     my $op = shift;
     my $name = $op->name();
     # ...
     my $curMethod = # ...
     # ...
     if ($name eq "gvsv") {
         my $stashName = $op->gv->STASH->NAME();
         my $gvName = $op->gv->NAME();
         $emit->getstatic($curMethod, "Stash/DEF_STASH", "LStash;");
         $emit->ldc($curMethod, cstring $stashName);
         $emit->invokevirtual($curMethod,
            "findNamespace(Ljava/lang/String;)LStash;");
         $emit->ldc($curMethod, cstring $gvName);
         $emit->invokevirtual($curMethod,
            "Stash/findGV(Ljava/lang/String;)Linternals/GV;");
         $emit->invokevirtual($curMethod, "GV/getScalar()LScalar;");
     }
     # ...
}

As an example, Figure 4.3 presents the code from B::JVM::Jasmin that handles the ``gvsv'' SVOP. In this code segment, we see part of the subroutine, B::SVOP::JVMJasmin. The name indicates that it is the code for handling SVOPs for the Jasmin-based JVM port. The B module identifies that a given OP is an SVOP, and calls the routine. As a user of B, B::JVM::Jasmin provides the JVMJasmin portion of the name. This name is given on the command-line via the O module, so the user can indicate that the Jasmin-based JVM back-end is desired.

The first argument when OP-code subroutines, such as B::SVOP::JVMJasmin, are invoked is the object referring to the current OP-code. Usually, the name method is called to find the exact type of the OP-code, and Figure 4.3 reflects this.

However, in Figure 4.3, only the code for handling the ``gvsv'' is shown. The ``gvsv'' OP-code is used when a global scalar variable is mentioned. This OP-code must find the actual data of the variable by searching for it in the name space. To generate the equivalent Jasmin code for this OP-code, the three Java classes, Stash, GV, and Scalar, must be used. These are equivalents to stashes, GVs and SVs on the PVM [1].

If the name of the variable for the given ``gvsv'' SVOP is, for example, $foo, then the code in Figure 4.3 generates Jasmin assembler that looks something like this:


getstatic        Stash/DEF_STASH LStash;
ldc              "main" 
invokevirtual    findNamespace(Ljava/lang/String;)LStash; 
ldc              "foo" 
invokevirtual    Stash/findGV(Ljava/lang/String;)Linternals/GV; 
invokevirtual    GV/getScalar()LScalar; 
      
or, as its (easier to read) Java equivalent4.2:

Stash.DEF_STASH.findNamespace("main").findGV("foo").getScalar();

If you compare this to the process described in [1] of how a stashes work inside perl, it is easy to see that this is equivalent code for a ``gvsv'' OP-code (given that the Stash and GV Java classes do their jobs correctly!).


Next: The ``Defined'' Example with Up: First Approach Direct Compilation Previous: Data Type Support   Contents

Copyright © 2000, 2001 Bradley M. Kuhn.

Verbatim copying and distribution of this entire thesis is permitted in any medium, provided this notice is preserved.