Giter VIP home page Giter VIP logo

mini-jvm's Introduction

CircleCIGitHubGitHub commit activityGitHub last commit

使用 Java 8 实现 JVM

特性

元循环(Metacircular)

mini-jvm on mini-jvm on hotspot. 可以在 mini-jvm 里运行 mini-jvm .

$ java -jar jvm-core/target/mini-jvm.jar -jar jvm-core/target/mini-jvm.jar -jar test.jar
# Hello World!

动机

  1. 尝试了解 JVM 原理, Learning by doing
  2. 纸上得来终觉浅, 实践
  3. 用简单的代码帮助 Javaer 理解 JVM

快速体验 [Macos 用户]

Hello world

brew tap guxingke/repo && brew install mini-jvm

cat <<EOF > HelloWorld.java
public class HelloWorld {
  public static void main(String[] args) {
    if (args.length == 0) {
      System.out.println("hello");
      return;
    }

    for(int i = 0; i < args.length; i ++) {
      System.out.println(args[i]);
    }
  }
}
EOF

javac HelloWorld.java

# no args
mini-jvm HelloWold
# => hello

# with program args
mini-jvm HelloWold hello mini-jvm
# =>  hello
# =>  mini-jvm

# 输入 mini-jvm -help 了解更多.

快速体验 [其他操作系统]

需要自行下载打包. Dev

规划

  • Class 文件解析 90%
  • 字节码执行 90%
  • 类加载 90%
  • 方法调用 90%
  • 实例化 90%
  • Native 方法 90%
  • 异常处理 60%
  • self-booting 70%

局限

  1. 不实现 GC
  2. 不实现多线程

变更记录

  • 实现了元循环(Metacircular)
  • 反射特性基本可用
  • 增加简单的调试器 bin/jdb.
  • 支持 Lambda 调用, closure, currying 可用.
  • Hello World 级别可用

个人记录

建议

  • 在JDK1.8.0_121环境下发现编译不过的情况,详情见#25,本项目的目的是学习JVM,为了项目足够小,清晰和易于理解,并不打算做各种适配工作,建议大家在MacOSX,Maven 3.3+,JDK 1.8.0_192+下学习;

联系作者

微信群

加个人微信 `guxingke_`,备注 mini-jvm 拉你进群。

参考

其他

新项目地址 mini-jvm_x, 使用多种语言实现。

mini-jvm's People

Contributors

brycelee avatar deepbreath avatar et-stack avatar guxingke avatar hesherya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mini-jvm's Issues

InvokeDynamicInst 的实现

关于这个指令的 BootstrapMethods 属性,我看了官方文档:
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.21
但是里面没有详细介绍 bootstrap_arguments,有点不太明白,想请教一下,这个 bootstrap 方法的参数列表是做啥的呢?
我个人的理解是,单纯的支持 lambda 表达式,拿 runnable 来说,第二个参数对应的是生成的目标方法,第一个参数与第三个参数是一样的,所以不太明白为啥会有两个,它们的作用是啥?

test failed locally

Tests in error:
test_fis(com.gxk.jvm.builtin.JavaIoTest)

Test success after deleting the method.(Jvm-core/src/test/java/com.gxk.jvm.builtin.JavaIoTest.test_fis)

Crash java.lang.IllegalStateException: must set env JAVA_HOME

On my Linux machine JAVA_HOME is not set, the JVM crashes with following error:

$ java -jar jvm-core/target/mini-jvm.jar -jar jvm-core/target/mini-jvm.jar -jar test.jar
Exception in thread "main" java.lang.IllegalStateException: must set env JAVA_HOME
        at com.gxk.jvm.util.Utils.classpath(Utils.java:263)           at com.gxk.jvm.VirtualMachine.run(VirtualMachine.java:58)                                                                   at com.gxk.jvm.Main.main(Main.java:28)

不支持对classloader的处理

