### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java,v retrieving revision 1.161 diff -u -r1.161 SourceTypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java 17 Sep 2008 09:33:00 -0000 1.161 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java 19 Sep 2008 14:31:11 -0000 @@ -1065,7 +1065,7 @@ public ReferenceBinding[] memberTypes() { return this.memberTypes; } -///** @deprecated */ +/** @deprecated */ public FieldBinding getUpdatedFieldBinding(FieldBinding targetField, ReferenceBinding newDeclaringClass) { if (this.synthetics == null) this.synthetics = new HashMap[MAX_SYNTHETICS]; Index: compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java,v retrieving revision 1.53 diff -u -r1.53 Clinit.java --- compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java 7 Jul 2008 17:08:07 -0000 1.53 +++ compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java 19 Sep 2008 14:31:09 -0000 @@ -16,6 +16,7 @@ import org.eclipse.jdt.internal.compiler.codegen.BranchLabel; import org.eclipse.jdt.internal.compiler.codegen.CodeStream; import org.eclipse.jdt.internal.compiler.codegen.ConstantPool; +import org.eclipse.jdt.internal.compiler.codegen.Opcodes; import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext; import org.eclipse.jdt.internal.compiler.flow.FlowInfo; import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext; @@ -173,7 +174,7 @@ falseLabel.place(); codeStream.iconst_0(); jumpLabel.place(); - codeStream.putstatic(this.assertionSyntheticFieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_putstatic, this.assertionSyntheticFieldBinding, null /* default declaringClass */); } // generate static fields/initializers/enum constants final FieldDeclaration[] fieldDeclarations = declaringType.fields; @@ -206,13 +207,13 @@ if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) { codeStream.dup(); codeStream.generateInlinedValue(fieldDecl.binding.id); - codeStream.getstatic(fieldDecl.binding); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, fieldDecl.binding, null /* default declaringClass */); codeStream.aastore(); } } } } - codeStream.putstatic(declaringType.enumValuesSyntheticfield); + codeStream.fieldAccess0(Opcodes.OPC_putstatic, declaringType.enumValuesSyntheticfield, null /* default declaringClass */); if (remainingFieldCount != 0) { // if fields that are not enum constants need to be generated (static initializer/static field) for (int i = 0, max = fieldDeclarations.length; i < max; i++) { Index: compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java,v retrieving revision 1.95 diff -u -r1.95 ConstructorDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 8 Jul 2008 02:01:42 -0000 1.95 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 19 Sep 2008 14:31:09 -0000 @@ -228,7 +228,7 @@ if ((syntheticArg = syntheticArgs[i]).matchingField != null) { codeStream.aload_0(); codeStream.load(syntheticArg); - codeStream.putfield(syntheticArg.matchingField); + codeStream.fieldAccess0(Opcodes.OPC_putfield, syntheticArg.matchingField, null /* default declaringClass */); } } syntheticArgs = nestedType.syntheticOuterLocalVariables(); @@ -237,7 +237,7 @@ if ((syntheticArg = syntheticArgs[i]).matchingField != null) { codeStream.aload_0(); codeStream.load(syntheticArg); - codeStream.putfield(syntheticArg.matchingField); + codeStream.fieldAccess0(Opcodes.OPC_putfield, syntheticArg.matchingField, null /* default declaringClass */); } } } Index: compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java,v retrieving revision 1.55 diff -u -r1.55 AssertStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java 12 Sep 2008 19:24:48 -0000 1.55 +++ compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java 19 Sep 2008 14:31:09 -0000 @@ -101,7 +101,7 @@ if (this.assertionSyntheticFieldBinding != null) { BranchLabel assertionActivationLabel = new BranchLabel(codeStream); - codeStream.getstatic(this.assertionSyntheticFieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, this.assertionSyntheticFieldBinding, null /* default declaringClass */); codeStream.ifne(assertionActivationLabel); BranchLabel falseLabel; Index: compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java,v retrieving revision 1.120 diff -u -r1.120 FieldReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java 17 Sep 2008 09:08:38 -0000 1.120 +++ compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java 19 Sep 2008 14:31:09 -0000 @@ -17,7 +17,6 @@ import org.eclipse.jdt.internal.compiler.codegen.Opcodes; import org.eclipse.jdt.internal.compiler.flow.FlowContext; import org.eclipse.jdt.internal.compiler.flow.FlowInfo; -import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; @@ -41,11 +40,10 @@ public Expression receiver; public char[] token; public FieldBinding binding; // exact binding resulting from lookup - protected FieldBinding codegenBinding; // actual binding used for code generation (if no synthetic accessor) public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor public long nameSourcePosition; //(start<<32)+end - public TypeBinding receiverType; + public TypeBinding actualReceiverType; public TypeBinding genericCast; public FieldReference(char[] source, long pos) { @@ -162,15 +160,16 @@ public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) { int pc = codeStream.position; + FieldBinding codegenBinding = this.binding.original(); this.receiver.generateCode( currentScope, codeStream, - !this.codegenBinding.isStatic()); + !codegenBinding.isStatic()); codeStream.recordPositionsFrom(pc, this.sourceStart); assignment.expression.generateCode(currentScope, codeStream, true); fieldStore( codeStream, - this.codegenBinding, + codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], valueRequired); if (valueRequired) { @@ -195,9 +194,10 @@ codeStream.recordPositionsFrom(pc, this.sourceStart); return; } - boolean isStatic = this.codegenBinding.isStatic(); + FieldBinding codegenBinding = this.binding.original(); + boolean isStatic = codegenBinding.isStatic(); boolean isThisReceiver = this.receiver instanceof ThisReference; - Constant fieldConstant = this.codegenBinding.constant(); + Constant fieldConstant = codegenBinding.constant(); if (fieldConstant != Constant.NotAConstant) { if (!isThisReceiver) { this.receiver.generateCode(currentScope, codeStream, !isStatic); @@ -218,7 +218,7 @@ || (this.genericCast != null)) { this.receiver.generateCode(currentScope, codeStream, !isStatic); pc = codeStream.position; - if (this.codegenBinding.declaringClass == null) { // array length + if (codegenBinding.declaringClass == null) { // array length codeStream.arraylength(); if (valueRequired) { codeStream.generateImplicitConversion(this.implicitConversion); @@ -228,10 +228,11 @@ } } else { if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) { + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); if (isStatic) { - codeStream.getstatic(this.codegenBinding); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass); } else { - codeStream.getfield(this.codegenBinding); + codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass); } } else { codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */); @@ -244,7 +245,7 @@ boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0; // conversion only generated if unboxing if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion); - switch (isUnboxing ? postConversionType(currentScope).id : this.codegenBinding.type.id) { + switch (isUnboxing ? postConversionType(currentScope).id : codegenBinding.type.id) { case T_long : case T_double : codeStream.pop2(); @@ -258,14 +259,15 @@ if (isThisReceiver) { if (isStatic){ // if no valueRequired, still need possible side-effects of invocation, if field belongs to different class - if (this.binding.original().declaringClass != this.receiverType.erasure()) { + if (this.binding.original().declaringClass != this.actualReceiverType.erasure()) { MethodBinding accessor = this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.READ]; if (accessor == null) { - codeStream.getstatic(this.codegenBinding); + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass); } else { codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); } - switch (this.codegenBinding.type.id) { + switch (codegenBinding.type.id) { case T_long : case T_double : codeStream.pop2(); @@ -288,20 +290,20 @@ public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { boolean isStatic; - this.receiver.generateCode( - currentScope, - codeStream, - !(isStatic = this.codegenBinding.isStatic())); + FieldBinding codegenBinding = this.binding.original(); + this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic())); if (isStatic) { if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) { - codeStream.getstatic(this.codegenBinding); + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass); } else { codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */); } } else { codeStream.dup(); if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) { - codeStream.getfield(this.codegenBinding); + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); + codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass); } else { codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */); } @@ -329,30 +331,26 @@ // cast the value back to the array reference type codeStream.generateImplicitConversion(assignmentImplicitConversion); } - fieldStore( - codeStream, - this.codegenBinding, - this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], - valueRequired); + fieldStore(codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], valueRequired); // no need for generic cast as value got dupped } public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { boolean isStatic; - this.receiver.generateCode( - currentScope, - codeStream, - !(isStatic = this.codegenBinding.isStatic())); + FieldBinding codegenBinding = this.binding.original(); + this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic())); if (isStatic) { if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) { - codeStream.getstatic(this.codegenBinding); + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass); } else { codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */); } } else { codeStream.dup(); if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) { - codeStream.getfield(this.codegenBinding); + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); + codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass); } else { codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */); } @@ -362,23 +360,29 @@ codeStream.checkcast(this.genericCast); operandType = this.genericCast; } else { - operandType = this.codegenBinding.type; + operandType = codegenBinding.type; } if (valueRequired) { if (isStatic) { - if ((operandType == TypeBinding.LONG) - || (operandType == TypeBinding.DOUBLE)) { - codeStream.dup2(); - } else { - codeStream.dup(); - } + switch (operandType.id) { + case TypeIds.T_long : + case TypeIds.T_double : + codeStream.dup2(); + break; + default : + codeStream.dup(); + break; + } } else { // Stack: [owner][old field value] ---> [old field value][owner][old field value] - if ((operandType == TypeBinding.LONG) - || (operandType == TypeBinding.DOUBLE)) { - codeStream.dup2_x1(); - } else { - codeStream.dup_x1(); - } + switch (operandType.id) { + case TypeIds.T_long : + case TypeIds.T_double : + codeStream.dup2_x1(); + break; + default : + codeStream.dup_x1(); + break; + } } } codeStream.generateImplicitConversion(this.implicitConversion); @@ -388,7 +392,7 @@ codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK); codeStream.generateImplicitConversion( postIncrement.preAssignImplicitConversion); - fieldStore(codeStream, this.codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], false); + fieldStore(codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], false); } /** @@ -412,16 +416,16 @@ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return; // if field from parameterized type got found, use the original field at codegen time - this.codegenBinding = this.binding.original(); + FieldBinding codegenBinding = this.binding.original(); if (this.binding.isPrivate()) { - if ((currentScope.enclosingSourceType() != this.codegenBinding.declaringClass) + if ((currentScope.enclosingSourceType() != codegenBinding.declaringClass) && this.binding.constant() == Constant.NotAConstant) { if (this.syntheticAccessors == null) this.syntheticAccessors = new MethodBinding[2]; this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = - ((SourceTypeBinding) this.codegenBinding.declaringClass).addSyntheticMethod(this.codegenBinding, isReadAccess); - currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess); + ((SourceTypeBinding) codegenBinding.declaringClass).addSyntheticMethod(codegenBinding, isReadAccess); + currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess); return; } @@ -433,8 +437,8 @@ .currentCompatibleType); if (this.syntheticAccessors == null) this.syntheticAccessors = new MethodBinding[2]; - this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = destinationType.addSyntheticMethod(this.codegenBinding, isReadAccess); - currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess); + this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = destinationType.addSyntheticMethod(codegenBinding, isReadAccess); + currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess); return; } else if (this.binding.isProtected()) { @@ -449,31 +453,11 @@ (this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT); if (this.syntheticAccessors == null) this.syntheticAccessors = new MethodBinding[2]; - this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = currentCompatibleType.addSyntheticMethod(this.codegenBinding, isReadAccess); - currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess); + this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = currentCompatibleType.addSyntheticMethod(codegenBinding, isReadAccess); + currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess); return; } } - // if the binding declaring class is not visible, need special action - // for runtime compatibility on 1.2 VMs : change the declaring class of the binding - // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type - // and not from Object or implicit static field access. - if (this.binding.declaringClass != this.receiverType - && !this.receiverType.isArrayType() - && this.binding.declaringClass != null // array.length - && this.binding.constant() == Constant.NotAConstant) { - CompilerOptions options = currentScope.compilerOptions(); - if ((options.targetJDK >= ClassFileConstants.JDK1_2 - && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(this.receiver.isImplicitThis() && this.codegenBinding.isStatic())) - && this.binding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields - || !this.binding.declaringClass.canBeSeenBy(currentScope)) { - - this.codegenBinding = - currentScope.enclosingSourceType().getUpdatedFieldBinding( - this.codegenBinding, - (ReferenceBinding) this.receiverType.erasure()); - } - } } public int nullStatus(FlowInfo flowInfo) { @@ -546,35 +530,35 @@ this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on receiverCast = true; } - this.receiverType = this.receiver.resolveType(scope); - if (this.receiverType == null) { + this.actualReceiverType = this.receiver.resolveType(scope); + if (this.actualReceiverType == null) { this.constant = Constant.NotAConstant; return null; } if (receiverCast) { // due to change of declaring class with receiver type, only identity cast should be notified - if (((CastExpression)this.receiver).expression.resolvedType == this.receiverType) { + if (((CastExpression)this.receiver).expression.resolvedType == this.actualReceiverType) { scope.problemReporter().unnecessaryCast((CastExpression)this.receiver); } } // the case receiverType.isArrayType and token = 'length' is handled by the scope API - FieldBinding fieldBinding = this.codegenBinding = this.binding = scope.getField(this.receiverType, this.token, this); + FieldBinding fieldBinding = this.binding = scope.getField(this.actualReceiverType, this.token, this); if (!fieldBinding.isValidBinding()) { this.constant = Constant.NotAConstant; if (this.receiver.resolvedType instanceof ProblemReferenceBinding) { // problem already got signaled on receiver, do not report secondary problem return null; } - scope.problemReporter().invalidField(this, this.receiverType); + scope.problemReporter().invalidField(this, this.actualReceiverType); return null; } - TypeBinding receiverErasure = this.receiverType.erasure(); + TypeBinding receiverErasure = this.actualReceiverType.erasure(); if (receiverErasure instanceof ReferenceBinding) { if (receiverErasure.findSuperTypeOriginatingFrom(fieldBinding.declaringClass) == null) { - this.receiverType = fieldBinding.declaringClass; // handle indirect inheritance thru variable secondary bound + this.actualReceiverType = fieldBinding.declaringClass; // handle indirect inheritance thru variable secondary bound } } - this.receiver.computeConversion(scope, this.receiverType, this.receiverType); + this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType); if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & ASTNode.IsStrictlyAssigned) !=0)) { scope.problemReporter().deprecatedField(fieldBinding, this); } @@ -589,7 +573,7 @@ } ReferenceBinding declaringClass = this.binding.declaringClass; if (!isImplicitThisRcv - && declaringClass != this.receiverType + && declaringClass != this.actualReceiverType && declaringClass.canBeSeenBy(scope)) { scope.problemReporter().indirectAccessToStaticField(this, fieldBinding); } @@ -620,7 +604,7 @@ } public void setActualReceiverType(ReferenceBinding receiverType) { - // ignored + this.actualReceiverType = receiverType; } public void setDepth(int depth) { Index: compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java,v retrieving revision 1.110 diff -u -r1.110 SingleNameReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 17 Sep 2008 09:08:38 -0000 1.110 +++ compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 19 Sep 2008 14:31:09 -0000 @@ -376,7 +376,8 @@ } // managing private access if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { - codeStream.getstatic(fieldBinding); + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, constantPoolDeclaringClass); } else { codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); } @@ -398,7 +399,8 @@ } // managing private access if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { - codeStream.getfield(fieldBinding); + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */); + codeStream.fieldAccess0(Opcodes.OPC_getfield, fieldBinding, constantPoolDeclaringClass); } else { codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); } @@ -473,7 +475,8 @@ FieldBinding fieldBinding; if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { - codeStream.getstatic(fieldBinding); + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, constantPoolDeclaringClass); } else { codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); } @@ -487,7 +490,8 @@ } codeStream.dup(); if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { - codeStream.getfield(fieldBinding); + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */); + codeStream.fieldAccess0(Opcodes.OPC_getfield, fieldBinding, constantPoolDeclaringClass); } else { codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); } @@ -586,7 +590,8 @@ FieldBinding fieldBinding; if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { - codeStream.getstatic(fieldBinding); + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, constantPoolDeclaringClass); } else { codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); } @@ -600,7 +605,8 @@ } codeStream.dup(); if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { - codeStream.getfield(fieldBinding); + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */); + codeStream.fieldAccess0(Opcodes.OPC_getfield, fieldBinding, constantPoolDeclaringClass); } else { codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); } @@ -723,26 +729,6 @@ currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, isReadAccess); return; } - // if the binding declaring class is not visible, need special action - // for runtime compatibility on 1.2 VMs : change the declaring class of the binding - // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type - // and not from Object or implicit static field access. - if (fieldBinding.declaringClass != this.actualReceiverType - && !this.actualReceiverType.isArrayType() - && fieldBinding.declaringClass != null // array.length - && fieldBinding.constant() == Constant.NotAConstant) { - CompilerOptions options = currentScope.compilerOptions(); - if ((options.targetJDK >= ClassFileConstants.JDK1_2 - && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic()) - && fieldBinding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields - || !fieldBinding.declaringClass.canBeSeenBy(currentScope)) { - - this.codegenBinding = - currentScope.enclosingSourceType().getUpdatedFieldBinding( - codegenField, - (ReferenceBinding)this.actualReceiverType.erasure()); - } - } } } Index: compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java,v retrieving revision 1.29 diff -u -r1.29 Reference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java 17 Sep 2008 09:08:38 -0000 1.29 +++ compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java 19 Sep 2008 14:31:09 -0000 @@ -10,8 +10,11 @@ *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.codegen.*; import org.eclipse.jdt.internal.compiler.flow.*; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.lookup.*; public abstract class Reference extends Expression { @@ -26,42 +29,53 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { return flowInfo; } + public FieldBinding fieldBinding() { //this method should be sent one FIELD-tagged references // (ref.bits & BindingIds.FIELD != 0)() return null ; } + public void fieldStore(CodeStream codeStream, FieldBinding fieldBinding, MethodBinding syntheticWriteAccessor, boolean valueRequired) { int pc = codeStream.position; if (fieldBinding.isStatic()) { if (valueRequired) { - if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) { - codeStream.dup2(); - } else { - codeStream.dup(); + switch (fieldBinding.type.id) { + case TypeIds.T_long : + case TypeIds.T_double : + codeStream.dup2(); + break; + default : + codeStream.dup(); + break; } } if (syntheticWriteAccessor == null) { - codeStream.putstatic(fieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_putstatic, fieldBinding, null /* default declaringClass */); } else { codeStream.invoke(Opcodes.OPC_invokestatic, syntheticWriteAccessor, null /* default declaringClass */); } } else { // Stack: [owner][new field value] ---> [new field value][owner][new field value] if (valueRequired) { - if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) { - codeStream.dup2_x1(); - } else { - codeStream.dup_x1(); + switch (fieldBinding.type.id) { + case TypeIds.T_long : + case TypeIds.T_double : + codeStream.dup2_x1(); + break; + default : + codeStream.dup_x1(); + break; } } if (syntheticWriteAccessor == null) { - codeStream.putfield(fieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_putfield, fieldBinding, null /* default declaringClass */); } else { codeStream.invoke(Opcodes.OPC_invokestatic, syntheticWriteAccessor, null /* default declaringClass */); } } codeStream.recordPositionsFrom(pc, this.sourceStart); } + public abstract void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired); public abstract void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired); Index: compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java,v retrieving revision 1.60 diff -u -r1.60 Javadoc.java --- compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java 27 Jun 2008 16:03:55 -0000 1.60 +++ compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java 19 Sep 2008 14:31:09 -0000 @@ -373,11 +373,11 @@ if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers(); scope.problemReporter().javadocInvalidValueReference(fieldRef.sourceStart, fieldRef.sourceEnd, scopeModifiers); } - else if (fieldRef.receiverType != null) { - if (scope.enclosingSourceType().isCompatibleWith(fieldRef.receiverType)) { + else if (fieldRef.actualReceiverType != null) { + if (scope.enclosingSourceType().isCompatibleWith(fieldRef.actualReceiverType)) { fieldRef.bits |= ASTNode.SuperAccess; } - fieldRef.methodBinding = scope.findMethod((ReferenceBinding)fieldRef.receiverType, fieldRef.token, new TypeBinding[0], fieldRef); + fieldRef.methodBinding = scope.findMethod((ReferenceBinding)fieldRef.actualReceiverType, fieldRef.token, new TypeBinding[0], fieldRef); } } @@ -390,8 +390,8 @@ } // Verify type references - if (!hasProblems && fieldRef.binding != null && fieldRef.binding.isValidBinding() && fieldRef.receiverType instanceof ReferenceBinding) { - ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.receiverType; + if (!hasProblems && fieldRef.binding != null && fieldRef.binding.isValidBinding() && fieldRef.actualReceiverType instanceof ReferenceBinding) { + ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.actualReceiverType; verifyTypeReference(fieldRef, fieldRef.receiver, scope, source15, resolvedType, fieldRef.binding.modifiers); } Index: compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java,v retrieving revision 1.134 diff -u -r1.134 MessageSend.java --- compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java 17 Sep 2008 11:11:09 -0000 1.134 +++ compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java 19 Sep 2008 14:31:09 -0000 @@ -193,7 +193,7 @@ return this.genericTypeArguments; } -protected TypeBinding getConstantPoolDeclaringClass(BlockScope currentScope) { +public static TypeBinding getConstantPoolDeclaringClass(BlockScope currentScope, MethodBinding methodBinding, TypeBinding actualReceiverType, boolean isReceiverImplicitThis, boolean hasGenericCast) { // constantpool declaringClass MethodBinding codegenBinding = this.binding.original(); TypeBinding constantPoolDeclaringClass = codegenBinding.declaringClass; @@ -209,7 +209,7 @@ // for runtime compatibility on 1.2 VMs : change the declaring class of the binding // NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type // and not from Object or implicit static method call. - if (constantPoolDeclaringClass != this.actualReceiverType && this.receiverGenericCast == null && !this.actualReceiverType.isArrayType()) { + if (constantPoolDeclaringClass != this.actualReceiverType.erasure() && this.receiverGenericCast == null && !this.actualReceiverType.isArrayType()) { CompilerOptions options = currentScope.compilerOptions(); if ((options.targetJDK >= ClassFileConstants.JDK1_2 && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(this.receiver.isImplicitThis() && codegenBinding.isStatic())) Index: compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java,v retrieving revision 1.29 diff -u -r1.29 JavadocFieldReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java 27 Jun 2008 16:03:56 -0000 1.29 +++ compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java 19 Sep 2008 14:31:09 -0000 @@ -41,19 +41,19 @@ this.constant = Constant.NotAConstant; if (this.receiver == null) { - this.receiverType = scope.enclosingReceiverType(); + this.actualReceiverType = scope.enclosingReceiverType(); } else if (scope.kind == Scope.CLASS_SCOPE) { - this.receiverType = this.receiver.resolveType((ClassScope) scope); + this.actualReceiverType = this.receiver.resolveType((ClassScope) scope); } else { - this.receiverType = this.receiver.resolveType((BlockScope)scope); + this.actualReceiverType = this.receiver.resolveType((BlockScope)scope); } - if (this.receiverType == null) { + if (this.actualReceiverType == null) { return null; } Binding fieldBinding = (this.receiver != null && this.receiver.isThis()) ? scope.classScope().getBinding(this.token, this.bits & RestrictiveFlagMASK, this, true /*resolve*/) - : scope.getField(this.receiverType, this.token, this); + : scope.getField(this.actualReceiverType, this.token, this); if (!fieldBinding.isValidBinding()) { // implicit lookup may discover issues due to static/constructor contexts. javadoc must be resilient switch (fieldBinding.problemId()) { @@ -72,8 +72,8 @@ // problem already got signaled on receiver, do not report secondary problem return null; } - if (this.receiverType instanceof ReferenceBinding) { - ReferenceBinding refBinding = (ReferenceBinding) this.receiverType; + if (this.actualReceiverType instanceof ReferenceBinding) { + ReferenceBinding refBinding = (ReferenceBinding) this.actualReceiverType; MethodBinding possibleMethod = this.receiver.isThis() ? scope.getImplicitMethod(this.token, Binding.NO_TYPES, this) : scope.getMethod(refBinding, this.token, Binding.NO_TYPES, this); @@ -82,7 +82,7 @@ } else { ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) possibleMethod; if (problemMethodBinding.closestMatch == null) { - scope.problemReporter().javadocInvalidField(this, fieldBinding, this.receiverType, scope.getDeclarationModifiers()); + scope.problemReporter().javadocInvalidField(this, fieldBinding, this.actualReceiverType, scope.getDeclarationModifiers()); } else { this.methodBinding = problemMethodBinding.closestMatch; } Index: compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java,v retrieving revision 1.131 diff -u -r1.131 QualifiedNameReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 17 Sep 2008 09:08:38 -0000 1.131 +++ compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 19 Sep 2008 14:31:09 -0000 @@ -391,15 +391,12 @@ codeStream.pop(); } } else { - SyntheticMethodBinding accessor = - this.syntheticReadAccessors == null - ? null - : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1]; + SyntheticMethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1]; if (accessor == null) { if (isStatic) { - codeStream.getstatic(lastFieldBinding); + codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */); } else { - codeStream.getfield(lastFieldBinding); + codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */); } } else { codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); @@ -451,14 +448,14 @@ : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1]; if (lastFieldBinding.isStatic()) { if (accessor == null) { - codeStream.getstatic(lastFieldBinding); + codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */); } else { codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); } } else { codeStream.dup(); if (accessor == null) { - codeStream.getfield(lastFieldBinding); + codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */); } else { codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); } @@ -500,14 +497,14 @@ : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1]; if (lastFieldBinding.isStatic()) { if (accessor == null) { - codeStream.getstatic(lastFieldBinding); + codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */); } else { codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); } } else { codeStream.dup(); if (accessor == null) { - codeStream.getfield(lastFieldBinding); + codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */); } else { codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); } @@ -624,9 +621,9 @@ MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i]; if (accessor == null) { if (lastFieldBinding.isStatic()) { - codeStream.getstatic(lastFieldBinding); + codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */); } else { - codeStream.getfield(lastFieldBinding); + codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */); } } else { codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); @@ -640,7 +637,7 @@ if (((FieldBinding)this.binding).original().declaringClass != this.actualReceiverType.erasure()) { MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i]; if (accessor == null) { - codeStream.getstatic(lastFieldBinding); + codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */); } else { codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); } Index: compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java,v retrieving revision 1.92 diff -u -r1.92 FieldDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java 11 Sep 2008 10:04:25 -0000 1.92 +++ compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java 19 Sep 2008 14:31:09 -0000 @@ -104,9 +104,9 @@ this.initialization.generateCode(currentScope, codeStream, true); // store into field if (isStatic) { - codeStream.putstatic(this.binding); + codeStream.fieldAccess0(Opcodes.OPC_putstatic, this.binding, null /* default declaringClass */); } else { - codeStream.putfield(this.binding); + codeStream.fieldAccess0(Opcodes.OPC_putfield, this.binding, null /* default declaringClass */); } } codeStream.recordPositionsFrom(pc, this.sourceStart); Index: compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java,v retrieving revision 1.166 diff -u -r1.166 CodeStream.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 17 Sep 2008 09:28:33 -0000 1.166 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 19 Sep 2008 14:31:10 -0000 @@ -21,6 +21,7 @@ import org.eclipse.jdt.internal.compiler.ast.OperatorIds; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.lookup.*; import org.eclipse.jdt.internal.compiler.problem.AbortMethod; @@ -1214,6 +1215,65 @@ this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fdiv; } +public void fieldAccess0(byte opcode, FieldBinding fieldBinding, TypeBinding declaringClass) { + if (declaringClass == null) declaringClass = fieldBinding.declaringClass; + if (declaringClass.leafComponentType().isNestedType()) { + this.classFile.recordInnerClasses(declaringClass); + } + TypeBinding returnType = fieldBinding.type; + int returnTypeSize; + switch (returnType.id) { + case TypeIds.T_long : + case TypeIds.T_double : + returnTypeSize = 2; + break; + default : + returnTypeSize = 1; + break; + } + this.fieldAccess(opcode, returnTypeSize, declaringClass.constantPoolName(), fieldBinding.name, returnType.signature()); +} + +private void fieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] fieldName, char[] signature) { + this.countLabels = 0; + switch(opcode) { + case Opcodes.OPC_getfield : + if (returnTypeSize == 2) { + this.stackDepth++; + } + break; + case Opcodes.OPC_getstatic : + if (returnTypeSize == 2) { + this.stackDepth += 2; + } else { + this.stackDepth++; + } + break; + case Opcodes.OPC_putfield : + if (returnTypeSize == 2) { + this.stackDepth -= 3; + } else { + this.stackDepth -= 2; + } + break; + case Opcodes.OPC_putstatic : + if (returnTypeSize == 2) { + this.stackDepth -= 2; + } else { + this.stackDepth--; + } + } + if (this.stackDepth > this.stackMax) { + this.stackMax = this.stackDepth; + } + if (this.classFileOffset + 2 >= this.bCodeStream.length) { + resizeByteArray(); + } + this.position++; + this.bCodeStream[this.classFileOffset++] = opcode; + writeUnsignedShort(this.constantPool.literalIndexForField(declaringClass, fieldName, signature)); +} + public void fload(int iArg) { this.countLabels = 0; this.stackDepth++; @@ -1641,7 +1701,7 @@ } else { BranchLabel endLabel = new BranchLabel(this); if (syntheticFieldBinding != null) { // non interface case - getstatic(syntheticFieldBinding); + fieldAccess0(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */); dup(); ifnonnull(endLabel); pop(); @@ -1684,7 +1744,7 @@ if (syntheticFieldBinding != null) { // non interface case dup(); - putstatic(syntheticFieldBinding); + fieldAccess0(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */); } goto_(endLabel); @@ -1877,57 +1937,6 @@ invokeAccessibleObjectSetAccessible(); } -private void generateFieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] name, char[] signature) { - this.countLabels = 0; - switch(opcode) { - case Opcodes.OPC_getfield : - if (returnTypeSize == 2) { - this.stackDepth++; - } - break; - case Opcodes.OPC_getstatic : - if (returnTypeSize == 2) { - this.stackDepth += 2; - } else { - this.stackDepth++; - } - break; - case Opcodes.OPC_putfield : - if (returnTypeSize == 2) { - this.stackDepth -= 3; - } else { - this.stackDepth -= 2; - } - break; - case Opcodes.OPC_putstatic : - if (returnTypeSize == 2) { - this.stackDepth -= 2; - } else { - this.stackDepth--; - } - } - if (this.stackDepth > this.stackMax) { - this.stackMax = this.stackDepth; - } - if (this.classFileOffset + 2 >= this.bCodeStream.length) { - resizeByteArray(); - } - this.position++; - this.bCodeStream[this.classFileOffset++] = opcode; - writeUnsignedShort(this.constantPool.literalIndexForField(declaringClass, name, signature)); -} - -private void generateFieldAccess(byte opcode, int returnTypeSize, ReferenceBinding binding, char[] name, TypeBinding type) { - if (binding.isNestedType()) { - this.classFile.recordInnerClasses(binding); - } - TypeBinding leafComponentType = type.leafComponentType(); - if (leafComponentType.isNestedType()) { - this.classFile.recordInnerClasses(leafComponentType); - } - this.generateFieldAccess(opcode, returnTypeSize, binding.constantPoolName(), name, type.signature()); -} - /** * Generates the sequence of instructions which will perform the conversion of the expression * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted). @@ -2251,14 +2260,14 @@ } else if (mappingSequence[0] instanceof FieldBinding) { FieldBinding fieldBinding = (FieldBinding) mappingSequence[0]; aload_0(); - getfield(fieldBinding); + fieldAccess0(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */); } else { load((LocalVariableBinding) mappingSequence[0]); } for (int i = 1, length = mappingSequence.length; i < length; i++) { if (mappingSequence[i] instanceof FieldBinding) { FieldBinding fieldBinding = (FieldBinding) mappingSequence[i]; - getfield(fieldBinding); + fieldAccess0(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */); } else { invoke(Opcodes.OPC_invokestatic, (MethodBinding) mappingSequence[i], null /* default declaringClass */); } @@ -2400,11 +2409,9 @@ //} public void generateSyntheticBodyForEnumValues(SyntheticMethodBinding methodBinding) { ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope; - FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield; initializeMaxLocals(methodBinding); TypeBinding enumArray = methodBinding.returnType; - - getstatic(enumValuesSyntheticfield); + fieldAccess0(Opcodes.OPC_getstatic, scope.referenceContext.enumValuesSyntheticfield, null /* default declaringClass */); dup(); astore_0(); iconst_0(); @@ -2425,11 +2432,11 @@ public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) { initializeMaxLocals(accessBinding); FieldBinding fieldBinding = accessBinding.targetReadField; - if (fieldBinding.isStatic()) - getstatic(fieldBinding); - else { + if (fieldBinding.isStatic()) { + fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, null /* default declaringClass */); + } else { aload_0(); - getfield(fieldBinding); + fieldAccess0(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */); } switch (fieldBinding.type.id) { // case T_void : @@ -2461,11 +2468,11 @@ FieldBinding fieldBinding = accessBinding.targetWriteField; if (fieldBinding.isStatic()) { load(fieldBinding.type, 0); - putstatic(fieldBinding); + fieldAccess0(Opcodes.OPC_putstatic, fieldBinding, null /* default declaringClass */); } else { aload_0(); load(fieldBinding.type, 1); - putfield(fieldBinding); + fieldAccess0(Opcodes.OPC_putfield, fieldBinding, null /* default declaringClass */); } return_(); } @@ -2551,7 +2558,7 @@ initializeMaxLocals(methodBinding); final BranchLabel nullLabel = new BranchLabel(this); FieldBinding syntheticFieldBinding = methodBinding.targetReadField; - getstatic(syntheticFieldBinding); + fieldAccess0(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */); dup(); ifnull(nullLabel); areturn(); @@ -2575,7 +2582,7 @@ final ExceptionLabel anyExceptionHandler = new ExceptionLabel(this, TypeBinding.LONG /* represents NoSuchFieldError*/); anyExceptionHandler.placeStart(); aload_0(); - getstatic(fieldBinding); + fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, null /* default declaringClass */); invokeEnumOrdinal(enumBinding.constantPoolName()); this.generateInlinedValue(fieldBinding.id + 1); // zero should not be returned see bug 141810 iastore(); @@ -2591,7 +2598,7 @@ } aload_0(); dup(); - putstatic(syntheticFieldBinding); + fieldAccess0(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */); areturn(); removeVariable(localVariableBinding); } @@ -2868,116 +2875,113 @@ return contents; } -public void getfield(FieldBinding fieldBinding) { - int returnTypeSize = 1; - if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) { - returnTypeSize = 2; - } - generateFieldAccess( - Opcodes.OPC_getfield, - returnTypeSize, - fieldBinding.declaringClass, - fieldBinding.name, - fieldBinding.type); +protected static TypeBinding getConstantPoolDeclaringClass(BlockScope currentScope, FieldBinding fieldBinding, TypeBinding actualReceiverType, boolean isImplicitThisReceiver) { + FieldBinding codegenBinding = fieldBinding.original(); + ReferenceBinding constantPoolDeclaringClass = codegenBinding.declaringClass; + // if the binding declaring class is not visible, need special action + // for runtime compatibility on 1.2 VMs : change the declaring class of the binding + // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type + // and not from Object or implicit static field access. + if (constantPoolDeclaringClass != actualReceiverType.erasure() + && !actualReceiverType.isArrayType() + && constantPoolDeclaringClass != null // array.length + && codegenBinding.constant() == Constant.NotAConstant) { + CompilerOptions options = currentScope.compilerOptions(); + if ((options.targetJDK >= ClassFileConstants.JDK1_2 + && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(isImplicitThisReceiver && codegenBinding.isStatic())) + && constantPoolDeclaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields + || !constantPoolDeclaringClass.canBeSeenBy(currentScope)) { + + return actualReceiverType.erasure(); + } + } + return constantPoolDeclaringClass; } protected int getPosition() { return this.position; } -public void getstatic(FieldBinding fieldBinding) { - int returnTypeSize = 1; - if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) { - returnTypeSize = 2; - } - generateFieldAccess( - Opcodes.OPC_getstatic, - returnTypeSize, - fieldBinding.declaringClass, - fieldBinding.name, - fieldBinding.type); -} - public void getTYPE(int baseTypeID) { this.countLabels = 0; switch (baseTypeID) { case TypeIds.T_byte : // getstatic: java.lang.Byte.TYPE - generateFieldAccess( + fieldAccess( Opcodes.OPC_getstatic, - 1, + 1, // return type size ConstantPool.JavaLangByteConstantPoolName, ConstantPool.TYPE, ConstantPool.JavaLangClassSignature); break; case TypeIds.T_short : // getstatic: java.lang.Short.TYPE - generateFieldAccess( + fieldAccess( Opcodes.OPC_getstatic, - 1, + 1, // return type size ConstantPool.JavaLangShortConstantPoolName, ConstantPool.TYPE, ConstantPool.JavaLangClassSignature); break; case TypeIds.T_char : // getstatic: java.lang.Character.TYPE - generateFieldAccess( + fieldAccess( Opcodes.OPC_getstatic, - 1, + 1, // return type size ConstantPool.JavaLangCharacterConstantPoolName, ConstantPool.TYPE, ConstantPool.JavaLangClassSignature); break; case TypeIds.T_int : // getstatic: java.lang.Integer.TYPE - generateFieldAccess( + fieldAccess( Opcodes.OPC_getstatic, - 1, + 1, // return type size ConstantPool.JavaLangIntegerConstantPoolName, ConstantPool.TYPE, ConstantPool.JavaLangClassSignature); break; case TypeIds.T_long : // getstatic: java.lang.Long.TYPE - generateFieldAccess( + fieldAccess( Opcodes.OPC_getstatic, - 1, + 1, // return type size ConstantPool.JavaLangLongConstantPoolName, ConstantPool.TYPE, ConstantPool.JavaLangClassSignature); break; case TypeIds.T_float : // getstatic: java.lang.Float.TYPE - generateFieldAccess( + fieldAccess( Opcodes.OPC_getstatic, - 1, + 1, // return type size ConstantPool.JavaLangFloatConstantPoolName, ConstantPool.TYPE, ConstantPool.JavaLangClassSignature); break; case TypeIds.T_double : // getstatic: java.lang.Double.TYPE - generateFieldAccess( + fieldAccess( Opcodes.OPC_getstatic, - 1, + 1, // return type size ConstantPool.JavaLangDoubleConstantPoolName, ConstantPool.TYPE, ConstantPool.JavaLangClassSignature); break; case TypeIds.T_boolean : // getstatic: java.lang.Boolean.TYPE - generateFieldAccess( + fieldAccess( Opcodes.OPC_getstatic, - 1, + 1, // return type size ConstantPool.JavaLangBooleanConstantPoolName, ConstantPool.TYPE, ConstantPool.JavaLangClassSignature); break; case TypeIds.T_void : // getstatic: java.lang.Void.TYPE - generateFieldAccess( + fieldAccess( Opcodes.OPC_getstatic, - 1, + 1, // return type size ConstantPool.JavaLangVoidConstantPoolName, ConstantPool.TYPE, ConstantPool.JavaLangClassSignature); @@ -3740,6 +3744,35 @@ writeUnsignedShort(this.constantPool.literalIndexForType(typeBinding)); } +protected void invoke(byte opcode, int receiverAndArgsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) { + this.countLabels = 0; + if (opcode == Opcodes.OPC_invokeinterface) { + // invokeinterface + if (this.classFileOffset + 4 >= this.bCodeStream.length) { + resizeByteArray(); + } + this.position +=3; + this.bCodeStream[this.classFileOffset++] = opcode; + writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, true)); + this.bCodeStream[this.classFileOffset++] = (byte) receiverAndArgsSize; + this.bCodeStream[this.classFileOffset++] = 0; + } else { + // invokespecial + // invokestatic + // invokevirtual + if (this.classFileOffset + 2 >= this.bCodeStream.length) { + resizeByteArray(); + } + this.position++; + this.bCodeStream[this.classFileOffset++] = opcode; + writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, false)); + } + this.stackDepth += returnTypeSize - receiverAndArgsSize; + if (this.stackDepth > this.stackMax) { + this.stackMax = this.stackDepth; + } +} + public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass) { if (declaringClass == null) declaringClass = methodBinding.declaringClass; if (declaringClass.isNestedType()) { @@ -3835,35 +3868,6 @@ methodBinding.signature(this.classFile)); } -protected void invoke(byte opcode, int receiverAndArgsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) { - this.countLabels = 0; - if (opcode == Opcodes.OPC_invokeinterface) { - // invokeinterface - if (this.classFileOffset + 4 >= this.bCodeStream.length) { - resizeByteArray(); - } - this.position +=3; - this.bCodeStream[this.classFileOffset++] = opcode; - writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, true)); - this.bCodeStream[this.classFileOffset++] = (byte) receiverAndArgsSize; - this.bCodeStream[this.classFileOffset++] = 0; - } else { - // invokespecial - // invokestatic - // invokevirtual - if (this.classFileOffset + 2 >= this.bCodeStream.length) { - resizeByteArray(); - } - this.position++; - this.bCodeStream[this.classFileOffset++] = opcode; - writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, false)); - } - this.stackDepth += returnTypeSize - receiverAndArgsSize; - if (this.stackDepth > this.stackMax) { - this.stackMax = this.stackDepth; - } -} - protected void invokeAccessibleObjectSetAccessible() { // invokevirtual: java.lang.reflect.AccessibleObject.setAccessible(Z)V; invoke( @@ -5142,7 +5146,7 @@ load(localBinding.type, localBinding.resolvedPosition); } -public final void load(TypeBinding typeBinding, int resolvedPosition) { +protected final void load(TypeBinding typeBinding, int resolvedPosition) { this.countLabels = 0; // Using dedicated int bytecode switch(typeBinding.id) { @@ -5685,32 +5689,6 @@ this.stackMax = this.stackDepth; } -public void putfield(FieldBinding fieldBinding) { - int returnTypeSize = 1; - if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) { - returnTypeSize = 2; - } - generateFieldAccess( - Opcodes.OPC_putfield, - returnTypeSize, - fieldBinding.declaringClass, - fieldBinding.name, - fieldBinding.type); -} - -public void putstatic(FieldBinding fieldBinding) { - int returnTypeSize = 1; - if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) { - returnTypeSize = 2; - } - generateFieldAccess( - Opcodes.OPC_putstatic, - returnTypeSize, - fieldBinding.declaringClass, - fieldBinding.name, - fieldBinding.type); -} - public void record(LocalVariableBinding local) { if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS | ClassFileConstants.ATTR_STACK_MAP_TABLE Index: compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java,v retrieving revision 1.25 diff -u -r1.25 StackMapFrameCodeStream.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java 8 Jul 2008 02:01:42 -0000 1.25 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java 19 Sep 2008 14:31:11 -0000 @@ -273,7 +273,7 @@ // use in CLDC mode BranchLabel endLabel = new BranchLabel(this); if (syntheticFieldBinding != null) { // non interface case - getstatic(syntheticFieldBinding); + fieldAccess0(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */); dup(); ifnonnull(endLabel); pop(); @@ -316,7 +316,7 @@ if (syntheticFieldBinding != null) { // non interface case dup(); - putstatic(syntheticFieldBinding); + fieldAccess0(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */); } int fromPC = this.position; goto_(endLabel); Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java,v retrieving revision 1.43 diff -u -r1.43 CodeSnippetFieldReference.java --- eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java 27 Jun 2008 16:04:07 -0000 1.43 +++ eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java 19 Sep 2008 14:31:11 -0000 @@ -15,19 +15,16 @@ import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FieldReference; import org.eclipse.jdt.internal.compiler.ast.IntLiteral; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.codegen.CodeStream; +import org.eclipse.jdt.internal.compiler.codegen.Opcodes; import org.eclipse.jdt.internal.compiler.flow.FlowInfo; -import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; -import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding; import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding; import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; -import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; -import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; +import org.eclipse.jdt.internal.compiler.lookup.TypeIds; public class CodeSnippetFieldReference extends FieldReference implements ProblemReasons, EvaluationConstants { @@ -43,26 +40,30 @@ this.evaluationContext = evaluationContext; } public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) { - - if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) { - this.receiver.generateCode(currentScope, codeStream, !this.codegenBinding.isStatic()); + FieldBinding codegenBinding = this.binding.original(); + if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) { + this.receiver.generateCode(currentScope, codeStream, !codegenBinding.isStatic()); assignment.expression.generateCode(currentScope, codeStream, true); - fieldStore(codeStream, this.codegenBinding, null, valueRequired); + fieldStore(codeStream, codegenBinding, null, valueRequired); } else { - codeStream.generateEmulationForField(this.codegenBinding); - this.receiver.generateCode(currentScope, codeStream, !this.codegenBinding.isStatic()); - if (this.codegenBinding.isStatic()) { // need a receiver? + codeStream.generateEmulationForField(codegenBinding); + this.receiver.generateCode(currentScope, codeStream, !codegenBinding.isStatic()); + if (codegenBinding.isStatic()) { // need a receiver? codeStream.aconst_null(); } assignment.expression.generateCode(currentScope, codeStream, true); if (valueRequired) { - if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) { - codeStream.dup2_x2(); - } else { - codeStream.dup_x2(); - } + switch (codegenBinding.type.id) { + case TypeIds.T_long : + case TypeIds.T_double : + codeStream.dup2_x2(); + break; + default : + codeStream.dup_x2(); + break; + } } - codeStream.generateEmulatedWriteAccessForField(this.codegenBinding); + codeStream.generateEmulatedWriteAccessForField(codegenBinding); } if (valueRequired){ codeStream.generateImplicitConversion(assignment.implicitConversion); @@ -76,33 +77,35 @@ * @param valueRequired boolean */ public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { - int pc = codeStream.position; if (this.constant != Constant.NotAConstant) { if (valueRequired) { codeStream.generateConstant(this.constant, this.implicitConversion); } } else { - boolean isStatic = this.codegenBinding.isStatic(); + FieldBinding codegenBinding = this.binding.original(); + boolean isStatic = codegenBinding.isStatic(); this.receiver.generateCode(currentScope, codeStream, !isStatic); if (valueRequired) { - Constant fieldConstant = this.codegenBinding.constant(); + Constant fieldConstant = codegenBinding.constant(); if (fieldConstant == Constant.NotAConstant) { - if (this.codegenBinding.declaringClass == null) { // array length + if (codegenBinding.declaringClass == null) { // array length codeStream.arraylength(); } else { - if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) { + if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) { + TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType; + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, someReceiverType, this.receiver.isImplicitThis()); if (isStatic) { - codeStream.getstatic(this.codegenBinding); + codeStream.fieldAccess0(Opcodes.OPC_getstatic , codegenBinding, constantPoolDeclaringClass); } else { - codeStream.getfield(this.codegenBinding); + codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass); } } else { if (isStatic) { // we need a null on the stack to use the reflect emulation codeStream.aconst_null(); } - codeStream.generateEmulatedReadAccessForField(this.codegenBinding); + codeStream.generateEmulatedReadAccessForField(codegenBinding); } } codeStream.generateImplicitConversion(this.implicitConversion); @@ -124,15 +127,17 @@ } public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { - boolean isStatic; - if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) { - this.receiver.generateCode(currentScope, codeStream, !(isStatic = this.codegenBinding.isStatic())); + FieldBinding codegenBinding = this.binding.original(); + if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) { + this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic())); + TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType; + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, someReceiverType, this.receiver.isImplicitThis()); if (isStatic) { - codeStream.getstatic(this.codegenBinding); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass); } else { codeStream.dup(); - codeStream.getfield(this.codegenBinding); + codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass); } int operationTypeID; switch(operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) { @@ -155,17 +160,17 @@ // cast the value back to the array reference type codeStream.generateImplicitConversion(assignmentImplicitConversion); } - fieldStore(codeStream, this.codegenBinding, null, valueRequired); + fieldStore(codeStream, codegenBinding, null, valueRequired); } else { - this.receiver.generateCode(currentScope, codeStream, !(isStatic = this.codegenBinding.isStatic())); + this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic())); if (isStatic) { // used to store the value - codeStream.generateEmulationForField(this.codegenBinding); + codeStream.generateEmulationForField(codegenBinding); codeStream.aconst_null(); // used to retrieve the actual value codeStream.aconst_null(); - codeStream.generateEmulatedReadAccessForField(this.codegenBinding); + codeStream.generateEmulatedReadAccessForField(codegenBinding); } else { // used to store the value codeStream.generateEmulationForField(this.binding); @@ -173,7 +178,7 @@ // used to retrieve the actual value codeStream.dup(); - codeStream.generateEmulatedReadAccessForField(this.codegenBinding); + codeStream.generateEmulatedReadAccessForField(codegenBinding); } int operationTypeID; if ((operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_JavaLangString) { @@ -195,7 +200,7 @@ // current stack is: // field receiver value if (valueRequired) { - if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) { + if ((codegenBinding.type == TypeBinding.LONG) || (codegenBinding.type == TypeBinding.DOUBLE)) { codeStream.dup2_x2(); } else { codeStream.dup_x2(); @@ -203,61 +208,69 @@ } // current stack is: // value field receiver value - codeStream.generateEmulatedWriteAccessForField(this.codegenBinding); + codeStream.generateEmulatedWriteAccessForField(codegenBinding); } } public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { boolean isStatic; - if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) { + FieldBinding codegenBinding = this.binding.original(); + if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) { super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired); } else { - this.receiver.generateCode(currentScope, codeStream, !(isStatic = this.codegenBinding.isStatic())); + this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic())); if (isStatic) { codeStream.aconst_null(); } // the actual stack is: receiver codeStream.dup(); // the actual stack is: receiver receiver - codeStream.generateEmulatedReadAccessForField(this.codegenBinding); + codeStream.generateEmulatedReadAccessForField(codegenBinding); // the actual stack is: receiver value // receiver value // value receiver value dup_x1 or dup2_x1 if value required - // value value receiver value dup_x1 or dup2_x1 - // value value receiver pop or pop2 + // value value receiver value dup_x1 or dup2_x1 + // value value receiver pop or pop2 // value value receiver field generateEmulationForField - // value value field receiver swap - // value field receiver value field receiver dup2_x1 or dup2_x2 - // value field receiver value pop2 - // value field receiver newvalue generate constant + op - // value store - if (valueRequired) { - if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) { + // value value field receiver swap + // value field receiver value field receiver dup2_x1 or dup2_x2 + // value field receiver value pop2 + // value field receiver newvalue generate constant + op + // value store + int typeID; + switch (typeID = codegenBinding.type.id) { + case TypeIds.T_long : + case TypeIds.T_double : + if (valueRequired) { + codeStream.dup2_x1(); + } codeStream.dup2_x1(); - } else { + codeStream.pop2(); + break; + default : + if (valueRequired) { + codeStream.dup_x1(); + } codeStream.dup_x1(); - } - } - if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) { - codeStream.dup2_x1(); - codeStream.pop2(); - } else { - codeStream.dup_x1(); - codeStream.pop(); + codeStream.pop(); + break; } - codeStream.generateEmulationForField(this.codegenBinding); + codeStream.generateEmulationForField(codegenBinding); codeStream.swap(); - - if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) { - codeStream.dup2_x2(); - } else { - codeStream.dup2_x1(); + switch (typeID) { + case TypeIds.T_long : + case TypeIds.T_double : + codeStream.dup2_x2(); + break; + default : + codeStream.dup2_x1(); + break; } codeStream.pop2(); codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion); - codeStream.sendOperator(postIncrement.operator, this.codegenBinding.type.id); + codeStream.sendOperator(postIncrement.operator, codegenBinding.type.id); codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion); - codeStream.generateEmulatedWriteAccessForField(this.codegenBinding); + codeStream.generateEmulatedWriteAccessForField(codegenBinding); } } /* @@ -267,43 +280,6 @@ // The private access will be managed through the code generation if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return; - - // if field from parameterized type got found, use the original field at codegen time - if (this.binding instanceof ParameterizedFieldBinding) { - ParameterizedFieldBinding parameterizedField = (ParameterizedFieldBinding) this.binding; - this.codegenBinding = parameterizedField.originalField; - // extra cast needed if field type was type variable - if (this.codegenBinding.type.isTypeVariable()) { - TypeVariableBinding variableReturnType = (TypeVariableBinding) this.codegenBinding.type; - if (variableReturnType.firstBound != parameterizedField.type) { // no need for extra cast if same as first bound anyway - this.genericCast = parameterizedField.type.erasure(); - } - } - } else { - this.codegenBinding = this.binding; - } - - // if the binding declaring class is not visible, need special action - // for runtime compatibility on 1.2 VMs : change the declaring class of the binding - // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type - TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.receiverType; - if (this.binding.declaringClass != someReceiverType - && !someReceiverType.isArrayType() - && this.binding.declaringClass != null // array.length - && this.binding.constant() == Constant.NotAConstant) { - - CompilerOptions options = currentScope.compilerOptions(); - if ((options.targetJDK >= ClassFileConstants.JDK1_2 - && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !this.receiver.isImplicitThis() || !this.codegenBinding.isStatic()) - && this.binding.declaringClass.id != T_JavaLangObject) // no change for Object fields - || !this.binding.declaringClass.canBeSeenBy(currentScope)) { - - this.codegenBinding = - currentScope.enclosingSourceType().getUpdatedFieldBinding( - this.codegenBinding, - (ReferenceBinding) someReceiverType.erasure()); - } - } } public TypeBinding resolveType(BlockScope scope) { // Answer the signature type of the field. @@ -311,13 +287,13 @@ // and initialized with a (compile time) constant // regular receiver reference - this.receiverType = this.receiver.resolveType(scope); - if (this.receiverType == null){ + this.actualReceiverType = this.receiver.resolveType(scope); + if (this.actualReceiverType == null){ this.constant = Constant.NotAConstant; return null; } // the case receiverType.isArrayType and token = 'length' is handled by the scope API - this.codegenBinding = this.binding = scope.getField(this.receiverType, this.token, this); + this.binding = scope.getField(this.actualReceiverType, this.token, this); FieldBinding firstAttempt = this.binding; boolean isNotVisible = false; if (!this.binding.isValidBinding()) { @@ -328,25 +304,25 @@ this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this); if (this.delegateThis == null){ // if not found then internal error, field should have been found this.constant = Constant.NotAConstant; - scope.problemReporter().invalidField(this, this.receiverType); + scope.problemReporter().invalidField(this, this.actualReceiverType); return null; } } else { this.constant = Constant.NotAConstant; - scope.problemReporter().invalidField(this, this.receiverType); + scope.problemReporter().invalidField(this, this.actualReceiverType); return null; } CodeSnippetScope localScope = new CodeSnippetScope(scope); - this.codegenBinding = this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.token, this); + this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.token, this); } } if (!this.binding.isValidBinding()) { this.constant = Constant.NotAConstant; if (isNotVisible) { - this.codegenBinding = this.binding = firstAttempt; + this.binding = firstAttempt; } - scope.problemReporter().invalidField(this, this.receiverType); + scope.problemReporter().invalidField(this, this.actualReceiverType); return null; } Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java,v retrieving revision 1.55 diff -u -r1.55 CodeSnippetSingleNameReference.java --- eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java 12 Sep 2008 13:28:54 -0000 1.55 +++ eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java 19 Sep 2008 14:31:11 -0000 @@ -18,11 +18,27 @@ import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.codegen.CodeStream; +import org.eclipse.jdt.internal.compiler.codegen.Opcodes; import org.eclipse.jdt.internal.compiler.flow.FlowContext; import org.eclipse.jdt.internal.compiler.flow.FlowInfo; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.impl.Constant; -import org.eclipse.jdt.internal.compiler.lookup.*; +import org.eclipse.jdt.internal.compiler.lookup.Binding; +import org.eclipse.jdt.internal.compiler.lookup.BlockScope; +import org.eclipse.jdt.internal.compiler.lookup.ClassScope; +import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; +import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; +import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; +import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding; +import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding; +import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding; +import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; +import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; +import org.eclipse.jdt.internal.compiler.lookup.Scope; +import org.eclipse.jdt.internal.compiler.lookup.TagBits; +import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.TypeIds; +import org.eclipse.jdt.internal.compiler.lookup.VariableBinding; /** * A single name reference inside a code snippet can denote a field of a remote @@ -218,9 +234,10 @@ Constant fieldConstant = fieldBinding.constant(); if (fieldConstant == Constant.NotAConstant) { // directly use inlined value for constant fields if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { - // directly use inlined value for constant fields - boolean isStatic; - if (!(isStatic = fieldBinding.isStatic())) { + TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */); + if (fieldBinding.isStatic()) { + codeStream.fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, constantPoolDeclaringClass); + } else { if ((this.bits & DepthMASK) != 0) { ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT); Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); @@ -228,12 +245,7 @@ } else { generateReceiver(codeStream); } - } - // managing private access - if (isStatic) { - codeStream.getstatic(fieldBinding); - } else { - codeStream.getfield(fieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_getfield, fieldBinding, constantPoolDeclaringClass); } } else { // managing private access @@ -285,7 +297,7 @@ FieldBinding fieldBinding = (FieldBinding) this.codegenBinding; if (fieldBinding.isStatic()) { if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { - codeStream.getstatic(fieldBinding); + codeStream.fieldAccess(Opcodes.OPC_getstatic, fieldBinding, null /* default declaringClass */); } else { // used to store the value codeStream.generateEmulationForField(fieldBinding); @@ -305,7 +317,7 @@ generateReceiver(codeStream); } codeStream.dup(); - codeStream.getfield(fieldBinding); + codeStream.fieldAccess(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */); } else { if ((this.bits & DepthMASK) != 0) { // internal error, per construction we should have found it @@ -478,7 +490,7 @@ public void generateReceiver(CodeStream codeStream) { codeStream.aload_0(); if (this.delegateThis != null) { - codeStream.getfield(this.delegateThis); // delegated field access + codeStream.fieldAccess0(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegate field access } } /** Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java,v retrieving revision 1.34 diff -u -r1.34 CodeSnippetThisReference.java --- eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java 27 Jun 2008 16:04:06 -0000 1.34 +++ eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java 19 Sep 2008 14:31:11 -0000 @@ -12,6 +12,7 @@ import org.eclipse.jdt.internal.compiler.ast.ThisReference; import org.eclipse.jdt.internal.compiler.codegen.CodeStream; +import org.eclipse.jdt.internal.compiler.codegen.Opcodes; import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; @@ -58,7 +59,7 @@ int pc = codeStream.position; if (valueRequired) { codeStream.aload_0(); - codeStream.getfield(this.delegateThis); + codeStream.fieldAccess0(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegate field access } codeStream.recordPositionsFrom(pc, this.sourceStart); } Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java,v retrieving revision 1.57 diff -u -r1.57 CodeSnippetQualifiedNameReference.java --- eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java 17 Sep 2008 09:08:39 -0000 1.57 +++ eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java 19 Sep 2008 14:31:11 -0000 @@ -107,9 +107,9 @@ } else { if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { if (lastFieldBinding.isStatic()) { - codeStream.getstatic(lastFieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */); } else { - codeStream.getfield(lastFieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */); } } else { codeStream.generateEmulatedReadAccessForField(lastFieldBinding); @@ -131,10 +131,10 @@ FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream); if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { if (lastFieldBinding.isStatic()){ - codeStream.getstatic(lastFieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */); } else { codeStream.dup(); - codeStream.getfield(lastFieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */); } // the last field access is a write access // perform the actual compound operation @@ -162,20 +162,15 @@ // actual assignment fieldStore(codeStream, lastFieldBinding, null, valueRequired); } else { + codeStream.generateEmulationForField(lastFieldBinding); + codeStream.swap(); if (lastFieldBinding.isStatic()){ - codeStream.generateEmulationForField(lastFieldBinding); - codeStream.swap(); codeStream.aconst_null(); codeStream.swap(); - - codeStream.generateEmulatedReadAccessForField(lastFieldBinding); } else { - codeStream.generateEmulationForField(lastFieldBinding); - codeStream.swap(); codeStream.dup(); - - codeStream.generateEmulatedReadAccessForField(lastFieldBinding); } + codeStream.generateEmulatedReadAccessForField(lastFieldBinding); // the last field access is a write access // perform the actual compound operation int operationTypeID; @@ -215,20 +210,19 @@ FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream); if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { - SyntheticMethodBinding accessor = - this.syntheticReadAccessors == null + SyntheticMethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1]; if (lastFieldBinding.isStatic()) { if (accessor == null) { - codeStream.getstatic(lastFieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */); } else { codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); } } else { codeStream.dup(); if (accessor == null) { - codeStream.getfield(lastFieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */); } else { codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); } @@ -380,9 +374,9 @@ } codeStream.generateConstant(fieldConstant, 0); } else if (lastFieldBinding.isStatic()) { - codeStream.getstatic(lastFieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */); } else { - codeStream.getfield(lastFieldBinding); + codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */); } } else { codeStream.generateEmulatedReadAccessForField(lastFieldBinding); @@ -410,7 +404,7 @@ public void generateReceiver(CodeStream codeStream) { codeStream.aload_0(); if (this.delegateThis != null) { - codeStream.getfield(this.delegateThis); // delegated field access + codeStream.fieldAccess0(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegated field access } } public TypeBinding getOtherFieldBindings(BlockScope scope) { Index: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java,v retrieving revision 1.26 diff -u -r1.26 CompletionOnMemberAccess.java --- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java 27 Jun 2008 16:03:59 -0000 1.26 +++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java 19 Sep 2008 14:31:09 -0000 @@ -53,9 +53,9 @@ public TypeBinding resolveType(BlockScope scope) { - this.receiverType = this.receiver.resolveType(scope); + this.actualReceiverType = this.receiver.resolveType(scope); - if ((this.receiverType == null || !this.receiverType.isValidBinding()) && this.receiver instanceof MessageSend) { + if ((this.actualReceiverType == null || !this.actualReceiverType.isValidBinding()) && this.receiver instanceof MessageSend) { MessageSend messageSend = (MessageSend) this.receiver; if(messageSend.receiver instanceof ThisReference) { Expression[] arguments = messageSend.arguments; @@ -73,10 +73,10 @@ } } - if (this.receiverType == null || this.receiverType.isBaseType() || !this.receiverType.isValidBinding()) + if (this.actualReceiverType == null || this.actualReceiverType.isBaseType() || !this.actualReceiverType.isValidBinding()) throw new CompletionNodeFound(); else - throw new CompletionNodeFound(this, this.receiverType, scope); + throw new CompletionNodeFound(this, this.actualReceiverType, scope); // array types are passed along to find the length field } } Index: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java,v retrieving revision 1.5 diff -u -r1.5 CompletionOnJavadocFieldReference.java --- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java 27 Jun 2008 16:03:59 -0000 1.5 +++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java 19 Sep 2008 14:31:09 -0000 @@ -93,11 +93,11 @@ // Resolve only receiver if (this.receiver == null) { - this.receiverType = scope.enclosingSourceType(); + this.actualReceiverType = scope.enclosingSourceType(); } else if (scope.kind == Scope.CLASS_SCOPE) { - this.receiverType = this.receiver.resolveType((ClassScope) scope); + this.actualReceiverType = this.receiver.resolveType((ClassScope) scope); } else { - this.receiverType = this.receiver.resolveType((BlockScope)scope); + this.actualReceiverType = this.receiver.resolveType((BlockScope)scope); } return null; } Index: codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java,v retrieving revision 1.376 diff -u -r1.376 CompletionEngine.java --- codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 18 Sep 2008 14:06:39 -0000 1.376 +++ codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 19 Sep 2008 14:31:08 -0000 @@ -1927,8 +1927,8 @@ long completionPosition = fieldRef.nameSourcePosition; this.javadocTagPosition = fieldRef.tagSourceStart; - if (fieldRef.receiverType != null && fieldRef.receiverType.isValidBinding()) { - ReferenceBinding receiverType = (ReferenceBinding) fieldRef.receiverType; + if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) { + ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType; int rangeStart = (int) (completionPosition >>> 32); if (fieldRef.receiver.isThis()) { if (fieldRef.completeInText()) { @@ -1984,8 +1984,8 @@ null, -1, -1); - if (fieldRef.receiverType instanceof ReferenceBinding) { - ReferenceBinding refBinding = (ReferenceBinding)fieldRef.receiverType; + if (fieldRef.actualReceiverType instanceof ReferenceBinding) { + ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType; if (this.completionToken == null || CharOperation.prefixEquals(this.completionToken, refBinding.sourceName) || (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {