codeStream.generateEmulatedReadAccessForField(fieldBinding);
}
}
break;
case Binding.LOCAL : // assigning to a local variable (cannot assign to outer local)
LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding;
Constant assignConstant;
int increment;
// using incr bytecode if possible
switch (localBinding.type.id) {
case T_JavaLangString :
codeStream.generateStringConcatenationAppend(currentScope, this, expression);
if (valueRequired) {
codeStream.dup();
}
codeStream.store(localBinding, false);
return;
case T_int :
if (((assignConstant = expression.constant) != Constant.NotAConstant)
&& (assignConstant.typeID() != T_float) // only for integral types
&& (assignConstant.typeID() != T_double)
&& ((increment = assignConstant.intValue()) == (short) increment)) { // 16 bits value
switch (operator) {
case PLUS :
codeStream.iinc(localBinding.resolvedPosition, increment);
if (valueRequired) {
codeStream.load(localBinding);
}
return;
case MINUS :
codeStream.iinc(localBinding.resolvedPosition, -increment);
if (valueRequired) {
codeStream.load(localBinding);
}
return;
}
}
default :
codeStream.load(localBinding);
}
}
// perform the actual compound operation
int operationTypeID;
switch(operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) {
case T_JavaLangString :
case T_JavaLangObject :
case T_undefined :
codeStream.generateStringConcatenationAppend(currentScope, null, expression);
break;
default :
// 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);
}
// store the result back into the variable
switch (this.bits & RestrictiveFlagMASK) {
case Binding.FIELD : // assigning to a field
FieldBinding fieldBinding = (FieldBinding) this.codegenBinding;
if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
fieldStore(codeStream, fieldBinding, writeAccessor, valueRequired);
} else {
// current stack is:
// field receiver value
if (valueRequired) {
if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) {
codeStream.dup2_x2();
} else {
codeStream.dup_x2();
}
}
// current stack is:
// value field receiver value
codeStream.generateEmulatedWriteAccessForField(fieldBinding);
}
return;
case Binding.LOCAL : // assigning to a local variable
LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding;
if (valueRequired) {
if ((localBinding.type == TypeBinding.LONG) || (localBinding.type == TypeBinding.DOUBLE)) {
codeStream.dup2();
} else {
codeStream.dup();