📄 ctfield.java
字号:
CtClass[] parameters, Javac drv) throws CannotCompileException { if (parameters != null && nthParam < parameters.length) { code.addAload(0); int nth = nthParamToLocal(nthParam, parameters, false); int s = code.addLoad(nth, type) + 1; code.addPutfield(Bytecode.THIS, name, Descriptor.of(type)); return s; // stack size } else return 0; // do not initialize } /** * Computes the index of the local variable that the n-th parameter * is assigned to. * * @param nth n-th parameter * @param params list of parameter types * @param isStatic true if the method is static. */ static int nthParamToLocal(int nth, CtClass[] params, boolean isStatic) { CtClass longType = CtClass.longType; CtClass doubleType = CtClass.doubleType; int k; if (isStatic) k = 0; else k = 1; // 0 is THIS. for (int i = 0; i < nth; ++i) { CtClass type = params[i]; if (type == longType || type == doubleType) k += 2; else ++k; } return k; } int compileIfStatic(CtClass type, String name, Bytecode code, Javac drv) throws CannotCompileException { return 0; } } /** * A field initialized with an object created by the new operator. */ static class NewInitializer extends Initializer { CtClass objectType; String[] stringParams; boolean withConstructorParams; NewInitializer() {} /** * Produces codes in which a new object is created and assigned to * the field as the initial value. */ int compile(CtClass type, String name, Bytecode code, CtClass[] parameters, Javac drv) throws CannotCompileException { int stacksize; code.addAload(0); code.addNew(objectType); code.add(Bytecode.DUP); code.addAload(0); if (stringParams == null) stacksize = 4; else stacksize = compileStringParameter(code) + 4; if (withConstructorParams) stacksize += CtNewWrappedMethod.compileParameterList(code, parameters, 1); code.addInvokespecial(objectType, "<init>", getDescriptor()); code.addPutfield(Bytecode.THIS, name, Descriptor.of(type)); return stacksize; } private String getDescriptor() { final String desc3 = "(Ljava/lang/Object;[Ljava/lang/String;[Ljava/lang/Object;)V"; if (stringParams == null) if (withConstructorParams) return "(Ljava/lang/Object;[Ljava/lang/Object;)V"; else return "(Ljava/lang/Object;)V"; else if (withConstructorParams) return desc3; else return "(Ljava/lang/Object;[Ljava/lang/String;)V"; } /** * Produces codes for a static field. */ int compileIfStatic(CtClass type, String name, Bytecode code, Javac drv) throws CannotCompileException { String desc; code.addNew(objectType); code.add(Bytecode.DUP); int stacksize = 2; if (stringParams == null) desc = "()V"; else { desc = "([Ljava/lang/String;)V"; stacksize += compileStringParameter(code); } code.addInvokespecial(objectType, "<init>", desc); code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type)); return stacksize; } protected final int compileStringParameter(Bytecode code) throws CannotCompileException { int nparam = stringParams.length; code.addIconst(nparam); code.addAnewarray(javaLangString); for (int j = 0; j < nparam; ++j) { code.add(Bytecode.DUP); // dup code.addIconst(j); // iconst_<j> code.addLdc(stringParams[j]); // ldc ... code.add(Bytecode.AASTORE); // aastore } return 4; } } /** * A field initialized with the result of a static method call. */ static class MethodInitializer extends NewInitializer { String methodName; // the method class is specified by objectType. MethodInitializer() {} /** * Produces codes in which a new object is created and assigned to * the field as the initial value. */ int compile(CtClass type, String name, Bytecode code, CtClass[] parameters, Javac drv) throws CannotCompileException { int stacksize; code.addAload(0); code.addAload(0); if (stringParams == null) stacksize = 2; else stacksize = compileStringParameter(code) + 2; if (withConstructorParams) stacksize += CtNewWrappedMethod.compileParameterList(code, parameters, 1); String typeDesc = Descriptor.of(type); String mDesc = getDescriptor() + typeDesc; code.addInvokestatic(objectType, methodName, mDesc); code.addPutfield(Bytecode.THIS, name, typeDesc); return stacksize; } private String getDescriptor() { final String desc3 = "(Ljava/lang/Object;[Ljava/lang/String;[Ljava/lang/Object;)"; if (stringParams == null) if (withConstructorParams) return "(Ljava/lang/Object;[Ljava/lang/Object;)"; else return "(Ljava/lang/Object;)"; else if (withConstructorParams) return desc3; else return "(Ljava/lang/Object;[Ljava/lang/String;)"; } /** * Produces codes for a static field. */ int compileIfStatic(CtClass type, String name, Bytecode code, Javac drv) throws CannotCompileException { String desc; int stacksize = 1; if (stringParams == null) desc = "()"; else { desc = "([Ljava/lang/String;)"; stacksize += compileStringParameter(code); } String typeDesc = Descriptor.of(type); code.addInvokestatic(objectType, methodName, desc + typeDesc); code.addPutstatic(Bytecode.THIS, name, typeDesc); return stacksize; } } static class IntInitializer extends Initializer { int value; IntInitializer(int v) { value = v; } void check(CtClass type) throws CannotCompileException { if (type != CtClass.intType) throw new CannotCompileException("type mismatch"); } int compile(CtClass type, String name, Bytecode code, CtClass[] parameters, Javac drv) throws CannotCompileException { code.addAload(0); code.addIconst(value); code.addPutfield(Bytecode.THIS, name, Descriptor.of(type)); return 2; // stack size } int compileIfStatic(CtClass type, String name, Bytecode code, Javac drv) throws CannotCompileException { code.addIconst(value); code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type)); return 1; // stack size } int getConstantValue(ConstPool cp, CtClass type) { if (type == CtClass.intType) return cp.addIntegerInfo(value); else return 0; } } static class LongInitializer extends Initializer { long value; LongInitializer(long v) { value = v; } void check(CtClass type) throws CannotCompileException { if (type != CtClass.longType) throw new CannotCompileException("type mismatch"); } int compile(CtClass type, String name, Bytecode code, CtClass[] parameters, Javac drv) throws CannotCompileException { code.addAload(0); code.addLdc2w(value); code.addPutfield(Bytecode.THIS, name, Descriptor.of(type)); return 3; // stack size } int compileIfStatic(CtClass type, String name, Bytecode code, Javac drv) throws CannotCompileException { code.addLdc2w(value); code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type)); return 2; // stack size } int getConstantValue(ConstPool cp, CtClass type) { if (type == CtClass.longType) return cp.addLongInfo(value); else return 0; } } static class DoubleInitializer extends Initializer { double value; DoubleInitializer(double v) { value = v; } void check(CtClass type) throws CannotCompileException { if (type != CtClass.doubleType) throw new CannotCompileException("type mismatch"); } int compile(CtClass type, String name, Bytecode code, CtClass[] parameters, Javac drv) throws CannotCompileException { code.addAload(0); code.addLdc2w(value); code.addPutfield(Bytecode.THIS, name, Descriptor.of(type)); return 3; // stack size } int compileIfStatic(CtClass type, String name, Bytecode code, Javac drv) throws CannotCompileException { code.addLdc2w(value); code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type)); return 2; // stack size } int getConstantValue(ConstPool cp, CtClass type) { if (type == CtClass.doubleType) return cp.addDoubleInfo(value); else return 0; } } static class StringInitializer extends Initializer { String value; StringInitializer(String v) { value = v; } void check(CtClass type) throws CannotCompileException { if (!type.getName().equals(javaLangString)) throw new CannotCompileException("type mismatch"); } int compile(CtClass type, String name, Bytecode code, CtClass[] parameters, Javac drv) throws CannotCompileException { code.addAload(0); code.addLdc(value); code.addPutfield(Bytecode.THIS, name, Descriptor.of(type)); return 2; // stack size } int compileIfStatic(CtClass type, String name, Bytecode code, Javac drv) throws CannotCompileException { code.addLdc(value); code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type)); return 1; // stack size } int getConstantValue(ConstPool cp, CtClass type) { if (type.getName().equals(javaLangString)) return cp.addStringInfo(value); else return 0; } } static class ArrayInitializer extends Initializer { CtClass type; int size; ArrayInitializer(CtClass t, int s) { type = t; size = s; } private void addNewarray(Bytecode code) { if (type.isPrimitive()) code.addNewarray(((CtPrimitiveType)type).getArrayType(), size); else code.addAnewarray(type, size); } int compile(CtClass type, String name, Bytecode code, CtClass[] parameters, Javac drv) throws CannotCompileException { code.addAload(0); addNewarray(code); code.addPutfield(Bytecode.THIS, name, Descriptor.of(type)); return 2; // stack size } int compileIfStatic(CtClass type, String name, Bytecode code, Javac drv) throws CannotCompileException { addNewarray(code); code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type)); return 1; // stack size } } static class MultiArrayInitializer extends Initializer { CtClass type; int[] dim; MultiArrayInitializer(CtClass t, int[] d) { type = t; dim = d; } void check(CtClass type) throws CannotCompileException { if (!type.isArray()) throw new CannotCompileException("type mismatch"); } int compile(CtClass type, String name, Bytecode code, CtClass[] parameters, Javac drv) throws CannotCompileException { code.addAload(0); int s = code.addMultiNewarray(type, dim); code.addPutfield(Bytecode.THIS, name, Descriptor.of(type)); return s + 1; // stack size } int compileIfStatic(CtClass type, String name, Bytecode code, Javac drv) throws CannotCompileException { int s = code.addMultiNewarray(type, dim); code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type)); return s; // stack size } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -