/* -*- Mode: Javascript -*- * -*- coding: UTF-8 -*- * Copyright (C) 2011 by Artur Ventura * * File: class.js * Time-stamp: Fri Jul 15 02:46:27 2011 * * Author: Artur Ventura * */ #define ACC_PUBLIC 0x0001 // Declared public; may be accessed from outside its package. #define ACC_PRIVATE 0x0002 // Declared private; usable only within the defining class. #define ACC_PROTECTED 0x0004 // Declared protected; may be accessed within subclasses. #define ACC_STATIC 0x0008 // Declared static. #define ACC_FINAL 0x0010 // Declared final; no subclasses allowed. #define ACC_SUPER 0x0020 // Treat superclass methods specially when invoked by the invokespecial instruction. #define ACC_VOLATILE 0x0040 // Declared volatile; cannot be cached. #define ACC_NATIVE 0x0100 // Declared native; implemented in a language other than Java. #define ACC_INTERFACE 0x0200 // Is an interface, not a class. #define ACC_ABSTRACT 0x0400 // Declared abstract; may not be instantiated. #define ACC_TRANSIENT 0x0080 // Declared transient; not written or read by a persistent object manager. function slurpFile (filename, fa) { var xmlHttpRequest, response, result ; // ie support if (typeof ActiveXObject == "function") return this.load_binary_ie9(filename, fa); xmlHttpRequest = new XMLHttpRequest(); xmlHttpRequest.open('GET', "testRuntime/" + filename, false); if ('mozResponseType' in xmlHttpRequest) { xmlHttpRequest.mozResponseType = 'arraybuffer'; } else if ('responseType' in xmlHttpRequest) { xmlHttpRequest.responseType = 'arraybuffer'; } else { xmlHttpRequest.overrideMimeType('text/plain; charset=x-user-defined'); } xmlHttpRequest.send(null); if (xmlHttpRequest.status != 200 && xmlHttpRequest.status != 0) { throw "Error while loading " + filename; } bf = true; if ('mozResponse' in xmlHttpRequest) { response = xmlHttpRequest.mozResponse; } else if (xmlHttpRequest.mozResponseArrayBuffer) { response = xmlHttpRequest.mozResponseArrayBuffer; } else if ('responseType' in xmlHttpRequest) { response = xmlHttpRequest.response; } else { response = xmlHttpRequest.responseText; bf = false; } if (bf) { result = [response.byteLength, response]; } else { throw "No typed arrays"; } return result; }; var ClassDefinition = function(jvm) { this.jvm = jvm; }; // bad bad code! This shouldn't be done this way! ClassDefinition.prototype.makeForArray = function(arrayDef){ this.magic = 0xCAFEBABE; this.minorVersion = 0; this.majorVersion = 50; this.constantPool = []; this.access_flags = 0; this.this_class = {id:CONSTANT_Class, name_ref:{str:arrayDef}}; this.super_class = null; this.interface_count = 0; this.interfaces = []; this.fields_count = 0; this.fields = []; this.methods_count = 1; this.methods = [ { access_flags:0, name_ref: {str:"clone"}, descriptor_ref: {str: "()Ljava.lang.Object;"}, attributes_count:0, attributes: [] } ]; ClassDefinition.prototype.isArrayClass = function (){ return true; } // extra info: this.dimensions = 0; var i=0; for (i=0; i 50 || this.majorVersion < 45){ throw "Unsuported java class file format version"; } this.constantPool = new ConstantPool(); this.constantPool.loadFromStream(dataStream); this.access_flags = dataStream.getU2(); this.this_class = ConstantPoolRef(dataStream.getU2(), this.constantPool, CONSTANT_Class); var superClassRef = dataStream.getU2(); if (superClassRef){ this.super_class = ConstantPoolRef(superClassRef, this.constantPool, CONSTANT_Class); }else{ this.super_class = null; } this.interface_count = dataStream.getU2(); this.interfaces = []; for(var i=0; i