Kathey Marsden wrote:
> I have a few newbie questions about MethodBuilder and BaseActivation
> and ClassBuilder
>
> If I look at this code in ExpressionClassBuilder:
>
> void pushPVSReference(MethodBuilder mb)
> {
> mb.pushThis();
> mb.getField(ClassName.BaseActivation, "pvs",
> ClassName.ParameterValueSet);
> }
>
> it would seem that pushThis() pushes an instance of BaseActivation
> onto the stack. How exactly does that happen?
> In BCMethod pushThis seems to push a ClassBuilder. I don't see how
> BaseActivation gets there.
I'm not sure what you are seeing in BCMethod.pushThis().
The first line is:
myCode.addInstr(VMOpcode.ALOAD_0);
This adds the instruction ALOAD_0 which is the instruction
that will push 'this' onto the operand stack.
The second line is:
growStack(1, cb.classType);
This is code that in the byte code builder maintains track of the types
of the operands that are on the operand stack. Pushing 'this' onto the
operand stack will put a reference of type X, where X is the name of the
generated class, e.g. org.apache.derby.exe.ac435340402342342. Here
'cb.classType' represents the class name of the generated class.
Thus pushThis() pushes a Java reference corresponding to 'this' and it
will be of type org.apache.derby.exe.ac435340402342342 (as an example name).
Now at the language level, e.g. pushPVSReference, it is known that the
generated class is a sub-class of BaseActivation, since the language
layer declared/created the generated class using BaseActivation as its
super-class.
> mb.getField(ClassName.BaseActivation, "pvs",
> ClassName.ParameterValueSet);
Now the first argument to getField here is the *declared* class of the
field. If the argument is null, then the declared class of the field is
taken from the type of the operand on the stack.
In this case the pvs field is declared in BaseActivation, so the jvm
class format requires that the description of the field is its declared
type, thus BaseActivation is needed. Basically the use of
ClassName.BaseActivation here is an "up cast". In Java language it's:
((BaseActivation) this).pvs;
If you were writing Java code, then you would just use:
this.pvs
but the Java compiler would perform the resolution of the field and
generate code that represents: ((BaseActivation) this).pvs.
The Derby byte code compiler does not perform field or method resolution
like the Java compiler, it expects the caller (the language layer) to
provide correct field and method descriptors.
Hope this helps,
Dan.