2014-07-13 01:07:11 +04:00
|
|
|
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/* vim: set shiftwidth=4 tabstop=4 autoindent cindent expandtab: */
|
|
|
|
|
2014-07-21 08:32:47 +04:00
|
|
|
'Use strict';
|
2014-07-13 01:07:11 +04:00
|
|
|
|
2014-07-21 08:32:47 +04:00
|
|
|
var Native = {};
|
2014-07-15 10:47:20 +04:00
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native.invoke = function(ctx, methodInfo) {
|
2014-07-21 09:08:08 +04:00
|
|
|
if (!methodInfo.native) {
|
|
|
|
var key = methodInfo.classInfo.className + "." + methodInfo.name + "." + methodInfo.signature;
|
2014-07-24 11:21:59 +04:00
|
|
|
methodInfo.native = Native[key];
|
2014-07-27 05:47:38 +04:00
|
|
|
if (!methodInfo.native)
|
|
|
|
console.log(key);
|
2014-07-21 09:08:08 +04:00
|
|
|
}
|
2014-07-26 00:06:48 +04:00
|
|
|
methodInfo.native.call(null, ctx, ctx.current().stack);
|
2014-07-13 01:07:11 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/System.arraycopy.(Ljava/lang/Object;ILjava/lang/Object;II)V"] = function(ctx, stack) {
|
|
|
|
var length = stack.pop(), dstOffset = stack.pop(), dst = stack.pop(), srcOffset = stack.pop(), src = stack.pop();
|
|
|
|
if (!src || !dst)
|
|
|
|
ctx.raiseException("java/lang/NullPointerException", "Cannot copy to/from a null array.");
|
2014-07-20 00:18:45 +04:00
|
|
|
var srcClass = src.class;
|
|
|
|
var dstClass = dst.class;
|
2014-07-26 00:06:48 +04:00
|
|
|
if (!srcClass.isArrayClass || !dstClass.isArrayClass)
|
|
|
|
ctx.raiseException("java/lang/ArrayStoreException", "Can only copy to/from array types.");
|
|
|
|
if (srcOffset < 0 || (srcOffset+length) > src.length || dstOffset < 0 || (dstOffset+length) > dst.length || length < 0)
|
|
|
|
ctx.raiseException("java/lang/ArrayIndexOutOfBoundsException", "Invalid index.");
|
2014-07-27 04:39:49 +04:00
|
|
|
if ((!!srcClass.elementClass != !!dstClass.elementClass) ||
|
|
|
|
(!srcClass.elementClass && srcClass != dstClass)) {
|
|
|
|
ctx.raiseException("java/lang/ArrayStoreException", "Incompatible component types.");
|
|
|
|
}
|
|
|
|
if (dstClass.elementClass) {
|
|
|
|
if (srcClass != dstClass && !srcClass.elementClass.isAssignableTo(dstClass.elementClass)) {
|
|
|
|
function copy(to, from) {
|
|
|
|
var obj = src[from];
|
|
|
|
if (obj && !obj.class.isAssignableTo(dstClass.elementClass))
|
|
|
|
ctx.raiseException("java/lang/ArrayStoreException", "Incompatible component types.");
|
|
|
|
dst[to] = obj;
|
|
|
|
}
|
|
|
|
if (dst !== src || dstOffset < srcOffset) {
|
|
|
|
for (var n = 0; n < length; ++n)
|
|
|
|
copy(dstOffset++, srcOffset++);
|
|
|
|
} else {
|
|
|
|
dstOffset += length;
|
|
|
|
srcOffset += length;
|
|
|
|
for (var n = 0; n < length; ++n)
|
|
|
|
copy(--dstOffset, --srcOffset);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2014-07-13 20:03:11 +04:00
|
|
|
if (dst !== src || dstOffset < srcOffset) {
|
|
|
|
for (var n = 0; n < length; ++n)
|
|
|
|
dst[dstOffset++] = src[srcOffset++];
|
|
|
|
} else {
|
|
|
|
dstOffset += length;
|
|
|
|
srcOffset += length;
|
|
|
|
for (var n = 0; n < length; ++n)
|
|
|
|
dst[--dstOffset] = src[--srcOffset];
|
2014-07-13 10:13:53 +04:00
|
|
|
}
|
|
|
|
}
|
2014-07-15 09:13:01 +04:00
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/System.getProperty0.(Ljava/lang/String;)Ljava/lang/String;"] = function(ctx, stack) {
|
|
|
|
var key = stack.pop();
|
|
|
|
var value;
|
2014-07-18 09:00:32 +04:00
|
|
|
switch (util.fromJavaString(key)) {
|
2014-07-15 09:13:01 +04:00
|
|
|
case "microedition.encoding":
|
2014-07-30 04:40:19 +04:00
|
|
|
value = CLASSES.newString("UTF-8");
|
2014-07-26 00:06:48 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
console.log("UNKNOWN PROPERTY: " + util.fromJavaString(key));
|
|
|
|
value = null;
|
|
|
|
break;
|
2014-07-15 09:13:01 +04:00
|
|
|
}
|
2014-07-26 00:06:48 +04:00
|
|
|
stack.push(value);
|
2014-07-15 09:13:01 +04:00
|
|
|
}
|
2014-07-15 10:19:26 +04:00
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/System.currentTimeMillis.()J"] = function(ctx, stack) {
|
|
|
|
stack.push2(Long.fromNumber(Date.now()));
|
2014-07-18 22:00:19 +04:00
|
|
|
}
|
|
|
|
|
2014-07-28 07:22:33 +04:00
|
|
|
Native["com/sun/cldchi/jvm/JVM.unchecked_char_arraycopy.([CI[CII)V"] =
|
|
|
|
Native["com/sun/cldchi/jvm/JVM.unchecked_int_arraycopy.([II[III)V"] =
|
|
|
|
Native["com/sun/cldchi/jvm/JVM.unchecked_obj_arraycopy.([Ljava/lang/Object;I[Ljava/lang/Object;II)V"] = function(ctx, stack) {
|
2014-07-26 00:06:48 +04:00
|
|
|
var length = stack.pop(), dstOffset = stack.pop(), dst = stack.pop(), srcOffset = stack.pop(), src = stack.pop();
|
2014-07-15 10:19:26 +04:00
|
|
|
if (dst !== src || dstOffset < srcOffset) {
|
|
|
|
for (var n = 0; n < length; ++n)
|
|
|
|
dst[dstOffset++] = src[srcOffset++];
|
|
|
|
} else {
|
|
|
|
dstOffset += length;
|
|
|
|
srcOffset += length;
|
|
|
|
for (var n = 0; n < length; ++n)
|
|
|
|
dst[--dstOffset] = src[--srcOffset];
|
|
|
|
}
|
|
|
|
}
|
2014-07-15 10:37:33 +04:00
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Object.getClass.()Ljava/lang/Class;"] = function(ctx, stack) {
|
|
|
|
stack.push(stack.pop().class.getClassObject());
|
2014-07-18 10:02:28 +04:00
|
|
|
}
|
|
|
|
|
2014-07-28 11:53:37 +04:00
|
|
|
Native["java/lang/Object.hashCode.()I"] = function(ctx, stack) {
|
|
|
|
var obj = stack.pop();
|
|
|
|
var hashCode = obj.hashCode;
|
|
|
|
while (!hashCode)
|
|
|
|
hashCode = obj.hashCode = util.id();
|
|
|
|
stack.push(hashCode);
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Object.wait.(J)V"] = function(ctx, stack) {
|
|
|
|
var timeout = stack.pop2(), obj = stack.pop();
|
2014-07-29 12:07:15 +04:00
|
|
|
ctx.wait(obj, timeout.toNumber());
|
2014-07-28 11:53:37 +04:00
|
|
|
}
|
2014-07-27 05:47:38 +04:00
|
|
|
|
2014-07-28 23:44:40 +04:00
|
|
|
Native["java/lang/Object.notify.()V"] = function(ctx, stack) {
|
|
|
|
var obj = stack.pop();
|
|
|
|
ctx.notify(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Object.notifyAll.()V"] = function(ctx, stack) {
|
|
|
|
var obj = stack.pop();
|
2014-07-29 13:08:04 +04:00
|
|
|
ctx.notify(obj, true);
|
2014-07-28 23:44:40 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 22:42:02 +04:00
|
|
|
Native["java/lang/Class.invoke_clinit.()V"] = function(ctx, stack) {
|
2014-07-28 23:42:42 +04:00
|
|
|
var classObject = stack.pop();
|
|
|
|
var classInfo = classObject.vmClass;
|
|
|
|
if (classInfo.initialized || classInfo.pending)
|
|
|
|
return;
|
|
|
|
classInfo.pending = true;
|
2014-07-26 22:42:02 +04:00
|
|
|
var clinit = CLASSES.getMethod(classInfo, "<clinit>", "()V", true);
|
2014-07-28 07:30:10 +04:00
|
|
|
if (clinit)
|
|
|
|
ctx.pushFrame(clinit, 0);
|
|
|
|
if (classInfo.superClass)
|
|
|
|
ctx.pushClassInitFrame(classInfo.superClass);
|
2014-07-26 22:42:02 +04:00
|
|
|
throw VM.Yield;
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Class.init9.()V"] = function(ctx, stack) {
|
|
|
|
var classObject = stack.pop();
|
|
|
|
var classInfo = classObject.vmClass;
|
2014-07-28 23:42:42 +04:00
|
|
|
if (classInfo.initialized)
|
|
|
|
return;
|
|
|
|
classInfo.pending = false;
|
2014-07-26 22:42:02 +04:00
|
|
|
classInfo.initialized = true;
|
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Class.getName.()Ljava/lang/String;"] = function(ctx, stack) {
|
2014-07-26 22:42:02 +04:00
|
|
|
var classObject = stack.pop();
|
|
|
|
stack.push(util.cache(classObject, "getName", function () {
|
2014-07-30 04:40:19 +04:00
|
|
|
return CLASSES.newString(classObject.vmClass.className.replace("/", ".", "g"));
|
2014-07-26 00:06:48 +04:00
|
|
|
}));
|
2014-07-18 10:02:28 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Class.forName.(Ljava/lang/String;)Ljava/lang/Class;"] = function(ctx, stack) {
|
|
|
|
var name = stack.pop();
|
2014-07-18 09:00:32 +04:00
|
|
|
var className = util.fromJavaString(name).replace(".", "/", "g");
|
2014-07-26 02:06:21 +04:00
|
|
|
var classInfo = null;
|
2014-07-27 05:20:54 +04:00
|
|
|
try {
|
|
|
|
classInfo = CLASSES.getClass(className);
|
|
|
|
} catch (e) {
|
|
|
|
if (e instanceof (Classes.ClassNotFoundException))
|
|
|
|
ctx.raiseException("java/lang/ClassNotFoundException", "'" + className + "' not found.");
|
|
|
|
throw e;
|
2014-07-15 10:47:20 +04:00
|
|
|
}
|
2014-07-26 00:06:48 +04:00
|
|
|
stack.push(classInfo.getClassObject());
|
2014-07-15 10:47:20 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Class.newInstance.()Ljava/lang/Object;"] = function(ctx, stack) {
|
|
|
|
var classObject = stack.pop();
|
|
|
|
var className = classObject.vmClass.className;
|
|
|
|
var syntheticMethod = {
|
|
|
|
classInfo: {
|
|
|
|
constant_pool: [
|
2014-07-26 00:23:10 +04:00
|
|
|
null,
|
2014-07-29 15:26:03 +04:00
|
|
|
{ tag: TAGS.CONSTANT_Class, name_index: 2 },
|
2014-07-26 00:06:48 +04:00
|
|
|
{ bytes: className },
|
2014-07-29 15:26:03 +04:00
|
|
|
{ tag: TAGS.CONSTANT_Methodref, class_index: 1, name_and_type_index: 4 },
|
2014-07-26 00:23:10 +04:00
|
|
|
{ name_index: 5, signature_index: 6 },
|
2014-07-26 00:06:48 +04:00
|
|
|
{ bytes: "<init>" },
|
|
|
|
{ bytes: "()V" },
|
|
|
|
]
|
|
|
|
},
|
|
|
|
code: [
|
2014-07-26 00:23:10 +04:00
|
|
|
0xbb, 0x00, 0x01, // new <idx=1>
|
2014-07-26 00:06:48 +04:00
|
|
|
0x59, // dup
|
2014-07-26 00:23:10 +04:00
|
|
|
0xb7, 0x00, 0x03, // invokespecial <idx=3>
|
2014-07-26 00:06:48 +04:00
|
|
|
0xb0 // areturn
|
|
|
|
],
|
|
|
|
};
|
|
|
|
ctx.pushFrame(syntheticMethod, 0);
|
|
|
|
throw VM.Yield;
|
2014-07-15 10:52:27 +04:00
|
|
|
};
|
2014-07-15 11:01:11 +04:00
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Class.isInterface.()Z"] = function(ctx, stack) {
|
|
|
|
var classObject = stack.pop();
|
2014-07-19 04:55:09 +04:00
|
|
|
var classInfo = classObject.vmClass;
|
2014-07-26 00:06:48 +04:00
|
|
|
stack.push(ACCESS_FLAGS.isInterface(classInfo.access_flags) ? 1 : 0);
|
2014-07-19 04:55:09 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Class.isArray.()Z"] = function(ctx, stack) {
|
|
|
|
var classObject = stack.pop();
|
2014-07-19 04:55:09 +04:00
|
|
|
var classInfo = classObject.vmClass;
|
2014-07-26 00:06:48 +04:00
|
|
|
stack.push(classInfo.isArrayClass ? 1 : 0);
|
2014-07-19 04:55:09 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Class.isAssignableFrom.(Ljava/lang/Class;)Z"] = function(ctx, stack) {
|
|
|
|
var fromClass = stack.pop(), classObject = stack.pop();
|
|
|
|
if (!fromClass)
|
|
|
|
ctx.raiseException("java/lang/NullPointerException");
|
|
|
|
stack.push(fromClass.vmClass.isAssignableTo(classObject.vmClass) ? 1 : 0);
|
2014-07-19 04:55:09 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Class.isInstance.(Ljava/lang/Object;)Z"] = function(ctx, stack) {
|
|
|
|
var obj = stack.pop(), classObject = stack.pop();
|
|
|
|
stack.push((obj && obj.class.isAssignableTo(classObject.vmClass)) ? 1 : 0);
|
2014-07-19 04:55:09 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 04:54:34 +04:00
|
|
|
Native["java/lang/Float.floatToIntBits.(F)I"] = (function() {
|
2014-07-29 06:13:32 +04:00
|
|
|
var fa = new Float32Array(1);
|
|
|
|
var ia = new Int32Array(fa.buffer);
|
2014-07-26 00:06:48 +04:00
|
|
|
return function(ctx, stack) {
|
|
|
|
fa[0] = stack.pop();
|
|
|
|
stack.push(ia[0]);
|
2014-07-19 01:44:50 +04:00
|
|
|
}
|
|
|
|
})();
|
|
|
|
|
2014-07-26 00:28:26 +04:00
|
|
|
Native["java/lang/Double.doubleToLongBits.(D)J"] = (function() {
|
2014-07-29 06:13:32 +04:00
|
|
|
var da = new Float64Array(1);
|
|
|
|
var ia = new Int32Array(da.buffer);
|
2014-07-26 00:28:26 +04:00
|
|
|
return function(ctx, stack) {
|
2014-07-26 00:06:48 +04:00
|
|
|
da[0] = stack.pop2();
|
|
|
|
stack.push2(Long.fromBits(ia[0], ia[1]));
|
2014-07-19 01:44:50 +04:00
|
|
|
}
|
|
|
|
})();
|
|
|
|
|
2014-07-26 00:28:26 +04:00
|
|
|
Native["java/lang/Float.intBitsToFloat.(I)F"] = (function() {
|
2014-07-29 06:13:32 +04:00
|
|
|
var fa = new Float32Array(1);
|
|
|
|
var ia = new Int32Array(fa.buffer);
|
2014-07-26 00:28:26 +04:00
|
|
|
return function(ctx, stack) {
|
2014-07-26 00:06:48 +04:00
|
|
|
ia[0] = stack.pop();
|
|
|
|
stack.push(fa[0]);
|
2014-07-19 05:09:55 +04:00
|
|
|
}
|
|
|
|
})();
|
|
|
|
|
2014-07-26 00:28:26 +04:00
|
|
|
Native["java/lang/Double.longBitsToDouble.(J)D"] = (function() {
|
2014-07-29 06:13:32 +04:00
|
|
|
var da = new Float64Array(1);
|
|
|
|
var ia = new Int32Array(da.buffer);
|
2014-07-26 00:28:26 +04:00
|
|
|
return function(ctx, stack) {
|
2014-07-26 00:06:48 +04:00
|
|
|
var l = stack.pop2();
|
2014-07-19 05:33:12 +04:00
|
|
|
ia[0] = l.low_;
|
|
|
|
ia[1] = l.high_;
|
2014-07-26 00:06:48 +04:00
|
|
|
stack.push2(da[0]);
|
2014-07-19 05:09:55 +04:00
|
|
|
}
|
|
|
|
})();
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Throwable.fillInStackTrace.()V"] = (function(ctx, stack) {
|
2014-07-18 10:02:28 +04:00
|
|
|
});
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Throwable.obtainBackTrace.()Ljava/lang/Object;"] = (function(ctx, stack) {
|
|
|
|
stack.push(null);
|
2014-07-19 04:55:09 +04:00
|
|
|
});
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Runtime.freeMemory.()J"] = function(ctx, stack) {
|
2014-07-26 00:42:44 +04:00
|
|
|
var runtime = stack.pop();
|
2014-07-26 00:06:48 +04:00
|
|
|
stack.push2(Long.fromInt(0x800000));
|
2014-07-19 20:23:14 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Runtime.totalMemory.()J"] = function(ctx, stack) {
|
2014-07-26 00:42:44 +04:00
|
|
|
var runtime = stack.pop();
|
2014-07-26 00:06:48 +04:00
|
|
|
stack.push2(Long.fromInt(0x1000000));
|
2014-07-19 20:23:14 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Runtime.gc.()V"] = function(ctx, stack) {
|
2014-07-26 00:42:44 +04:00
|
|
|
var runtime = stack.pop();
|
2014-07-19 20:23:14 +04:00
|
|
|
}
|
|
|
|
|
2014-07-27 02:00:19 +04:00
|
|
|
Native["java/lang/Math.floor.(D)D"] = function(ctx, stack) {
|
|
|
|
stack.push2(Math.floor(stack.pop2()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Math.asin.(D)D"] = function(ctx, stack) {
|
|
|
|
stack.push2(Math.asin(stack.pop2()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Math.acos.(D)D"] = function(ctx, stack) {
|
|
|
|
stack.push2(Math.acos(stack.pop2()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Math.atan.(D)D"] = function(ctx, stack) {
|
|
|
|
stack.push2(Math.atan(stack.pop2()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Math.atan2.(DD)D"] = function(ctx, stack) {
|
|
|
|
var y = stack.pop2(), x = stack.pop2();
|
|
|
|
stack.push2(Math.atan2(x, y));
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Math.sin.(D)D"] = function(ctx, stack) {
|
|
|
|
stack.push2(Math.sin(stack.pop2()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Math.cos.(D)D"] = function(ctx, stack) {
|
|
|
|
stack.push2(Math.cos(stack.pop2()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Math.tan.(D)D"] = function(ctx, stack) {
|
|
|
|
stack.push2(Math.tan(stack.pop2()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Math.sqrt.(D)D"] = function(ctx, stack) {
|
|
|
|
stack.push2(Math.sqrt(stack.pop2()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Math.ceil.(D)D"] = function(ctx, stack) {
|
|
|
|
stack.push2(Math.ceil(stack.pop2()));
|
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Math.floor.(D)D"] = function(ctx, stack) {
|
|
|
|
stack.push2(Math.floor(stack.pop2()));
|
2014-07-19 22:53:27 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Thread.currentThread.()Ljava/lang/Thread;"] = function(ctx, stack) {
|
|
|
|
stack.push(ctx.thread);
|
2014-07-20 11:35:00 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Thread.setPriority0.(II)V"] = function(ctx, stack) {
|
|
|
|
var newPriority = stack.pop(), oldPriority = stack.pop(), thread = stack.pop();
|
2014-07-20 11:35:00 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["java/lang/Thread.start0.()V"] = function(ctx, stack) {
|
|
|
|
var thread = stack.pop();
|
2014-07-21 03:28:26 +04:00
|
|
|
// The main thread starts during bootstrap and don't allow calling start()
|
|
|
|
// on already running threads.
|
2014-07-26 04:54:34 +04:00
|
|
|
if (thread === CLASSES.mainThread || thread.Thread$running)
|
2014-07-26 00:06:48 +04:00
|
|
|
ctx.raiseException("java/lang/IllegalThreadStateException");
|
2014-07-29 13:19:10 +04:00
|
|
|
thread.alive = true;
|
2014-07-28 11:53:37 +04:00
|
|
|
thread.pid = util.id();
|
2014-07-21 03:27:24 +04:00
|
|
|
var run = CLASSES.getMethod(thread.class, "run", "()V", false, true);
|
2014-07-28 10:39:41 +04:00
|
|
|
// Create a context for the thread and start it.
|
2014-07-26 04:54:34 +04:00
|
|
|
var ctx = new Context();
|
|
|
|
ctx.thread = thread;
|
|
|
|
var caller = new Frame();
|
|
|
|
ctx.frames.push(caller);
|
2014-07-28 10:39:41 +04:00
|
|
|
caller.stack.push(thread);
|
|
|
|
var syntheticMethod = {
|
|
|
|
classInfo: {
|
|
|
|
constant_pool: [
|
|
|
|
null,
|
2014-07-29 15:26:03 +04:00
|
|
|
{ tag: TAGS.CONSTANT_Methodref, class_index: 2, name_and_type_index: 4 },
|
|
|
|
{ tag: TAGS.CONSTANT_Class, name_index: 3 },
|
2014-07-28 10:39:41 +04:00
|
|
|
{ bytes: "java/lang/Thread" },
|
2014-07-29 15:26:03 +04:00
|
|
|
{ tag: TAGS.CONSTANT_Methodref, name_index: 5, signature_index: 6 },
|
2014-07-28 10:39:41 +04:00
|
|
|
{ bytes: "run" },
|
|
|
|
{ bytes: "()V" },
|
2014-07-29 15:26:03 +04:00
|
|
|
{ tag: TAGS.CONSTANT_Methodref, class_index: 2, name_and_type_index: 8 },
|
2014-07-28 10:39:41 +04:00
|
|
|
{ name_index: 9, signature_index: 10 },
|
|
|
|
{ bytes: "internalExit" },
|
|
|
|
{ bytes: "()V" },
|
|
|
|
],
|
|
|
|
},
|
|
|
|
code: [
|
|
|
|
0x2a, // aload_0
|
|
|
|
0x59, // dup
|
2014-07-28 11:53:37 +04:00
|
|
|
0xb6, 0x00, 0x01, // invokespecial <idx=1>
|
2014-07-28 10:39:41 +04:00
|
|
|
0xb7, 0x00, 0x07, // invokespecial <idx=7>
|
|
|
|
0xb1, // return
|
|
|
|
],
|
|
|
|
exception_table: [],
|
|
|
|
};
|
|
|
|
ctx.pushFrame(syntheticMethod, 1);
|
2014-07-26 04:54:34 +04:00
|
|
|
ctx.start(caller);
|
2014-07-20 11:35:00 +04:00
|
|
|
}
|
|
|
|
|
2014-07-28 10:39:41 +04:00
|
|
|
Native["java/lang/Thread.internalExit.()V"] = function(ctx, stack) {
|
2014-07-29 13:19:10 +04:00
|
|
|
stack.pop().alive = false;
|
2014-07-28 10:39:41 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Thread.isAlive.()Z"] = function(ctx, stack) {
|
2014-07-29 13:19:10 +04:00
|
|
|
stack.push(stack.pop().alive ? 1 : 0);
|
2014-07-28 10:39:41 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 04:54:34 +04:00
|
|
|
Native["java/lang/Thread.sleep.(J)V"] = function(ctx, stack) {
|
|
|
|
var delay = stack.pop2().toNumber();
|
|
|
|
window.setTimeout(function() {
|
|
|
|
ctx.resume();
|
|
|
|
}, delay);
|
2014-07-29 02:19:07 +04:00
|
|
|
throw VM.Pause;
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["java/lang/Thread.yield.()V"] = function(ctx, stack) {
|
|
|
|
throw VM.Yield;
|
2014-07-21 09:24:07 +04:00
|
|
|
}
|
|
|
|
|
2014-07-24 11:21:59 +04:00
|
|
|
Native["com/sun/cldchi/io/ConsoleOutputStream.write.(I)V"] = (function() {
|
2014-07-15 11:01:11 +04:00
|
|
|
var s = "";
|
2014-07-26 00:06:48 +04:00
|
|
|
return function(ctx, stack) {
|
|
|
|
var ch = stack.pop(), obj = stack.pop();
|
2014-07-15 11:01:11 +04:00
|
|
|
if (ch === 10) {
|
2014-07-17 12:41:50 +04:00
|
|
|
document.getElementById("output").textContent += s + "\n";
|
2014-07-15 11:01:11 +04:00
|
|
|
s = "";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
s += String.fromCharCode(ch);
|
2014-07-26 04:54:34 +04:00
|
|
|
};
|
2014-07-15 11:01:11 +04:00
|
|
|
})();
|
2014-07-19 04:55:09 +04:00
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["com/sun/cldc/io/ResourceInputStream.open.(Ljava/lang/String;)Ljava/lang/Object;"] = function(ctx, stack) {
|
|
|
|
var name = stack.pop();
|
2014-07-19 04:55:09 +04:00
|
|
|
var fileName = util.fromJavaString(name);
|
|
|
|
var data = CLASSES.loadFile(fileName);
|
2014-07-26 00:06:48 +04:00
|
|
|
var obj = null;
|
|
|
|
if (data) {
|
|
|
|
obj = CLASSES.newObject(CLASSES.java_lang_Object);
|
|
|
|
obj.data = Uint8Array(data);
|
|
|
|
obj.pos = 0;
|
|
|
|
}
|
|
|
|
stack.push(obj);
|
2014-07-19 04:55:09 +04:00
|
|
|
};
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["com/sun/cldc/io/ResourceInputStream.bytesRemain.(Ljava/lang/Object;)I"] = function(ctx, stack) {
|
|
|
|
var handle = stack.pop();
|
|
|
|
stack.push(handle.data.length - handle.pos);
|
2014-07-19 04:55:09 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["com/sun/cldc/io/ResourceInputStream.readByte.(Ljava/lang/Object;)I"] = function(ctx, stack) {
|
|
|
|
var handle = stack.pop();
|
|
|
|
stack.push(handle.data[handle.pos++]);
|
2014-07-19 04:55:09 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["com/sun/cldc/io/ResourceInputStream.readBytes.(Ljava/lang/Object;[BII)I"] = function(ctx, stack) {
|
|
|
|
var len = stack.pop(), off = stack.pop(), b = stack.pop(), handle = stack.pop();
|
2014-07-19 04:55:09 +04:00
|
|
|
var data = handle.data;
|
|
|
|
var remaining = data.length - handle.pos;
|
|
|
|
if (remaining > len)
|
|
|
|
len = remaining;
|
|
|
|
for (var n = 0; n < len; ++n)
|
|
|
|
b[off+n] = data[n];
|
|
|
|
handle.pos += len;
|
2014-07-26 00:06:48 +04:00
|
|
|
stack.push(len);
|
2014-07-19 04:55:09 +04:00
|
|
|
}
|
2014-07-19 05:23:49 +04:00
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["com/sun/cldc/i18n/uclc/DefaultCaseConverter.toLowerCase.(C)C"] = function(ctx, stack) {
|
|
|
|
stack.push(String.fromCharCode(stack.pop()).toLowerCase().charCodeAt(0));
|
2014-07-19 22:53:27 +04:00
|
|
|
}
|
|
|
|
|
2014-07-26 00:06:48 +04:00
|
|
|
Native["com/sun/cldc/i18n/uclc/DefaultCaseConverter.toUpperCase.(C)C"] = function(ctx, stack) {
|
|
|
|
stack.push(String.fromCharCode(stack.pop()).toUpperCase().charCodeAt(0));
|
2014-07-19 05:23:49 +04:00
|
|
|
}
|