private void visitIncDec()

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();
        }
    }