📄 membercodegen.java
字号:
fi = addFieldrefInfo(f, finfo); else fi = 0; } else fi = atFieldRead(f, is_static); int fType = exprType; int fDim = arrayDim; String cname = className; atAssignCore(expr, op, right, fType, fDim, cname); boolean is2w = is2word(fType, fDim); if (doDup) { int dup_code; if (is_static) dup_code = (is2w ? DUP2 : DUP); else dup_code = (is2w ? DUP2_X1 : DUP_X1); bytecode.addOpcode(dup_code); } atFieldAssignCore(f, is_static, fi, is2w); exprType = fType; arrayDim = fDim; className = cname; } /* If fi == 0, the field must be a private field in an enclosing class. */ private void atFieldAssignCore(CtField f, boolean is_static, int fi, boolean is2byte) throws CompileError { if (fi != 0) { if (is_static) { bytecode.add(PUTSTATIC); bytecode.growStack(is2byte ? -2 : -1); } else { bytecode.add(PUTFIELD); bytecode.growStack(is2byte ? -3 : -2); } bytecode.addIndex(fi); } else { CtClass declClass = f.getDeclaringClass(); AccessorMaker maker = declClass.getAccessorMaker(); // make should be non null. FieldInfo finfo = f.getFieldInfo2(); MethodInfo minfo = maker.getFieldSetter(finfo, is_static); bytecode.addInvokestatic(declClass, minfo.getName(), minfo.getDescriptor()); } } /* overwritten in JvstCodeGen. */ public void atMember(Member mem) throws CompileError { atFieldRead(mem); } protected void atFieldRead(ASTree expr) throws CompileError { CtField f = fieldAccess(expr, true); if (f == null) { atArrayLength(expr); return; } boolean is_static = resultStatic; ASTree cexpr = TypeChecker.getConstantFieldValue(f); if (cexpr == null) atFieldRead(f, is_static); else { cexpr.accept(this); setFieldType(f.getFieldInfo2()); } } 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 * one declared in an enclosing class. */ private int atFieldRead(CtField f, boolean isStatic) throws CompileError { FieldInfo finfo = f.getFieldInfo2(); boolean is2byte = setFieldType(finfo); AccessorMaker maker = isAccessibleField(f, finfo); if (maker != null) { MethodInfo minfo = maker.getFieldGetter(finfo, isStatic); bytecode.addInvokestatic(f.getDeclaringClass(), minfo.getName(), minfo.getDescriptor()); return 0; } else { int fi = addFieldrefInfo(f, finfo); if (isStatic) { bytecode.add(GETSTATIC); bytecode.growStack(is2byte ? 2 : 1); } else { bytecode.add(GETFIELD); bytecode.growStack(is2byte ? 1 : 0); } bytecode.addIndex(fi); return fi; } } /** * Returns null if the field is accessible. Otherwise, it throws * an exception or it returns AccessorMaker if the field is a private * one declared in an enclosing class. */ private AccessorMaker isAccessibleField(CtField f, FieldInfo finfo) throws CompileError { if (AccessFlag.isPrivate(finfo.getAccessFlags()) && f.getDeclaringClass() != thisClass) { CtClass declClass = f.getDeclaringClass(); if (isEnclosing(declClass, thisClass)) { AccessorMaker maker = declClass.getAccessorMaker(); if (maker != null) return maker; else throw new CompileError("fatal error. bug?"); } else throw new CompileError("Field " + f.getName() + " in " + declClass.getName() + " is private."); } return null; // accessible field } /** * Sets exprType, arrayDim, and className. * * @return true if the field type is long or double. */ private boolean setFieldType(FieldInfo finfo) throws CompileError { String type = finfo.getDescriptor(); int i = 0; int dim = 0; char c = type.charAt(i); while (c == '[') { ++dim; c = type.charAt(++i); } arrayDim = dim; exprType = MemberResolver.descToType(c); if (c == 'L') className = type.substring(i + 1, type.indexOf(';', i + 1)); else className = null; boolean is2byte = (c == 'J' || c == 'D'); return is2byte; } private int addFieldrefInfo(CtField f, FieldInfo finfo) { ConstPool cp = bytecode.getConstPool(); String cname = f.getDeclaringClass().getName(); int ci = cp.addClassInfo(cname); String name = finfo.getName(); String type = finfo.getDescriptor(); return cp.addFieldrefInfo(ci, name, type); } protected void atFieldPlusPlus(int token, boolean isPost, ASTree oprand, Expr expr, boolean doDup) throws CompileError { CtField f = fieldAccess(oprand, false); boolean is_static = resultStatic; if (!is_static) bytecode.addOpcode(DUP); int fi = atFieldRead(f, is_static); int t = exprType; boolean is2w = is2word(t, arrayDim); int dup_code; if (is_static) dup_code = (is2w ? DUP2 : DUP); else dup_code = (is2w ? DUP2_X1 : DUP_X1); atPlusPlusCore(dup_code, doDup, token, isPost, expr); atFieldAssignCore(f, is_static, fi, is2w); } /* This method also returns a value in resultStatic. * * @param acceptLength true if array length is acceptable */ protected CtField fieldAccess(ASTree expr, boolean acceptLength) throws CompileError { if (expr instanceof Member) { String name = ((Member)expr).get(); CtField f = null; try { f = thisClass.getField(name); } catch (NotFoundException e) { // EXPR might be part of a static member access? throw new NoFieldException(name, expr); } boolean is_static = Modifier.isStatic(f.getModifiers()); if (!is_static) if (inStaticMethod) throw new CompileError( "not available in a static method: " + name); else bytecode.addAload(0); // this resultStatic = is_static; return f; } else if (expr instanceof Expr) { Expr e = (Expr)expr; int op = e.getOperator(); if (op == MEMBER) { /* static member by # (extension by Javassist) * For example, if int.class is parsed, the resulting tree * is (# "java.lang.Integer" "TYPE"). */ CtField f = resolver.lookupField(((Symbol)e.oprand1()).get(), (Symbol)e.oprand2()); resultStatic = true; return f; } else if (op == '.') { CtField f = null; try { e.oprand1().accept(this); /* Don't call lookupFieldByJvmName2(). * The left operand of . is not a class name but * a normal expression. */ 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(); boolean is_static = Modifier.isStatic(f.getModifiers()); if (is_static) bytecode.addOpcode(POP); resultStatic = is_static; return f; } catch (NoFieldException nfe) { if (nfe.getExpr() != e.oprand1()) throw nfe; /* EXPR should be a static field. * If EXPR might be part of a qualified class name, * lookupFieldByJvmName2() throws NoFieldException. */ Symbol fname = (Symbol)e.oprand2(); String cname = nfe.getField(); f = resolver.lookupFieldByJvmName2(cname, fname, expr); resolver.recordPackage(cname); resultStatic = true; return f; } } else badLvalue(); } else badLvalue(); resultStatic = false; return null; // never reach } private static void badLvalue() throws CompileError { throw new CompileError("bad l-value"); } public CtClass[] makeParamList(MethodDecl md) throws CompileError { CtClass[] params; ASTList plist = md.getParams(); if (plist == null) params = new CtClass[0]; else { int i = 0; params = new CtClass[plist.length()]; while (plist != null) { params[i++] = resolver.lookupClass((Declarator)plist.head()); plist = plist.tail(); } } return params; } public CtClass[] makeThrowsList(MethodDecl md) throws CompileError { CtClass[] clist; ASTList list = md.getThrows(); if (list == null) return null; else { int i = 0; clist = new CtClass[list.length()]; while (list != null) { clist[i++] = resolver.lookupClassByName((ASTList)list.head()); list = list.tail(); } return clist; } } /* Converts a class name into a JVM-internal representation. * * It may also expand a simple class name to java.lang.*. * For example, this converts Object into java/lang/Object. */ protected String resolveClassName(ASTList name) throws CompileError { return resolver.resolveClassName(name); } /* Expands a simple class name to java.lang.*. * For example, this converts Object into java/lang/Object. */ protected String resolveClassName(String jvmName) throws CompileError { return resolver.resolveJvmClassName(jvmName); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -