}
break;
case Binding.LOCAL : // assigning to a local variable (cannot assign to outer local)
LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
// using incr bytecode if possible
Constant assignConstant;
switch (localBinding.type.id) {
case T_JavaLangString :
codeStream.generateStringConcatenationAppend(currentScope, this, expression);
if (valueRequired) {
codeStream.dup();
}
codeStream.store(localBinding, false);
return;
case T_int :
assignConstant = expression.constant;
if (localBinding.resolvedPosition == -1) {
if (valueRequired) {
/*
* restart code gen because we either:
* - need the value
* - the constant can have potential side-effect
*/
localBinding.useFlag = LocalVariableBinding.USED;
throw new AbortMethod(CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE, null);
} else if (assignConstant == Constant.NotAConstant) {
// we only need to generate the value of the expression's constant if it is not a constant expression
expression.generateCode(currentScope, codeStream, false);
}
return;
}
if ((assignConstant != Constant.NotAConstant)
&& (assignConstant.typeID() != TypeIds.T_float) // only for integral types
&& (assignConstant.typeID() != TypeIds.T_double)) { // TODO (philippe) is this test needed ?
switch (operator) {
case PLUS :
int increment = assignConstant.intValue();
if (increment != (short) increment) break; // not representable as a 16-bits value
codeStream.iinc(localBinding.resolvedPosition, increment);
if (valueRequired) {
codeStream.load(localBinding);
}
return;
case MINUS :
increment = -assignConstant.intValue();
if (increment != (short) increment) break; // not representable as a 16-bits value
codeStream.iinc(localBinding.resolvedPosition, increment);
if (valueRequired) {
codeStream.load(localBinding);
}