NativeArrays, Strings working
This commit is contained in:
parent
6df45ebf93
commit
7dec232268
@ -267,6 +267,10 @@ ClassDefinition.prototype.calculateEffectiveMembers = function(){
|
||||
return [this.effectiveFields,this.effectiveMethods];
|
||||
}
|
||||
|
||||
function instanceToString(){
|
||||
return "<" + this["class"].className + ">";
|
||||
}
|
||||
|
||||
ClassDefinition.prototype.makeInstance = function(){
|
||||
if (!this.inited) { this.initializeClass(); }
|
||||
var newInstance = {};
|
||||
@ -276,6 +280,7 @@ ClassDefinition.prototype.makeInstance = function(){
|
||||
}
|
||||
}
|
||||
newInstance["class"] = this;
|
||||
newInstance["toString"] = instanceToString;
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,9 @@ var constLong = function(){
|
||||
this.low = null;
|
||||
this.id = CONSTANT_Long;
|
||||
this.read = function (dStream){
|
||||
this.value = dStream.getInt64();
|
||||
var high = dStream.getU4();
|
||||
var low = dStream.getU4();
|
||||
this.value = math.Long.fromBits(low,high)
|
||||
}
|
||||
};
|
||||
|
||||
@ -124,6 +126,7 @@ var constClass = function(){
|
||||
throw "Class name index doesn't point to Utf8 in the Constant Pool";
|
||||
}
|
||||
this.name_ref = ref;
|
||||
this.jvmClassName = canonicalName(this.name_ref);
|
||||
}
|
||||
};
|
||||
|
||||
|
28
src/cpu.js
28
src/cpu.js
@ -22,6 +22,28 @@ var JVM = function(params,args){
|
||||
this.method_area = {};
|
||||
this.level = 0;
|
||||
this.classpath = params.classes_to_load;
|
||||
for (var i=0; i<this.args; i++){
|
||||
if (typeof this.args[i] != "string"){
|
||||
throw "Argument " + i + " is not a string.";;
|
||||
}
|
||||
}
|
||||
this.stringHashCode = function(string){
|
||||
var hash = 0;
|
||||
if (string.length == 0) return hash;
|
||||
for (i = 0; i < string.length; i++) {
|
||||
Char = string.charCodeAt(i);
|
||||
hash = ((hash<<5)-hash)+Char;
|
||||
hash = hash & hash; // Convert to 32bit integer
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
this.makeInstanceOfStringFromJSSTring = function(string){
|
||||
var inst = this.java_lang_string.makeInstance();
|
||||
inst["java/lang/String value"] = string;
|
||||
inst["java/lang/String hash"] = this.stringHashCode(string)
|
||||
return inst;
|
||||
}
|
||||
|
||||
this.classForName = function (name){
|
||||
if (!name) { PANIC("undefined className")}
|
||||
@ -72,7 +94,11 @@ var JVM = function(params,args){
|
||||
if (method == null){
|
||||
PANIC(this.args[0] + " doesn't have a a main method");
|
||||
}
|
||||
method.invoke(null,this.main_class);
|
||||
var array = make1DNativeArray(this.args.length,false,this.java_lang_string);
|
||||
for (var i=0; i<this.args.length; i++){
|
||||
array.value[i] = this.makeInstanceOfStringFromJSSTring(this.args[i]);
|
||||
}
|
||||
method.invoke([array],this.main_class);
|
||||
};
|
||||
};
|
||||
/** @constructor */
|
||||
|
11
src/cpu.jsh
11
src/cpu.jsh
@ -13,6 +13,16 @@
|
||||
|
||||
#include "log.jsh"
|
||||
|
||||
#define T_BOOLEAN 4
|
||||
#define T_CHAR 5
|
||||
#define T_FLOAT 6
|
||||
#define T_DOUBLE 7
|
||||
#define T_BYTE 8
|
||||
#define T_SHORT 9
|
||||
#define T_INT 10
|
||||
#define T_LONG 11
|
||||
|
||||
|
||||
#define JVM_THROWS_NEW(exception) throw "VER: throws new exception"
|
||||
#ifdef DEBUG_INTRP
|
||||
#define LOG_INTRP(x) LOG(x)
|
||||
@ -36,6 +46,7 @@
|
||||
#define OPPUSHD(v) (operand_stack.push(v) && operand_stack.push(null))
|
||||
|
||||
#define OPSTACK(v) operand_stack[v]
|
||||
#define OPSTACK_MULTIPOP(x) operand_stack.splice(x)
|
||||
#define OPSTACK_LENGTH() operand_stack.length
|
||||
|
||||
#define LOCAL_VAR(v) local_variables[v]
|
||||
|
@ -52,7 +52,11 @@ var MethodInfo = function(dStream, constantPool){
|
||||
for (var i=0; i<this.attributes_count; i++){
|
||||
var attr = this.attributes[i];
|
||||
if (attr.id == ATTR_CODE){
|
||||
interpret(frame,attr.code,this,xl);
|
||||
var result = interpret(frame,attr.code,this,xl);
|
||||
#ifdef DEBUG_INTRP
|
||||
LOG("Returing from " + this.name_ref.str + this.descriptor_ref.str)
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ DEFOP(ACONST_NULL)
|
||||
ENDDEF
|
||||
|
||||
DEFOP(ALOAD)
|
||||
var i = OPPOP();
|
||||
var i = READ_NEXT();
|
||||
OPPUSH(LOCAL_VAR(i))
|
||||
ENDDEF
|
||||
|
||||
@ -61,8 +61,8 @@ DEFOP(ANEWARRAY)
|
||||
if (count < 0){
|
||||
JVM_THROWS_NEW(java.lang.NegativeArraySizeException);
|
||||
}
|
||||
var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var instance = {length:count, dimensions:1, value:[], 'class':xl.jvm.classForName(clRef)};
|
||||
var clRef = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var instance = make1DNativeArray(count,false,xl.jvm.classForName(clRef));
|
||||
OPPUSH(instance);
|
||||
ENDDEF
|
||||
|
||||
@ -516,9 +516,9 @@ DEFOP(GETFIELD)
|
||||
var objectref = OPPOP();
|
||||
|
||||
CHECK_NULL(objectref)
|
||||
var field = objectref["class"].constantPool[(indexbyte1 << 8) | indexbyte2];
|
||||
var field = objectref["class"].constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
//check if static
|
||||
OPPUSH(objectref[canonicalName(field.class_ref.name_ref.str) + " " + field.name_and_type_ref.name_ref.str]);
|
||||
OPPUSH(objectref[canonicalName(field.class_ref.name_ref) + " " + field.name_and_type_ref.name_ref.str]);
|
||||
ENDDEF
|
||||
|
||||
DEFOP(GETSTATIC)
|
||||
@ -526,11 +526,11 @@ DEFOP(GETSTATIC)
|
||||
var indexbyte2 = READ_NEXT();
|
||||
|
||||
CHECK_NULL(objectref)
|
||||
var field = this_method_class.constantPool[(indexbyte1 << 8) | indexbyte2];
|
||||
var field = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var aClass = field.class_ref.name_ref.str;
|
||||
|
||||
//check if static
|
||||
OPPUSH(jvm.classForName(aClass)[canonicalName(field.class_ref.name_ref.str) + " " + field.name_and_type_ref.name_ref.str]);
|
||||
OPPUSH(jvm.classForName(aClass)[canonicalName(field.class_ref.name_ref) + " " + field.name_and_type_ref.name_ref.str]);
|
||||
ENDDEF
|
||||
|
||||
DEFOP(GOTO)
|
||||
@ -612,10 +612,10 @@ DEFOP(IAND)
|
||||
ENDDEF
|
||||
|
||||
DEFOP(IASTORE)
|
||||
var value = OPPOP();
|
||||
var index = OPPOP();
|
||||
var arrayref = OPPOP();
|
||||
var value = OPPOP();
|
||||
|
||||
|
||||
CHECK_NULL(arrayref);
|
||||
CHECK_ARRAY_INDEX(index,arrayref);
|
||||
|
||||
@ -869,7 +869,7 @@ DEFOP(INSTANCEOF)
|
||||
OPPUSH(0);
|
||||
break;
|
||||
}
|
||||
var className = canonicalName(this_method_class.constantPool[(indexbyte1 << 8) | indexbyte2].name_ref.str);
|
||||
var className = canonicalName(xl.constantPool.get((indexbyte1 << 8) | indexbyte2).name_ref);
|
||||
|
||||
if(objectref["class"].isAssignable(jvm.classForName(className))){
|
||||
OPPUSH(1);
|
||||
@ -889,7 +889,7 @@ DEFOP(INVOKEINTERFACE)
|
||||
/* expected 0*/ READ_NEXT();
|
||||
var args = [];
|
||||
|
||||
var method = this_method_class.constantPool[(indexbyte1 << 8) | indexbyte2];
|
||||
var method = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
for(var i=0; i<method.descriptor.args.length; i++){
|
||||
args.push(OPPOP());
|
||||
}
|
||||
@ -901,15 +901,21 @@ ENDDEF
|
||||
DEFOP(INVOKESPECIAL)
|
||||
var indexbyte1 = READ_NEXT();
|
||||
var indexbyte2 = READ_NEXT();
|
||||
var args = [];
|
||||
|
||||
var method = this_method_class.constantPool[(indexbyte1 << 8) | indexbyte2];
|
||||
for(var i=0; i<method.descriptor.args.length; i++){
|
||||
args.push(OPPOP());
|
||||
var methodDesrc = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var cl = xl.jvm.classForName(methodDesrc.class_ref.jvmClassName);
|
||||
var methodId = "method " + methodDesrc.name_and_type_ref.name_ref.str + methodDesrc.name_and_type_ref.descriptor_ref.str
|
||||
var method = cl[methodId];
|
||||
var args = OPSTACK_MULTIPOP(OPSTACK_LENGTH() - method.descriptor.args.length-1);
|
||||
var result;
|
||||
if(method.access_flags & ACC_NATIVE){
|
||||
PANIC("INVOKESPECIAL NATIVE CALL")
|
||||
}else{
|
||||
result = method.invoke(args,cl);
|
||||
}
|
||||
if (result != undefined){
|
||||
OPPUSH(result.return_object);
|
||||
}
|
||||
|
||||
var objectref = OPPOP();
|
||||
PANIC("NOT IMPLEMENTED YET");
|
||||
ENDDEF
|
||||
|
||||
DEFOP(INVOKESTATIC)
|
||||
@ -917,7 +923,7 @@ DEFOP(INVOKESTATIC)
|
||||
var indexbyte2 = READ_NEXT();
|
||||
var args = [];
|
||||
|
||||
var method = this_method_class.constantPool[(indexbyte1 << 8) | indexbyte2];
|
||||
var method = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
for(var i=0; i<method.descriptor.args.length; i++){
|
||||
args.push(OPPOP());
|
||||
}
|
||||
@ -930,13 +936,20 @@ DEFOP(INVOKEVIRTUAL)
|
||||
var indexbyte2 = READ_NEXT();
|
||||
var args = [];
|
||||
|
||||
var method = this_method_class.constantPool[(indexbyte1 << 8) | indexbyte2];
|
||||
for(var i=0; i<method.descriptor.args.length; i++){
|
||||
|
||||
args.push(OPPOP());
|
||||
var methodDesrc = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var cl = xl.jvm.classForName(methodDesrc.class_ref.jvmClassName);
|
||||
var methodId = "method " + methodDesrc.name_and_type_ref.name_ref.str + methodDesrc.name_and_type_ref.descriptor_ref.str
|
||||
var method = cl[methodId];
|
||||
var args = OPSTACK_MULTIPOP(OPSTACK_LENGTH() - method.descriptor.args.length);
|
||||
var result;
|
||||
if(method.access_flags & ACC_NATIVE){
|
||||
PANIC("INVOKEVIRTUAL NATIVE CALL")
|
||||
}else{
|
||||
result = method.invoke(args,cl);
|
||||
}
|
||||
if (result != undefined){
|
||||
OPPUSH(result.return_object);
|
||||
}
|
||||
|
||||
method.invoke([])
|
||||
ENDDEF
|
||||
|
||||
DEFOP(IOR)
|
||||
@ -1122,14 +1135,14 @@ ENDDEF
|
||||
|
||||
DEFOP(LDC)
|
||||
var index = READ_NEXT();
|
||||
var cstt = this_method_class.constantPool.get(index);
|
||||
var cstt = xl.constantPool.get(index);
|
||||
switch(cstt.id){
|
||||
case CONSTANT_Integer:
|
||||
case CONSTANT_Float:
|
||||
OPPUSH(cstt.value);
|
||||
break;
|
||||
case CONSTANT_String:
|
||||
PANIC("NEW STRING FROM CONSTANT POOL NOT IMPLEMENTED");
|
||||
OPPUSH(xl.jvm.makeInstanceOfStringFromJSSTring(cstt.string_ref.str));
|
||||
break;
|
||||
default:
|
||||
PANIC("What now?");
|
||||
@ -1141,7 +1154,7 @@ DEFOP(LDC_W)
|
||||
var index1 = READ_NEXT();
|
||||
var index2 = READ_NEXT();
|
||||
var index = (indexbyte1 << 8) | indexbyte2
|
||||
var cstt = this_method_class.constantPool.get(index);
|
||||
var cstt = xl.constantPool.get(index);
|
||||
switch(cstt.id){
|
||||
case CONSTANT_Integer:
|
||||
OPPUSHD(cstt.value);
|
||||
@ -1360,7 +1373,7 @@ DEFOP(MULTIANEWARRAY)
|
||||
for(var i=0; i<dimensions; i++){
|
||||
counts.add(OPPOP());
|
||||
}
|
||||
var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var clRef = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var instance = {length:counts, dimensions:dimensions, value:[], 'class':xl.jvm.classForName(clRef)};
|
||||
OPPUSH(instance);
|
||||
ENDDEF
|
||||
@ -1369,14 +1382,25 @@ DEFOP(NEW)
|
||||
var indexbyte1 = READ_NEXT();
|
||||
var indexbyte2 = READ_NEXT();
|
||||
|
||||
var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var newInstance = xl.jvm.classForName(clRef).makeInstance();
|
||||
var clRef = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var newInstance = xl.jvm.classForName(clRef.jvmClassName).makeInstance();
|
||||
OPPUSH(newInstance);
|
||||
ENDDEF
|
||||
|
||||
DEFOP(NOP)
|
||||
ENDDEF
|
||||
|
||||
DEFOP(NEWARRAY)
|
||||
var atype = READ_NEXT();
|
||||
var count = OPPOP();
|
||||
if (count < 0){
|
||||
JVM_THROWS_NEW(java.lang.NegativeArraySizeException);
|
||||
}
|
||||
var clRef = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var instance = make1DNativeArray(count,true,atype);
|
||||
OPPUSH(instance);
|
||||
ENDDEF
|
||||
|
||||
DEFOP(POP)
|
||||
OPPOP();
|
||||
ENDDEF
|
||||
@ -1393,9 +1417,9 @@ DEFOP(PUTFIELD)
|
||||
var objectref = OPPOP();
|
||||
|
||||
CHECK_NULL(objectref)
|
||||
var field = objectref["class"].constantPool[(indexbyte1 << 8) | indexbyte2];
|
||||
var field = objectref["class"].constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
//check if static
|
||||
objectref[canonicalName(field.class_ref.name_ref.str) + " " + field.name_and_type_ref.name_ref.str] = value;
|
||||
objectref[canonicalName(field.class_ref.name_ref) + " " + field.name_and_type_ref.name_ref.str] = value;
|
||||
ENDDEF
|
||||
|
||||
DEFOP(GETSTATIC)
|
||||
@ -1404,11 +1428,11 @@ DEFOP(GETSTATIC)
|
||||
var value = OPPOP();
|
||||
|
||||
CHECK_NULL(objectref)
|
||||
var field = this_method_class.constantPool[(indexbyte1 << 8) | indexbyte2];
|
||||
var field = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var aClass = field.class_ref.name_ref.str;
|
||||
|
||||
//check if static
|
||||
jvm.classForName(aClass)[canonicalName(field.class_ref.name_ref.str) + " " + field.name_and_type_ref.name_ref.str] = value;
|
||||
jvm.classForName(aClass)[canonicalName(field.class_ref.name_ref) + " " + field.name_and_type_ref.name_ref.str] = value;
|
||||
ENDDEF
|
||||
|
||||
DEFOP(RET)
|
||||
|
@ -7,10 +7,15 @@
|
||||
* Author: Artur Ventura
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DEBUG
|
||||
#define LOG(msg)
|
||||
#else
|
||||
|
||||
|
||||
function htmlentities(str) {
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
#define LOG(msg) write(msg);\
|
||||
if (console){\
|
||||
console.log(msg);\
|
||||
|
52
src/nativeArrays.js
Normal file
52
src/nativeArrays.js
Normal file
@ -0,0 +1,52 @@
|
||||
/* -*- Mode: Javascript -*-
|
||||
* -*- coding: UTF-8 -*-
|
||||
* Copyright (C) 2011 by Artur Ventura
|
||||
*
|
||||
* File: nativeArray.js
|
||||
* Time-stamp: Fri Jul 15 02:46:27 2011
|
||||
*
|
||||
* Author: Artur Ventura
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cpu.jsh"
|
||||
|
||||
function printNativeArray(){
|
||||
var result = "[";
|
||||
if(this.primitive){
|
||||
switch(this['class']){
|
||||
case T_BOOLEAN:
|
||||
result += "Z";
|
||||
break;
|
||||
case T_BYTE:
|
||||
result += "B";
|
||||
break;
|
||||
case T_CHAR:
|
||||
result += "C";
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
result += "D";
|
||||
break;
|
||||
case T_FLOAT:
|
||||
result += "F";
|
||||
break
|
||||
case T_INT:
|
||||
result += "I";
|
||||
break
|
||||
case T_LONG:
|
||||
result += "J";
|
||||
break
|
||||
case T_SHORT:
|
||||
result += "B";
|
||||
break
|
||||
}
|
||||
}else{
|
||||
result+="L" + this['class'].className + ";";
|
||||
}
|
||||
return result + "#" + this.length;
|
||||
}
|
||||
|
||||
function make1DNativeArray(count,primitive,type){
|
||||
var inst = {toString: printNativeArray,length:count, dimensions:1, value:[], primitive:primitive, 'class':type};
|
||||
return inst;
|
||||
}
|
@ -4,7 +4,20 @@
|
||||
<script>
|
||||
write = function(msg){
|
||||
var l = document.getElementById("log");
|
||||
var match;
|
||||
if ((match = msg.match(/(\d+): (\w+) (op:\[[^\]]*]) (.*)/))){
|
||||
var space3 = "";
|
||||
for(var i=0; i<3-(match[1].length); i++){space3 += " " }
|
||||
var space1 = "";
|
||||
for(var i=0; i<23-(match[1].length + space3.length + match[2].length);i++ ){space1 += " " }
|
||||
var space2 = "";
|
||||
for(var i=0; i<30-(match[3].length); i++ ){space2 += " " }
|
||||
msg = "<span style='color:DarkOrchid '>" + match[1] + "</span>:"+ space3 +"<a style='color:red;' href='http://homepages.inf.ed.ac.uk/kwxm/JVM/" + match[2].toLowerCase().replace(/\d+/,"n") + ".html'>" + match[2] + "</a>" + space1 + htmlentities(match[3]) + space2 +" "+ htmlentities(match[4]) ;
|
||||
}else{
|
||||
msg=htmlentities(msg);
|
||||
}
|
||||
l.innerHTML = l.innerHTML + msg + "\n";
|
||||
|
||||
}
|
||||
</script>
|
||||
<script src="jvm.js" type="text/javascript"></script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user