private void visitStandardCall(Node node, Node child)
    {
        if (node.getType() != Token.CALL) throw Codegen.badTree();

        Node firstArgChild = child.getNext();
        int childType = child.getType();

        String methodName;
        String signature;

        if (firstArgChild == null) {
            if (childType == Token.NAME) {
                // name() call
                String name = child.getString();
                cfw.addPush(name);
                methodName = "callName0";
                signature = "(Ljava/lang/String;"
                            +"Lorg/mozilla/javascript/Context;"
                            +"Lorg/mozilla/javascript/Scriptable;"
                            +")Ljava/lang/Object;";
            } else if (childType == Token.GETPROP) {
                // x.name() call
                Node propTarget = child.getFirstChild();
                generateExpression(propTarget, node);
                Node id = propTarget.getNext();
                String property = id.getString();
                cfw.addPush(property);
                methodName = "callProp0";
                signature = "(Ljava/lang/Object;"
                            +"Ljava/lang/String;"
                            +"Lorg/mozilla/javascript/Context;"
                            +"Lorg/mozilla/javascript/Scriptable;"
                            +")Ljava/lang/Object;";
            } else if (childType == Token.GETPROPNOWARN) {
                throw Kit.codeBug();
            } else {
                generateFunctionAndThisObj(child, node);
                methodName = "call0";
                signature = "(Lorg/mozilla/javascript/Callable;"
                            +"Lorg/mozilla/javascript/Scriptable;"
                            +"Lorg/mozilla/javascript/Context;"
                            +"Lorg/mozilla/javascript/Scriptable;"
                            +")Ljava/lang/Object;";
            }

        } else if (childType == Token.NAME) {
            // XXX: this optimization is only possible if name
            // resolution
            // is not affected by arguments evaluation and currently
            // there are no checks for it
            String name = child.getString();
            generateCallArgArray(node, firstArgChild, false);
            cfw.addPush(name);
            methodName = "callName";
            signature = "([Ljava/lang/Object;"
                        +"Ljava/lang/String;"
                        +"Lorg/mozilla/javascript/Context;"
                        +"Lorg/mozilla/javascript/Scriptable;"
                        +")Ljava/lang/Object;";
        } else {
            int argCount = 0;
            for (Node arg = firstArgChild; arg != null; arg = arg.getNext()) {
                ++argCount;
            }
            generateFunctionAndThisObj(child, node);
            // stack: ... functionObj thisObj
            if (argCount == 1) {
                generateExpression(firstArgChild, node);
                methodName = "call1";
                signature = "(Lorg/mozilla/javascript/Callable;"
                            +"Lorg/mozilla/javascript/Scriptable;"
                            +"Ljava/lang/Object;"
                            +"Lorg/mozilla/javascript/Context;"
                            +"Lorg/mozilla/javascript/Scriptable;"
                            +")Ljava/lang/Object;";
            } else if (argCount == 2) {
                generateExpression(firstArgChild, node);
                generateExpression(firstArgChild.getNext(), node);
                methodName = "call2";
                signature = "(Lorg/mozilla/javascript/Callable;"
                            +"Lorg/mozilla/javascript/Scriptable;"
                            +"Ljava/lang/Object;"
                            +"Ljava/lang/Object;"
                            +"Lorg/mozilla/javascript/Context;"
                            +"Lorg/mozilla/javascript/Scriptable;"
                            +")Ljava/lang/Object;";
            } else {
                generateCallArgArray(node, firstArgChild, false);
                methodName = "callN";
                signature = "(Lorg/mozilla/javascript/Callable;"
                            +"Lorg/mozilla/javascript/Scriptable;"
                            +"[Ljava/lang/Object;"
                            +"Lorg/mozilla/javascript/Context;"
                            +"Lorg/mozilla/javascript/Scriptable;"
                            +")Ljava/lang/Object;";
            }
        }

        cfw.addALoad(contextLocal);
        cfw.addALoad(variableObjectLocal);
        addOptRuntimeInvoke(methodName, signature);
    }