您好,在执行如以下包含classloader代码时,mini-jvm好像无法解析。

    try {
      Class cls = Class.forName("TestClass");
      cl = cls.getClassLoader();
      cl.getResource("name");
    } catch (Exception e) { 
      System.out.println(-1);
    }

报错如下所示:

Exception in thread "main" java.lang.NullPointerException
	at com.gxk.jvm.instruction.references.InvokeVirtualInst.execute(InvokeVirtualInst.java:80)
	at com.gxk.jvm.interpret.Interpreter.execute(Interpreter.java:53)
	at com.gxk.jvm.interpret.Interpreter.runMain(Interpreter.java:77)
	at com.gxk.jvm.VirtualMachine.run(VirtualMachine.java:79)
	at com.gxk.jvm.Main.main(Main.java:24)

JDK 基础类库测试. java.util.Map

  1. 编写测试用例
    e.g
import java.util.*;

public class testMap {

    public static void main(String[] args){

    Map map = new HashMap<>();
    map.put("a", 12);

    System.out.println(map.get("a"));

    }
}

2.以 mini-jvm 运行, 判定结果是否符合预期.
3.若符合预期, 提交 PR.
4.若不合预期, 尝试修复, 若碰到问题, 评论即可.

异常处理 输出堆栈信息

Exception in thread "main" java.lang.RuntimeException: no exception handler
	at com.gxk.jvm.instruction.AThrowInst.execute(AThrowInst.java:27)
	at com.gxk.jvm.interpret.Interpreter.loop(Interpreter.java:106)
	at com.gxk.jvm.interpret.Interpreter.doInterpret(Interpreter.java:75)
	at com.gxk.jvm.interpret.Interpreter.interpret(Interpreter.java:29)
	at com.gxk.jvm.VirtualMachine.run(VirtualMachine.java:71)
	at com.gxk.jvm.Main.main(Main.java:28)

superClazz 的逻辑意义个人觉得存在问题

image

Interceptor.java

