用nodejs 写一个 jvm

知识背景:

我们大家都听过 Java 常量池,其实他里面就存了 class 相关信息,比如 这个类的包名,那么 当 执行到 这一句的时候,要加载类的时候,

我们就可以 去做我们自己事,比如 调用js 处理这些事情,而当一些计算型的事情我们同样可以这么做,也就是 说我们 只要,把Java基础库写完,就可以用node 跑 class


这思想就是指令解析,有点类似汇编,这里我贴一点代码理解下:


这是一段比较有趣的指令解析,就是从常量池里拿出 className,然后去load class or js 去处理一些事,看到这里也许你也明白了,为什么Java内部类 会生成一个独立的class

文件


Frame.prototype.putstatic = function(done) {
    var idx = this._read16();
    var className = this._cp[this._cp[this._cp[idx].class_index].name_index].bytes;
    var fieldName = this._cp[this._cp[this._cp[idx].name_and_type_index].name_index].bytes;
    CLASSES.setStaticField(className, fieldName, this._stack.pop());
    return done();
}

Frame.prototype.invokestatic = function(done) {
    var self = this;
    
    var idx = this._read16();
    
    var className = this._cp[this._cp[this._cp[idx].class_index].name_index].bytes;
    var methodName = this._cp[this._cp[this._cp[idx].name_and_type_index].name_index].bytes;
    var signature = Signature.parse(this._cp[this._cp[this._cp[idx].name_and_type_index].signature_index].bytes);
    
    var args = [];
    for (var i=0; i<signature.IN.length; i++) {
        if (!signature.IN[i].isArray && ["long", "double"].indexOf(signature.IN[i].type) !== -1) {
            args.unshift("");
            args.unshift(this._stack.pop());
        } else {
            args.unshift(this._stack.pop());
        }
    }
    
    var method = CLASSES.getStaticMethod(className, methodName, signature);


    if (method instanceof Frame) {

        method.setPid(self._pid);
        method.run(args, function(res) {
            if (signature.OUT.length != 0) {                        
               self._stack.push(res);
            }
            return done();
        });
    } else {
        var res = method.apply(null, args);
        if (signature.OUT.length != 0) {                        
            self._stack.push(res);                        
        }
        return done();
    }
}    


这里就是 判断去load class 还是 js,node 就像是个翻译器

Classes.prototype.getClass = function(className) {
    var ca = this.classes[className];
    if (ca) {
        return ca;
    }
    for(var i=0; i<this.paths.length; i++) {
        var fileName = util.format("%s/%s", this.paths[i], className);
        if (fs.existsSync(fileName + ".js")) {
            return this.loadJSFile(fileName + ".js");
        }
        if(fs.existsSync(fileName + ".class")) {
            return this.loadClassFile(fileName + ".class");
        }
    }
    throw new Error(util.format("Implementation of the %s class is not found.", className));
};


这是通过 javap 生成的指令集


Compiled from "Main.java"
public class Main {
  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class Clazz
       3: dup
       4: invokespecial #3                  // Method Clazz."<init>":()V
       7: astore_1
       8: aload_1
       9: getfield      #4                  // Field Clazz.test:LClazz$Test;
      12: ldc           #5                  // String print from nested class
      14: invokevirtual #6                  // Method Clazz$Test.print:(Ljava/la
ng/String;)V
      17: return
}


猜你喜欢

转载自blog.csdn.net/qq948993066/article/details/77979529