This commit is contained in:
Marco Castelluccio 2014-09-26 21:41:04 -07:00
Родитель e148d53811 c808335c82
Коммит fc02394056
16 изменённых файлов: 286 добавлений и 166 удалений

Просмотреть файл

@ -139,9 +139,8 @@ Classes.prototype.initPrimitiveArrayType = function(typeName, constructor) {
return classInfo;
}
Classes.prototype.getField = function(classInfo, fieldName, signature, staticFlag) {
var fieldKey = ~~!!staticFlag + "." + fieldName + "." + signature;
if (classInfo.vfc && classInfo.vfc[fieldKey]) {
Classes.prototype.getField = function(classInfo, fieldKey) {
if (classInfo.vfc[fieldKey]) {
return classInfo.vfc[fieldKey];
}
@ -150,24 +149,18 @@ Classes.prototype.getField = function(classInfo, fieldName, signature, staticFla
for (var i=0; i<fields.length; ++i) {
var field = fields[i];
if (!field.key) {
field.key = ~~(ACCESS_FLAGS.isStatic(field.access_flags)) + "." + field.name + "." + field.signature;
field.key = (ACCESS_FLAGS.isStatic(field.access_flags) ? "S" : "I") + "." + field.name + "." + field.signature;
}
if (field.key === fieldKey) {
if (classInfo.vfc) {
classInfo.vfc[fieldKey] = field;
}
return field;
return classInfo.vfc[fieldKey] = field;
}
}
if (staticFlag) {
if (fieldKey[0] === 'S') {
for (var n = 0; n < classInfo.interfaces.length; ++n) {
var field = this.getField(classInfo.interfaces[n], fieldName, signature, staticFlag);
var field = this.getField(classInfo.interfaces[n], fieldKey);
if (field) {
if (classInfo.vfc) {
classInfo.vfc[fieldKey] = field;
}
return field;
return classInfo.vfc[fieldKey] = field;
}
}
}
@ -184,14 +177,10 @@ Classes.prototype.getMethod = function(classInfo, methodKey) {
for (var i=0; i<methods.length; ++i) {
var method = methods[i];
if (!method.key) {
method.key = ~~(ACCESS_FLAGS.isStatic(method.access_flags)) + "." + method.name + "." + method.signature;
method.key = (ACCESS_FLAGS.isStatic(method.access_flags) ? "S" : "I") + "." + method.name + "." + method.signature;
}
if (method.key === methodKey) {
if (classInfo.vmc) {
classInfo.vmc[methodKey] = method;
}
return method;
return classInfo.vmc[methodKey] = method;
}
}
c = c.superClass;
@ -201,11 +190,7 @@ Classes.prototype.getMethod = function(classInfo, methodKey) {
for (var n = 0; n < classInfo.interfaces.length; ++n) {
var method = this.getMethod(classInfo.interfaces[n], methodKey);
if (method) {
if (classInfo.vmc) {
classInfo.vmc[methodKey] = method;
}
return method;
return classInfo.vmc[methodKey] = method;
}
}
}

Просмотреть файл

@ -131,8 +131,8 @@ ClassInfo.prototype.getClassObject = function(ctx) {
return classObject;
}
ClassInfo.prototype.getField = function(name, signature, isStatic) {
return CLASSES.getField(this, name, signature, isStatic);
ClassInfo.prototype.getField = function(fieldKey) {
return CLASSES.getField(this, fieldKey);
}
ClassInfo.prototype.toString = function() {
@ -144,6 +144,8 @@ var ArrayClass = function(className, elementClass) {
this.superClassName = "java/lang/Object";
this.access_flags = 0;
this.elementClass = elementClass;
this.vmc = {};
this.vfc = {};
}
ArrayClass.prototype.methods = [];

Просмотреть файл

@ -44,6 +44,8 @@ Context.prototype.pushClassInitFrame = function(classInfo) {
var syntheticMethod = {
syntheticKey: "ClassInitSynthetic:" + classInfo.className,
classInfo: {
vmc: {},
vfc: {},
constant_pool: [
null,
{ tag: TAGS.CONSTANT_Methodref, class_index: 2, name_and_type_index: 4 },
@ -82,6 +84,8 @@ Context.prototype.raiseException = function(className, message) {
var syntheticMethod = {
syntheticKey: "RaiseExceptionSynthetic",
classInfo: {
vmc: {},
vfc: {},
constant_pool: [
null,
{ tag: TAGS.CONSTANT_Class, name_index: 2 },

Просмотреть файл

@ -123,13 +123,13 @@ Instrument.enter["com/sun/midp/ssl/SSLStreamConnection.<init>.(Ljava/lang/String
Instrument.enter["com/sun/midp/ssl/Out.write.(I)V"] = function(caller, callee) {
var _this = caller.stack.read(3);
var connection = _this.class.getField("ssc", "Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
var connection = _this.class.getField("I.ssc.Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
connection.logBuffer += String.fromCharCode(callee.stack.read(1));
};
Instrument.enter["com/sun/midp/ssl/Out.write.([BII)V"] = function(caller, callee) {
var len = caller.stack.read(1), off = caller.stack.read(2), b = caller.stack.read(3), _this = caller.stack.read(4);
var connection = _this.class.getField("ssc", "Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
var connection = _this.class.getField("I.ssc.Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
var range = b.subarray(off, off + len);
for (var i = 0; i < range.length; i++) {
connection.logBuffer += String.fromCharCode(range[i] & 0xff);
@ -138,13 +138,13 @@ Instrument.enter["com/sun/midp/ssl/Out.write.([BII)V"] = function(caller, callee
Instrument.exit["com/sun/midp/ssl/In.read.()I"] = function(caller, callee) {
var _this = caller.stack.read(3);
var connection = _this.class.getField("ssc", "Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
var connection = _this.class.getField("I.ssc.Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
connection.logBuffer += String.fromCharCode(callee.stack.read(1));
};
Instrument.exit["com/sun/midp/ssl/In.read.([BII)I"] = function(caller, callee) {
var len = caller.stack.read(4), off = caller.stack.read(5), b = caller.stack.read(6), _this = caller.stack.read(7);
var connection = _this.class.getField("ssc", "Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
var connection = _this.class.getField("I.ssc.Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
var range = b.subarray(off, off + len);
for (var i = 0; i < range.length; i++) {
connection.logBuffer += String.fromCharCode(range[i] & 0xff);

10
jvm.js
Просмотреть файл

@ -44,17 +44,17 @@ JVM.prototype.startIsolate0 = function(className, args) {
caller.stack.push(isolate);
caller.stack.push(ctx.newString(className.replace(/\./g, "/")));
caller.stack.push(array);
ctx.pushFrame(CLASSES.getMethod(com_sun_cldc_isolate_Isolate, "0.<init>.(Ljava/lang/String;[Ljava/lang/String;)V"), 3);
ctx.pushFrame(CLASSES.getMethod(com_sun_cldc_isolate_Isolate, "I.<init>.(Ljava/lang/String;[Ljava/lang/String;)V"), 3);
ctx.execute(caller);
caller.stack.push(isolate);
ctx.pushFrame(CLASSES.getMethod(com_sun_cldc_isolate_Isolate, "0.start.()V"), 1);
ctx.pushFrame(CLASSES.getMethod(com_sun_cldc_isolate_Isolate, "I.start.()V"), 1);
ctx.start(caller);
}
JVM.prototype.startIsolate = function(isolate) {
var mainClass = util.fromJavaString(isolate.class.getField("_mainClass", "Ljava/lang/String;", false).get(isolate)).replace(/\./g, "/");
var mainArgs = isolate.class.getField("_mainArgs", "[Ljava/lang/String;", false).get(isolate);
var mainClass = util.fromJavaString(isolate.class.getField("I._mainClass.Ljava/lang/String;").get(isolate)).replace(/\./g, "/");
var mainArgs = isolate.class.getField("I._mainArgs.[Ljava/lang/String;").get(isolate);
mainArgs.forEach(function(str, n) {
mainArgs[n] = util.fromJavaString(str);
});
@ -83,7 +83,7 @@ JVM.prototype.startIsolate = function(isolate) {
ctx.thread.alive = true;
caller.stack.push(runtime.mainThread);
caller.stack.push(ctx.newString("main"));
ctx.pushFrame(CLASSES.getMethod(CLASSES.java_lang_Thread, "0.<init>.(Ljava/lang/String;)V"), 2);
ctx.pushFrame(CLASSES.getMethod(CLASSES.java_lang_Thread, "I.<init>.(Ljava/lang/String;)V"), 2);
ctx.execute(caller);
var args = ctx.newArray("[Ljava/lang/String;", mainArgs.length);

Просмотреть файл

@ -140,8 +140,8 @@
}
function setImageData(imageData, width, height, data) {
imageData.class.getField("width", "I").set(imageData, width);
imageData.class.getField("height", "I").set(imageData, height);
imageData.class.getField("I.width.I").set(imageData, width);
imageData.class.getField("I.height.I").set(imageData, height);
imageData.nativeImageData = data;
}
@ -205,16 +205,16 @@
Native["com/nokia/mid/ui/DirectUtils.makeMutable.(Ljavax/microedition/lcdui/Image;)V"] = function(ctx, stack) {
var image = stack.pop();
var imageData = image.class.getField("imageData", "Ljavax/microedition/lcdui/ImageData;").get(image);
imageData.class.getField("isMutable", "Z").set(imageData, 1);
var imageData = image.class.getField("I.imageData.Ljavax/microedition/lcdui/ImageData;").get(image);
imageData.class.getField("I.isMutable.Z").set(imageData, 1);
}
Native["com/nokia/mid/ui/DirectUtils.setPixels.(Ljavax/microedition/lcdui/Image;I)V"] = function(ctx, stack) {
var argb = stack.pop(), image = stack.pop();
var width = image.class.getField("width", "I").get(image);
var height = image.class.getField("height", "I").get(image);
var imageData = image.class.getField("imageData", "Ljavax/microedition/lcdui/ImageData;").get(image);
var width = image.class.getField("I.width.I").get(image);
var height = image.class.getField("I.height.I").get(image);
var imageData = image.class.getField("I.imageData.Ljavax/microedition/lcdui/ImageData;").get(image);
var ctx = createContext2d(width, height);
setImageData(imageData, width, height, ctx);
@ -270,8 +270,8 @@
else
face = "Arial, Helvetica, sans-serif";
_this.class.getField("baseline", "I").set(_this, (size/2)|0);
_this.class.getField("height", "I").set(_this, (size * 1.3)|0);
_this.class.getField("I.baseline.I").set(_this, (size/2)|0);
_this.class.getField("I.height.I").set(_this, (size * 1.3)|0);
_this.css = style + " " + size + "pt " + face;
}
@ -318,26 +318,26 @@
var BASELINE = 64;
function withGraphics(g, cb) {
var img = g.class.getField("img", "Ljavax/microedition/lcdui/Image;").get(g),
var img = g.class.getField("I.img.Ljavax/microedition/lcdui/Image;").get(g),
c = null;
if (img === null) {
c = MIDP.Context2D;
} else {
var imgData = img.class.getField("imageData", "Ljavax/microedition/lcdui/ImageData;").get(img),
var imgData = img.class.getField("I.imageData.Ljavax/microedition/lcdui/ImageData;").get(img),
c = imgData.nativeImageData;
}
cb(c);
}
function withClip(g, c, x, y, cb) {
var clipX1 = g.class.getField("clipX1", "S").get(g),
clipY1 = g.class.getField("clipY1", "S").get(g),
clipX2 = g.class.getField("clipX2", "S").get(g),
clipY2 = g.class.getField("clipY2", "S").get(g),
clipped = g.class.getField("clipped", "Z").get(g),
transX = g.class.getField("transX", "I").get(g),
transY = g.class.getField("transY", "I").get(g);
var clipX1 = g.class.getField("I.clipX1.S").get(g),
clipY1 = g.class.getField("I.clipY1.S").get(g),
clipX2 = g.class.getField("I.clipX2.S").get(g),
clipY2 = g.class.getField("I.clipY2.S").get(g),
clipped = g.class.getField("I.clipped.Z").get(g),
transX = g.class.getField("I.transX.I").get(g),
transY = g.class.getField("I.transY.I").get(g);
c.save();
if (clipped) {
c.beginPath();
@ -370,7 +370,7 @@
function withTextAnchor(g, c, anchor, x, y, str, cb) {
withClip(g, c, x, y, function(x, y) {
withFont(g.class.getField("currentFont", "Ljavax/microedition/lcdui/Font;").get(g), c, str, function(w, c) {
withFont(g.class.getField("I.currentFont.Ljavax/microedition/lcdui/Font;").get(g), c, str, function(w, c) {
c.textAlign = "left";
c.textBaseline = "top";
if (anchor & RIGHT)
@ -397,7 +397,7 @@
};
function withPixel(g, c, cb) {
var pixel = g.class.getField("pixel", "I").get(g);
var pixel = g.class.getField("I.pixel.I").get(g);
c.save();
c.fillStyle = c.strokeStyle = abgrIntToCSS(pixel);
cb();
@ -410,7 +410,7 @@
* incorrectly, although we should actually figure out why that's happening.
*/
function withOpaquePixel(g, c, cb) {
var pixel = g.class.getField("pixel", "I").get(g);
var pixel = g.class.getField("I.pixel.I").get(g);
c.save();
var b = (pixel >> 16) & 0xff;
var g = (pixel >> 8) & 0xff;
@ -441,20 +441,20 @@
Native["com/nokia/mid/ui/DirectGraphicsImp.setARGBColor.(I)V"] = function(ctx, stack) {
var rgba = stack.pop(), _this = stack.pop();
var g = _this.class.getField("graphics", "Ljavax/microedition/lcdui/Graphics;").get(_this);
var g = _this.class.getField("I.graphics.Ljavax/microedition/lcdui/Graphics;").get(_this);
var red = (rgba >> 16) & 0xff;
var green = (rgba >> 8) & 0xff;
var blue = rgba & 0xff;
g.class.getField("pixel", "I").set(g, swapRB(rgba));
g.class.getField("rgbColor", "I").set(g, rgba & 0x00ffffff);
g.class.getField("I.pixel.I").set(g, swapRB(rgba));
g.class.getField("I.rgbColor.I").set(g, rgba & 0x00ffffff);
// Conversion matches Graphics#grayVal(int, int, int).
g.class.getField("gray", "I").set(g, (red * 76 + green * 150 + blue * 29) >> 8);
g.class.getField("I.gray.I").set(g, (red * 76 + green * 150 + blue * 29) >> 8);
}
Native["com/nokia/mid/ui/DirectGraphicsImp.getAlphaComponent.()I"] = function(ctx, stack) {
var _this = stack.pop();
var g = _this.class.getField("graphics", "Ljavax/microedition/lcdui/Graphics;").get(_this);
var pixel = g.class.getField("pixel", "I").get(g);
var g = _this.class.getField("I.graphics.Ljavax/microedition/lcdui/Graphics;").get(_this);
var pixel = g.class.getField("I.pixel.I").get(g);
stack.push((pixel >> 24) & 0xff);
}
@ -486,9 +486,9 @@
ctx.raiseExceptionAndYield("java/lang/IllegalArgumentException", "Format unsupported");
}
var graphics = _this.class.getField("graphics", "Ljavax/microedition/lcdui/Graphics;").get(_this);
var image = graphics.class.getField("img", "Ljavax/microedition/lcdui/Image;").get(graphics);
var imageData = image.class.getField("imageData", "Ljavax/microedition/lcdui/ImageData;").get(image);
var graphics = _this.class.getField("I.graphics.Ljavax/microedition/lcdui/Graphics;").get(_this);
var image = graphics.class.getField("I.img.Ljavax/microedition/lcdui/Image;").get(graphics);
var imageData = image.class.getField("I.imageData.Ljavax/microedition/lcdui/ImageData;").get(image);
contextToRgbData(convertNativeImageData(imageData), pixels, offset, scanlength, x, y, width, height, converterFunc);
}
@ -515,7 +515,7 @@
ctx.raiseExceptionAndYield("java/lang/IllegalArgumentException", "Format unsupported");
}
var graphics = _this.class.getField("graphics", "Ljavax/microedition/lcdui/Graphics;").get(_this);
var graphics = _this.class.getField("I.graphics.Ljavax/microedition/lcdui/Graphics;").get(_this);
var context = createContext2d(width, height);
rgbDataToContext(context, pixels, offset, scanlength, converterFunc);
@ -528,7 +528,7 @@
Native["javax/microedition/lcdui/Graphics.render.(Ljavax/microedition/lcdui/Image;III)Z"] = function(ctx, stack) {
var anchor = stack.pop(), y = stack.pop(), x = stack.pop(), image = stack.pop(), _this = stack.pop(),
imgData = image.class.getField("imageData", "Ljavax/microedition/lcdui/ImageData;").get(image),
imgData = image.class.getField("I.imageData.Ljavax/microedition/lcdui/ImageData;").get(image),
texture = imgData.nativeImageData;
if (!texture) {
@ -701,7 +701,7 @@
ctx.raiseExceptionAndYield("java/lang/NullPointerException", "src image is null");
}
var imgData = image.class.getField("imageData", "Ljavax/microedition/lcdui/ImageData;").get(image),
var imgData = image.class.getField("I.imageData.Ljavax/microedition/lcdui/ImageData;").get(image),
texture = imgData.nativeImageData;
if (texture instanceof CanvasRenderingContext2D) {

Просмотреть файл

@ -229,12 +229,12 @@ Native["com/sun/midp/security/Permissions.loadGroupPermissions.(Ljava/lang/Strin
Native["com/sun/midp/main/CommandState.restoreCommandState.(Lcom/sun/midp/main/CommandState;)V"] = function(ctx, stack) {
var state = stack.pop();
var suiteId = (MIDP.midletClassName === "internal") ? -1 : 1;
state.class.getField("suiteId", "I").set(state, suiteId);
state.class.getField("midletClassName", "Ljava/lang/String;").set(state, ctx.newString(MIDP.midletClassName));
state.class.getField("I.suiteId.I").set(state, suiteId);
state.class.getField("I.midletClassName.Ljava/lang/String;").set(state, ctx.newString(MIDP.midletClassName));
var args = urlParams.args;
state.class.getField("arg0", "Ljava/lang/String;").set(state, ctx.newString((args.length > 0) ? args[0] : ""));
state.class.getField("arg1", "Ljava/lang/String;").set(state, ctx.newString((args.length > 1) ? args[1] : ""));
state.class.getField("arg2", "Ljava/lang/String;").set(state, ctx.newString((args.length > 2) ? args[2] : ""));
state.class.getField("I.arg0.Ljava/lang/String;").set(state, ctx.newString((args.length > 0) ? args[0] : ""));
state.class.getField("I.arg1.Ljava/lang/String;").set(state, ctx.newString((args.length > 1) ? args[1] : ""));
state.class.getField("I.arg2.Ljava/lang/String;").set(state, ctx.newString((args.length > 2) ? args[2] : ""));
}
MIDP.domainTBL = [
@ -629,7 +629,7 @@ Native["com/sun/midp/midletsuite/MIDletSuiteImpl.unlockMIDletSuite.(I)V"] = func
Native["com/sun/midp/midletsuite/SuiteSettings.load.()V"] = function(ctx, stack) {
var suiteSettings = stack.pop();
suiteSettings.class.getField("pushInterruptSetting", "B").set(suiteSettings, 1);
suiteSettings.class.getField("I.pushInterruptSetting.B").set(suiteSettings, 1);
console.warn("com/sun/midp/midletsuite/SuiteSettings.load.()V incomplete");
}
@ -642,7 +642,7 @@ Native["com/sun/midp/midletsuite/SuiteSettings.save0.(IBI[B)V"] = function(ctx,
Native["com/sun/midp/midletsuite/InstallInfo.load.()V"] = function(ctx, stack) {
var _this = stack.pop();
// The MIDlet has to be trusted for opening SSL connections using port 443.
_this.class.getField("trusted", "Z").set(_this, 1);
_this.class.getField("I.trusted.Z").set(_this, 1);
console.warn("com/sun/midp/midletsuite/InstallInfo.load.()V incomplete");
}
@ -762,7 +762,7 @@ MIDP.waitingNativeEventContexts = {};
MIDP.copyEvent = function(obj, isolateId) {
var e = MIDP.nativeEventQueues[isolateId].shift();
obj.class.getField("type", "I").set(obj, e.type);
obj.class.getField("I.type.I").set(obj, e.type);
obj.class.fields.forEach(function(field) {
field.set(obj, e[field.name]);
});
@ -777,7 +777,7 @@ MIDP.deliverWaitForNativeEventResult = function(ctx, isolateId) {
}
MIDP.sendEvent = function(obj, isolateId) {
var e = { type: obj.class.getField("type", "I").get(obj) };
var e = { type: obj.class.getField("I.type.I").get(obj) };
obj.class.fields.forEach(function(field) {
e[field.name] = field.get(obj);
});
@ -895,7 +895,7 @@ Native["javax/microedition/lcdui/Display.drawTrustedIcon0.(IZ)V"] = function(ctx
Native["com/sun/midp/events/EventQueue.sendShutdownEvent.()V"] = function(ctx, stack) {
var _this = stack.pop();
var obj = ctx.newObject(CLASSES.getClass("com/sun/midp/events/NativeEvent"));
obj.class.getField("type", "I").set(obj, MIDP.EVENT_QUEUE_SHUTDOWN);
obj.class.getField("I.type.I").set(obj, MIDP.EVENT_QUEUE_SHUTDOWN);
MIDP.sendEvent(obj);
}

Просмотреть файл

@ -100,11 +100,11 @@ Native["com/sun/midp/io/j2me/sms/Protocol.receive0.(IIILcom/sun/midp/io/j2me/sms
address[i] = addr.charCodeAt(i);
}
smsPacket.class.getField("message", "[B").set(smsPacket, message);
smsPacket.class.getField("address", "[B").set(smsPacket, address);
smsPacket.class.getField("port", "I").set(smsPacket, port);
smsPacket.class.getField("sentAt", "J").set(smsPacket, Long.fromNumber(Date.now()));
smsPacket.class.getField("messageType", "I").set(smsPacket, 0); // GSM_TEXT
smsPacket.class.getField("I.message.[B").set(smsPacket, message);
smsPacket.class.getField("I.address.[B").set(smsPacket, address);
smsPacket.class.getField("I.port.I").set(smsPacket, port);
smsPacket.class.getField("I.sentAt.J").set(smsPacket, Long.fromNumber(Date.now()));
smsPacket.class.getField("I.messageType.I").set(smsPacket, 0); // GSM_TEXT
stack.push(text.length);
}

Просмотреть файл

@ -236,9 +236,9 @@ Native["java/lang/Class.invoke_clinit.()V"] = function(ctx, stack) {
runtime.pending[className] = true;
if (className === "com/sun/cldc/isolate/Isolate") {
// The very first isolate is granted access to the isolate API.
ctx.runtime.setStatic(CLASSES.getField(classInfo, "_API_access_ok", "I", true), 1);
ctx.runtime.setStatic(CLASSES.getField(classInfo, "S._API_access_ok.I"), 1);
}
var clinit = CLASSES.getMethod(classInfo, "1.<clinit>.()V");
var clinit = CLASSES.getMethod(classInfo, "S.<clinit>.()V");
if (clinit)
ctx.pushFrame(clinit, 0);
if (classInfo.superClass)
@ -283,6 +283,8 @@ Native["java/lang/Class.newInstance.()Ljava/lang/Object;"] = function(ctx, stack
var syntheticMethod = {
syntheticKey: "ClassNewInstanceSynthetic:" + className,
classInfo: {
vmc: {},
vfc: {},
constant_pool: [
null,
{ tag: TAGS.CONSTANT_Class, name_index: 2 },
@ -494,7 +496,7 @@ Native["java/lang/Thread.start0.()V"] = function(ctx, stack) {
ctx.raiseExceptionAndYield("java/lang/IllegalThreadStateException");
thread.alive = true;
thread.pid = util.id();
var run = CLASSES.getMethod(thread.class, "0.run.()V");
var run = CLASSES.getMethod(thread.class, "I.run.()V");
// Create a context for the thread and start it.
var ctx = new Context(ctx.runtime);
ctx.thread = thread;
@ -504,6 +506,8 @@ Native["java/lang/Thread.start0.()V"] = function(ctx, stack) {
var syntheticMethod = {
syntheticKey: "ThreadStart0Synthetic:" + thread.class.className + "." + run.name + "." + run.signature,
classInfo: {
vmc: {},
vfc: {},
constant_pool: [
null,
{ tag: TAGS.CONSTANT_Methodref, class_index: 2, name_and_type_index: 4 },
@ -575,7 +579,7 @@ Native["com/sun/cldc/io/ResourceInputStream.open.(Ljava/lang/String;)Ljava/lang/
Override["com/sun/cldc/io/ResourceInputStream.available.()I"] = function(ctx, stack) {
var _this = stack.pop();
var handle = _this.class.getField("fileDecoder", "Ljava/lang/Object;").get(_this);
var handle = _this.class.getField("I.fileDecoder.Ljava/lang/Object;").get(_this);
if (!handle) {
ctx.raiseExceptionAndYield("java/io/IOException");
@ -586,7 +590,7 @@ Override["com/sun/cldc/io/ResourceInputStream.available.()I"] = function(ctx, st
Override["com/sun/cldc/io/ResourceInputStream.read.()I"] = function(ctx, stack) {
var _this = stack.pop();
var handle = _this.class.getField("fileDecoder", "Ljava/lang/Object;").get(_this);
var handle = _this.class.getField("I.fileDecoder.Ljava/lang/Object;").get(_this);
if (!handle) {
ctx.raiseExceptionAndYield("java/io/IOException");
@ -707,8 +711,8 @@ Native["com/sun/midp/links/LinkPortal.getLinks0.([Lcom/sun/midp/links/Link;)V"]
var isolateId = ctx.runtime.isolate.id;
for (var i = 0; i < links[isolateId].length; i++) {
var nativePointer = links[isolateId][i].class.getField("nativePointer", "I").get(links[isolateId][i]);
linkArray[i].class.getField("nativePointer", "I").set(linkArray[i], nativePointer);
var nativePointer = links[isolateId][i].class.getField("I.nativePointer.I").get(links[isolateId][i]);
linkArray[i].class.getField("I.nativePointer.I").set(linkArray[i], nativePointer);
linkArray[i].sender = links[isolateId][i].sender;
linkArray[i].receiver = links[isolateId][i].receiver;
}
@ -728,7 +732,7 @@ Native["com/sun/midp/links/Link.init0.(II)V"] = function(ctx, stack) {
var receiver = stack.pop(), sender = stack.pop(), _this = stack.pop();
_this.sender = sender;
_this.receiver = receiver;
_this.class.getField("nativePointer", "I").set(_this, util.id());
_this.class.getField("I.nativePointer.I").set(_this, util.id());
}
Native["com/sun/midp/links/Link.receive0.(Lcom/sun/midp/links/LinkMessage;Lcom/sun/midp/links/Link;)V"] = function(ctx, stack) {

Просмотреть файл

@ -39,3 +39,121 @@ Override["java/lang/Math.min.(II)I"] = function(ctx, stack) {
var b = stack.pop(), a = stack.pop();
stack.push(a <= b ? a : b);
}
Override["java/io/ByteArrayOutputStream.write.([BII)V"] = function(ctx, stack) {
var len = stack.pop(), off = stack.pop(), b = stack.pop(), _this = stack.pop();
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length)) {
ctx.raiseExceptionAndYield("java/lang/IndexOutOfBoundsException");
}
if (len == 0) {
return;
}
var count = _this.class.getField("I.count.I").get(_this);
var buf = _this.class.getField("I.buf.[B").get(_this);
var newcount = count + len;
if (newcount > buf.length) {
var newbuf = ctx.newPrimitiveArray("B", Math.max(buf.length << 1, newcount));
newbuf.set(buf);
buf = newbuf;
_this.class.getField("I.buf.[B").set(_this, buf);
}
buf.set(b.subarray(off, off + len), count);
_this.class.getField("I.count.I").set(_this, newcount);
}
Override["java/io/ByteArrayInputStream.<init>.([B)V"] = function(ctx, stack) {
var buf = stack.pop(), _this = stack.pop();
if (!buf) {
ctx.raiseExceptionAndYield("java/lang/NullPointerException");
}
_this.buf = buf;
_this.pos = _this.mark = 0;
_this.count = buf.length;
}
Override["java/io/ByteArrayInputStream.<init>.([BII)V"] = function(ctx, stack) {
var length = stack.pop(), offset = stack.pop(), buf = stack.pop(), _this = stack.pop();
if (!buf) {
ctx.raiseExceptionAndYield("java/lang/NullPointerException");
}
_this.buf = buf;
_this.pos = _this.mark = offset;
_this.count = (offset + length <= buf.length) ? (offset + length) : buf.length;
}
Override["java/io/ByteArrayInputStream.read.()I"] = function(ctx, stack) {
var _this = stack.pop();
stack.push((_this.pos < _this.count) ? (_this.buf[_this.pos++] & 0xFF) : -1);
}
Override["java/io/ByteArrayInputStream.read.([BII)I"] = function(ctx, stack) {
var len = stack.pop(), off = stack.pop(), b = stack.pop(), _this = stack.pop();
if (!b) {
ctx.raiseExceptionAndYield("java/lang/NullPointerException");
}
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length)) {
ctx.raiseExceptionAndYield("java/lang/IndexOutOfBoundsException");
}
if (_this.pos >= _this.count) {
stack.push(-1);
return;
}
if (_this.pos + len > _this.count) {
len = _this.count - _this.pos;
}
if (len === 0) {
stack.push(0);
return;
}
b.set(_this.buf.subarray(_this.pos, _this.pos + len), off);
_this.pos += len;
stack.push(len);
}
Override["java/io/ByteArrayInputStream.skip.(J)J"] = function(ctx, stack) {
var n = stack.pop2().toNumber(), _this = stack.pop();
if (_this.pos + n > _this.count) {
n = _this.count - _this.pos;
}
if (n < 0) {
stack.push2(Long.fromNumber(0));
return;
}
_this.pos += n;
stack.push2(Long.fromNumber(n));
}
Override["java/io/ByteArrayInputStream.available.()I"] = function(ctx, stack) {
var _this = stack.pop();
stack.push(_this.count - _this.pos);
}
Override["java/io/ByteArrayInputStream.mark.(I)V"] = function(ctx, stack) {
var readAheadLimit = stack.pop(), _this = stack.pop();
_this.mark = _this.pos;
}
Override["java/io/ByteArrayInputStream.reset.()V"] = function(ctx, stack) {
var _this = stack.pop();
_this.pos = _this.mark;
}

Просмотреть файл

@ -82,9 +82,9 @@ Runtime.prototype.newString = function(s) {
var chars = this.newPrimitiveArray("C", length);
for (var n = 0; n < length; ++n)
chars[n] = s.charCodeAt(n);
CLASSES.java_lang_String.getField("value", "[C").set(obj, chars);
CLASSES.java_lang_String.getField("offset", "I").set(obj, 0);
CLASSES.java_lang_String.getField("count", "I").set(obj, length);
CLASSES.java_lang_String.getField("I.value.[C").set(obj, chars);
CLASSES.java_lang_String.getField("I.offset.I").set(obj, 0);
CLASSES.java_lang_String.getField("I.count.I").set(obj, length);
return obj;
}
@ -93,9 +93,9 @@ Runtime.prototype.newStringFromUint16Array = function(buf) {
throw new Error('buf must be an instanceof Uint16Array, was ' + buf);
}
var obj = this.newObject(CLASSES.java_lang_String);
CLASSES.java_lang_String.getField("value", "[C").set(obj, buf);
CLASSES.java_lang_String.getField("offset", "I").set(obj, 0);
CLASSES.java_lang_String.getField("count", "I").set(obj, buf.length);
CLASSES.java_lang_String.getField("I.value.[C").set(obj, buf);
CLASSES.java_lang_String.getField("I.offset.I").set(obj, 0);
CLASSES.java_lang_String.getField("I.count.I").set(obj, buf.length);
return obj;
}

Просмотреть файл

@ -48,9 +48,9 @@ Override["java/lang/String.indexOf.(Ljava/lang/String;I)I"] = function(ctx, stac
Override["java/lang/String.indexOf.(II)I"] = function(ctx, stack) {
var fromIndex = stack.pop(), ch = stack.pop(), _this = stack.pop();
var value = CLASSES.java_lang_String.getField("value", "[C").get(_this);
var offset = CLASSES.java_lang_String.getField("offset", "I").get(_this);
var count = CLASSES.java_lang_String.getField("count", "I").get(_this);
var value = CLASSES.java_lang_String.getField("I.value.[C").get(_this);
var offset = CLASSES.java_lang_String.getField("I.offset.I").get(_this);
var count = CLASSES.java_lang_String.getField("I.count.I").get(_this);
var max = offset + count;
if (fromIndex < 0) {
@ -150,7 +150,7 @@ function substringSearch(haystack, needle) {
if (nlen <= 0 || !haystack || !needle) {
return -1;
}
for (scan = 0; scan < last; scan++) {
badCharSkip[needle[scan]] = last - scan;
}
@ -166,6 +166,6 @@ function substringSearch(haystack, needle) {
hlen -= skip;
offset += skip;
}
return -1;
}

Просмотреть файл

@ -36,7 +36,7 @@ casper.test.begin("unit tests", 5 + gfxTests.length, function(test) {
casper
.start("http://localhost:8000/index.html")
.waitForText("DONE", function() {
test.assertTextExists("DONE: 4900 pass, 0 fail, 168 known fail, 0 unknown pass", "run unit tests");
test.assertTextExists("DONE: 4901 pass, 0 fail, 168 known fail, 0 unknown pass", "run unit tests");
});
casper

Просмотреть файл

@ -5,56 +5,63 @@ import gnu.testlet.*;
public class ByteArrayInputStreamTest implements Testlet {
public void test(TestHarness th) {
byte[] a = new byte[11];
for (int i = 0; i < a.length; i++) {
a[i] = (byte)(i*i);
}
for (int i = 0; i < a.length; i++) {
th.check(a[i] == i*i);
}
ByteArrayInputStream s = new ByteArrayInputStream(a);
th.check(s.available() == 11);
th.check(s.read() == 0);
th.check(s.skip(4) == 4);
th.check(s.available() == 6);
byte[] bb = new byte[5];
th.check(s.read(bb, 1, 3) == 3);
th.check(bb[0] == 0);
th.check(bb[1] == 25);
th.check(bb[2] == 36);
th.check(bb[3] == 49);
th.check(bb[4] == 0);
th.check(s.markSupported());
th.check(s.available() == 3);
s.reset();
th.check(s.available() == 11);
for (int i = 0; i < a.length; i++) {
th.check(s.read() == i*i);
}
th.check(s.read() == -1);
th.check(s.available() == 0);
s.reset();
s.read();
s.mark(5);
s.reset();
byte[] a = new byte[11];
for (int i = 0; i < a.length; i++) {
a[i] = (byte)(i*i);
}
for (int i = 0; i < a.length; i++) {
th.check(a[i], i*i);
}
ByteArrayInputStream s = new ByteArrayInputStream(a);
th.check(s.available(), 11);
th.check(s.read(), 0);
th.check(s.skip(4), 4);
th.check(s.available(), 6);
byte[] bb = new byte[5];
th.check(s.read(bb, 1, 3), 3);
th.check(bb[0], 0);
th.check(bb[1], 25);
th.check(bb[2], 36);
th.check(bb[3], 49);
th.check(bb[4], 0);
th.check(s.markSupported());
th.check(s.available(), 3);
s.reset();
th.check(s.available(), 11);
for (int i = 0; i < a.length; i++) {
th.check(s.read(), i*i);
}
th.check(s.read(), -1);
th.check(s.available(), 0);
s.reset();
s.read();
s.mark(5);
s.reset();
th.check(s.available(), 10);
th.check(s.read(), 1);
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
ByteArrayInputStream s2 = new ByteArrayInputStream(a, 2, 5);
for (int i = 2; i < 7; i++) {
th.check(s2.read(), i*i);
}
th.check(s.available() == 10);
th.check(s.read() == 1);
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
ByteArrayInputStream s2 = new ByteArrayInputStream(a, 2, 5);
for (int i = 2; i < 7; i++) {
th.check(s2.read() == i*i);
}
try {
ByteArrayInputStream s3 = new ByteArrayInputStream(null);
th.check(false);
} catch (NullPointerException e) {
th.check(true);
}
}
try {
ByteArrayInputStream s3 = new ByteArrayInputStream(null);
th.check(false);
} catch (NullPointerException e) {
th.check(true);
}
try {
ByteArrayInputStream s3 = new ByteArrayInputStream(null, 0, 0);
th.check(false);
} catch (NullPointerException e) {
th.check(true);
}
}
}

12
util.js
Просмотреть файл

@ -51,9 +51,9 @@ var util = (function () {
function fromJavaString(str) {
if (!str)
return null;
var chars = CLASSES.java_lang_String.getField("value", "[C").get(str);
var offset = CLASSES.java_lang_String.getField("offset", "I").get(str);
var count = CLASSES.java_lang_String.getField("count", "I").get(str);
var chars = CLASSES.java_lang_String.getField("I.value.[C").get(str);
var offset = CLASSES.java_lang_String.getField("I.offset.I").get(str);
var count = CLASSES.java_lang_String.getField("I.count.I").get(str);
return fromJavaChars(chars, offset, count);
}
@ -67,9 +67,9 @@ var util = (function () {
function javaStringToArrayBuffer(str) {
if (!str)
return null;
var chars = CLASSES.java_lang_String.getField("value", "[C").get(str);
var offset = CLASSES.java_lang_String.getField("offset", "I").get(str);
var count = CLASSES.java_lang_String.getField("count", "I").get(str);
var chars = CLASSES.java_lang_String.getField("I.value.[C").get(str);
var offset = CLASSES.java_lang_String.getField("I.offset.I").get(str);
var count = CLASSES.java_lang_String.getField("I.count.I").get(str);
return chars.subarray(offset, offset + count);
}

10
vm.js
Просмотреть файл

@ -58,7 +58,7 @@ VM.execute = function(ctx) {
function buildExceptionLog(ex, stackTrace) {
var className = ex.class.className;
var detailMessage = util.fromJavaString(CLASSES.getField(ex.class, "detailMessage", "Ljava/lang/String;", false).get(ex));
var detailMessage = util.fromJavaString(CLASSES.getField(ex.class, "I.detailMessage.Ljava/lang/String;").get(ex));
return className + ": " + (detailMessage || "") + "\n" + stackTrace.join("\n") + "\n\n";
}
@ -153,7 +153,7 @@ VM.execute = function(ctx) {
var classInfo = resolve(op, constant.class_index);
var fieldName = cp[cp[constant.name_and_type_index].name_index].bytes;
var signature = cp[cp[constant.name_and_type_index].signature_index].bytes;
constant = CLASSES.getField(classInfo, fieldName, signature, (op === 0xb2 || op == 0xb3));
constant = CLASSES.getField(classInfo, ((op === 0xb2 || op === 0xb3) ? "S" : "I") + "." + fieldName + "." + signature);
if (!constant)
ctx.raiseExceptionAndYield("java/lang/RuntimeException",
classInfo.className + "." + fieldName + "." + signature + " not found");
@ -163,7 +163,7 @@ VM.execute = function(ctx) {
var classInfo = resolve(op, constant.class_index);
var methodName = cp[cp[constant.name_and_type_index].name_index].bytes;
var signature = cp[cp[constant.name_and_type_index].signature_index].bytes;
constant = CLASSES.getMethod(classInfo, ~~(op === 0xb8) + "." + methodName + "." + signature);
constant = CLASSES.getMethod(classInfo, ((op === 0xb8) ? "S" : "I") + "." + methodName + "." + signature);
if (!constant)
ctx.raiseExceptionAndYield("java/lang/RuntimeException",
classInfo.className + "." + methodName + "." + signature + " not found");
@ -1038,11 +1038,11 @@ VM.execute = function(ctx) {
case OPCODES.invokeinterface:
if (methodInfo.classInfo != obj.class) {
if (!methodInfo.key) {
methodInfo.key = "0." + methodInfo.name + "." + methodInfo.signature;
methodInfo.key = "I." + methodInfo.name + "." + methodInfo.signature;
}
// Check if the method is already in the virtual method cache
if (obj.class.vmc && obj.class.vmc[methodInfo.key]) {
if (obj.class.vmc[methodInfo.key]) {
methodInfo = obj.class.vmc[methodInfo.key];
} else {
methodInfo = CLASSES.getMethod(obj.class, methodInfo.key);