public void doInterpret(Thread thread, Frame frame) {
thread.pushFrame(frame);
KClass clazz = frame.method.clazz;
if (clazz != null) {
// super clazz static interfaceInit
KClass superClazz = clazz.getUnStaticInitSuperClass();

clazz.name = "HelloWorld"
superClazz.name = "HelloWorld"

感觉 superClazz 的逻辑意义 和 实际扮演的角色 不符吧

支持 JDK 动态代理

通过测试案例

interface Interface {
  void doSomething();
  void somethingElse(String arg);
}

class RealObject implements Interface {
  @Override
  public void doSomething() {
    System.out.println("doSomething");
  }
  @Override
  public void somethingElse(String arg) {
    System.out.println("somethingElse " + arg);
  }
}


class DynamicProxyHandler implements InvocationHandler {
  private Object proxied;
  DynamicProxyHandler(Object proxied) {
    this.proxied = proxied;
  }
  @Override
  public Object
  invoke(Object proxy, Method method, Object[] args)
  throws Throwable {
    System.out.println(
      "**** proxy: " + proxy.getClass() +
      ", method: " + method + ", args: " + args);
    if(args != null)
      for(Object arg : args)
        System.out.println("  " + arg);
    return method.invoke(proxied, args);
  }
}

class SimpleDynamicProxy {
  public static void consumer(Interface iface) {
    iface.doSomething();
    iface.somethingElse("bonobo");
  }
  public static void main(String[] args) {
    RealObject real = new RealObject();
    consumer(real);
    // Insert a proxy and call again:
    Interface proxy = (Interface)Proxy.newProxyInstance(
      Interface.class.getClassLoader(),
      new Class[]{ Interface.class },
      new DynamicProxyHandler(real));
    consumer(proxy);
  }
}

=>

doSomething
somethingElse bonobo
SimpleProxy doSomething
doSomething
SimpleProxy somethingElse bonobo
somethingElse bonobo

JDK 基础类库测试. java.util.ArrayList

  1. 编写测试用例
    e.g
import java.util.ArrayList;
public class TestArrayList {
  public static void main(String[] args) {
      ArrayList<String> list = new ArrayList<>(2);
      list.add("1");
      list.add("2");
      
      int size = list.size();
      String l1 = list.get(0);
      
      System.out.println(size);
      System.out.println(l1);
  }
}
  1. 以 mini-jvm 运行, 判定结果是否符合预期.
  2. 若符合预期, 提交 PR.
  3. 若不合预期, 尝试修复, 若碰到问题, 评论即可.

IfICmpEqInst.execute Integer equal issue

`public class IfICmpEqInst implements Instruction {
public final int offset;

public IfICmpEqInst(int offset) {
this.offset = offset;
}

@OverRide
public int offset() {
return 3;
}

@OverRide
public void execute(Frame frame) {
Integer val2= frame.popInt();
Integer val1= frame.popInt();
### if (val1 == val2) { //Objects.equals(val1, val2)
frame.nextPc = frame.thread.getPc() + offset;
}
}
}
`

执行同一个程序, 基于 mini-jvm 的不报错, 基于 mini-jvm 的 mini-jvm 报错

执行同一个程序, 基于 mini-jvm 的不报错, 基于 mini-jvm 的 mini-jvm 报错
master:mini-jvm jerry$ javac Test06LoadRefEachOther.java
master:mini-jvm jerry$ java -jar jvm-core/target/mini-jvm.jar -cp . Test06LoadRefEachOther
1
1
master:mini-jvm jerry$ java -jar jvm-core/target/mini-jvm.jar -jar jvm-core/target/mini-jvm.jar -cp . Test06LoadRefEachOther
java.lang.ArrayIndexOutOfBoundsException: 256
at com.gxk.jvm.instruction.AAStoreInst.execute(AAStoreInst.java:13)
at com.gxk.jvm.interpret.Interpreter.loop(Interpreter.java:119)
at com.gxk.jvm.interpret.Interpreter.doInterpret(Interpreter.java:75)
at com.gxk.jvm.interpret.Interpreter.interpret(Interpreter.java:45)
at com.gxk.jvm.VirtualMachine.run(VirtualMachine.java:74)
at com.gxk.jvm.Main.main(Main.java:23)
com/gxk/jvm/instruction/CAStoreInst.execute(CAStoreInst.java:13)
Exception in thread "main" java.lang.IllegalStateException
at com.gxk.jvm.interpret.Interpreter.loop(Interpreter.java:126)
at com.gxk.jvm.interpret.Interpreter.doInterpret(Interpreter.java:75)
at com.gxk.jvm.interpret.Interpreter.interpret(Interpreter.java:45)
at com.gxk.jvm.VirtualMachine.run(VirtualMachine.java:74)
at com.gxk.jvm.Main.main(Main.java:23)
master:mini-jvm jerry$

测试用例如下
/**

// Test06LoadRefEachOther
// refer : https://hllvm-group.iteye.com/group/topic/38847
public static void main(String[] args) {

System.out.println(Clazz1.x1);

// System.out.println(Clazz2.x1);
System.out.println(Clazz2.x2);

}

/**

/**

}

<clinit> 的执行时机

... 放到这里 感觉有点别扭呀, 和规范 描述的差距太大了, 另外 放在这里 感觉还是有点不合适

基类的 clinit 被执行多次

master:mini-jvm jerry$ java -jar jvm-core/target/mini-jvm.jar -jar jvm-core/target/mini-jvm.jar -cp . HelloWorld
HelloWorldSuper
HelloWorldSuper
hello world

HelloWorld.java
public class HelloWorld extends HelloWorldSuper {
// static {
// System.out.println("");
// }
public static void main(String[] args) {
System.out.println("hello world");
}
}

HelloWorldSuper.java
public class HelloWorldSuper {
static {
System.out.println("HelloWorldSuper ");
}
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.