advancing closure compilation process

This commit is contained in:
Artur Ventura 2011-07-19 15:17:34 +01:00
parent 2025c82c99
commit d0d347dc84
11 changed files with 59 additions and 51 deletions

View File

@ -5,10 +5,10 @@ ids:
preprocess: preprocess:
mkdir -p build mkdir -p build
/usr/bin/cpp -P -undef -Wundef -std=c99 -nostdinc -Wtrigraphs -fdollars-in-identifiers src/main.js build/pp_jvm.js /usr/bin/cpp -P -undef -CC -Wundef -std=c99 -nostdinc -Wtrigraphs -fdollars-in-identifiers src/main.js build/pp_jvm.js
compile: preprocess compile: preprocess
java -jar lib/compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js build/pp_jvm.js --js_output_file build/jvm.js java -jar lib/compiler.jar --warning_level VERBOSE --compilation_level ADVANCED_OPTIMIZATIONS --js build/pp_jvm.js --js_output_file build/jvm.js
clean: clean:
rm -dR build rm -dR build

View File

@ -9,6 +9,7 @@
* *
*/ */
/** @constructor */
var ExceptionTableEntry = function(dStream, constantPool){ var ExceptionTableEntry = function(dStream, constantPool){
this.start_pc = dStream.getU2(); this.start_pc = dStream.getU2();
this.end_pc = dStream.getU2(); this.end_pc = dStream.getU2();
@ -21,6 +22,7 @@ var ExceptionTableEntry = function(dStream, constantPool){
} }
} }
/** @constructor */
var InnerClass = function(dStream, constantPool){ var InnerClass = function(dStream, constantPool){
this.inner_class_info = ConstantPoolRef(dStream.getU2(), constantPool,CONSTANT_Class); this.inner_class_info = ConstantPoolRef(dStream.getU2(), constantPool,CONSTANT_Class);
var outerClassIndex = dStream.getU2(); var outerClassIndex = dStream.getU2();
@ -33,11 +35,13 @@ var InnerClass = function(dStream, constantPool){
this.inner_class_access_flags = dStream.getU2(); this.inner_class_access_flags = dStream.getU2();
} }
/** @constructor */
var LineNumberTableEntry = function(dStream){ var LineNumberTableEntry = function(dStream){
this.start_pt = dStream.getU2(); this.start_pt = dStream.getU2();
this.line_number = dStream.getU2(); this.line_number = dStream.getU2();
} }
/** @constructor */
var LocalVariableTableEntry = function(dStream, constantPool){ var LocalVariableTableEntry = function(dStream, constantPool){
this.start_pc = dStream.getU2(); this.start_pc = dStream.getU2();
this.length =dStream.getU2(); this.length =dStream.getU2();
@ -47,6 +51,7 @@ var LocalVariableTableEntry = function(dStream, constantPool){
} }
var Attributes_table = { var Attributes_table = {
/** @constructor */
ConstantValue: function(){ ConstantValue: function(){
this.read = function(dStream, constantPool){ this.read = function(dStream, constantPool){
this.constantvalue = ConstantPoolRef(dStream.getU2(), constantPool); this.constantvalue = ConstantPoolRef(dStream.getU2(), constantPool);
@ -63,7 +68,7 @@ var Attributes_table = {
} }
} }
}, },
/** @constructor */
Code: function(){ Code: function(){
this.read = function(dStream, constantPool){ this.read = function(dStream, constantPool){
this.max_stack = dStream.getU2(); this.max_stack = dStream.getU2();
@ -100,7 +105,7 @@ var Attributes_table = {
} }
} }
}, },
/** @constructor */
Exceptions: function(){ Exceptions: function(){
this.read = function(dStream, constantPool){ this.read = function(dStream, constantPool){
this.number_of_exceptions = dStream.getU2(); this.number_of_exceptions = dStream.getU2();
@ -110,7 +115,7 @@ var Attributes_table = {
} }
} }
}, },
/** @constructor */
InnerClasses: function(){ InnerClasses: function(){
this.read = function(dStream, constantPool){ this.read = function(dStream, constantPool){
this.number_of_classes = dStream.getU2(); this.number_of_classes = dStream.getU2();
@ -120,7 +125,7 @@ var Attributes_table = {
} }
} }
}, },
/** @constructor */
Synthetic: function(){ Synthetic: function(){
this.read = function(dStream,constantPool){ this.read = function(dStream,constantPool){
if (this.attribute_length != 0){ if (this.attribute_length != 0){
@ -128,13 +133,13 @@ var Attributes_table = {
} }
} }
}, },
/** @constructor */
SourceFile: function(){ SourceFile: function(){
this.read = function(dStream,constantPool){ this.read = function(dStream,constantPool){
this.soucefile = ConstantPoolRef(dStream.getU2(), constantPool,CONSTANT_Utf8); this.soucefile = ConstantPoolRef(dStream.getU2(), constantPool,CONSTANT_Utf8);
} }
}, },
/** @constructor */
LineNumberTable: function(){ LineNumberTable: function(){
this.read = function(dStream,constantPool){ this.read = function(dStream,constantPool){
this.line_number_table_length = dStream.getU2(); this.line_number_table_length = dStream.getU2();
@ -144,17 +149,17 @@ var Attributes_table = {
} }
} }
}, },
/** @constructor */
LocalVariableTable: function(){ LocalVariableTable: function(){
this.read=function(dStream,constantPool){ this.read=function(dStream,constantPool){
this.local_variable_table_length = dStream.getU2(); this.local_variable_table_length = dStream.getU2();
this.local_variable_table = []; this.local_variable_table = [];
for(var i=0; i<local_variable_table_length; i++){ for(var i=0; i<this.local_variable_table_length; i++){
this.local_variable_table[i] = new LocalVariableTableEntry(dSteam,constantPool); this.local_variable_table[i] = new LocalVariableTableEntry(dStream,constantPool);
} }
} }
}, },
/** @constructor */
Deprecated: function(){ Deprecated: function(){
this.read = function(dStream,constantPool){ this.read = function(dStream,constantPool){
if (this.attribute_length != 0){ if (this.attribute_length != 0){
@ -163,7 +168,7 @@ var Attributes_table = {
} }
} }
}; };
/** @constructor */
function UnkownAttr(){ function UnkownAttr(){
this.read = function(dStream){ this.read = function(dStream){
this.info = []; this.info = [];

View File

@ -39,7 +39,7 @@ function slurpFile (filename, fa) {
if (xmlHttpRequest.status != 200 && xmlHttpRequest.status != 0) { if (xmlHttpRequest.status != 200 && xmlHttpRequest.status != 0) {
throw "Error while loading " + filename; throw "Error while loading " + filename;
} }
bf = true; var bf = true;
if ('mozResponse' in xmlHttpRequest) { if ('mozResponse' in xmlHttpRequest) {
response = xmlHttpRequest.mozResponse; response = xmlHttpRequest.mozResponse;
} else if (xmlHttpRequest.mozResponseArrayBuffer) { } else if (xmlHttpRequest.mozResponseArrayBuffer) {
@ -57,7 +57,7 @@ function slurpFile (filename, fa) {
} }
return result; return result;
}; };
/** @constructor */
var ClassDefinition = function(jvm) { var ClassDefinition = function(jvm) {
this.jvm = jvm; this.jvm = jvm;
}; };
@ -181,11 +181,11 @@ ClassDefinition.prototype.isAssignable = function (T) {
if (T.isInterface()){ if (T.isInterface()){
return (T == this.jvm.java_lang_cloneable || T == this.jvm.java_io_serializable); return (T == this.jvm.java_lang_cloneable || T == this.jvm.java_io_serializable);
}else if (T.isArrayClass()){ }else if (T.isArrayClass()){
if (T.arrayType.charAt(i) == this.arrayType.charAt(i) && (this.arrayType.charAt(i) == "L" || this.arrayType.charAt(i) == "[")){ if (T.arrayType.charAt(0) == this.arrayType.charAt(0) && (this.arrayType.charAt(0) == "L" || this.arrayType.charAt(0) == "[")){
return this.jvm.classForName(this.arrayType).isAssignable(T.arrayType); return this.jvm.classForName(this.arrayType).isAssignable(T.arrayType);
}else{ }else{
// VER: check if elements are primitive. // VER: check if elements are primitive.
if (T.arrayType.charAt(i) == this.arrayType.charAt(i)){ if (T.arrayType.charAt(0) == this.arrayType.charAt(0)){
return true; return true;
}else{ }else{
return false; return false;

View File

@ -24,6 +24,7 @@
// constant pool members // constant pool members
/** @constructor */
var constUtf8 = function(){ var constUtf8 = function(){
this.str = null; this.str = null;
this.id = CONSTANT_Utf8; this.id = CONSTANT_Utf8;
@ -32,7 +33,7 @@ var constUtf8 = function(){
var charCnt; var charCnt;
var byte_x,byte_y,byte_z; var byte_x,byte_y,byte_z;
var result; var result;
one_char = '\u0000'; var one_char = '\u0000';
this.length = dStream.getU2(); this.length = dStream.getU2();
strBuf = ""; strBuf = "";
charCnt = 0; charCnt = 0;
@ -59,6 +60,7 @@ var constUtf8 = function(){
return this; return this;
}; };
/** @constructor */
var constInt = function(){ var constInt = function(){
this.value = null; this.value = null;
this.id = CONSTANT_Integer; this.id = CONSTANT_Integer;
@ -67,6 +69,7 @@ var constInt = function(){
} }
}; };
/** @constructor */
var constFloat = function(){ var constFloat = function(){
this.value = null; this.value = null;
this.id = CONSTANT_Float; this.id = CONSTANT_Float;
@ -75,6 +78,7 @@ var constFloat = function(){
} }
}; };
/** @constructor */
var constLong = function(){ var constLong = function(){
this.high = null; this.high = null;
this.low = null; this.low = null;
@ -85,6 +89,7 @@ var constLong = function(){
} }
}; };
/** @constructor */
var constDouble = function(){ var constDouble = function(){
this.high = null; this.high = null;
this.low = null; this.low = null;
@ -95,6 +100,7 @@ var constDouble = function(){
} }
}; };
/** @constructor */
var constClass = function(){ var constClass = function(){
this.name_index = null; this.name_index = null;
this.id = CONSTANT_Class; this.id = CONSTANT_Class;
@ -110,6 +116,7 @@ var constClass = function(){
} }
}; };
/** @constructor */
var constString = function(){ var constString = function(){
this.string_index = null; this.string_index = null;
this.id = CONSTANT_String; this.id = CONSTANT_String;
@ -125,6 +132,7 @@ var constString = function(){
} }
}; };
/** @constructor */
var constRef = function(){ var constRef = function(){
this.class_index = null; this.class_index = null;
this.name_and_type_index = null; this.name_and_type_index = null;
@ -147,24 +155,28 @@ var constRef = function(){
} }
}; };
/** @constructor */
var constFieldRef = function(){ var constFieldRef = function(){
var temp = new constRef(); var temp = new constRef();
temp.id = CONSTANT_Fieldref; temp.id = CONSTANT_Fieldref;
return temp; return temp;
}; };
/** @constructor */
var constMethodRef = function(){ var constMethodRef = function(){
var temp = new constRef(); var temp = new constRef();
temp.id = CONSTANT_Methodref; temp.id = CONSTANT_Methodref;
return temp; return temp;
}; };
/** @constructor */
var constInterfaceMethodRef = function(){ var constInterfaceMethodRef = function(){
var temp = new constRef(); var temp = new constRef();
temp.id = CONSTANT_InterfaceMethodref; temp.id = CONSTANT_InterfaceMethodref;
return temp; return temp;
}; };
/** @constructor */
var constName_and_Type_info = function(){ var constName_and_Type_info = function(){
this.name_index = null; this.name_index = null;
this.descriptor_index = null; this.descriptor_index = null;
@ -271,7 +283,6 @@ var constTagName = function (info){
default: default:
return "??0x" + info.toString(16) + "??"; return "??0x" + info.toString(16) + "??";
} }
return null;
} }
var ConstantPoolRef = function(index, constantPool, expected){ var ConstantPoolRef = function(index, constantPool, expected){
@ -319,5 +330,5 @@ ConstantPool.prototype.loadFromStream = function(dStream){
} }
ConstantPool.prototype.get = function (i){ ConstantPool.prototype.get = function (i){
return this.constantPoll[i]; return this.constantPool[i];
} }

View File

@ -10,18 +10,21 @@
*/ */
#import "opcodes.js" #import "opcodes.js"
#import "types.js"
#define JVM_THROWS_NEW(exception) throw "VER: throws new exception" #define JVM_THROWS_NEW(exception) throw "VER: throws new exception"
#ifdef DEBUG_INTRP #ifdef DEBUG_INTRP
#define LOG_INTRP(x) LOG(x) #define LOG_INTRP(x) LOG(x)
#define DEFALIAS(opx) case opx: if(temp!=null) { temp = pc + ": opx" } #define DEFALIAS(opx) case opx: if(temp!=null) { temp = pc + ": opx" }
#else #else
#define LOG_INTRP(x) #define LOG_INTRP(x)
#define DEFALIAS(opx) case opx: #define DEFALIAS(opx) case opx:
#endif #endif
#define PANIC(msg) throw new JVMPanic(msg)
#define DEFOP(opx) case opx: LOG_INTRP(pc + ": opx"); #define DEFOP(opx) case opx: LOG_INTRP(pc + ": opx");
#define DEFNOP() LOG_INTRP(temp); #define DEFNOP() LOG_INTRP(temp)
#define ENDDEF break; #define ENDDEF break;
#define OPPOP() operand_stack.pop() #define OPPOP() operand_stack.pop()
@ -40,7 +43,7 @@
#define READ_NEXT() code[++pc] #define READ_NEXT() code[++pc]
#define canonicalName(ref) ref.str.replace(/\//g,".") #define canonicalName(ref) ref.str.replace(/\//g,".")
/** @constructor */
var JVM = function(params,args){ var JVM = function(params,args){
this.nativeMappingTable = {} this.nativeMappingTable = {}
this.params = params; this.params = params;
@ -95,30 +98,31 @@ var JVM = function(params,args){
this.classForName(this.mainClass).makeInstance(); this.classForName(this.mainClass).makeInstance();
}; };
}; };
/** @constructor */
var JVMThread = function(){ var JVMThread = function(){
this.pc = null; this.pc = null;
this.stack = []; this.stack = [];
} }
/** @constructor */
var JVMFrame = function(){ var JVMFrame = function(){
this.local_variables = []; this.local_variables = [];
this.operand_stack = []; this.operand_stack = [];
} }
/** @constructor */
function JVMPanic(message){ function JVMPanic(message){
this.toString = function(){ this.toString = function(){
return "JVMPanic: " + message return "JVMPanic: " + message
} }
}; };
#define PANIC(msg) throw new JVMPanic(msg)
function interpret(frame){ function interpret(frame){
var operand_stack = frame.operand_stack; var operand_stack = frame.operand_stack;
var local_variables = frame.local_variables; var local_variables = frame.local_variables;
var code = 0; //resolve code from method; var code = 0; //resolve code from method;
var opcode;
var pc;
var xl;
#ifdef DEBUG_INTRP #ifdef DEBUG_INTRP
var temp = null; var temp = null;

View File

@ -9,6 +9,7 @@
* *
*/ */
/** @constructor */
var FieldInfo = function(dStream,constantPool){ var FieldInfo = function(dStream,constantPool){
this.access_flags = dStream.getU2(); this.access_flags = dStream.getU2();
this.name_ref = ConstantPoolRef(dStream.getU2(), constantPool, CONSTANT_Utf8); this.name_ref = ConstantPoolRef(dStream.getU2(), constantPool, CONSTANT_Utf8);
@ -22,6 +23,7 @@ var FieldInfo = function(dStream,constantPool){
} }
} }
/** @constructor */
var MethodInfo = function(dStream, constantPool){ var MethodInfo = function(dStream, constantPool){
this.access_flags = dStream.getU2(); this.access_flags = dStream.getU2();
this.name_ref = ConstantPoolRef(dStream.getU2(), constantPool, CONSTANT_Utf8); this.name_ref = ConstantPoolRef(dStream.getU2(), constantPool, CONSTANT_Utf8);

View File

@ -14,7 +14,7 @@
#define CHECK_ARRAY_INDEX(ind,ref) if (ind >= ref.length){ JVM_THROWS_NEW(java.lang.ArrayIndexOutOfBoundsException); } #define CHECK_ARRAY_INDEX(ind,ref) if (ind >= ref.length){ JVM_THROWS_NEW(java.lang.ArrayIndexOutOfBoundsException); }
#define TO_INT(value) if (isNaN(value)){ OPPUSH(0); }else if(IS_OVERFLOW(value,INT_MAX_VALUE)){ OPPUSH(INT_MAX_VALUE); }else if(IS_UNDERFLOW(value,INT_MIN_VALUE)){ OPPUSH(INT_MIN_VALUE); }else{ OPPUSH(Math.round(value)); } #define TO_INT(value) if (isNaN(value)){ OPPUSH(0); }else if(IS_OVERFLOW(value,INT_MAX_VALUE)){ OPPUSH(INT_MAX_VALUE); }else if(IS_UNDERFLOW(value,INT_MIN_VALUE)){ OPPUSH(INT_MIN_VALUE); }else{ OPPUSH(Math.round(value)); }
#define TO_FLOAT(value) if (isNaN(value)){ OPPUSHD(NaN); }else if(IS_OVERFLOW(value,FLOAT_MAX_VALUE)){ OPPUSHD(POSITIVE_INF); }else if (IS_UNDEFLOW(value,FLOAT_MIN_VALUE)){ OPPUSHD(NEGATIVE_INF); }else{ OPPUSHD(value);} #define TO_FLOAT(value) if (isNaN(value)){ OPPUSHD(NaN); }else if(IS_OVERFLOW(value,FLOAT_MAX_VALUE)){ OPPUSHD(POSITIVE_INF); }else if (IS_UNDERFLOW(value,FLOAT_MIN_VALUE)){ OPPUSHD(NEGATIVE_INF); }else{ OPPUSHD(value);}
#define TO_LONG(value) if (isNaN(value)){ OPPUSH(0); }else if(IS_OVERFLOW(value,LONG_MAX_VALUE)){ OPPUSH(LONG_MAX_VALUE); }else if(IS_UNDERFLOW(value,LONG_MIN_VALUE)){ OPPUSH(LONG_MIN_VALUE); }else{ OPPUSH(Math.round(value));} #define TO_LONG(value) if (isNaN(value)){ OPPUSH(0); }else if(IS_OVERFLOW(value,LONG_MAX_VALUE)){ OPPUSH(LONG_MAX_VALUE); }else if(IS_UNDERFLOW(value,LONG_MIN_VALUE)){ OPPUSH(LONG_MIN_VALUE); }else{ OPPUSH(Math.round(value));}
DEFOP(AALOAD) DEFOP(AALOAD)
@ -70,7 +70,7 @@ DEFOP(ANEWARRAY)
JVM_THROWS_NEW(java.lang.NegativeArraySizeException); JVM_THROWS_NEW(java.lang.NegativeArraySizeException);
} }
var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2); var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2);
var instance = {length:count, value:[], 'class':this.jvm.classForName(clRef)}; var instance = {length:count, value:[], 'class':xl.jvm.classForName(clRef)};
OPPUSH(instance); OPPUSH(instance);
ENDDEF ENDDEF
@ -532,7 +532,7 @@ DEFOP(GETFIELD)
var objectref = OPPOP(); var objectref = OPPOP();
CHECK_NULL(objectref) CHECK_NULL(objectref)
field = objectref["class"].constantPool[(indexbyte1 << 8) | indexbyte2]; var field = objectref["class"].constantPool[(indexbyte1 << 8) | indexbyte2];
//check if static //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.str) + " " + field.name_and_type_ref.name_ref.str]);
ENDDEF ENDDEF

View File

@ -45,10 +45,6 @@ function DataStream(data){
result = new DataView(data,this.i,4).getUint32(0); result = new DataView(data,this.i,4).getUint32(0);
this.i += 4; this.i += 4;
break; break;
case 8:
result = new DataView(data,this.i,8).getUint64(0);
this.i += 8;
break;
default: default:
throw "Weird size " + size; throw "Weird size " + size;
} }
@ -70,10 +66,6 @@ function DataStream(data){
result = new DataView(data,this.i,4).getInt32(0); result = new DataView(data,this.i,4).getInt32(0);
this.i += 4; this.i += 4;
break; break;
case 8:
result = new DataView(data,this.i,8).getInt64(0);
this.i += 8;
break;
default: default:
throw "Weird size " + size; throw "Weird size " + size;
} }

View File

@ -9,11 +9,8 @@
* *
*/ */
#define DEBUG
#define DEBUG_INTRP
#ifndef DEBUG #ifndef DEBUG
#define log(msg) #define LOG(msg)
#else #else
#define LOG(msg) write(msg);\ #define LOG(msg) write(msg);\
if (console){\ if (console){\

View File

@ -8,9 +8,6 @@
* Author: Artur Ventura * Author: Artur Ventura
* *
*/ */
#ifndef _TYPES_JS_
#define _TYPES_JS_
// Local Variables Types // Local Variables Types
#define LOC_VAR_boolean 0x001; #define LOC_VAR_boolean 0x001;
@ -81,13 +78,13 @@
#define USHR(value1,value2) ((value1)>0?(value1)>>s:((value1)>>s) + (2<<~s)) #define USHR(value1,value2) ((value1)>0?(value1)>>s:((value1)>>s) + (2<<~s))
#define XOR(value1,value2) ((value1)^(value2)) #define XOR(value1,value2) ((value1)^(value2))
function getRefClass(ref){ /*function getRefClass(ref){
if (ref.type == REF_TYPE_array){ if (ref.type == REF_TYPE_array){
return getArrayClass(); return getArrayClass(ref);
}else{ }else{
return ref.classRef; return ref.classRef;
} }
} }*/
#endif //_TYPES_JS_

View File

@ -27,7 +27,7 @@ class index:
return "" return ""
if filename.endswith(".js"): if filename.endswith(".js"):
web.header('Content-Type', 'text/javascript') web.header('Content-Type', 'text/javascript')
return commands.getstatusoutput("/usr/bin/cpp -P -undef -Wundef -std=c99 -nostdinc -Wtrigraphs -fdollars-in-identifiers ../src/" + filename)[1] return commands.getstatusoutput("/usr/bin/cpp -P -DDEBUG -DDEBUG_INTRP -undef -Wundef -std=c99 -nostdinc -Wtrigraphs -fdollars-in-identifiers ../src/" + filename)[1]
if "testRuntime" in filename: if "testRuntime" in filename:
alphex = filename[filename.rfind("/") + 1:]; alphex = filename[filename.rfind("/") + 1:];
return file("../runtime/" + alphex.replace(".","/") + ".class"); return file("../runtime/" + alphex.replace(".","/") + ".class");