public LocalInfo declareLocal(TypeInfo type, String name, bool mark) {
     checkCreated();
     var currentScope = this.scopes[this.scopes.size() - 1];
     var result = new LocalInfo(type, name, currentScope.localIndex, null, currentScope.endLabel);
     switch (type.getTypeKind()) {
     case Long:
     case Double:
         currentScope.localIndex += 2;
         break;
     default:
         currentScope.localIndex++;
         break;
     }
     locals.add(result);
     currentScope.locals[name] = result;
 
     if (mark) {
         if (result.beginLabel == null) {
             if (instructions[instructions.size() - 1].Opcode == Opcode.LabelMarker) {
                 result.beginLabel = ((LabelMarker)instructions[instructions.size() - 1]).Label;
             } else {
                 result.beginLabel = new Label();
                 instructions.add(new LabelMarker(result.beginLabel));
             }
         }
     }
     return result;
 }
        public void emit(Opcode opcode, LocalInfo local) {
            checkCreated();
            int operand = local.Index;
            switch (opcode) {
            case Aload:
                switch (operand) {
                case 0:
                    instructions.add(Instruction.Aload_0);
                    break;

                case 1:
                    instructions.add(Instruction.Aload_1);
                    break;

                case 2:
                    instructions.add(Instruction.Aload_2);
                    break;

                case 3:
                    instructions.add(Instruction.Aload_3);
                    break;

                default:
                    instructions.add(new LocalVariableInstruction(opcode, operand));
                    break;
                }
                break;
                
            case Astore:
                switch (operand) {
                case 0:
                    instructions.add(Instruction.Astore_0);
                    break;

                case 1:
                    instructions.add(Instruction.Astore_1);
                    break;

                case 2:
                    instructions.add(Instruction.Astore_2);
                    break;

                case 3:
                    instructions.add(Instruction.Astore_3);
                    break;

                default:
                    instructions.add(new LocalVariableInstruction(opcode, operand));
                    break;
                }
                break;
                
            case Dload:
                switch (operand) {
                case 0:
                    instructions.add(Instruction.Dload_0);
                    break;

                case 1:
                    instructions.add(Instruction.Dload_1);
                    break;

                case 2:
                    instructions.add(Instruction.Dload_2);
                    break;

                case 3:
                    instructions.add(Instruction.Dload_3);
                    break;

                default:
                    instructions.add(new LocalVariableInstruction(opcode, operand));
                    break;
                }
                break;
                
            case Dstore:
                switch (operand) {
                case 0:
                    instructions.add(Instruction.Dstore_0);
                    break;

                case 1:
                    instructions.add(Instruction.Dstore_1);
                    break;

                case 2:
                    instructions.add(Instruction.Dstore_2);
                    break;

                case 3:
                    instructions.add(Instruction.Dstore_3);
                    break;

                default:
                    instructions.add(new LocalVariableInstruction(opcode, operand));
                    break;
                }
                break;
                
            case Fload:
                switch (operand) {
                case 0:
                    instructions.add(Instruction.Fload_0);
                    break;

                case 1:
                    instructions.add(Instruction.Fload_1);
                    break;

                case 2:
                    instructions.add(Instruction.Fload_2);
                    break;

                case 3:
                    instructions.add(Instruction.Fload_3);
                    break;

                default:
                    instructions.add(new LocalVariableInstruction(opcode, operand));
                    break;
                }
                break;
                
            case Fstore:
                switch (operand) {
                case 0:
                    instructions.add(Instruction.Fstore_0);
                    break;

                case 1:
                    instructions.add(Instruction.Fstore_1);
                    break;

                case 2:
                    instructions.add(Instruction.Fstore_2);
                    break;

                case 3:
                    instructions.add(Instruction.Fstore_3);
                    break;

                default:
                    instructions.add(new LocalVariableInstruction(opcode, operand));
                    break;
                }
                break;
                
            case Iload:
                switch (operand) {
                case 0:
                    instructions.add(Instruction.Iload_0);
                    break;

                case 1:
                    instructions.add(Instruction.Iload_1);
                    break;

                case 2:
                    instructions.add(Instruction.Iload_2);
                    break;

                case 3:
                    instructions.add(Instruction.Iload_3);
                    break;

                default:
                    instructions.add(new LocalVariableInstruction(opcode, operand));
                    break;
                }
                break;
                
            case Istore:
                switch (operand) {
                case 0:
                    instructions.add(Instruction.Istore_0);
                    break;

                case 1:
                    instructions.add(Instruction.Istore_1);
                    break;

                case 2:
                    instructions.add(Instruction.Istore_2);
                    break;

                case 3:
                    instructions.add(Instruction.Istore_3);
                    break;

                default:
                    instructions.add(new LocalVariableInstruction(opcode, operand));
                    break;
                }
                break;
                
            case Lload:
                switch (operand) {
                case 0:
                    instructions.add(Instruction.Lload_0);
                    break;

                case 1:
                    instructions.add(Instruction.Lload_1);
                    break;

                case 2:
                    instructions.add(Instruction.Lload_2);
                    break;

                case 3:
                    instructions.add(Instruction.Lload_3);
                    break;

                default:
                    instructions.add(new LocalVariableInstruction(opcode, operand));
                    break;
                }
                break;
                
            case Lstore:
                switch (operand) {
                case 0:
                    instructions.add(Instruction.Lstore_0);
                    break;

                case 1:
                    instructions.add(Instruction.Lstore_1);
                    break;

                case 2:
                    instructions.add(Instruction.Lstore_2);
                    break;

                case 3:
                    instructions.add(Instruction.Lstore_3);
                    break;

                default:
                    instructions.add(new LocalVariableInstruction(opcode, operand));
                    break;
                }
                break;

            case Ret:
                instructions.add(new LocalVariableInstruction(opcode, operand));
                break;
                
            default:
                throw new IllegalStateException("Illegal opcode usage: " + opcode);
            }
            if (local.beginLabel == null) {
                if (instructions[instructions.size() - 1].Opcode == Opcode.LabelMarker) {
                    local.beginLabel = ((LabelMarker)instructions[instructions.size() - 1]).Label;
                } else {
                    local.beginLabel = new Label();
                    instructions.add(new LabelMarker(local.beginLabel));
                }
            }
        }
 public void emit(Opcode opcode, LocalInfo local, int increment) {
     checkCreated();
     if (opcode != Opcode.Iinc) {
         throw new IllegalStateException("Illegal opcode usage: " + opcode);
     }
     instructions.add(new IncrementInstruction(local.getIndex(), increment));
 }