Search in sources :

Example 26 with Char

use of com.codename1.ui.TextSelection.Char in project CodenameOne by codenameone.

the class BytecodeMethod method optimize.

boolean optimize() {
    int instructionCount = instructions.size();
    // optimize away a method that only contains the void return instruction e.g. blank constructors etc.
    if (instructionCount < 6) {
        int realCount = instructionCount;
        Instruction actual = null;
        for (int iter = 0; iter < instructionCount; iter++) {
            Instruction current = instructions.get(iter);
            if (current instanceof LabelInstruction) {
                realCount--;
                continue;
            }
            if (current instanceof LineNumber) {
                realCount--;
                continue;
            }
            actual = current;
        }
        if (realCount == 1 && actual != null && actual.getOpcode() == Opcodes.RETURN) {
            return false;
        }
    }
    boolean astoreCalls = false;
    boolean hasInstructions = false;
    boolean hasTryCatch = false;
    for (int iter = 0; iter < instructionCount - 1; iter++) {
        Instruction current = instructions.get(iter);
        if (current instanceof TryCatch) {
            hasTryCatch = true;
        }
        current.setMethod(this);
        if (current.isOptimized()) {
            continue;
        }
        int currentOpcode = current.getOpcode();
        switch(currentOpcode) {
            case Opcodes.CHECKCAST:
                {
                    // Remove the check cast for now as it gets in the way of other optimizations
                    instructions.remove(iter);
                    iter--;
                    instructionCount--;
                    break;
                }
        }
    }
    for (int iter = 0; iter < instructionCount - 1; iter++) {
        Instruction current = instructions.get(iter);
        if (current.isOptimized()) {
            // we should skip it and proceed to the next one
            continue;
        }
        Instruction next = instructions.get(iter + 1);
        int currentOpcode = current.getOpcode();
        int nextOpcode = next.getOpcode();
        if (ArithmeticExpression.isArithmeticOp(current)) {
            int addedIndex = ArithmeticExpression.tryReduce(instructions, iter);
            if (addedIndex >= 0) {
                iter = addedIndex;
                instructionCount = instructions.size();
                continue;
            }
        }
        if (current instanceof Field) {
            int newIter = Field.tryReduce(instructions, iter);
            if (newIter >= 0) {
                iter = newIter;
                instructionCount = instructions.size();
                continue;
            }
        }
        switch(currentOpcode) {
            case Opcodes.ARRAYLENGTH:
                {
                    if (!dependentClasses.contains("java_lang_NullPointerException")) {
                        dependentClasses.add("java_lang_NullPointerException");
                    }
                    int newIter = ArrayLengthExpression.tryReduce(instructions, iter);
                    if (newIter >= 0) {
                        instructionCount = instructions.size();
                        iter = newIter;
                        continue;
                    }
                    break;
                }
            case Opcodes.DUP:
                {
                    int newIter = DupExpression.tryReduce(instructions, iter);
                    if (newIter >= 0) {
                        iter = newIter;
                        instructionCount = instructions.size();
                        continue;
                    }
                    break;
                }
            case Opcodes.POP:
                {
                    if (iter > 0) {
                        Instruction prev = instructions.get(iter - 1);
                        if (prev instanceof CustomInvoke) {
                            CustomInvoke inv = (CustomInvoke) prev;
                            if (inv.methodHasReturnValue() && !inv.isNoReturn()) {
                                inv.setNoReturn(true);
                                instructions.remove(iter);
                                iter--;
                                instructionCount--;
                                continue;
                            }
                        }
                    }
                    break;
                }
            case Opcodes.ASTORE:
            case Opcodes.ISTORE:
            case Opcodes.DSTORE:
            case Opcodes.LSTORE:
            case Opcodes.FSTORE:
                {
                    if (iter > 0 && current instanceof VarOp) {
                        VarOp currentVarOp = (VarOp) current;
                        Instruction prev = instructions.get(iter - 1);
                        if (prev instanceof AssignableExpression) {
                            AssignableExpression expr = (AssignableExpression) prev;
                            StringBuilder sb = new StringBuilder();
                            if (currentVarOp.assignFrom(expr, sb)) {
                                instructions.remove(iter - 1);
                                instructions.remove(iter - 1);
                                instructions.add(iter - 1, new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
                                iter = iter - 1;
                                instructionCount = instructions.size();
                                continue;
                            }
                        } else if (prev instanceof CustomInvoke) {
                            CustomInvoke inv = (CustomInvoke) prev;
                            StringBuilder sb = new StringBuilder();
                            if (currentVarOp.assignFrom(inv, sb)) {
                                instructions.remove(iter - 1);
                                instructions.remove(iter - 1);
                                instructions.add(iter - 1, new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
                                iter = iter - 1;
                                instructionCount = instructions.size();
                                continue;
                            }
                        }
                    }
                    break;
                }
            case Opcodes.IRETURN:
            case Opcodes.FRETURN:
            case Opcodes.ARETURN:
            case Opcodes.LRETURN:
            case Opcodes.DRETURN:
                {
                    if (iter > 0 && current instanceof BasicInstruction) {
                        Instruction prev = instructions.get(iter - 1);
                        if (prev instanceof AssignableExpression) {
                            AssignableExpression expr = (AssignableExpression) prev;
                            StringBuilder sb = new StringBuilder();
                            if (expr.assignTo(null, sb)) {
                                instructions.remove(iter - 1);
                                instructions.remove(iter - 1);
                                String exprString = sb.toString().trim();
                                String retVal = exprString;
                                sb.setLength(0);
                                if (!prev.isConstant()) {
                                    sb.append("\n{\n    ");
                                    switch(currentOpcode) {
                                        case Opcodes.IRETURN:
                                            sb.append("JAVA_INT");
                                            break;
                                        case Opcodes.FRETURN:
                                            sb.append("JAVA_FLOAT");
                                            break;
                                        case Opcodes.ARETURN:
                                            sb.append("JAVA_OBJECT");
                                            break;
                                        case Opcodes.LRETURN:
                                            sb.append("JAVA_LONG");
                                            break;
                                        case Opcodes.DRETURN:
                                            sb.append("JAVA_DOUBLE");
                                            break;
                                    }
                                    sb.append(" ___returnValue=").append(exprString).append(";\n");
                                    retVal = "___returnValue";
                                }
                                if (synchronizedMethod) {
                                    if (staticMethod) {
                                        sb.append("    monitorExitBlock(threadStateData, (JAVA_OBJECT)&class__");
                                        sb.append(getClsName());
                                        sb.append(");\n");
                                    } else {
                                        sb.append("    monitorExitBlock(threadStateData, __cn1ThisObject);\n");
                                    }
                                }
                                if (hasTryCatch) {
                                    sb.append("    releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); return ").append(retVal).append(";\n");
                                } else {
                                    sb.append("    releaseForReturn(threadStateData, cn1LocalsBeginInThread); return ").append(retVal).append(";\n");
                                }
                                if (!prev.isConstant()) {
                                    sb.append("}\n");
                                }
                                instructions.add(iter - 1, new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
                                iter--;
                                instructionCount = instructions.size();
                                continue;
                            }
                        } else if (prev instanceof CustomInvoke) {
                            CustomInvoke expr = (CustomInvoke) prev;
                            String returnType = expr.getReturnValue();
                            if (returnType != null && !"JAVA_OBJECT".equals(returnType)) {
                                // We can't safely return a JAVA_OBJECT directly because it needs to be added
                                // to the stack for the GC
                                StringBuilder sb = new StringBuilder();
                                if (expr.appendExpression(sb)) {
                                    instructions.remove(iter - 1);
                                    instructions.remove(iter - 1);
                                    String exprString = sb.toString().trim();
                                    String retVal = exprString;
                                    sb.setLength(0);
                                    if (!expr.isConstant()) {
                                        sb.append("\n{\n    ");
                                        switch(currentOpcode) {
                                            case Opcodes.IRETURN:
                                                sb.append("JAVA_INT");
                                                break;
                                            case Opcodes.FRETURN:
                                                sb.append("JAVA_FLOAT");
                                                break;
                                            case Opcodes.ARETURN:
                                                sb.append("JAVA_OBJECT");
                                                break;
                                            case Opcodes.LRETURN:
                                                sb.append("JAVA_LONG");
                                                break;
                                            case Opcodes.DRETURN:
                                                sb.append("JAVA_DOUBLE");
                                                break;
                                        }
                                        sb.append(" ___returnValue=").append(exprString).append(";\n");
                                        retVal = "___returnValue";
                                    }
                                    if (synchronizedMethod) {
                                        if (staticMethod) {
                                            sb.append("    monitorExitBlock(threadStateData, (JAVA_OBJECT)&class__");
                                            sb.append(getClsName());
                                            sb.append(");\n");
                                        } else {
                                            sb.append("    monitorExitBlock(threadStateData, __cn1ThisObject);\n");
                                        }
                                    }
                                    if (hasTryCatch) {
                                        sb.append("    releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); return ").append(retVal).append(";\n");
                                    } else {
                                        sb.append("    releaseForReturn(threadStateData, cn1LocalsBeginInThread); return ").append(retVal).append(";\n");
                                    }
                                    if (!expr.isConstant()) {
                                        sb.append("}\n");
                                    }
                                    instructions.add(iter - 1, new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
                                    iter--;
                                    instructionCount = instructions.size();
                                    continue;
                                }
                            }
                        }
                    }
                    break;
                }
            case Opcodes.BASTORE:
            case Opcodes.SASTORE:
            case Opcodes.CASTORE:
            case Opcodes.AASTORE:
            case Opcodes.IASTORE:
            case Opcodes.DASTORE:
            case Opcodes.LASTORE:
            case Opcodes.FASTORE:
                {
                    if (iter > 2 && current instanceof BasicInstruction) {
                        StringBuilder devNull = new StringBuilder();
                        String arrayLiteral = null;
                        String indexLiteral = null;
                        String valueLiteral = null;
                        Instruction prev3 = instructions.get(iter - 3);
                        if (prev3 instanceof AssignableExpression) {
                            if (((AssignableExpression) prev3).assignTo(null, devNull)) {
                                arrayLiteral = devNull.toString().trim();
                            }
                        }
                        devNull.setLength(0);
                        Instruction prev2 = instructions.get(iter - 2);
                        if (prev2 instanceof AssignableExpression) {
                            if (((AssignableExpression) prev2).assignTo(null, devNull)) {
                                indexLiteral = devNull.toString().trim();
                            }
                        }
                        devNull.setLength(0);
                        Instruction prev1 = instructions.get(iter - 1);
                        if (prev1 instanceof AssignableExpression) {
                            if (((AssignableExpression) prev1).assignTo(null, devNull)) {
                                valueLiteral = devNull.toString().trim();
                            }
                        } else if (prev1 instanceof CustomInvoke) {
                            devNull.setLength(0);
                            if (((CustomInvoke) prev1).appendExpression(devNull)) {
                                valueLiteral = devNull.toString().trim();
                            }
                        }
                        if (arrayLiteral != null && indexLiteral != null && valueLiteral != null) {
                            String elementType = null;
                            switch(current.getOpcode()) {
                                case Opcodes.AASTORE:
                                    elementType = "OBJECT";
                                    break;
                                case Opcodes.IASTORE:
                                    elementType = "INT";
                                    break;
                                case Opcodes.DASTORE:
                                    elementType = "DOUBLE";
                                    break;
                                case Opcodes.LASTORE:
                                    elementType = "LONG";
                                    break;
                                case Opcodes.FASTORE:
                                    elementType = "FLOAT";
                                    break;
                                case Opcodes.CASTORE:
                                    elementType = "CHAR";
                                    break;
                                case Opcodes.BASTORE:
                                    elementType = "BYTE";
                                    break;
                                case Opcodes.SASTORE:
                                    elementType = "SHORT";
                                    break;
                            }
                            if (elementType == null) {
                                break;
                            }
                            instructions.remove(iter - 3);
                            instructions.remove(iter - 3);
                            instructions.remove(iter - 3);
                            instructions.remove(iter - 3);
                            String code = "    CN1_SET_ARRAY_ELEMENT_" + elementType + "(" + arrayLiteral + ", " + indexLiteral + ", " + valueLiteral + ");\n";
                            instructions.add(iter - 3, new CustomIntruction(code, code, dependentClasses));
                            iter = iter - 3;
                            instructionCount = instructions.size();
                            continue;
                        }
                    }
                    break;
                }
            case Opcodes.FALOAD:
            case Opcodes.BALOAD:
            case Opcodes.IALOAD:
            case Opcodes.LALOAD:
            case Opcodes.DALOAD:
            case Opcodes.AALOAD:
            case Opcodes.SALOAD:
            case Opcodes.CALOAD:
                {
                    int newIter = ArrayLoadExpression.tryReduce(instructions, iter);
                    if (newIter >= 0) {
                        iter = newIter;
                        instructionCount = instructions.size();
                        continue;
                    }
                    break;
                }
            /* Try to optimize if statements that just use constants
                   and local variables so that they don't need the intermediate
                   push and pop from the stack.
                */
            case Opcodes.IF_ACMPEQ:
            case Opcodes.IF_ACMPNE:
            case Opcodes.IF_ICMPLE:
            case Opcodes.IF_ICMPLT:
            case Opcodes.IF_ICMPNE:
            case Opcodes.IF_ICMPGT:
            case Opcodes.IF_ICMPEQ:
            case Opcodes.IF_ICMPGE:
                {
                    if (iter > 1) {
                        Instruction leftArg = instructions.get(iter - 2);
                        Instruction rightArg = instructions.get(iter - 1);
                        String leftLiteral = null;
                        String rightLiteral = null;
                        if (leftArg instanceof AssignableExpression) {
                            StringBuilder sb = new StringBuilder();
                            if (((AssignableExpression) leftArg).assignTo(null, sb)) {
                                leftLiteral = sb.toString().trim();
                            }
                        } else if (leftArg instanceof CustomInvoke) {
                            CustomInvoke inv = (CustomInvoke) leftArg;
                            StringBuilder sb = new StringBuilder();
                            if (!"JAVA_OBJECT".equals(inv.getReturnValue()) && inv.appendExpression(sb)) {
                                leftLiteral = sb.toString().trim();
                            }
                        }
                        if (rightArg instanceof AssignableExpression) {
                            StringBuilder sb = new StringBuilder();
                            if (((AssignableExpression) rightArg).assignTo(null, sb)) {
                                rightLiteral = sb.toString().trim();
                            }
                        } else if (rightArg instanceof CustomInvoke) {
                            CustomInvoke inv = (CustomInvoke) rightArg;
                            StringBuilder sb = new StringBuilder();
                            if (!"JAVA_OBJECT".equals(inv.getReturnValue()) && inv.appendExpression(sb)) {
                                rightLiteral = sb.toString().trim();
                            }
                        }
                        if (rightLiteral != null && leftLiteral != null) {
                            Jump jmp = (Jump) current;
                            instructions.remove(iter - 2);
                            instructions.remove(iter - 2);
                            instructions.remove(iter - 2);
                            // instructions.remove(iter-2);
                            iter -= 2;
                            // instructionCount -= 2;
                            StringBuilder sb = new StringBuilder();
                            String operator = null;
                            String opName = null;
                            switch(currentOpcode) {
                                case Opcodes.IF_ICMPLE:
                                    operator = "<=";
                                    opName = "IF_ICMPLE";
                                    break;
                                case Opcodes.IF_ICMPLT:
                                    operator = "<";
                                    opName = "IF_IMPLT";
                                    break;
                                case Opcodes.IF_ICMPNE:
                                    operator = "!=";
                                    opName = "IF_ICMPNE";
                                    break;
                                case Opcodes.IF_ICMPGT:
                                    operator = ">";
                                    opName = "IF_ICMPGT";
                                    break;
                                case Opcodes.IF_ICMPGE:
                                    operator = ">=";
                                    opName = "IF_ICMPGE";
                                    break;
                                case Opcodes.IF_ICMPEQ:
                                    operator = "==";
                                    opName = "IF_ICMPEQ";
                                    break;
                                case Opcodes.IF_ACMPEQ:
                                    operator = "==";
                                    opName = "IF_ACMPEQ";
                                    break;
                                case Opcodes.IF_ACMPNE:
                                    operator = "!=";
                                    opName = "IF_ACMPNE";
                                    break;
                                default:
                                    throw new RuntimeException("Invalid operator during optimization of integer comparison");
                            }
                            sb.append("if (").append(leftLiteral).append(operator).append(rightLiteral).append(") /* ").append(opName).append(" CustomJump */ ");
                            CustomJump newJump = CustomJump.create(jmp, sb.toString());
                            // jmp.setCustomCompareCode(sb.toString());
                            newJump.setOptimized(true);
                            instructions.add(iter, newJump);
                            instructionCount = instructions.size();
                        }
                    }
                    break;
                }
            case Opcodes.IFNONNULL:
            case Opcodes.IFNULL:
            case Opcodes.IFLE:
            case Opcodes.IFLT:
            case Opcodes.IFNE:
            case Opcodes.IFGT:
            case Opcodes.IFEQ:
            case Opcodes.IFGE:
                {
                    String rightArg = "0";
                    if (currentOpcode == Opcodes.IFNONNULL || currentOpcode == Opcodes.IFNULL) {
                        rightArg = "JAVA_NULL";
                    }
                    if (iter > 0) {
                        Instruction leftArg = instructions.get(iter - 1);
                        String leftLiteral = null;
                        if (leftArg instanceof AssignableExpression) {
                            StringBuilder sb = new StringBuilder();
                            if (((AssignableExpression) leftArg).assignTo(null, sb)) {
                                leftLiteral = sb.toString().trim();
                            }
                        } else if (leftArg instanceof CustomInvoke) {
                            CustomInvoke inv = (CustomInvoke) leftArg;
                            StringBuilder sb = new StringBuilder();
                            if (inv.appendExpression(sb)) {
                                leftLiteral = sb.toString().trim();
                            }
                        }
                        if (leftLiteral != null) {
                            Jump jmp = (Jump) current;
                            instructions.remove(iter - 1);
                            instructions.remove(iter - 1);
                            // instructions.remove(iter-2);
                            iter -= 1;
                            // instructionCount -= 2;
                            StringBuilder sb = new StringBuilder();
                            String operator = null;
                            String opName = null;
                            switch(currentOpcode) {
                                case Opcodes.IFLE:
                                    operator = "<=";
                                    opName = "IFLE";
                                    break;
                                case Opcodes.IFLT:
                                    operator = "<";
                                    opName = "IFLT";
                                    break;
                                case Opcodes.IFNE:
                                    operator = "!=";
                                    opName = "IFNE";
                                    break;
                                case Opcodes.IFGT:
                                    operator = ">";
                                    opName = "IFGT";
                                    break;
                                case Opcodes.IFGE:
                                    operator = ">=";
                                    opName = "IFGE";
                                    break;
                                case Opcodes.IFEQ:
                                    operator = "==";
                                    opName = "IFEQ";
                                    break;
                                case Opcodes.IFNULL:
                                    operator = "==";
                                    opName = "IFNULL";
                                    break;
                                case Opcodes.IFNONNULL:
                                    operator = "!=";
                                    opName = "IFNONNULL";
                                    break;
                                default:
                                    throw new RuntimeException("Invalid operator during optimization of integer comparison");
                            }
                            sb.append("if (").append(leftLiteral).append(operator).append(rightArg).append(") /* ").append(opName).append(" CustomJump */ ");
                            CustomJump newJump = CustomJump.create(jmp, sb.toString());
                            // jmp.setCustomCompareCode(sb.toString());
                            newJump.setOptimized(true);
                            instructions.add(iter, newJump);
                            instructionCount = instructions.size();
                        }
                    }
                    break;
                }
            case Opcodes.INVOKEVIRTUAL:
            case Opcodes.INVOKESTATIC:
            case Opcodes.INVOKESPECIAL:
            case Opcodes.INVOKEINTERFACE:
                {
                    if (current instanceof Invoke) {
                        Invoke inv = (Invoke) current;
                        List<ByteCodeMethodArg> invocationArgs = inv.getArgs();
                        int numArgs = invocationArgs.size();
                        // }
                        if (iter >= numArgs) {
                            String[] argLiterals = new String[numArgs];
                            StringBuilder devNull = new StringBuilder();
                            for (int i = 0; i < numArgs; i++) {
                                devNull.setLength(0);
                                Instruction instr = instructions.get(iter - numArgs + i);
                                if (instr instanceof AssignableExpression && ((AssignableExpression) instr).assignTo(null, devNull)) {
                                    argLiterals[i] = devNull.toString().trim();
                                } else if (instr instanceof CustomInvoke) {
                                    CustomInvoke cinv = (CustomInvoke) instr;
                                    devNull.setLength(0);
                                    if (!"JAVA_OBJECT".equals(cinv.getReturnValue()) && cinv.appendExpression(devNull)) {
                                        // We can't add invocations that return objects directly
                                        // because they need to be added to the stack for GC
                                        argLiterals[i] = devNull.toString().trim();
                                    }
                                } else if (instr instanceof ArithmeticExpression) {
                                    argLiterals[i] = ((ArithmeticExpression) instr).getExpressionAsString().trim();
                                } else if (instr instanceof VarOp) {
                                    VarOp var = (VarOp) instr;
                                    switch(instr.getOpcode()) {
                                        case Opcodes.ALOAD:
                                            {
                                                if (!isStatic() && var.getIndex() == 0) {
                                                    argLiterals[i] = "__cn1ThisObject";
                                                } else {
                                                    argLiterals[i] = "locals[" + var.getIndex() + "].data.o";
                                                }
                                                break;
                                            }
                                        case Opcodes.ILOAD:
                                            {
                                                argLiterals[i] = "ilocals_" + var.getIndex() + "_";
                                                break;
                                            }
                                        case Opcodes.ACONST_NULL:
                                            {
                                                argLiterals[i] = "JAVA_NULL";
                                                break;
                                            }
                                        case Opcodes.DLOAD:
                                            {
                                                argLiterals[i] = "dlocals_" + var.getIndex() + "_";
                                                break;
                                            }
                                        case Opcodes.FLOAD:
                                            {
                                                argLiterals[i] = "flocals_" + var.getIndex() + "_";
                                                break;
                                            }
                                        case Opcodes.LLOAD:
                                            {
                                                argLiterals[i] = "llocals_" + var.getIndex() + "_";
                                                break;
                                            }
                                        case Opcodes.ICONST_0:
                                            {
                                                argLiterals[i] = "0";
                                                break;
                                            }
                                        case Opcodes.ICONST_1:
                                            {
                                                argLiterals[i] = "1";
                                                break;
                                            }
                                        case Opcodes.ICONST_2:
                                            {
                                                argLiterals[i] = "2";
                                                break;
                                            }
                                        case Opcodes.ICONST_3:
                                            {
                                                argLiterals[i] = "3";
                                                break;
                                            }
                                        case Opcodes.ICONST_4:
                                            {
                                                argLiterals[i] = "4";
                                                break;
                                            }
                                        case Opcodes.ICONST_5:
                                            {
                                                argLiterals[i] = "5";
                                                break;
                                            }
                                        case Opcodes.ICONST_M1:
                                            {
                                                argLiterals[i] = "-1";
                                                break;
                                            }
                                        case Opcodes.LCONST_0:
                                            {
                                                argLiterals[i] = "(JAVA_LONG)0";
                                                break;
                                            }
                                        case Opcodes.LCONST_1:
                                            {
                                                argLiterals[i] = "(JAVA_LONG)1";
                                                break;
                                            }
                                        case Opcodes.BIPUSH:
                                        case Opcodes.SIPUSH:
                                            {
                                                argLiterals[i] = String.valueOf(var.getIndex());
                                                break;
                                            }
                                    }
                                } else {
                                    switch(instr.getOpcode()) {
                                        case Opcodes.ACONST_NULL:
                                            {
                                                argLiterals[i] = "JAVA_NULL";
                                                break;
                                            }
                                        case Opcodes.ICONST_0:
                                            {
                                                argLiterals[i] = "0";
                                                break;
                                            }
                                        case Opcodes.ICONST_1:
                                            {
                                                argLiterals[i] = "1";
                                                break;
                                            }
                                        case Opcodes.ICONST_2:
                                            {
                                                argLiterals[i] = "2";
                                                break;
                                            }
                                        case Opcodes.ICONST_3:
                                            {
                                                argLiterals[i] = "3";
                                                break;
                                            }
                                        case Opcodes.ICONST_4:
                                            {
                                                argLiterals[i] = "4";
                                                break;
                                            }
                                        case Opcodes.ICONST_5:
                                            {
                                                argLiterals[i] = "5";
                                                break;
                                            }
                                        case Opcodes.ICONST_M1:
                                            {
                                                argLiterals[i] = "-1";
                                                break;
                                            }
                                        case Opcodes.LCONST_0:
                                            {
                                                argLiterals[i] = "(JAVA_LONG)0";
                                                break;
                                            }
                                        case Opcodes.LCONST_1:
                                            {
                                                argLiterals[i] = "(JAVA_LONG)1";
                                                break;
                                            }
                                        case Opcodes.BIPUSH:
                                            {
                                                if (instr instanceof BasicInstruction) {
                                                    argLiterals[i] = String.valueOf(((BasicInstruction) instr).getValue());
                                                }
                                                break;
                                            }
                                        case Opcodes.LDC:
                                            {
                                                if (instr instanceof Ldc) {
                                                    Ldc ldc = (Ldc) instr;
                                                    argLiterals[i] = ldc.getValueAsString();
                                                }
                                                break;
                                            }
                                    }
                                }
                            }
                            // Check to make sure that we have all the args as literals.
                            boolean missingLiteral = false;
                            for (String lit : argLiterals) {
                                if (lit == null) {
                                    missingLiteral = true;
                                    break;
                                }
                            }
                            // add them to our invoke instruction.
                            if (!missingLiteral) {
                                CustomInvoke newInvoke = CustomInvoke.create(inv);
                                instructions.remove(iter);
                                instructions.add(iter, newInvoke);
                                int newIter = iter;
                                for (int i = 0; i < numArgs; i++) {
                                    instructions.remove(iter - numArgs);
                                    newIter--;
                                    newInvoke.setLiteralArg(i, argLiterals[i]);
                                }
                                if (inv.getOpcode() != Opcodes.INVOKESTATIC) {
                                    Instruction ldTarget = instructions.get(iter - numArgs - 1);
                                    if (ldTarget instanceof AssignableExpression) {
                                        StringBuilder targetExprStr = new StringBuilder();
                                        if (((AssignableExpression) ldTarget).assignTo(null, targetExprStr)) {
                                            newInvoke.setTargetObjectLiteral(targetExprStr.toString().trim());
                                            instructions.remove(iter - numArgs - 1);
                                            newIter--;
                                        }
                                    } else if (ldTarget instanceof CustomInvoke) {
                                    // WE Can't pass a custom invoke as the target directly
                                    // because it the return value needs to be added to the
                                    // stack for the GC
                                    } else {
                                        switch(ldTarget.getOpcode()) {
                                            case Opcodes.ALOAD:
                                                {
                                                    VarOp v = (VarOp) ldTarget;
                                                    if (isStatic() && v.getIndex() == 0) {
                                                        newInvoke.setTargetObjectLiteral("__cn1ThisObject");
                                                    } else {
                                                        newInvoke.setTargetObjectLiteral("locals[" + v.getIndex() + "].data.o");
                                                    }
                                                    instructions.remove(iter - numArgs - 1);
                                                    newIter--;
                                                    break;
                                                }
                                        }
                                    }
                                }
                                newInvoke.setOptimized(true);
                                // iter = 0;
                                instructionCount = instructions.size();
                                iter = newIter;
                            }
                        }
                    }
                    break;
                }
        }
        astoreCalls = astoreCalls || currentOpcode == Opcodes.ASTORE || currentOpcode == Opcodes.ISTORE || currentOpcode == Opcodes.LSTORE || currentOpcode == Opcodes.DSTORE || currentOpcode == Opcodes.FSTORE;
        hasInstructions = hasInstructions | current.getOpcode() != -1;
    }
    return hasInstructions;
}
Also used : TryCatch(com.codename1.tools.translator.bytecodes.TryCatch) VarOp(com.codename1.tools.translator.bytecodes.VarOp) CustomIntruction(com.codename1.tools.translator.bytecodes.CustomIntruction) LabelInstruction(com.codename1.tools.translator.bytecodes.LabelInstruction) Ldc(com.codename1.tools.translator.bytecodes.Ldc) BasicInstruction(com.codename1.tools.translator.bytecodes.BasicInstruction) SwitchInstruction(com.codename1.tools.translator.bytecodes.SwitchInstruction) TypeInstruction(com.codename1.tools.translator.bytecodes.TypeInstruction) Instruction(com.codename1.tools.translator.bytecodes.Instruction) LabelInstruction(com.codename1.tools.translator.bytecodes.LabelInstruction) ArithmeticExpression(com.codename1.tools.translator.bytecodes.ArithmeticExpression) CustomInvoke(com.codename1.tools.translator.bytecodes.CustomInvoke) Jump(com.codename1.tools.translator.bytecodes.Jump) CustomJump(com.codename1.tools.translator.bytecodes.CustomJump) LineNumber(com.codename1.tools.translator.bytecodes.LineNumber) CustomInvoke(com.codename1.tools.translator.bytecodes.CustomInvoke) Invoke(com.codename1.tools.translator.bytecodes.Invoke) Field(com.codename1.tools.translator.bytecodes.Field) BasicInstruction(com.codename1.tools.translator.bytecodes.BasicInstruction) AssignableExpression(com.codename1.tools.translator.bytecodes.AssignableExpression) CustomJump(com.codename1.tools.translator.bytecodes.CustomJump) ArrayList(java.util.ArrayList) List(java.util.List)

Example 27 with Char

use of com.codename1.ui.TextSelection.Char in project CodenameOne by codenameone.

the class SpinnerRenderer method drawCharPerspectivePosition.

/**
 * Draws the character with the given perspective effect
 */
private int drawCharPerspectivePosition(Graphics g, char c, int x, int y) {
    if (imageCache == null) {
        imageCache = new HashMap[PERSPECTIVES];
        for (int iter = 0; iter < PERSPECTIVES; iter++) {
            if (iter != FRONT_ANGLE) {
                imageCache[iter] = new HashMap<Character, Image>();
            }
        }
    }
    Character chr = new Character(c);
    Image i = imageCache[perspective].get(chr);
    if (i == null) {
        // UIManager.getInstance().getLookAndFeel().setFG(g, this);
        Font f = getStyle().getFont();
        int w = f.charWidth(c);
        int h = f.getHeight();
        i = ImageFactory.createImage(this, w, h, 0);
        g = i.getGraphics();
        UIManager.getInstance().getLookAndFeel().setFG(g, this);
        int alpha = g.concatenateAlpha(getStyle().getFgAlpha());
        g.drawChar(c, 0, 0);
        g.setAlpha(alpha);
        i = Effects.verticalPerspective(i, TOP_SCALE[perspective], BOTTOM_SCALE[perspective], VERTICAL_SHRINK[perspective]);
        imageCache[perspective].put(chr, i);
    }
    g.drawImage(i, x, y);
    return i.getWidth();
}
Also used : Image(com.codename1.ui.Image) Font(com.codename1.ui.Font)

Example 28 with Char

use of com.codename1.ui.TextSelection.Char in project CodenameOne by codenameone.

the class RSSService method readResponse.

/**
 * {@inheritDoc}
 */
protected void readResponse(InputStream input) throws IOException {
    results = new Vector();
    class FinishParsing extends RuntimeException {
    }
    XMLParser p = new XMLParser() {

        private String lastTag;

        private Hashtable current;

        private String url;

        protected boolean startTag(String tag) {
            if ("item".equalsIgnoreCase(tag) || "entry".equalsIgnoreCase(tag)) {
                if (startOffset > 0) {
                    return true;
                }
                current = new Hashtable();
                if (iconPlaceholder != null) {
                    current.put("icon", iconPlaceholder);
                }
            }
            lastTag = tag;
            return true;
        }

        protected void attribute(String tag, String attributeName, String value) {
            if (current != null) {
                if ("media:thumbnail".equalsIgnoreCase(tag) && "url".equalsIgnoreCase(attributeName)) {
                    current.put("thumb", value);
                } else {
                    if ("media:player".equalsIgnoreCase(tag) && "url".equalsIgnoreCase(attributeName)) {
                        current.put("player", value);
                    }
                }
            }
        }

        protected void textElement(String text) {
            if (lastTag != null && current != null) {
                // make "ATOM" seem like RSS
                if ("summary".equals(lastTag)) {
                    current.put("details", text);
                } else {
                    if ("content".equals(lastTag)) {
                        current.put("description", text);
                    } else {
                        current.put(lastTag, text);
                    }
                }
            }
        }

        protected void endTag(String tag) {
            if ("item".equalsIgnoreCase(tag) || "entry".equalsIgnoreCase(tag)) {
                if (startOffset > 0) {
                    startOffset--;
                    return;
                }
                results.addElement(current);
                current = null;
                if (limit > -1 && results.size() >= limit) {
                    throw new FinishParsing();
                }
            }
            if (tag.equals(lastTag)) {
                lastTag = null;
            }
        }
    };
    p.setParserCallback(this);
    input.mark(10);
    // Skip the bom marking UTF-8 in some streams
    while (input.read() != '<') {
    // input.mark(4);
    }
    int question = input.read();
    String cType = "UTF-8";
    if (question == '?') {
        // we are in an XML header, check if the encoding section exists
        StringBuilder cs = new StringBuilder();
        question = input.read();
        while (question != '>') {
            cs.append((char) question);
            question = input.read();
        }
        String str = cs.toString();
        int index = str.indexOf("encoding=\"") + 10;
        if (index > -1) {
            cType = str.substring(index, Math.max(str.indexOf("\"", index), str.indexOf("'", index)));
        }
    } else {
        // oops, continue as usual
        input.reset();
    }
    String resultType = getResponseContentType();
    if (resultType != null && resultType.indexOf("charset=") > -1) {
        cType = resultType.substring(resultType.indexOf("charset=") + 8);
    }
    try {
        int pos2 = cType.indexOf(';');
        if (pos2 > 0) {
            cType = cType.substring(0, pos2);
        }
        p.eventParser(new InputStreamReader(input, cType));
    } catch (FinishParsing ignor) {
        hasMore = true;
    }
    if (isCreatePlainTextDetails()) {
        int elementCount = results.size();
        for (int iter = 0; iter < elementCount; iter++) {
            Hashtable h = (Hashtable) results.elementAt(iter);
            String s = (String) h.get("description");
            if (s != null && !h.containsKey("details")) {
                XMLParser x = new XMLParser();
                Element e = x.parse(new CharArrayReader(("<xml>" + s + "</xml>").toCharArray()));
                Vector results = e.getTextDescendants(null, false);
                StringBuilder endResult = new StringBuilder();
                for (int i = 0; i < results.size(); i++) {
                    endResult.append(((Element) results.elementAt(i)).getText());
                }
                h.put("details", endResult.toString());
            }
        }
    }
    fireResponseListener(new NetworkEvent(this, results));
}
Also used : CharArrayReader(com.codename1.io.CharArrayReader) InputStreamReader(java.io.InputStreamReader) Hashtable(java.util.Hashtable) Element(com.codename1.xml.Element) NetworkEvent(com.codename1.io.NetworkEvent) XMLParser(com.codename1.xml.XMLParser) Vector(java.util.Vector)

Example 29 with Char

use of com.codename1.ui.TextSelection.Char in project CodenameOne by codenameone.

the class DefaultLookAndFeel method getTextFieldCursorX.

/**
 * Calculates the position of the text field cursor within the string
 */
private int getTextFieldCursorX(TextArea ta) {
    Style style = ta.getStyle();
    Font f = style.getFont();
    // display ******** if it is a password field
    String displayText = getTextFieldString(ta);
    String inputMode = ta.getInputMode();
    int inputModeWidth = f.stringWidth(inputMode);
    // QWERTY devices don't quite have an input mode hide it also when we have a VK
    if (ta.isQwertyInput() || Display.getInstance().isVirtualKeyboardShowing()) {
        inputMode = "";
        inputModeWidth = 0;
    }
    int xPos = 0;
    int cursorCharPosition = ta.getCursorX();
    int cursorX = 0;
    int x = 0;
    if (reverseAlignForBidi(ta) == Component.RIGHT) {
        if (Display.getInstance().isBidiAlgorithm()) {
            // char[] dest = displayText.toCharArray();
            cursorCharPosition = Display.getInstance().getCharLocation(displayText, cursorCharPosition - 1);
            if (cursorCharPosition == -1) {
                xPos = f.stringWidth(displayText);
            } else {
                displayText = Display.getInstance().convertBidiLogicalToVisual(displayText);
                if (!isRTLOrWhitespace((displayText.charAt(cursorCharPosition)))) {
                    cursorCharPosition++;
                }
                xPos = f.stringWidth(displayText.substring(0, cursorCharPosition));
            }
        }
        int displayX = ta.getX() + ta.getWidth() - style.getPaddingLeft(ta.isRTL()) - f.stringWidth(displayText);
        cursorX = displayX + xPos;
        x = 0;
    } else {
        if (cursorCharPosition > 0) {
            cursorCharPosition = Math.min(displayText.length(), cursorCharPosition);
            xPos = f.stringWidth(displayText.substring(0, cursorCharPosition));
        }
        cursorX = ta.getX() + style.getPaddingLeft(ta.isRTL()) + xPos;
        if (ta.isSingleLineTextArea() && ta.getWidth() > (f.getHeight() * 2) && cursorX >= ta.getWidth() - inputModeWidth - style.getPaddingLeft(ta.isRTL())) {
            if (x + xPos >= ta.getWidth() - inputModeWidth - style.getPaddingLeftNoRTL() - style.getPaddingRightNoRTL()) {
                x = ta.getWidth() - inputModeWidth - style.getPaddingLeftNoRTL() - style.getPaddingRightNoRTL() - xPos - 1;
            }
        }
    }
    return cursorX + x;
}
Also used : Font(com.codename1.ui.Font)

Example 30 with Char

use of com.codename1.ui.TextSelection.Char in project CodenameOne by codenameone.

the class DefaultLookAndFeel method calculateSpanForLabelText.

public Span calculateSpanForLabelText(TextSelection sel, Label l, String text, int x, int y, int textSpaceW) {
    Span span = sel.newSpan(l);
    Style style = l.getStyle();
    Font f = style.getFont();
    int h = f.getHeight() + (int) (f.getHeight() * 0.25);
    y -= (int) (f.getHeight() * 0.25);
    boolean rtl = l.isRTL();
    boolean isTickerRunning = l.isTickerRunning();
    int txtW = l.getStringWidth(f);
    int curPos = text.length();
    if ((!isTickerRunning) || rtl) {
        // if there is no space to draw the text add ... at the end
        if (txtW > textSpaceW && textSpaceW > 0) {
            if (rtl) {
                if ((!isTickerRunning) && (l.isEndsWith3Points())) {
                    String points = "...";
                    int pointsW = f.stringWidth(points);
                    // xPos = f.stringWidth(displayText.substring(0, cursorCharPosition));
                    // g.drawString(points, l.getShiftText() + x, y,l.getStyle().getTextDecoration());
                    // g.clipRect(pointsW+l.getShiftText() + x, y, textSpaceW - pointsW, f.getHeight());
                    Char nextChar = sel.newChar(curPos, pointsW + l.getShiftText() + x, y, textSpaceW - pointsW, h);
                    span.add(nextChar);
                }
                x = x - txtW + textSpaceW;
            } else {
                if (l.isEndsWith3Points()) {
                    String points = "...";
                    int index = 1;
                    int widest = f.charWidth('W');
                    int pointsW = f.stringWidth(points);
                    int tlen = text.length();
                    while (fastCharWidthCheck(text, index, textSpaceW - pointsW, widest, f) && index < tlen) {
                        index++;
                    }
                    text = text.substring(0, Math.min(text.length(), Math.max(1, index - 1))) + points;
                    txtW = f.stringWidth(text);
                }
            }
        }
    }
    int len = text.length();
    int xPos = 0;
    curPos = 1;
    while (curPos <= len) {
        int newXpos = f.stringWidth(text.substring(0, curPos));
        Char next = sel.newChar(curPos - 1, l.getShiftText() + x + xPos, y, newXpos - xPos, h);
        span.add(next);
        xPos = newXpos;
        curPos++;
    }
    // System.out.println("Span: "+span);
    return span.translate(l.getAbsoluteX() - sel.getSelectionRoot().getAbsoluteX() - l.getX(), l.getAbsoluteY() - sel.getSelectionRoot().getAbsoluteY() - l.getY());
}
Also used : Char(com.codename1.ui.TextSelection.Char) Span(com.codename1.ui.TextSelection.Span) Font(com.codename1.ui.Font)

Aggregations

Style (com.codename1.ui.plaf.Style)15 Font (com.codename1.ui.Font)8 ArrayList (java.util.ArrayList)5 ComponentImage (ca.weblite.shared.components.ComponentImage)4 Image (com.codename1.ui.Image)4 Point (java.awt.Point)4 Hashtable (java.util.Hashtable)4 MultiButton (com.codename1.components.MultiButton)3 SpanButton (com.codename1.components.SpanButton)3 EventObject (java.util.EventObject)3 List (java.util.List)3 Vector (java.util.Vector)3 SpanLabel (com.codename1.components.SpanLabel)2 BadgeUIID (com.codename1.rad.attributes.BadgeUIID)2 IconUIID (com.codename1.rad.attributes.IconUIID)2 UIID (com.codename1.rad.attributes.UIID)2 Button (com.codename1.ui.Button)2 TextArea (com.codename1.ui.TextArea)2 BorderLayout (com.codename1.ui.layouts.BorderLayout)2 UIManager (com.codename1.ui.plaf.UIManager)2