// Path: jbbvm/bbvm-core/src/main/java/me/wener/bbvm/dev/StringManager.java
// @ImplementedBy(DefaultStringManager.class)
// public interface StringManager extends ResourceManager<StringManager, StringResource> {
// 
//     @Override
//     default String getType() {
//         return "string";
//     }
// }
// 
// Path: jbbvm/bbvm-core/src/main/java/me/wener/bbvm/exception/ExecutionException.java
// public class ExecutionException extends RuntimeException {
//     private VM vm;
// 
//     public ExecutionException() {
//     }
// 
//     public ExecutionException(String message) {
//         super(message);
//     }
// 
//     public ExecutionException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public ExecutionException(Throwable cause) {
//         super(cause);
//     }
// 
//     public VM getVm() {
//         return vm;
//     }
// 
//     public ExecutionException setVm(VM vm) {
//         this.vm = vm;
//         return this;
//     }
// }
// 
// Path: jbbvm/bbvm-core/src/main/java/me/wener/bbvm/exception/ResourceMissingException.java
// public class ResourceMissingException extends ExecutionException {
//     private String type;
//     private int handler;
// 
//     public ResourceMissingException(String message, String type, int handler) {
//         super(message);
//         this.type = type;
//         this.handler = handler;
//     }
// 
//     public ResourceMissingException(String type, int handler) {
//         this.type = type;
//         this.handler = handler;
//     }
// 
//     @Override
//     public String toString() {
//         return MoreObjects.toStringHelper(this)
//             .add("type", type)
//             .add("handler", handler)
//             .add("message", getMessage())
//             .toString();
//     }
// }
// 
// Path: jbbvm/bbvm-core/src/main/java/me/wener/bbvm/util/IntEnums.java
// public class IntEnums {
//     private static final Table<Class, Integer, Object> cache = HashBasedTable.create();
// 
//     @SafeVarargs
//     public static <T extends Enum & IsInt> void cache(Class<? extends T>... type) {
//         for (Class<? extends T> t : type) {
//             cache(t);
//         }
//     }
// 
//     private static <T extends Enum & IsInt> void cache(Class<? extends T> type) {
//         for (T item : type.getEnumConstants()) {
//             cache.put(type, item.asInt(), item);
//         }
//     }
// 
//     @SuppressWarnings("unchecked")
//     public static <T extends Enum & IsInt> T fromInt(Class<T> type, int value) {
//         return (T) cache.get(type, value);
//     }
// }
// 
// Path: jbbvm/bbvm-core/src/main/java/me/wener/bbvm/vm/event/ResetEvent.java
// public class ResetEvent extends EventObject {
//     public ResetEvent(VM source) {
//         super(source);
//     }
// }


