codeStream.store(this.indexVariable, false);
codeStream.addVariable(this.indexVariable);
break;
}
// label management
BranchLabel actionLabel = new BranchLabel(codeStream);
actionLabel.tagBits |= BranchLabel.USED;
BranchLabel conditionLabel = new BranchLabel(codeStream);
conditionLabel.tagBits |= BranchLabel.USED;
this.breakLabel.initialize(codeStream);
if (this.continueLabel == null) {
// generate the condition (swapped for optimizing)
conditionLabel.place();
int conditionPC = codeStream.position;
switch(this.kind) {
case ARRAY :
// inline the arraylength call
// collectionVariable is already on execution stack
codeStream.arraylength();
codeStream.ifeq(this.breakLabel);
break;
case RAW_ITERABLE :
case GENERIC_ITERABLE :
codeStream.load(this.indexVariable);
codeStream.invokeJavaUtilIteratorHasNext();
codeStream.ifeq(this.breakLabel);
break;
}
codeStream.recordPositionsFrom(conditionPC, this.elementVariable.sourceStart);
} else {
this.continueLabel.initialize(codeStream);
this.continueLabel.tagBits |= BranchLabel.USED;
// jump over the actionBlock
codeStream.goto_(conditionLabel);
}
// generate the loop action
actionLabel.place();
// generate the loop action
switch(this.kind) {
case ARRAY :
if (this.elementVariable.binding.resolvedPosition != -1) {
codeStream.load(this.collectionVariable);
if (this.continueLabel == null) {
codeStream.iconst_0(); // no continue, thus simply hardcode offset 0
} else {
codeStream.load(this.indexVariable);
}
codeStream.arrayAt(this.collectionElementType.id);
if (this.elementVariableImplicitWidening != -1) {
codeStream.generateImplicitConversion(this.elementVariableImplicitWidening);
}
codeStream.store(this.elementVariable.binding, false);
codeStream.addVisibleLocalVariable(this.elementVariable.binding);
if (this.postCollectionInitStateIndex != -1) {
codeStream.addDefinitelyAssignedVariables(
currentScope,
this.postCollectionInitStateIndex);
}
}
break;
case RAW_ITERABLE :
case GENERIC_ITERABLE :
codeStream.load(this.indexVariable);
codeStream.invokeJavaUtilIteratorNext();
if (this.elementVariable.binding.type.id != T_JavaLangObject) {
if (this.elementVariableImplicitWidening != -1) {
codeStream.checkcast(this.collectionElementType);
codeStream.generateImplicitConversion(this.elementVariableImplicitWidening);
} else {
codeStream.checkcast(this.elementVariable.binding.type);
}
}
if (this.elementVariable.binding.resolvedPosition == -1) {
codeStream.pop();
} else {
codeStream.store(this.elementVariable.binding, false);
codeStream.addVisibleLocalVariable(this.elementVariable.binding);
if (this.postCollectionInitStateIndex != -1) {
codeStream.addDefinitelyAssignedVariables(
currentScope,
this.postCollectionInitStateIndex);
}
}
break;
}
if (!hasEmptyAction) {
this.action.generateCode(this.scope, codeStream);
}
codeStream.removeVariable(this.elementVariable.binding);
if (this.postCollectionInitStateIndex != -1) {
codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.postCollectionInitStateIndex);
}
// continuation point
if (this.continueLabel != null) {
this.continueLabel.place();
int continuationPC = codeStream.position;
// generate the increments for next iteration
switch(this.kind) {
case ARRAY :
if (!hasEmptyAction || this.elementVariable.binding.resolvedPosition >= 0) {
codeStream.iinc(this.indexVariable.resolvedPosition, 1);
}
// generate the condition
conditionLabel.place();
codeStream.load(this.indexVariable);
codeStream.load(this.maxVariable);
codeStream.if_icmplt(actionLabel);
break;
case RAW_ITERABLE :
case GENERIC_ITERABLE :
// generate the condition
conditionLabel.place();
codeStream.load(this.indexVariable);
codeStream.invokeJavaUtilIteratorHasNext();
codeStream.ifne(actionLabel);
break;
}