Пример #1
0
  public void generateCode(BlockScope currentScope, CodeStream codeStream) {
    if ((this.bits & IsReachable) == 0) {
      return;
    }
    int pc = codeStream.position;

    if (this.assertionSyntheticFieldBinding != null) {
      BranchLabel assertionActivationLabel = new BranchLabel(codeStream);
      codeStream.fieldAccess(
          Opcodes.OPC_getstatic,
          this.assertionSyntheticFieldBinding,
          null /* default declaringClass */);
      codeStream.ifne(assertionActivationLabel);

      BranchLabel falseLabel;
      this.assertExpression.generateOptimizedBoolean(
          currentScope, codeStream, (falseLabel = new BranchLabel(codeStream)), null, true);
      codeStream.newJavaLangAssertionError();
      codeStream.dup();
      if (this.exceptionArgument != null) {
        this.exceptionArgument.generateCode(currentScope, codeStream, true);
        codeStream.invokeJavaLangAssertionErrorConstructor(
            this.exceptionArgument.implicitConversion & 0xF);
      } else {
        codeStream.invokeJavaLangAssertionErrorDefaultConstructor();
      }
      codeStream.athrow();

      // May loose some local variable initializations : affecting the local variable attributes
      if (this.preAssertInitStateIndex != -1) {
        codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preAssertInitStateIndex);
      }
      falseLabel.place();
      assertionActivationLabel.place();
    } else {
      // May loose some local variable initializations : affecting the local variable attributes
      if (this.preAssertInitStateIndex != -1) {
        codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preAssertInitStateIndex);
      }
    }
    codeStream.recordPositionsFrom(pc, this.sourceStart);
  }
 public void generateCompoundAssignment(
     BlockScope currentScope,
     CodeStream codeStream,
     Expression expression,
     int operator,
     int assignmentImplicitConversion,
     boolean valueRequired) {
   boolean isStatic;
   // check if compound assignment is the only usage of a private field
   reportOnlyUselesslyReadPrivateField(currentScope, this.binding, valueRequired);
   FieldBinding codegenBinding = this.binding.original();
   this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
   if (isStatic) {
     if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
       TypeBinding constantPoolDeclaringClass =
           CodeStream.getConstantPoolDeclaringClass(
               currentScope,
               codegenBinding,
               this.actualReceiverType,
               this.receiver.isImplicitThis());
       codeStream.fieldAccess(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) {
       TypeBinding constantPoolDeclaringClass =
           CodeStream.getConstantPoolDeclaringClass(
               currentScope,
               codegenBinding,
               this.actualReceiverType,
               this.receiver.isImplicitThis());
       codeStream.fieldAccess(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
     } else {
       codeStream.invoke(
           Opcodes.OPC_invokestatic,
           this.syntheticAccessors[FieldReference.READ],
           null /* default declaringClass */);
     }
   }
   int operationTypeID;
   switch (operationTypeID = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) {
     case T_JavaLangString:
     case T_JavaLangObject:
     case T_undefined:
       codeStream.generateStringConcatenationAppend(currentScope, null, expression);
       break;
     default:
       if (this.genericCast != null) codeStream.checkcast(this.genericCast);
       // promote the array reference to the suitable operation type
       codeStream.generateImplicitConversion(this.implicitConversion);
       // generate the increment value (will by itself  be promoted to the operation value)
       if (expression == IntLiteral.One) { // prefix operation
         codeStream.generateConstant(expression.constant, this.implicitConversion);
       } else {
         expression.generateCode(currentScope, codeStream, true);
       }
       // perform the operation
       codeStream.sendOperator(operator, operationTypeID);
       // cast the value back to the array reference type
       codeStream.generateImplicitConversion(assignmentImplicitConversion);
   }
   fieldStore(
       currentScope,
       codeStream,
       codegenBinding,
       this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE],
       this.actualReceiverType,
       this.receiver.isImplicitThis(),
       valueRequired);
   // no need for generic cast as value got dupped
 }
 public void generatePostIncrement(
     BlockScope currentScope,
     CodeStream codeStream,
     CompoundAssignment postIncrement,
     boolean valueRequired) {
   boolean isStatic;
   // check if postIncrement is the only usage of a private field
   reportOnlyUselesslyReadPrivateField(currentScope, this.binding, valueRequired);
   FieldBinding codegenBinding = this.binding.original();
   this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
   if (isStatic) {
     if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
       TypeBinding constantPoolDeclaringClass =
           CodeStream.getConstantPoolDeclaringClass(
               currentScope,
               codegenBinding,
               this.actualReceiverType,
               this.receiver.isImplicitThis());
       codeStream.fieldAccess(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) {
       TypeBinding constantPoolDeclaringClass =
           CodeStream.getConstantPoolDeclaringClass(
               currentScope,
               codegenBinding,
               this.actualReceiverType,
               this.receiver.isImplicitThis());
       codeStream.fieldAccess(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
     } else {
       codeStream.invoke(
           Opcodes.OPC_invokestatic,
           this.syntheticAccessors[FieldReference.READ],
           null /* default declaringClass */);
     }
   }
   TypeBinding operandType;
   if (this.genericCast != null) {
     codeStream.checkcast(this.genericCast);
     operandType = this.genericCast;
   } else {
     operandType = codegenBinding.type;
   }
   if (valueRequired) {
     if (isStatic) {
       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]
       switch (operandType.id) {
         case TypeIds.T_long:
         case TypeIds.T_double:
           codeStream.dup2_x1();
           break;
         default:
           codeStream.dup_x1();
           break;
       }
     }
   }
   codeStream.generateImplicitConversion(this.implicitConversion);
   codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
   codeStream.sendOperator(
       postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
   codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
   fieldStore(
       currentScope,
       codeStream,
       codegenBinding,
       this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE],
       this.actualReceiverType,
       this.receiver.isImplicitThis(),
       false);
 }
 /**
  * Field reference code generation
  *
  * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
  * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
  * @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);
     }
     codeStream.recordPositionsFrom(pc, this.sourceStart);
     return;
   }
   FieldBinding codegenBinding = this.binding.original();
   boolean isStatic = codegenBinding.isStatic();
   boolean isThisReceiver = this.receiver instanceof ThisReference;
   Constant fieldConstant = codegenBinding.constant();
   if (fieldConstant != Constant.NotAConstant) {
     if (!isThisReceiver) {
       this.receiver.generateCode(currentScope, codeStream, !isStatic);
       if (!isStatic) {
         codeStream.invokeObjectGetClass();
         codeStream.pop();
       }
     }
     if (valueRequired) {
       codeStream.generateConstant(fieldConstant, this.implicitConversion);
     }
     codeStream.recordPositionsFrom(pc, this.sourceStart);
     return;
   }
   if (valueRequired
       || (!isThisReceiver
           && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
       || ((this.implicitConversion & TypeIds.UNBOXING) != 0)
       || (this.genericCast != null)) {
     this.receiver.generateCode(currentScope, codeStream, !isStatic);
     if ((this.bits & NeedReceiverGenericCast) != 0) {
       codeStream.checkcast(this.actualReceiverType);
     }
     pc = codeStream.position;
     if (codegenBinding.declaringClass == null) { // array length
       codeStream.arraylength();
       if (valueRequired) {
         codeStream.generateImplicitConversion(this.implicitConversion);
       } else {
         // could occur if !valueRequired but compliance >= 1.4
         codeStream.pop();
       }
     } else {
       if (this.syntheticAccessors == null
           || this.syntheticAccessors[FieldReference.READ] == null) {
         TypeBinding constantPoolDeclaringClass =
             CodeStream.getConstantPoolDeclaringClass(
                 currentScope,
                 codegenBinding,
                 this.actualReceiverType,
                 this.receiver.isImplicitThis());
         if (isStatic) {
           codeStream.fieldAccess(
               Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
         } else {
           codeStream.fieldAccess(
               Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
         }
       } else {
         codeStream.invoke(
             Opcodes.OPC_invokestatic,
             this.syntheticAccessors[FieldReference.READ],
             null /* default declaringClass */);
       }
       // required cast must occur even if no value is required
       if (this.genericCast != null) codeStream.checkcast(this.genericCast);
       if (valueRequired) {
         codeStream.generateImplicitConversion(this.implicitConversion);
       } else {
         boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
         // conversion only generated if unboxing
         if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
         switch (isUnboxing ? postConversionType(currentScope).id : codegenBinding.type.id) {
           case T_long:
           case T_double:
             codeStream.pop2();
             break;
           default:
             codeStream.pop();
         }
       }
     }
   } else {
     if (isThisReceiver) {
       if (isStatic) {
         // if no valueRequired, still need possible side-effects of <clinit> invocation, if field
         // belongs to different class
         if (this.binding.original().declaringClass != this.actualReceiverType.erasure()) {
           MethodBinding accessor =
               this.syntheticAccessors == null
                   ? null
                   : this.syntheticAccessors[FieldReference.READ];
           if (accessor == null) {
             TypeBinding constantPoolDeclaringClass =
                 CodeStream.getConstantPoolDeclaringClass(
                     currentScope,
                     codegenBinding,
                     this.actualReceiverType,
                     this.receiver.isImplicitThis());
             codeStream.fieldAccess(
                 Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
           } else {
             codeStream.invoke(
                 Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
           }
           switch (codegenBinding.type.id) {
             case T_long:
             case T_double:
               codeStream.pop2();
               break;
             default:
               codeStream.pop();
           }
         }
       }
     } else {
       this.receiver.generateCode(currentScope, codeStream, !isStatic);
       if (!isStatic) {
         codeStream.invokeObjectGetClass(); // perform null check
         codeStream.pop();
       }
     }
   }
   codeStream.recordPositionsFrom(pc, this.sourceEnd);
 }