All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.codename1.tools.translator.bytecodes.BasicInstruction Maven / Gradle / Ivy

/*
 * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Codename One designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *  
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 * 
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * Please contact Codename One through http://www.codenameone.com/ if you 
 * need additional information or have any questions.
 */

package com.codename1.tools.translator.bytecodes;

import java.util.List;
import org.objectweb.asm.Opcodes;

/**
 *
 * @author Shai Almog
 */
public class BasicInstruction extends Instruction implements AssignableExpression  {
    private final int value;
    private int maxStack;
    private int maxLocals;
    private static boolean synchronizedMethod;
    private static boolean staticMethod;
    private static String className;
    
    public BasicInstruction(int opcode, int value) {
        super(opcode);
        this.value = value;
    }
    
    public int getValue() {
        return value;
    }
    
    public static void setSynchronizedMethod(boolean b, boolean stat, String cls) {
        synchronizedMethod = b;
        staticMethod = stat;
        className = cls;
    }
    
    public void setMaxes(int maxStack, int maxLocals) {
        this.maxLocals = maxLocals;
        this.maxStack = maxStack;
    }

    private void appendSynchronized(StringBuilder b) {
        if(synchronizedMethod) {
            if(staticMethod) {
                b.append("    monitorExitBlock(threadStateData, (JAVA_OBJECT)&class__");
                b.append(className);
                b.append(");\n");
            } else {
                b.append("    monitorExitBlock(threadStateData, __cn1ThisObject);\n");
            }
        }
    }
    
    public static boolean isSynchronizedMethod() {
        return synchronizedMethod;
    }

    @Override
    public boolean isConstant() {
        switch (opcode) {
            case Opcodes.ACONST_NULL:
            case Opcodes.ICONST_0:
            case Opcodes.ICONST_1:
            case Opcodes.ICONST_2:
            case Opcodes.ICONST_3:
            case Opcodes.ICONST_4:
            case Opcodes.ICONST_5:
            case Opcodes.ICONST_M1:
            case Opcodes.FCONST_0:
            case Opcodes.FCONST_1:
            case Opcodes.FCONST_2:
            case Opcodes.DCONST_0:
            case Opcodes.DCONST_1:
            case Opcodes.LCONST_0:
            case Opcodes.LCONST_1:
            case Opcodes.LDC:
                return true;
        }
        return super.isConstant();
    }
    
    
    
