in rhino/src/main/java/org/mozilla/javascript/optimizer/BodyCodegen.java [3581:3752]
private void visitIncDec(Node node) {
int incrDecrMask = node.getExistingIntProp(Node.INCRDECR_PROP);
Node child = node.getFirstChild();
if (child.getIntProp(Node.SUPER_PROPERTY_ACCESS, 0) == 1) {
visitSuperIncDec(node, child, incrDecrMask);
return;
}
switch (child.getType()) {
case Token.GETVAR:
if (!hasVarsInRegs) Kit.codeBug();
boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
int varIndex = fnCurrent.getVarIndex(child);
int reg = varRegisters[varIndex];
boolean[] constDeclarations = fnCurrent.fnode.getParamAndVarConst();
if (constDeclarations[varIndex]) {
if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
int offset = varIsDirectCallParameter(varIndex) ? 1 : 0;
cfw.addDLoad(reg + offset);
if (!post) {
cfw.addPush(1.0);
if ((incrDecrMask & Node.DECR_FLAG) == 0) {
cfw.add(ByteCode.DADD);
} else {
cfw.add(ByteCode.DSUB);
}
}
} else {
if (varIsDirectCallParameter(varIndex)) {
dcpLoadAsObject(reg);
} else {
cfw.addALoad(reg);
}
if (post) {
cfw.add(ByteCode.DUP);
addObjectToDouble();
cfw.add(ByteCode.POP2);
} else {
addObjectToDouble();
cfw.addPush(1.0);
if ((incrDecrMask & Node.DECR_FLAG) == 0) {
cfw.add(ByteCode.DADD);
} else {
cfw.add(ByteCode.DSUB);
}
addDoubleWrap();
}
}
break;
}
if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
int offset = varIsDirectCallParameter(varIndex) ? 1 : 0;
cfw.addDLoad(reg + offset);
if (post) {
cfw.add(ByteCode.DUP2);
}
cfw.addPush(1.0);
if ((incrDecrMask & Node.DECR_FLAG) == 0) {
cfw.add(ByteCode.DADD);
} else {
cfw.add(ByteCode.DSUB);
}
if (!post) {
cfw.add(ByteCode.DUP2);
}
cfw.addDStore(reg + offset);
} else {
if (varIsDirectCallParameter(varIndex)) {
dcpLoadAsObject(reg);
} else {
cfw.addALoad(reg);
}
addObjectToDouble();
if (post) {
cfw.add(ByteCode.DUP2);
}
cfw.addPush(1.0);
if ((incrDecrMask & Node.DECR_FLAG) == 0) {
cfw.add(ByteCode.DADD);
} else {
cfw.add(ByteCode.DSUB);
}
addDoubleWrap();
if (!post) {
cfw.add(ByteCode.DUP);
}
cfw.addAStore(reg);
if (post) {
addDoubleWrap();
}
}
break;
case Token.NAME:
cfw.addALoad(variableObjectLocal);
cfw.addPush(child.getString()); // push name
cfw.addALoad(contextLocal);
cfw.addPush(incrDecrMask);
addScriptRuntimeInvoke(
"nameIncrDecr",
"(Lorg/mozilla/javascript/Scriptable;"
+ "Ljava/lang/String;"
+ "Lorg/mozilla/javascript/Context;"
+ "I)Ljava/lang/Object;");
break;
case Token.GETPROPNOWARN:
throw Kit.codeBug();
case Token.GETPROP:
{
Node getPropChild = child.getFirstChild();
generateExpression(getPropChild, node);
generateExpression(getPropChild.getNext(), node);
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
cfw.addPush(incrDecrMask);
addScriptRuntimeInvoke(
"propIncrDecr",
"(Ljava/lang/Object;"
+ "Ljava/lang/String;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ "I)Ljava/lang/Object;");
break;
}
case Token.GETELEM:
{
Node elemChild = child.getFirstChild();
generateExpression(elemChild, node);
generateExpression(elemChild.getNext(), node);
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
cfw.addPush(incrDecrMask);
if (elemChild.getNext().getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
addOptRuntimeInvoke(
"elemIncrDecr",
"(Ljava/lang/Object;"
+ "D"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ "I"
+ ")Ljava/lang/Object;");
} else {
addScriptRuntimeInvoke(
"elemIncrDecr",
"(Ljava/lang/Object;"
+ "Ljava/lang/Object;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ "I"
+ ")Ljava/lang/Object;");
}
break;
}
case Token.GET_REF:
{
Node refChild = child.getFirstChild();
generateExpression(refChild, node);
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
cfw.addPush(incrDecrMask);
addScriptRuntimeInvoke(
"refIncrDecr",
"(Lorg/mozilla/javascript/Ref;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ "I)Ljava/lang/Object;");
break;
}
default:
Codegen.badTree();
}
}