ASTree oprand = expr.oprand1();
if (token == '.') {
String member = ((Symbol)expr.oprand2()).get();
- if (member.equals("length"))
- atArrayLength(expr);
- else if (member.equals("class"))
+ if (member.equals("class"))
atClassObject(expr); // .class
else
atFieldRead(expr);
className = "java/lang/Class";
}
- public void atArrayLength(Expr expr) throws CompileError {
- expr.oprand1().accept(this);
- if (arrayDim == 0)
- throw new CompileError(".length applied to a non array");
-
- bytecode.addOpcode(ARRAYLENGTH);
- exprType = INT;
- arrayDim = 0;
- }
-
public void atArrayRead(ASTree array, ASTree index)
throws CompileError
{
protected void atFieldAssign(Expr expr, int op, ASTree left,
ASTree right, boolean doDup) throws CompileError
{
- CtField f = fieldAccess(left);
+ CtField f = fieldAccess(left, false);
boolean is_static = resultStatic;
if (op != '=' && !is_static)
bytecode.addOpcode(DUP);
protected void atFieldRead(ASTree expr) throws CompileError
{
- CtField f = fieldAccess(expr);
+ CtField f = fieldAccess(expr, true);
+ if (f == null) {
+ atArrayLength(expr);
+ return;
+ }
+
boolean is_static = resultStatic;
ASTree cexpr = TypeChecker.getConstantFieldValue(f);
if (cexpr == null)
}
}
+ private void atArrayLength(ASTree expr) throws CompileError {
+ if (arrayDim == 0)
+ throw new CompileError(".length applied to a non array");
+
+ bytecode.addOpcode(ARRAYLENGTH);
+ exprType = INT;
+ arrayDim = 0;
+ }
+
/**
* Generates bytecode for reading a field value.
* It returns a fieldref_info index or zero if the field is a private
ASTree oprand, Expr expr, boolean doDup)
throws CompileError
{
- CtField f = fieldAccess(oprand);
+ CtField f = fieldAccess(oprand, false);
boolean is_static = resultStatic;
if (!is_static)
bytecode.addOpcode(DUP);
}
/* This method also returns a value in resultStatic.
+ *
+ * @param acceptLength true if array length is acceptable
*/
- protected CtField fieldAccess(ASTree expr) throws CompileError {
+ protected CtField fieldAccess(ASTree expr, boolean acceptLength)
+ throws CompileError
+ {
if (expr instanceof Member) {
String name = ((Member)expr).get();
CtField f = null;
if (exprType == CLASS && arrayDim == 0)
f = resolver.lookupFieldByJvmName(className,
(Symbol)e.oprand2());
+ else if (acceptLength && arrayDim > 0
+ && ((Symbol)e.oprand2()).get().equals("length"))
+ return null; // expr is an array length.
else
badLvalue();