    @Override
    public void appendInstruction(StringBuilder b, List instructions) {
        switch(opcode) {
            case Opcodes.NOP:
                break;
                
            case Opcodes.ACONST_NULL:
                b.append("    PUSH_POINTER(JAVA_NULL); /* ACONST_NULL */\n");
                break;
                
            case Opcodes.ICONST_M1:
                b.append("    PUSH_INT(-1); /* ICONST_M1 */\n");
                break;
                
            case Opcodes.ICONST_0:
                b.append("    PUSH_INT(0); /* ICONST_0 */\n");
                break;

            case Opcodes.ICONST_1:
                b.append("    PUSH_INT(1); /* ICONST_1 */\n");
                break;

            case Opcodes.ICONST_2:
                b.append("    PUSH_INT(2); /* ICONST_2 */\n");
                break;

            case Opcodes.ICONST_3:
                b.append("    PUSH_INT(3); /* ICONST_3 */\n");
                break;

            case Opcodes.ICONST_4:
                b.append("    PUSH_INT(4); /* ICONST_4 */\n");
                break;

            case Opcodes.ICONST_5:
                b.append("    PUSH_INT(5); /* ICONST_5 */\n");
                break;

            case Opcodes.LCONST_0:
                b.append("    PUSH_LONG(0); /* LCONST_0 */\n");
                break;

            case Opcodes.LCONST_1:
                b.append("    PUSH_LONG(1); /* LCONST_1 */\n");
                break;

            case Opcodes.FCONST_0:
                b.append("    PUSH_FLOAT(0); /* FCONST_0 */\n");
                break;

            case Opcodes.FCONST_1:
                b.append("    PUSH_FLOAT(1); /* FCONST_1 */\n");
                break;

            case Opcodes.FCONST_2:
                b.append("    PUSH_FLOAT(2); /* FCONST_2 */\n");
                break;

            case Opcodes.DCONST_0:
                b.append("    PUSH_DOUBLE(0); /* DCONST_0 */\n");
                break;

            case Opcodes.DCONST_1:
                b.append("    PUSH_DOUBLE(1); /* DCONST_1 */\n");
                break;

            case Opcodes.BALOAD:
                b.append("    { CHECK_ARRAY_ACCESS(2, SP[-1].data.i); /* BALOAD */ \n" +
                    "    SP--; SP[-1].type = CN1_TYPE_INT; \n" +
                    "    SP[-1].data.i = ((JAVA_ARRAY_BYTE*) (*(JAVA_ARRAY)SP[-1].data.o).data)[(*SP).data.i]; \n" +
                    "    }\n");
                break;

            case Opcodes.CALOAD:
                b.append("    CHECK_ARRAY_ACCESS(2, SP[-1].data.i); /* CALOAD */\n" +
                    "    SP--; SP[-1].type = CN1_TYPE_INT; \n" +
                    "    SP[-1].data.i = ((JAVA_ARRAY_CHAR*) (*(JAVA_ARRAY)SP[-1].data.o).data)[(*SP).data.i];\n");
                break;
                
            case Opcodes.IALOAD:
                b.append("    CHECK_ARRAY_ACCESS(2, SP[-1].data.i); /* IALOAD */\n" +
                        "    SP--; SP[-1].type = CN1_TYPE_INT; \n" +
                        "    SP[-1].data.i = ((JAVA_ARRAY_INT*) (*(JAVA_ARRAY)SP[-1].data.o).data)[(*SP).data.i];\n");
                break;

            case Opcodes.SALOAD:
                b.append("    CHECK_ARRAY_ACCESS(2, SP[-1].data.i); \n" +
                        "    SP--; SP[-1].type = CN1_TYPE_INT; \n" +
                        "    SP[-1].data.i = ((JAVA_ARRAY_SHORT*) (*(JAVA_ARRAY)SP[-1].data.o).data)[(*SP).data.i]; /* SALOAD */\n");
                break;

            case Opcodes.LALOAD:
                b.append("    CHECK_ARRAY_ACCESS(2, SP[-1].data.i); /* LALOAD */\n" +
                        "    SP--; SP[-1].type = CN1_TYPE_LONG; \n" +
                        "    SP[-1].data.l = LONG_ARRAY_LOOKUP((JAVA_ARRAY)SP[-1].data.o, (*SP).data.i);\n");
                break;

            case Opcodes.FALOAD:
                b.append("    CHECK_ARRAY_ACCESS(2, SP[-1].data.i); /* FALOAD */\n" +
                        "    SP--; SP[-1].type = CN1_TYPE_FLOAT; \n" +
                        "    SP[-1].data.f = FLOAT_ARRAY_LOOKUP((JAVA_ARRAY)SP[-1].data.o, (*SP).data.i);\n");
                break;

            case Opcodes.DALOAD:
                b.append("    CHECK_ARRAY_ACCESS(2, SP[-1].data.i); /* DALOAD */\n" +
                        "    SP--; SP[-1].type = CN1_TYPE_DOUBLE; \n" +
                        "    SP[-1].data.d = DOUBLE_ARRAY_LOOKUP((JAVA_ARRAY)SP[-1].data.o, (*SP).data.i);\n");
                break;

            case Opcodes.AALOAD:
                b.append("    CHECK_ARRAY_ACCESS(2, SP[-1].data.i); /* AALOAD */\n" +
                        "    SP--; SP[-1].type = CN1_TYPE_INVALID; \n" +
                        "    SP[-1].data.o = ((JAVA_ARRAY_OBJECT*) (*(JAVA_ARRAY)SP[-1].data.o).data)[(*SP).data.i]; \n" +
                        "    SP[-1].type = CN1_TYPE_OBJECT; \n");
                break;

            case Opcodes.BASTORE:
                b.append("    CHECK_ARRAY_ACCESS(3, SP[-2].data.i); /* BASTORE */\n" +
                        "    ((JAVA_ARRAY_BYTE*) (*(JAVA_ARRAY)SP[-3].data.o).data)[SP[-2].data.i] = SP[-1].data.i; SP -= 3;\n");
                break;

            case Opcodes.CASTORE:
                b.append("    CHECK_ARRAY_ACCESS(3, SP[-2].data.i); /* CASTORE */\n" +
                        "    ((JAVA_ARRAY_CHAR*) (*(JAVA_ARRAY)SP[-3].data.o).data)[SP[-2].data.i] = SP[-1].data.i; SP -= 3;\n\n");
                break;

            case Opcodes.SASTORE:
                b.append("    CHECK_ARRAY_ACCESS(3, SP[-2].data.i); /* SASTORE */\n" +
                        "    ((JAVA_ARRAY_SHORT*) (*(JAVA_ARRAY)SP[-3].data.o).data)[SP[-2].data.i] = SP[-1].data.i; SP -= 3;\n");
                break;

            case Opcodes.IASTORE:
                b.append("    CHECK_ARRAY_ACCESS(3, SP[-2].data.i); /* IASTORE */\n" +
                        "    ((JAVA_ARRAY_INT*) (*(JAVA_ARRAY)SP[-3].data.o).data)[SP[-2].data.i] = SP[-1].data.i; SP -= 3;\n");
                break;

            case Opcodes.LASTORE:
                b.append("    CHECK_ARRAY_ACCESS(3, SP[-2].data.i); /* LASTORE */\n" +
                        "    LONG_ARRAY_LOOKUP((JAVA_ARRAY)SP[-3].data.o, SP[-2].data.i) = SP[-1].data.l; SP -= 3;\n");
                break;

            case Opcodes.FASTORE:
                b.append("    CHECK_ARRAY_ACCESS(3, SP[-2].data.i); /* FASTORE */\n" +
                        "    FLOAT_ARRAY_LOOKUP((JAVA_ARRAY)SP[-3].data.o, SP[-2].data.i) = SP[-1].data.f; SP -= 3;\n");
                break;

            case Opcodes.DASTORE:
                b.append("    CHECK_ARRAY_ACCESS(3, SP[-2].data.i); /* DASTORE */\n" +
                        "    DOUBLE_ARRAY_LOOKUP((JAVA_ARRAY)SP[-3].data.o, SP[-2].data.i) = SP[-1].data.d; SP -= 3;\n");
                break;

            case Opcodes.AASTORE:
                b.append("    CHECK_ARRAY_ACCESS(3, SP[-2].data.i); { /* BC_AASTORE */\n" +
                        "    JAVA_OBJECT aastoreTmp = SP[-3].data.o; \n" +
                        "    ((JAVA_ARRAY_OBJECT*) (*(JAVA_ARRAY)aastoreTmp).data)[SP[-2].data.i] = SP[-1].data.o; \n" +
                        "    SP -= 3; }\n");
                break;

            case Opcodes.POP:
                b.append("    SP--; /* POP */\n");
                break;

            case Opcodes.POP2:
                b.append("    popMany(threadStateData, 2, &SP); /* POP2 */\n");
                break;

            /*case Opcodes.DUP:
                b.append("    PUSH_INT(PEEK_INT(1));\n");
                break;

            case Opcodes.DUP_X1:
                b.append("    DUP_X1();\n");
                break;
                
            case Opcodes.DUP_X2:
                b.append("    DUP_X2();\n");
                break;*/
                
            case Opcodes.DUP:
                b.append("    BC_DUP(); /* DUP */\n");
                break;

            case Opcodes.DUP2:
                b.append("    BC_DUP2(); /* DUP2 */\n");
                break;
                
            case Opcodes.DUP_X1:
                b.append("    BC_DUP_X1(); /* DUP_X1 */\n");
                break;
                
            case Opcodes.DUP2_X1:
                b.append("    BC_DUP2_X1(); /* DUP2_X1 */\n");
                break;
                
            case Opcodes.DUP_X2:
                b.append("    BC_DUP_X2(); /* DUP_X2 */\n");
                break;
                
            case Opcodes.DUP2_X2:
                b.append("    BC_DUP2_X2(); /* DUP2_X2 */\n");
                break;
                
            case Opcodes.SWAP:
                b.append("    swapStack(SP); /* SWAP */\n");
                break;
                
            case Opcodes.IADD:
                b.append("    SP--; SP[-1].data.i = SP[-1].data.i + (*SP).data.i; /* IADD */\n");
                break;
                
            case Opcodes.LADD:
                b.append("    SP--; SP[-1].data.l = SP[-1].data.l + (*SP).data.l; /* LADD */\n");
                break;
                
            case Opcodes.FADD:
                b.append("    SP--; SP[-1].data.f = SP[-1].data.f + (*SP).data.f; /* FADD */\n");
                break;
                
            case Opcodes.DADD:
                b.append("    SP--; SP[-1].data.d = SP[-1].data.d + (*SP).data.d; /* DADD */\n");
                break;
                
            case Opcodes.ISUB:
                b.append("    SP--; SP[-1].data.i = (SP[-1].data.i - (*SP).data.i); /* ISUB */\n");
                break;
                
            case Opcodes.LSUB:
                b.append("    SP--; SP[-1].data.l = (SP[-1].data.l - (*SP).data.l); /* LSUB */\n");
                break;
                
            case Opcodes.FSUB:
                b.append("    SP--; SP[-1].data.f = (SP[-1].data.f - (*SP).data.f); /* FSUB */\n");
                break;
                
            case Opcodes.DSUB:
                b.append("    SP--; SP[-1].data.d = (SP[-1].data.d - (*SP).data.d); /* DSUB */\n");
                break;
                
            case Opcodes.IMUL:
                b.append("    SP--; SP[-1].data.i = SP[-1].data.i * (*SP).data.i; /* IMUL */\n");
                break;
                
            case Opcodes.LMUL:
                b.append("    SP--; SP[-1].data.l = SP[-1].data.l * (*SP).data.l; /* LMUL */\n");
                break;
                
            case Opcodes.FMUL:
                b.append("    SP--; SP[-1].data.f = SP[-1].data.f * (*SP).data.f; /* FMUL */\n");
                break;
                
            case Opcodes.DMUL:
                b.append("    SP--; SP[-1].data.d = SP[-1].data.d * (*SP).data.d; /* DMUL */\n");
                break;
                
            case Opcodes.IDIV:
                b.append("    SP--; SP[-1].data.i = SP[-1].data.i / (*SP).data.i; /* IDIV */\n");
                break;
                
            case Opcodes.LDIV:
                b.append("    SP--; SP[-1].data.l = SP[-1].data.l / (*SP).data.l; /* LDIV */\n");
                break;
                
            case Opcodes.FDIV:
                b.append("    SP--; SP[-1].data.f = SP[-1].data.f / (*SP).data.f; /* FDIV */\n");
                break;
                
            case Opcodes.DDIV:
                b.append("    SP--; SP[-1].data.d = SP[-1].data.d / (*SP).data.d; /* DDIV */\n");
                break;
                
            case Opcodes.IREM:
                b.append("    SP--; SP[-1].data.i = SP[-1].data.i % (*SP).data.i; /* IREM */\n");
                break;
                
            case Opcodes.LREM:
                b.append("    SP--; SP[-1].data.l = SP[-1].data.l % (*SP).data.l; /* LREM */\n");
                break;
                
            case Opcodes.FREM:
                b.append("    SP--; SP[-1].data.f = fmod(SP[-1].data.f, (*SP).data.f); /* FREM */\n");
                break;
                
            case Opcodes.DREM:
                b.append("    SP--; SP[-1].data.d = fmod(SP[-1].data.d, (*SP).data.d); /* DREM */\n");
                break;
                
            case Opcodes.INEG:
                b.append("    SP[-1].data.i *= -1; /* INEG */\n");
                break;
                
            case Opcodes.LNEG:
                b.append("    SP[-1].data.l *= -1; /* LNEG */\n");
                break;
                
            case Opcodes.FNEG:
                b.append("    SP[-1].data.f *= -1; /* FNEG */\n");
                break;
                
            case Opcodes.DNEG:
                b.append("    SP[-1].data.d *= -1; /* DNEG */\n");
                break;
                
            case Opcodes.ISHL:
                b.append("    SP--; SP[-1].data.i = (SP[-1].data.i << (0x1f & (*SP).data.i)); /* ISHL */\n");
                break;
                
            case Opcodes.LSHL:
                b.append("    SP--; SP[-1].data.l = (SP[-1].data.l << (0x3f & (*SP).data.i)); /* LSHL */\n");
                break;
                
            case Opcodes.ISHR:
                b.append("    SP--; SP[-1].data.i = (SP[-1].data.i >> (0x1f & (*SP).data.i)); /* ISHR */\n");
                break;
                
            case Opcodes.LSHR:
                b.append("    SP--; SP[-1].data.l = (SP[-1].data.l >> (0x3f & (*SP).data.l)); /* LSHR */\n");
                break;
                
            case Opcodes.IUSHR:
                b.append("    SP--; SP[-1].data.i = (((unsigned int)SP[-1].data.i) >> (0x1f & ((unsigned int)(*SP).data.i))); /* IUSHR */\n");
                break;
                
            case Opcodes.LUSHR:
                b.append("    SP--; SP[-1].data.l = (((unsigned long long)SP[-1].data.l) >> (0x3f & ((unsigned long long)(*SP).data.i))); /* LUSHR */\n");
                break;
                
            case Opcodes.IAND:
                b.append("    SP--; SP[-1].data.i = SP[-1].data.i & (*SP).data.i; /* IAND */\n") ;
                break;
                
            case Opcodes.LAND:
                b.append("    SP--; SP[-1].data.l = SP[-1].data.l & (*SP).data.l; /* LAND */\n") ;
                break;
                
            case Opcodes.IOR:
                b.append("    SP--; SP[-1].data.i = SP[-1].data.i | (*SP).data.i; /* IOR */\n") ;
                break;
                
            case Opcodes.LOR:
                b.append("    SP--; SP[-1].data.l = SP[-1].data.l | (*SP).data.l; /* LOR */\n") ;
                break;
                
            case Opcodes.IXOR:
                b.append("    SP--; SP[-1].data.i = SP[-1].data.i ^ (*SP).data.i; /* IXOR */\n") ;
                break;
                
            case Opcodes.LXOR:
                b.append("    SP--; SP[-1].data.l = SP[-1].data.l ^ (*SP).data.l; /* LXOR */\n") ;
                break;
                
            case Opcodes.I2L:
                b.append("    SP[-1].data.l = SP[-1].data.i; /* I2L */\n");
                break;
                
            case Opcodes.I2F:
                b.append("    SP[-1].data.f = (JAVA_FLOAT)SP[-1].data.i; /* I2F */\n");
                break;
                
            case Opcodes.I2D:
                b.append("    SP[-1].data.d = SP[-1].data.i; /* I2D */;\n");
                break;
                
            case Opcodes.L2I:
                b.append("    SP[-1].data.i = (JAVA_INT)SP[-1].data.l; /* L2I */\n");
                break;
                
            case Opcodes.L2F:
                b.append("    SP[-1].data.f = (JAVA_FLOAT)SP[-1].data.l; /* L2F */\n");
                break;
                
            case Opcodes.L2D:
                b.append("    SP[-1].data.d = (JAVA_DOUBLE)SP[-1].data.l; /* L2D */\n");
                break;
                
            case Opcodes.F2I:
                b.append("    SP[-1].data.i = (JAVA_INT)SP[-1].data.f; /* F2I */\n");
                break;
                
            case Opcodes.F2L:
                b.append("    SP[-1].data.l = (JAVA_LONG)SP[-1].data.f; /* F2L */\n");
                break;
                
            case Opcodes.F2D:
                b.append("    SP[-1].data.d = SP[-1].data.f; /* F2D */\n");
                break;
                
            case Opcodes.D2I:
                b.append("    SP[-1].data.i = (JAVA_INT)SP[-1].data.d; /* D2I */\n");
                break;
                
            case Opcodes.D2L:
                b.append("    SP[-1].data.l = (JAVA_LONG)SP[-1].data.d; /* D2L */\n");
                break;
                
            case Opcodes.D2F:
                b.append("    SP[-1].data.f = (JAVA_FLOAT)SP[-1].data.d; /* D2F */\n");
                break;
                
            case Opcodes.I2B:
                b.append("    SP[-1].data.i = ((SP[-1].data.i << 24) >> 24); /* I2B */\n");
                break;
                
            case Opcodes.I2C:
                b.append("    SP[-1].data.i = (SP[-1].data.i & 0xffff); /* I2C */\n");
                break;
                
            case Opcodes.I2S:
                b.append("    SP[-1].data.i = ((SP[-1].data.i << 16) >> 16); /* I2S */\n");
                break;
                
            case Opcodes.LCMP:
                b.append("    BC_LCMP();\n");
                break;
                
            case Opcodes.FCMPG:
            case Opcodes.FCMPL:
                b.append("    BC_FCMPL();\n");
                break;
                
            case Opcodes.DCMPL:
            case Opcodes.DCMPG:
                b.append("    BC_DCMPL();\n");
                break;                  
                
            case Opcodes.IRETURN:
                appendSynchronized(b);
                
                if(TryCatch.isTryCatchInMethod()) {
                    b.append("    releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); return SP[-1].data.i;\n");
//                    b.append(maxLocals);
//                    b.append(", stack, locals, methodBlockOffset); \n    return SP[-1].data.i;\n");
                } else {
                    b.append("    releaseForReturn(threadStateData, cn1LocalsBeginInThread); return SP[-1].data.i;\n");
//                    b.append(maxLocals);
//                    b.append(", stack, locals); \n    return SP[-1].data.i;\n");
                }
                break;                
                
            case Opcodes.LRETURN:
                appendSynchronized(b);
                                
                if(TryCatch.isTryCatchInMethod()) {
                    b.append("    releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); \n    return POP_LONG();\n");
                } else {
                    b.append("    releaseForReturn(threadStateData, cn1LocalsBeginInThread); \n    return POP_LONG();\n");
                }
                break;                
                
            case Opcodes.FRETURN:
                appendSynchronized(b);
                
                if(TryCatch.isTryCatchInMethod()) {
                    b.append("    releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); \n    return POP_FLOAT();\n");
                } else {
                    b.append("    releaseForReturn(threadStateData, cn1LocalsBeginInThread); \n    return POP_FLOAT();\n");
                }
                break;                
                
            case Opcodes.DRETURN:
                appendSynchronized(b);
                
                if(TryCatch.isTryCatchInMethod()) {
                    b.append("    releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); \n    return POP_DOUBLE();\n");
                } else {
                    b.append("    releaseForReturn(threadStateData, cn1LocalsBeginInThread); \n    return POP_DOUBLE();\n");
                }
                break;
                
            case Opcodes.ARETURN:
                appendSynchronized(b);
                
                if(TryCatch.isTryCatchInMethod()) {
                    b.append("    releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); \n    return POP_OBJ();\n");
                } else {
                    b.append("    releaseForReturn(threadStateData, cn1LocalsBeginInThread); \n    return POP_OBJ();\n");
                }
                break;
                
            case Opcodes.RETURN:
                appendSynchronized(b);
                
                if(!hasInstructions) {
                    b.append("    return;\n");
                    break;
                }
                if(TryCatch.isTryCatchInMethod()) {
                    b.append("    releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); \n    return;\n");
                } else {
                    b.append("    releaseForReturn(threadStateData, cn1LocalsBeginInThread); \n    return;\n");
                }
                break;
                
            case Opcodes.ARRAYLENGTH:
                b.append("    { /* ARRAYLENGTH */\n" +
                    "        if(SP[-1].data.o == JAVA_NULL) { \n" +
                    "            throwException(threadStateData, __NEW_INSTANCE_java_lang_NullPointerException(threadStateData)); \n" +
                    "        }; \n" +
                    "        SP[-1].type = CN1_TYPE_INT; \n" +
                    "        SP[-1].data.i = (*((JAVA_ARRAY)SP[-1].data.o)).length; \n" +
                    "    }\n");
                break;                
                
            case Opcodes.ATHROW:
                //b.append("    NSLog(@\"Exception thrown %s %d %s %s\\n\", __FILE__, __LINE__, __PRETTY_FUNCTION__, __FUNCTION__);\n");
                b.append("    throwException(threadStateData, POP_OBJ());\n");
                break;                
                
            case Opcodes.MONITORENTER:
                b.append("    monitorEnter(threadStateData, POP_OBJ());\n");
                break;                
                
            case Opcodes.MONITOREXIT:
                b.append("    monitorExit(threadStateData, POP_OBJ());\n");
                break;                
                
            // int instructions
            case Opcodes.SIPUSH:
            case Opcodes.BIPUSH:
                b.append("    PUSH_INT(");
                b.append(value);
                b.append(");\n");
                break;                
                
            case Opcodes.NEWARRAY:
                switch(value) {
                    case 4: // boolean
                        b.append("    SP--; PUSH_OBJ(allocArray(threadStateData, (*SP).data.i, &class_array1__JAVA_BOOLEAN, sizeof(JAVA_ARRAY_BOOLEAN), 1));\n");
                        break;
                    case 5: // char
                        b.append("    SP--; PUSH_OBJ(allocArray(threadStateData, (*SP).data.i, &class_array1__JAVA_CHAR, sizeof(JAVA_ARRAY_CHAR), 1));\n");
                        break;
                    case 6: // float
                        b.append("    SP--; PUSH_OBJ(allocArray(threadStateData, (*SP).data.i, &class_array1__JAVA_FLOAT, sizeof(JAVA_ARRAY_FLOAT), 1));\n");
                        break;
                    case 7: // double
                        b.append("    SP--; PUSH_OBJ(allocArray(threadStateData, (*SP).data.i, &class_array1__JAVA_DOUBLE, sizeof(JAVA_ARRAY_DOUBLE), 1));\n");
                        break;
                    case 8: // byte
                        b.append("    SP--; PUSH_OBJ(allocArray(threadStateData, (*SP).data.i, &class_array1__JAVA_BYTE, sizeof(JAVA_ARRAY_BYTE), 1));\n");
                        break;
                    case 9: // short
                        b.append("    SP--; PUSH_OBJ(allocArray(threadStateData, (*SP).data.i, &class_array1__JAVA_SHORT, sizeof(JAVA_ARRAY_SHORT), 1));\n");
                        break;
                    case 10: // int
                        b.append("    SP--; PUSH_OBJ(allocArray(threadStateData, (*SP).data.i, &class_array1__JAVA_INT, sizeof(JAVA_ARRAY_INT), 1));\n");
                        break;
                    case 11: // long 
                        b.append("    SP--; PUSH_OBJ(allocArray(threadStateData, (*SP).data.i, &class_array1__JAVA_LONG, sizeof(JAVA_ARRAY_LONG), 1));\n");
                        break;
                }
                break;
        }
    }