import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.eventbus.EventBus;
import com.google.inject.Guice;
import io.netty.buffer.ByteBuf;
import me.wener.bbvm.dev.StringManager;
import me.wener.bbvm.exception.ExecutionException;
import me.wener.bbvm.exception.ResourceMissingException;
import me.wener.bbvm.util.IntEnums;
import me.wener.bbvm.vm.event.ResetEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import java.util.Iterator;
import java.util.Map;
import java.util.NavigableMap;
import static com.google.common.base.Preconditions.checkState;
    void jmp(int i) {
        rp.set(i);
    }

    void ret() {
        rp.set(pop());
    }

    VM push(int v) {
        memory.push(v);
        return this;
    }

    int pop() {
        return memory.pop();
    }

    /**
     * If i >= 0 then read the string from memory, if i < 0 will get string from string resource.
     * If i > memory size or ResourceMissing will return null
     */
    public String getString(int i) {
        if (i >= 0) {
            if (i > memory.getMemorySize()) {
                return null;
            }
            return memory.getString(i, config.getCharset());
        }
        try {
            return stringManager.getResource(i).getValue();
// Path: jbbvm/bbvm-core/src/main/java/me/wener/bbvm/dev/StringManager.java
// @ImplementedBy(DefaultStringManager.class)
// public interface StringManager extends ResourceManager<StringManager, StringResource> {
// 
//     @Override
//     default String getType() {
//         return "string";
//     }
// }
// 
// Path: jbbvm/bbvm-core/src/main/java/me/wener/bbvm/exception/ExecutionException.java
// public class ExecutionException extends RuntimeException {
//     private VM vm;
// 
//     public ExecutionException() {
//     }
// 
//     public ExecutionException(String message) {
//         super(message);
//     }
// 
//     public ExecutionException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public ExecutionException(Throwable cause) {
//         super(cause);
//     }
// 
//     public VM getVm() {
//         return vm;
//     }
// 
//     public ExecutionException setVm(VM vm) {
//         this.vm = vm;
//         return this;
//     }
// }
// 
// Path: jbbvm/bbvm-core/src/main/java/me/wener/bbvm/exception/ResourceMissingException.java
// public class ResourceMissingException extends ExecutionException {
//     private String type;
//     private int handler;
// 
//     public ResourceMissingException(String message, String type, int handler) {
//         super(message);
//         this.type = type;
//         this.handler = handler;
//     }
// 
//     public ResourceMissingException(String type, int handler) {
//         this.type = type;
//         this.handler = handler;
//     }
// 
//     @Override
//     public String toString() {
//         return MoreObjects.toStringHelper(this)
//             .add("type", type)
//             .add("handler", handler)
//             .add("message", getMessage())
//             .toString();
//     }
// }
// 
// Path: jbbvm/bbvm-core/src/main/java/me/wener/bbvm/util/IntEnums.java
// public class IntEnums {
//     private static final Table<Class, Integer, Object> cache = HashBasedTable.create();
// 
//     @SafeVarargs
//     public static <T extends Enum & IsInt> void cache(Class<? extends T>... type) {
//         for (Class<? extends T> t : type) {
//             cache(t);
//         }
//     }
// 
//     private static <T extends Enum & IsInt> void cache(Class<? extends T> type) {
//         for (T item : type.getEnumConstants()) {
//             cache.put(type, item.asInt(), item);
//         }
//     }
// 
//     @SuppressWarnings("unchecked")
//     public static <T extends Enum & IsInt> T fromInt(Class<T> type, int value) {
//         return (T) cache.get(type, value);
//     }
// }
// 
// Path: jbbvm/bbvm-core/src/main/java/me/wener/bbvm/vm/event/ResetEvent.java
// public class ResetEvent extends EventObject {
//     public ResetEvent(VM source) {
//         super(source);
//     }
// }


// Path: jbbvm/bbvm-core/src/main/java/me/wener/bbvm/vm/VM.java
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.eventbus.EventBus;
import com.google.inject.Guice;
import io.netty.buffer.ByteBuf;
import me.wener.bbvm.dev.StringManager;
import me.wener.bbvm.exception.ExecutionException;
import me.wener.bbvm.exception.ResourceMissingException;
import me.wener.bbvm.util.IntEnums;
import me.wener.bbvm.vm.event.ResetEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import java.util.Iterator;
import java.util.Map;
import java.util.NavigableMap;
import static com.google.common.base.Preconditions.checkState;

    void jmp(int i) {
        rp.set(i);
    }

    void ret() {
        rp.set(pop());
    }

    VM push(int v) {
        memory.push(v);
        return this;
    }

    int pop() {
        return memory.pop();
    }

    /**
     * If i >= 0 then read the string from memory, if i < 0 will get string from string resource.
     * If i > memory size or ResourceMissing will return null
     */
    public String getString(int i) {
        if (i >= 0) {
            if (i > memory.getMemorySize()) {
                return null;
            }
            return memory.getString(i, config.getCharset());
        }
        try {
            return stringManager.getResource(i).getValue();
        } catch (ResourceMissingException e) {