Friday, December 7, 2018

Lisp flavoured java modification procedures

The first part of this process of abstracting the Java virtual machine dealt mainly with the construction of expressions from atoms and functions, and less with the aspect of modifying storage locations. This lead to a minimal abstraction of Java bytecode, however, I want to create not only a minimal abstraction but an elegant one as well. Towards that it is useful to introduce generalized variables. In the Java virtual machine there are four types of things that can be considered to be generalized variables: local variables, class variables, instance variables, and array index variables. These are displayed below. By abstracting these different types of variables away, we can modify any of them using a single function and then the compiler can produce the appropriate function associated with them. The Lisp way of doing this is to have a function like setf which modifies variables.
(type I x)
(setf x 10)
(type D y)
(setf y 1.0)
The appropriate local variable modification instructions are introduced by the compiler corresponding to the form of the variable being modified.
bipush 10
istore_0
dconst_1
dstore_1
This is how you might deal with modifying a static variable of a class:
(setf MainClass/name 0)
This will be compiled to a putstatic instruction with the appropriate type:
iconst_0
putstatic MainClass.name I
When dealing with compound variables a special form can be placed in as the first argument to the setf rather then an atom. The form appears exactly as an access to the variable would appear.
(type (arr I) coll)
(setf (aload coll 0) 10)
(setf (aload coll 1) 20)
These two function calls are expanded into two different iastore instructions. The appropriate instruction in this case is determined by the element type component of the array type of the variable being referenced. The ordering of the operations on the stack produced by the modification procedure is preserved, because the lvalues in the Java virtual machine instruction set always come first. This means this is still a simple abstraction of the Java virtual machine instruction set which corresponds directly to its bytecode.
aload_0
iconst_0
bipush 10
iastore
aload_0
iconst_1
bipush 20
iastore
The other type of compound variable, the instance variable can be dealt with as you would expect.
(type java.awt.Point p)
(setf (.-x p) 10)
(setf (.-y p) 20)
The type of the field being modified is determined at compile time by reflection.
aload_0
bipush 10
putfield java/awt/Point.x I
aload_0
bipush 20
putfield java/awt/Point.y I
Well all of these different uses of the assignment procedure have been interesting, the Java virtual machine does support one other type of modification procedure that deals with variables and that is the iinc procedure. The iinc procedure only deals with integer valued local variables though, so I believe it is worthwhile to abstract it away with a procedure like incf. This incf function can then be applied to any of the different types of variables.
(type I x)
(incf x 1)
(type (arr I) coll) 
(incf (aload coll 0) 1)
When the variable being dealt with by incf is an integer then it will produce the appropriate iinc instruction in order to provide you with more compact byte code. Otherwise, it will be necessary to get the value of the variable being addressed, push the amount it is to be added by onto the stack, and then add them in order to get what the value is going to be set to.
iinc 0 1
aload_1
iconst_0
aload_1
iconst_0
iaload
iconst_1
iadd
iastore
These two types of instructions will allow you to produce any of the modification instructions available to the Java virtual machine in an effective and generalized manner. We can now see how there are two different types of data operations available in the Java virtual machine: functions that deal with modifying values on the stack, and modification procedures that assign values to variables. Together these two types of instructions already described here define all the data operations of the Java virtual machine. The only instructions that have not been dealt with yet are the control flow instructions which will be dealt with in a later post.

No comments:

Post a Comment