    public boolean isComplexInstruction() {
        return opcode == Opcodes.ATHROW;
    }

    @Override
    public boolean assignTo(String varName, StringBuilder sb) {
        StringBuilder b = new StringBuilder();
        //StringBuilder b2 = new StringBuilder();
        //if (typeVarName != null) {
        //    b2.append(typeVarName).append(" = ");
        //    
        //}
        if (varName != null) {
            b.append(varName).append(" = ");
        }
        switch(opcode) {
            case Opcodes.ACONST_NULL:
                b.append("JAVA_NULL /* ACONST_NULL */");
                //b2.append("CN1_TYPE_OBJECT");
                break;
                
            case Opcodes.ICONST_M1:
                b.append("-1 /* ICONST_M1 */");
                //b2.append("CN1_TYPE_INT");
                break;
                
            case Opcodes.ICONST_0:
                b.append("0 /* ICONST_0 */");
                //b2.append("CN1_TYPE_INT");
                break;

            case Opcodes.ICONST_1:
                b.append("1 /* ICONST_1 */");
                //b2.append("CN1_TYPE_INT");
                break;

            case Opcodes.ICONST_2:
                b.append("2 /* ICONST_2 */");
                //b2.append("CN1_TYPE_INT");
                break;

            case Opcodes.ICONST_3:
                b.append("3 /* ICONST_3 */");
                //b2.append("CN1_TYPE_INT");
                break;

            case Opcodes.ICONST_4:
                b.append("4/* ICONST_4 */");
                //b2.append("CN1_TYPE_INT");
                break;

            case Opcodes.ICONST_5:
                b.append("5 /* ICONST_5 */");
                ///b2.append("CN1_TYPE_INT");
                break;

            case Opcodes.LCONST_0:
                b.append("0 /* LCONST_0 */");
                //b2.append("CN1_TYPE_LONG");
                break;

            case Opcodes.LCONST_1:
                b.append("1 /* LCONST_1 */");
                //b2.append("CN1_TYPE_LONG");
                break;

            case Opcodes.FCONST_0:
                b.append("0 /* FCONST_0 */");
                //b2.append("CN1_TYPE_FLOAT");
                break;

            case Opcodes.FCONST_1:
                b.append("1 /* FCONST_1 */");
                //b2.append("CN1_TYPE_FLOAT");
                break;

            case Opcodes.FCONST_2:
                b.append("2 /* FCONST_2 */");
                //b2.append("CN1_TYPE_FLOAT");
                break;

            case Opcodes.DCONST_0:
                b.append("0 /* DCONST_0 */");
                //b2.append("CN1_TYPE_DOUBLE");
                break;

            case Opcodes.DCONST_1:
                b.append("1 /* DCONST_1 */");
                //b2.append("CN1_TYPE_DOUBLE");
                break;
       
                
            // int instructions
            case Opcodes.SIPUSH:
            case Opcodes.BIPUSH:
                b.append(value);
                b.append("/* SIPUSH */");
                //b2.append("CN1_TYPE_INT");
                break;   
                
            
            
            default:
                return false;
        }
        
        if (varName != null) {
            sb.append("    ");
            b.append("; \n");
        }
        
        
        //if (typeVarName != null) {
        //    sb.append(b2).append("; ");
        //}
        sb.append(b);
        
        return true;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy