10.3 Compiling Statements and Expressions

A Java compiler generally follows three rules about the stack when compiling expressions and statements. These rules help guarantee that the code produced will be verifiable.

  1. Each statement begins with an empty stack, and there is an empty stack when it ends.

  2. Each expression has no effect on the stack except to place an additional element on top of the stack.

  3. If a compound expression or statement is composed of subexpressions, the subexpressions are evaluated first, leaving the result of each on the stack. The subexpressions are used as operands to the compound expression or statement, which removes them from the stack.

The steps of evaluating a statement may cause the stack to grow temporarily, but at the end the stack will be empty. Evaluating an expression increases the height of the stack by exactly one, without affecting any of the elements on the stack beneath it.

If a statement uses subexpressions, then each subexpression increases the height of the stack by one, but each is removed before the statement is finished executing. For example, consider the statement

 System.out.write(bytes, 0, bytes.length); 

where bytes is an array of type byte. This statement contains four subexpressions, System.out, bytes, 0, and bytes.length. In accordance with the third rule, the subexpressions are evaluated first. Suppose that bytes is contained in local variable 1. The subexpressions are translated into

 getstatic java/lang/System/out Ljava/io/PrintStream   ; System.out aload_1                                               ; bytes iconst_0                                              ; 0 aload_1                                               ; bytes arraylength                                           ; .length 

In compiling the expression bytes.length, the code first evaluates the subexpression bytes by loading variable 1 onto the stack. Then it applies the arraylength instruction to it, which pops the result of the subexpression bytes and pushes the value of bytes.length.

The four expressions have increased the height of the stack by four. To finish the statement, all four must be removed from the stack. The next instruction is a method call:

 invokevirtual java/io/PrintStream/write ([BII)V 

This instruction takes four values off the stack (a PrintStream, an array of bytes, and two ints), returning nothing. Thus, there is no net effect on the stack, even though the stack height was as high as four.

As the compiler compiles the code, it remembers the maximum height the stack can achieve during execution. The class file must specify the maximum allowable height of the stack for each method. This allows the JVM to allocate the smallest possible amount of memory when the method is invoked, improving execution time and memory efficiency. The JVM verification algorithm rejects any programs that attempt to use more stack space than the maximum stack height permits.



Programming for the Java Virtual Machine
Programming for the Javaв„ў Virtual Machine
ISBN: 0201309726
EAN: 2147483647
Year: 1998
Pages: 158
Authors: Joshua Engel

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net