diff --git a/class.js b/class.js index fa11e58..d2788b6 100644 --- a/class.js +++ b/class.js @@ -52,7 +52,7 @@ var log = function (msg){ } } -var ClassDefinition = function (file){ +var ClassDefinition = function (file,jvm){ var dataStream = new DataStream(slurpFile(file)[1]); this.magic = dataStream.getU4(); if (this.magic != 0xCAFEBABE){ @@ -75,7 +75,6 @@ var ClassDefinition = function (file){ } this.interface_count = dataStream.getU2(); - // VER: interfaces refs must be classes this.interfaces = []; for(var i=0; i>>>>> " + classFile); - var loaded_class = LoadClassFile(classFile); - var className = loaded_class.this_class.name_ref.str.replace(/\//g,"."); + this.classForName = function (name){ + var superClass, loaded_class = this.method_area[name]; + + if (!loaded_class){ + loaded_class = LoadClassFile(name, this); this.method_area[className] = loaded_class; - var superClass; - if(loaded_class.super_class){ - superClass = canonicalName(loaded_class.super_class.name_ref); - }else{ - superClass = "java.lang.Object"; - } - this.verifyAndLoadClass(superClass); + this.verifyAndLoadClass(loaded_class); + log("[Loaded " + className + " from runtime/" + classFile + "]"); + } + + return loaded_class; + + } + + this.verifyAndLoadClass = function(classFile){ + var superClass; + if(loaded_class.super_class){ + superClass = canonicalName(loaded_class.super_class.name_ref); + }else{ + superClass = "java.lang.Object"; + } + this.classForName(superClass); + + // this doesn't seem right. doing this will cause the entire JRE to be loaded + // as soon as you start JVM. + + /* var that = this; - + loaded_class.constantPool.each(function(constant){ if (constant.name_ref.str.charAt(0) == "[") { return; } that.verifyAndLoadClass(canonicalName(constant.name_ref)); - }, CONSTANT_Class); - - log("[Loaded " + className + " from runtime/" + classFile + "]"); - } + }, CONSTANT_Class);*/ }; this.run = function (){ + this.java_lang_object = this.classForName("java.lang.Object"); + this.java_lang_cloneable = this.classForName("java.lang.Cloneable"); + this.java_io_serializable = this.classForName("java.io.Serializable"); + var mainClass = this.args[0]; - this.verifyAndLoadClass(mainClass); + this.classForName(mainClass); }; }; @@ -52,4 +67,46 @@ var JVMFrame = function(){ this.local_variables = []; this.operand_stack = []; +} + +function JVM_THROWS_NEW(exception){ + throw "VER: throws new " + exception; +} + +function (frame){ + var operand_stack = frame.operand_stack; + + switch(opcode){ + case 0x32: // aaload + var index = operand_stack.pop(); + var arrayref = operand_stack.pop(); + + if (arrayref == NULL){ + JVM_THROWS_NEW("java.lang.NullPointerException"); + } + if (index >= arrayref.length){ + JVM_THROWS_NEW("java.lang.ArrayIndexOutOfBoundsException"); + } + operand_stack.push(arrayref.value[index.value]); + break; + + case 0x53: // aastore + var value = operand_stack.pop(); + var index = operand_stack.pop(); + var arrayref = operand_stack.pop(); + + if (arrayref == NULL){ + JVM_THROWS_NEW("java.lang.NullPointerException"); + } + if (index >= arrayref.length){ + JVM_THROWS_NEW("java.lang.ArrayIndexOutOfBoundsException"); + } + + if (value.ref_of == REF_TYPE_class){ + if (isSubClass(value.ref_of,arrayref.of)); + } + + + + } } \ No newline at end of file diff --git a/types.js b/types.js new file mode 100644 index 0000000..dfcdf96 --- /dev/null +++ b/types.js @@ -0,0 +1,39 @@ + +// Local Variables Types +var LOC_VAR_boolean = 0x001; +var LOC_VAR_byte = 0x002; +var LOC_VAR_char = 0x004; +var LOC_VAR_short = 0x008; +var LOC_VAR_int = 0x010; +var LOC_VAR_float = 0x020; +var LOC_VAR_reference = 0x040; +var LOC_VAR_returnAddress = 0x080; +var LOC_VAR_long = 0x100; +var LOC_VAR_double = 0x200; + +// Reference Types +var REF_TYPE_class = 0x1; +var REF_TYPE_interface = 0x2; +var REF_TYPE_array = 0x4 + +function makeLocalVar(kind){ + return {id:kind}; +} + +function getRefClass(ref){ + if (ref.type == REF_TYPE_array){ + return getArrayClass(); + }else{ + return ref.classRef; + } +} + +var NULL = makeLocalVar(LOC_VAR_reference); + +function isSubClass(refS,refT){ + +} + +function implements(refS,refT){ + +} \ No newline at end of file