private void visitFunction(OptFunctionNode ofn, int functionType)
    {
        int fnIndex = codegen.getIndex(ofn.fnode);
        cfw.add(ByteCode.NEW, codegen.mainClassName);
        // Call function constructor
        cfw.add(ByteCode.DUP);
        cfw.addALoad(variableObjectLocal);
        cfw.addALoad(contextLocal);           // load 'cx'
        cfw.addPush(fnIndex);
        cfw.addInvoke(ByteCode.INVOKESPECIAL, codegen.mainClassName,
                      "<init>", Codegen.FUNCTION_CONSTRUCTOR_SIGNATURE);

        // Init mainScript field;
        cfw.add(ByteCode.DUP);
        if (isTopLevel) {
            cfw.add(ByteCode.ALOAD_0);
        } else {
            cfw.add(ByteCode.ALOAD_0);
            cfw.add(ByteCode.GETFIELD,
                    codegen.mainClassName,
                    Codegen.DIRECT_CALL_PARENT_FIELD,
                    codegen.mainClassSignature);
        }
        cfw.add(ByteCode.PUTFIELD,
                codegen.mainClassName,
                Codegen.DIRECT_CALL_PARENT_FIELD,
                codegen.mainClassSignature);

        int directTargetIndex = ofn.getDirectTargetIndex();
        if (directTargetIndex >= 0) {
            cfw.add(ByteCode.DUP);
            if (isTopLevel) {
                cfw.add(ByteCode.ALOAD_0);
            } else {
                cfw.add(ByteCode.ALOAD_0);
                cfw.add(ByteCode.GETFIELD,
                        codegen.mainClassName,
                        Codegen.DIRECT_CALL_PARENT_FIELD,
                        codegen.mainClassSignature);
            }
            cfw.add(ByteCode.SWAP);
            cfw.add(ByteCode.PUTFIELD,
                    codegen.mainClassName,
                    Codegen.getDirectTargetFieldName(directTargetIndex),
                    codegen.mainClassSignature);
        }

        if (functionType == FunctionNode.FUNCTION_EXPRESSION) {
            // Leave closure object on stack and do not pass it to
            // initFunction which suppose to connect statements to scope
            return;
        }
        cfw.addPush(functionType);
        cfw.addALoad(variableObjectLocal);
        cfw.addALoad(contextLocal);           // load 'cx'
        addOptRuntimeInvoke("initFunction",
                            "(Lorg/mozilla/javascript/NativeFunction;"
                            +"I"
                            +"Lorg/mozilla/javascript/Scriptable;"
                            +"Lorg/mozilla/javascript/Context;"
                            +")V");
    }