BicaVM/src/cpu.js

154 lines
4.4 KiB
JavaScript
Raw Normal View History

2011-07-15 02:50:47 +01:00
/* -*- Mode: Javascript -*-
* -*- coding: UTF-8 -*-
* Copyright (C) 2011 by Artur Ventura
*
* File: cpu.js
* Time-stamp: Fri Jul 15 02:46:27 2011
*
* Author: Artur Ventura
*
*/
2011-07-20 18:19:50 +01:00
#include "constantPool.jsh"
#include "opcodes.jsh"
#include "types.jsh"
#include "cpu.jsh"
2011-07-15 02:50:47 +01:00
2011-07-19 15:17:34 +01:00
/** @constructor */
2011-07-04 18:20:27 +01:00
var JVM = function(params,args){
this.JNITable = params.JNITable || {}
this.internalJNITable =
#include "internalJNI.jsh"
2011-07-04 18:20:27 +01:00
this.params = params;
this.args = args;
this.method_area = {};
this.level = 0;
this.classpath = params.classes_to_load;
2011-08-06 01:03:21 +01:00
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 count"] = string.length;
var x = make1DNativeArray(string.length,true,T_CHAR);
x.value = string.toArray();
inst["java/lang/String value"] = x;
2011-08-06 01:03:21 +01:00
inst["java/lang/String hash"] = this.stringHashCode(string)
return inst;
}
2011-07-04 18:20:27 +01:00
this.classForName = function (name){
2011-07-17 18:42:58 +01:00
if (!name) { PANIC("undefined className")}
var superClass, loaded_class = this.method_area[name];
if (!loaded_class){
loaded_class = LoadClassFile(name, this);
this.method_area[name] = loaded_class;
this.verifyAndLoadClass(loaded_class);
2011-07-04 18:20:27 +01:00
2011-07-15 02:50:47 +01:00
LOG("[Loaded " + name + "]");
}
2011-11-10 23:14:01 +00:00
if(!loaded_class.inited){
loaded_class.initializeClass();
}
return loaded_class;
}
this.verifyAndLoadClass = function(loaded_class){
var superClass;
if(loaded_class.super_class){
// if super_class not java.lang.Object
2011-07-17 18:42:58 +01:00
superClass = canonicalName(loaded_class.super_class.name_ref);
loaded_class.super_class_ref = this.classForName(superClass);
}
// this doesn't seem right. doing this will cause the entire JRE to be loaded
// as soon as you start JVM.
2011-07-04 18:20:27 +01:00
/*
var that = this;
2011-07-04 18:20:27 +01:00
loaded_class.constantPool.each(function(constant){
if (constant.name_ref.str.charAt(0) == "[") {
return;
}
that.verifyAndLoadClass(canonicalName(constant.name_ref));
}, CONSTANT_Class);*/
2011-07-04 18:20:27 +01:00
};
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");
2011-07-21 19:03:57 +01:00
this.java_lang_string = this.classForName("java.lang.String");
2011-08-03 00:32:54 +01:00
this.main_class = this.classForName(this.args[0])
this.main_class.initializeClass();
var method = this.main_class["method main([Ljava/lang/String;)V"];
if (method == null){
PANIC(this.args[0] + " doesn't have a a main method");
}
2011-08-06 01:03:21 +01:00
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);
2011-07-04 18:20:27 +01:00
};
};
2011-07-19 15:17:34 +01:00
/** @constructor */
2011-07-04 18:20:27 +01:00
var JVMThread = function(){
this.pc = null;
this.stack = [];
}
2011-07-19 15:17:34 +01:00
/** @constructor */
2011-07-04 18:20:27 +01:00
var JVMFrame = function(){
this.local_variables = [];
this.operand_stack = [];
}
2011-07-19 15:17:34 +01:00
/** @constructor */
2011-07-15 02:50:47 +01:00
function JVMPanic(message){
this.toString = function(){
return "JVMPanic: " + message
}
2011-08-03 00:32:54 +01:00
}
2011-07-15 02:50:47 +01:00
2011-08-03 00:32:54 +01:00
function interpret(frame,code,method,xl){
var operand_stack = frame.operand_stack;
var local_variables = frame.local_variables;
2011-07-19 15:17:34 +01:00
var opcode;
2011-08-03 00:32:54 +01:00
var pc = 0;
2011-07-18 00:56:41 +01:00
#ifdef DEBUG_INTRP
var temp = null;
2011-07-18 00:56:41 +01:00
#endif
2011-08-03 00:32:54 +01:00
while(pc < code.length){
opcode = READ_NEXT();
switch(OPCODE){
2011-08-02 14:08:37 +01:00
#include "intrp.def"
default:
PANIC("Invalid OPCODE " + opcode);
}
2011-08-03 00:32:54 +01:00
#ifdef DEBUG_INTRP
temp = null;
2011-08-03 00:32:54 +01:00
#endif
}
PANIC("PC overran CODE");
2011-07-20 18:19:50 +01:00
}
2011-08-03 00:32:54 +01:00