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-09-05 22:36:46 +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-10-14 22:25:31 +04:00
|
|
|
Native.create = createAlternateImpl.bind(null, Native);
|
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/System.arraycopy.(Ljava/lang/Object;ILjava/lang/Object;II)V", function(src, srcOffset, dst, dstOffset, length) {
|
2014-07-26 00:06:48 +04:00
|
|
|
if (!src || !dst)
|
2014-10-14 22:25:31 +04:00
|
|
|
throw new JavaException("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)
|
2014-10-14 22:25:31 +04:00
|
|
|
throw new JavaException("java/lang/ArrayStoreException", "Can only copy to/from array types.");
|
2014-07-26 00:06:48 +04:00
|
|
|
if (srcOffset < 0 || (srcOffset+length) > src.length || dstOffset < 0 || (dstOffset+length) > dst.length || length < 0)
|
2014-10-14 22:25:31 +04:00
|
|
|
throw new JavaException("java/lang/ArrayIndexOutOfBoundsException", "Invalid index.");
|
2014-07-27 04:39:49 +04:00
|
|
|
if ((!!srcClass.elementClass != !!dstClass.elementClass) ||
|
|
|
|
(!srcClass.elementClass && srcClass != dstClass)) {
|
2014-10-14 22:25:31 +04:00
|
|
|
throw new JavaException("java/lang/ArrayStoreException",
|
|
|
|
"Incompatible component types: " + srcClass.constructor.name + " -> " + dstClass.constructor.name);
|
2014-07-27 04:39:49 +04:00
|
|
|
}
|
|
|
|
if (dstClass.elementClass) {
|
|
|
|
if (srcClass != dstClass && !srcClass.elementClass.isAssignableTo(dstClass.elementClass)) {
|
2014-09-05 22:36:46 +04:00
|
|
|
var copy = function(to, from) {
|
2014-07-27 04:39:49 +04:00
|
|
|
var obj = src[from];
|
|
|
|
if (obj && !obj.class.isAssignableTo(dstClass.elementClass))
|
2014-10-14 22:25:31 +04:00
|
|
|
throw new JavaException("java/lang/ArrayStoreException", "Incompatible component types.");
|
2014-07-27 04:39:49 +04:00
|
|
|
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-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-15 09:13:01 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/System.getProperty0.(Ljava/lang/String;)Ljava/lang/String;", function(key) {
|
2014-07-26 00:06:48 +04:00
|
|
|
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-31 19:59:30 +04:00
|
|
|
value = "UTF-8";
|
|
|
|
break;
|
|
|
|
case "microedition.locale":
|
|
|
|
value = navigator.language;
|
2014-07-26 00:06:48 +04:00
|
|
|
break;
|
2014-08-02 06:37:12 +04:00
|
|
|
case "microedition.platform":
|
2014-10-22 12:39:10 +04:00
|
|
|
value = urlParams.platform ? urlParams.platform : "NOKIA503/JAVA_RUNTIME_VERSION=NOKIA_ASHA_1_2";
|
2014-08-02 06:37:12 +04:00
|
|
|
break;
|
2014-08-08 07:35:02 +04:00
|
|
|
case "microedition.platformimpl":
|
|
|
|
value = "";
|
|
|
|
break;
|
2014-08-07 22:51:33 +04:00
|
|
|
case "microedition.profiles":
|
|
|
|
value = "MIDP-2.0"
|
|
|
|
break;
|
2014-11-08 20:21:31 +03:00
|
|
|
case "microedition.pim.version":
|
|
|
|
value = "1.0";
|
|
|
|
break;
|
2014-11-15 00:57:46 +03:00
|
|
|
case "microedition.amms.version":
|
|
|
|
value = "1.1";
|
|
|
|
break;
|
2014-11-15 00:58:48 +03:00
|
|
|
case "mmapi-configuration":
|
|
|
|
value = null;
|
|
|
|
break;
|
2014-08-02 07:25:58 +04:00
|
|
|
case "fileconn.dir.memorycard":
|
2014-10-21 22:07:57 +04:00
|
|
|
value = "file:///";
|
2014-08-02 07:25:58 +04:00
|
|
|
break;
|
|
|
|
case "fileconn.dir.private":
|
2014-10-21 22:07:57 +04:00
|
|
|
value = "file:///";
|
2014-08-05 08:51:46 +04:00
|
|
|
break;
|
2014-09-04 06:03:11 +04:00
|
|
|
case "fileconn.dir.applications.bookmarks":
|
2014-10-21 22:07:57 +04:00
|
|
|
value = "file:///";
|
2014-09-04 06:03:11 +04:00
|
|
|
break;
|
|
|
|
case "fileconn.dir.received":
|
2014-10-21 22:07:57 +04:00
|
|
|
value = "file:///";
|
2014-09-04 06:03:11 +04:00
|
|
|
break;
|
2014-10-31 13:31:02 +03:00
|
|
|
case "fileconn.dir.photos":
|
2014-11-02 21:48:29 +03:00
|
|
|
value = "file:///Photos/";
|
2014-10-31 13:31:02 +03:00
|
|
|
break;
|
2014-09-20 04:17:47 +04:00
|
|
|
case "fileconn.dir.roots.names":
|
2014-09-20 04:18:25 +04:00
|
|
|
// The names here should be localized.
|
2014-09-20 04:17:47 +04:00
|
|
|
value = "Memory card;Phone memory;Private"
|
|
|
|
break;
|
|
|
|
case "fileconn.dir.roots.external":
|
2014-10-21 22:07:57 +04:00
|
|
|
value = "file:///MemoryCard;file:///;file:///";
|
2014-09-20 04:26:56 +04:00
|
|
|
break;
|
|
|
|
case "fileconn.dir.photos.name":
|
|
|
|
value = "Photos";
|
|
|
|
break;
|
|
|
|
case "fileconn.dir.videos.name":
|
|
|
|
value = "Videos";
|
|
|
|
break;
|
|
|
|
case "fileconn.dir.recordings.name":
|
|
|
|
value = "Recordings";
|
2014-09-20 04:17:47 +04:00
|
|
|
break;
|
2014-08-04 06:58:29 +04:00
|
|
|
case "file.separator":
|
2014-08-05 08:51:46 +04:00
|
|
|
value = "/";
|
|
|
|
break;
|
2014-08-05 22:12:49 +04:00
|
|
|
case "com.sun.cldc.util.j2me.TimeZoneImpl.timezone":
|
2014-09-17 23:13:30 +04:00
|
|
|
// Date.toString() returns something like the following:
|
|
|
|
// "Wed Sep 17 2014 12:11:23 GMT-0700 (PDT)"
|
|
|
|
//
|
|
|
|
// Per http://www.spectrum3847.org/frc2013api/com/sun/cldc/util/j2me/TimeZoneImpl.html,
|
|
|
|
// timezones can be of the format GMT+0600, which is what this
|
|
|
|
// regex currently matches. (Those actually in GMT would not
|
|
|
|
// match the regex, causing the default "GMT" to be returned.)
|
|
|
|
// If we find this to be a problem, we could alternately return the
|
|
|
|
// zone name as provided in parenthesis, but that seems locale-specific.
|
|
|
|
var match = /GMT[+-]\d+/.exec(new Date().toString());
|
|
|
|
value = (match && match[0]) || "GMT";
|
2014-08-05 22:12:49 +04:00
|
|
|
break;
|
2014-08-08 00:29:46 +04:00
|
|
|
case "javax.microedition.io.Connector.protocolpath":
|
2014-08-21 20:14:28 +04:00
|
|
|
value = "com.sun.midp.io";
|
2014-08-08 00:29:46 +04:00
|
|
|
break;
|
|
|
|
case "javax.microedition.io.Connector.protocolpath.fallback":
|
2014-08-21 20:14:28 +04:00
|
|
|
value = "com.sun.cldc.io";
|
2014-08-08 00:29:46 +04:00
|
|
|
break;
|
2014-09-04 06:10:11 +04:00
|
|
|
case "com.nokia.keyboard.type":
|
|
|
|
value = "None";
|
|
|
|
break;
|
2014-08-08 07:35:02 +04:00
|
|
|
case "com.nokia.multisim.slots":
|
2014-09-04 06:10:11 +04:00
|
|
|
console.warn("Property 'com.nokia.multisim.slots' is a stub");
|
2014-08-08 07:35:02 +04:00
|
|
|
value = "1";
|
|
|
|
break;
|
2014-09-09 04:06:40 +04:00
|
|
|
case "com.nokia.multisim.imsi.sim2":
|
|
|
|
console.warn("Property 'com.nokia.multisim.imsi.sim2' is a stub");
|
|
|
|
value = null;
|
|
|
|
break;
|
2014-08-08 07:35:02 +04:00
|
|
|
case "com.nokia.mid.imsi":
|
2014-09-04 06:10:11 +04:00
|
|
|
console.warn("Property 'com.nokia.mid.imsi' is a stub");
|
2014-08-08 07:35:02 +04:00
|
|
|
value = "000000000000000";
|
|
|
|
break;
|
|
|
|
case "com.nokia.mid.ui.version":
|
2014-09-04 06:10:11 +04:00
|
|
|
console.warn("Property 'com.nokia.mid.ui.version' is a stub");
|
2014-08-08 07:35:02 +04:00
|
|
|
value = "1.6";
|
|
|
|
break;
|
2014-08-09 03:17:00 +04:00
|
|
|
case "com.nokia.mid.mnc":
|
2014-09-06 01:57:32 +04:00
|
|
|
// The concatenation of the MCC and MNC for the ICC (i.e. SIM card).
|
2014-09-06 03:06:38 +04:00
|
|
|
value = util.pad(mobileInfo.icc.mcc, 3) + util.pad(mobileInfo.icc.mnc, 3);
|
2014-09-06 01:57:32 +04:00
|
|
|
break;
|
|
|
|
case "com.nokia.mid.networkID":
|
|
|
|
// The concatenation of MCC and MNC for the network.
|
2014-09-06 03:06:38 +04:00
|
|
|
value = util.pad(mobileInfo.network.mcc, 3) + util.pad(mobileInfo.network.mnc, 3);
|
2014-08-09 03:17:00 +04:00
|
|
|
break;
|
2014-10-29 01:56:22 +03:00
|
|
|
case "com.nokia.mid.imei":
|
|
|
|
console.warn("Property 'com.nokia.mid.imei' is a stub");
|
|
|
|
value = "";
|
|
|
|
break;
|
2014-09-05 02:27:51 +04:00
|
|
|
case "com.nokia.mid.ui.customfontsize":
|
|
|
|
console.warn("Property 'com.nokia.mid.ui.customfontsize' is a stub");
|
|
|
|
value = "false";
|
|
|
|
break;
|
2014-08-08 05:32:14 +04:00
|
|
|
case "classpathext":
|
2014-08-08 20:41:58 +04:00
|
|
|
value = null;
|
2014-08-08 05:32:14 +04:00
|
|
|
break;
|
2014-07-26 00:06:48 +04:00
|
|
|
default:
|
2014-09-08 12:22:18 +04:00
|
|
|
console.warn("UNKNOWN PROPERTY (java/lang/System): " + util.fromJavaString(key));
|
2014-07-26 00:06:48 +04:00
|
|
|
break;
|
2014-07-15 09:13:01 +04:00
|
|
|
}
|
2014-10-14 22:25:31 +04:00
|
|
|
return value ? value : null;
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-15 10:19:26 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/System.currentTimeMillis.()J", function() {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Long.fromNumber(Date.now());
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-18 22:00:19 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldchi/jvm/JVM.unchecked_char_arraycopy.([CI[CII)V", function(src, srcOffset, dst, dstOffset, length) {
|
2014-09-25 03:06:43 +04:00
|
|
|
dst.set(src.subarray(srcOffset, srcOffset + length), dstOffset);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-10-14 22:25:31 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldchi/jvm/JVM.unchecked_int_arraycopy.([II[III)V", function(src, srcOffset, dst, dstOffset, length) {
|
2014-10-14 22:25:31 +04:00
|
|
|
dst.set(src.subarray(srcOffset, srcOffset + length), dstOffset);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-09-25 03:06:43 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldchi/jvm/JVM.unchecked_obj_arraycopy.([Ljava/lang/Object;I[Ljava/lang/Object;II)V", function(src, srcOffset, dst, dstOffset, length) {
|
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-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-15 10:37:33 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldchi/jvm/JVM.monotonicTimeMillis.()J", function() {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Long.fromNumber(performance.now());
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-08-03 00:19:32 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("java/lang/Object.getClass.()Ljava/lang/Class;", function(ctx) {
|
|
|
|
return this.class.getClassObject(ctx);
|
|
|
|
});
|
2014-07-18 10:02:28 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Object.hashCode.()I", function() {
|
2014-10-14 22:25:31 +04:00
|
|
|
var hashCode = this.hashCode;
|
2014-07-28 11:53:37 +04:00
|
|
|
while (!hashCode)
|
2014-10-14 22:25:31 +04:00
|
|
|
hashCode = this.hashCode = util.id();
|
|
|
|
return hashCode;
|
|
|
|
});
|
2014-07-28 11:53:37 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Object.wait.(J)V", function(timeout, _, ctx) {
|
2014-10-14 22:25:31 +04:00
|
|
|
ctx.wait(this, timeout.toNumber());
|
|
|
|
});
|
2014-07-27 05:47:38 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("java/lang/Object.notify.()V", function(ctx) {
|
|
|
|
ctx.notify(this);
|
|
|
|
});
|
2014-07-28 23:44:40 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("java/lang/Object.notifyAll.()V", function(ctx) {
|
|
|
|
ctx.notify(this, true);
|
|
|
|
});
|
2014-07-28 23:44:40 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("java/lang/Class.invoke_clinit.()V", function(ctx) {
|
|
|
|
var classInfo = this.vmClass;
|
2014-08-07 04:11:27 +04:00
|
|
|
var className = classInfo.className;
|
|
|
|
var runtime = ctx.runtime;
|
|
|
|
if (runtime.initialized[className] || runtime.pending[className])
|
2014-07-28 23:42:42 +04:00
|
|
|
return;
|
2014-08-07 04:11:27 +04:00
|
|
|
runtime.pending[className] = true;
|
2014-08-07 09:06:14 +04:00
|
|
|
if (className === "com/sun/cldc/isolate/Isolate") {
|
|
|
|
// The very first isolate is granted access to the isolate API.
|
2014-09-26 22:48:06 +04:00
|
|
|
ctx.runtime.setStatic(CLASSES.getField(classInfo, "S._API_access_ok.I"), 1);
|
2014-08-07 09:06:14 +04:00
|
|
|
}
|
2014-09-26 22:48:06 +04:00
|
|
|
var clinit = CLASSES.getMethod(classInfo, "S.<clinit>.()V");
|
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;
|
2014-10-14 22:25:31 +04:00
|
|
|
});
|
2014-07-26 22:42:02 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("java/lang/Class.init9.()V", function(ctx) {
|
|
|
|
var classInfo = this.vmClass;
|
2014-08-07 04:11:27 +04:00
|
|
|
var className = classInfo.className;
|
|
|
|
var runtime = ctx.runtime;
|
|
|
|
if (runtime.initialized[className])
|
2014-07-28 23:42:42 +04:00
|
|
|
return;
|
2014-08-07 04:11:27 +04:00
|
|
|
runtime.pending[className] = false;
|
|
|
|
runtime.initialized[className] = true;
|
2014-10-14 22:25:31 +04:00
|
|
|
});
|
2014-07-26 22:42:02 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Class.getName.()Ljava/lang/String;", function() {
|
2014-10-14 22:25:31 +04:00
|
|
|
return this.vmClass.className.replace(/\//g, ".");
|
|
|
|
});
|
2014-07-18 10:02:28 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Class.forName.(Ljava/lang/String;)Ljava/lang/Class;", function(name, ctx) {
|
2014-07-27 05:20:54 +04:00
|
|
|
try {
|
2014-08-01 02:01:10 +04:00
|
|
|
if (!name)
|
|
|
|
throw new Classes.ClassNotFoundException();
|
2014-08-02 22:27:25 +04:00
|
|
|
var className = util.fromJavaString(name).replace(/\./g, "/");
|
2014-08-01 02:01:10 +04:00
|
|
|
var classInfo = null;
|
2014-07-27 05:20:54 +04:00
|
|
|
classInfo = CLASSES.getClass(className);
|
|
|
|
} catch (e) {
|
|
|
|
if (e instanceof (Classes.ClassNotFoundException))
|
2014-10-27 14:37:53 +03:00
|
|
|
throw new JavaException("java/lang/ClassNotFoundException", "'" + className + "' not found.");
|
2014-07-27 05:20:54 +04:00
|
|
|
throw e;
|
2014-07-15 10:47:20 +04:00
|
|
|
}
|
2014-10-14 22:25:31 +04:00
|
|
|
return classInfo.getClassObject(ctx);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-15 10:47:20 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("java/lang/Class.newInstance.()Ljava/lang/Object;", function(ctx) {
|
|
|
|
var className = this.vmClass.className;
|
2014-10-10 03:20:18 +04:00
|
|
|
var syntheticMethod = new MethodInfo({
|
2014-10-01 02:16:38 +04:00
|
|
|
name: "ClassNewInstanceSynthetic",
|
|
|
|
signature: "()Ljava/lang/Object;",
|
2014-10-10 12:30:30 +04:00
|
|
|
isStatic: true,
|
2014-07-26 00:06:48 +04:00
|
|
|
classInfo: {
|
2014-10-01 02:16:38 +04:00
|
|
|
className: className,
|
2014-09-26 06:20:41 +04:00
|
|
|
vmc: {},
|
|
|
|
vfc: {},
|
2014-07-26 00:06:48 +04:00
|
|
|
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" },
|
|
|
|
]
|
|
|
|
},
|
2014-10-02 23:26:23 +04:00
|
|
|
code: new Uint8Array([
|
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
|
2014-10-02 23:26:23 +04:00
|
|
|
]),
|
2014-10-10 03:20:18 +04:00
|
|
|
});
|
2014-10-10 12:30:30 +04:00
|
|
|
ctx.pushFrame(syntheticMethod);
|
2014-07-26 00:06:48 +04:00
|
|
|
throw VM.Yield;
|
2014-10-14 22:25:31 +04:00
|
|
|
});
|
2014-07-15 11:01:11 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Class.isInterface.()Z", function() {
|
2014-10-14 22:25:31 +04:00
|
|
|
return ACCESS_FLAGS.isInterface(this.vmClass.access_flags);
|
|
|
|
});
|
2014-07-19 04:55:09 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Class.isArray.()Z", function() {
|
2014-10-14 22:25:31 +04:00
|
|
|
return !!this.vmClass.isArrayClass;
|
|
|
|
});
|
2014-07-19 04:55:09 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Class.isAssignableFrom.(Ljava/lang/Class;)Z", function(fromClass) {
|
2014-07-26 00:06:48 +04:00
|
|
|
if (!fromClass)
|
2014-10-14 22:25:31 +04:00
|
|
|
throw new JavaException("java/lang/NullPointerException");
|
|
|
|
return fromClass.vmClass.isAssignableTo(this.vmClass);
|
|
|
|
});
|
2014-07-19 04:55:09 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Class.isInstance.(Ljava/lang/Object;)Z", function(obj) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return obj && obj.class.isAssignableTo(this.vmClass);
|
|
|
|
});
|
2014-07-19 04:55:09 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("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-10-27 14:37:53 +03:00
|
|
|
return function(val) {
|
2014-10-14 22:25:31 +04:00
|
|
|
fa[0] = val;
|
|
|
|
return ia[0];
|
2014-07-19 01:44:50 +04:00
|
|
|
}
|
2014-10-15 03:38:16 +04:00
|
|
|
})());
|
2014-07-19 01:44:50 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("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-10-27 14:37:53 +03:00
|
|
|
return function(val, _) {
|
2014-10-14 22:25:31 +04:00
|
|
|
da[0] = val;
|
|
|
|
return Long.fromBits(ia[0], ia[1]);
|
2014-07-19 01:44:50 +04:00
|
|
|
}
|
2014-10-15 03:38:16 +04:00
|
|
|
})());
|
2014-07-19 01:44:50 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("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-10-27 14:37:53 +03:00
|
|
|
return function(val) {
|
2014-10-14 22:25:31 +04:00
|
|
|
ia[0] = val;
|
|
|
|
return fa[0];
|
2014-07-19 05:09:55 +04:00
|
|
|
}
|
2014-10-15 03:38:16 +04:00
|
|
|
})());
|
2014-07-19 05:09:55 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("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-10-27 14:37:53 +03:00
|
|
|
return function(l, _) {
|
2014-07-19 05:33:12 +04:00
|
|
|
ia[0] = l.low_;
|
|
|
|
ia[1] = l.high_;
|
2014-10-14 22:25:31 +04:00
|
|
|
return da[0];
|
2014-07-19 05:09:55 +04:00
|
|
|
}
|
2014-10-15 03:38:16 +04:00
|
|
|
})());
|
2014-07-19 05:09:55 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("java/lang/Throwable.fillInStackTrace.()V", function(ctx) {
|
|
|
|
this.stackTrace = [];
|
2014-07-31 02:49:58 +04:00
|
|
|
ctx.frames.forEach(function(frame) {
|
|
|
|
if (!frame.methodInfo)
|
|
|
|
return;
|
|
|
|
var methodInfo = frame.methodInfo;
|
|
|
|
var methodName = methodInfo.name;
|
2014-07-31 02:56:57 +04:00
|
|
|
if (!methodName)
|
|
|
|
return;
|
2014-07-31 02:49:58 +04:00
|
|
|
var classInfo = methodInfo.classInfo;
|
|
|
|
var className = classInfo.className;
|
2014-10-14 22:25:31 +04:00
|
|
|
this.stackTrace.unshift({ className: className, methodName: methodName, offset: frame.ip });
|
|
|
|
}.bind(this));
|
2014-07-18 10:02:28 +04:00
|
|
|
});
|
|
|
|
|
2014-10-27 15:13:54 +03:00
|
|
|
Native.create("java/lang/Throwable.obtainBackTrace.()Ljava/lang/Object;", function() {
|
2014-07-31 02:49:58 +04:00
|
|
|
var result = null;
|
2014-10-14 22:25:31 +04:00
|
|
|
if (this.stackTrace) {
|
|
|
|
var depth = this.stackTrace.length;
|
2014-10-27 15:13:54 +03:00
|
|
|
var classNames = util.newArray("[Ljava/lang/Object;", depth);
|
|
|
|
var methodNames = util.newArray("[Ljava/lang/Object;", depth);
|
|
|
|
var offsets = util.newPrimitiveArray("I", depth);
|
2014-10-14 22:25:31 +04:00
|
|
|
this.stackTrace.forEach(function(e, n) {
|
2014-10-27 15:13:54 +03:00
|
|
|
classNames[n] = util.newString(e.className);
|
|
|
|
methodNames[n] = util.newString(e.methodName);
|
2014-07-31 02:49:58 +04:00
|
|
|
offsets[n] = e.offset;
|
|
|
|
});
|
2014-10-27 15:13:54 +03:00
|
|
|
result = util.newArray("[Ljava/lang/Object;", 3);
|
2014-07-31 02:49:58 +04:00
|
|
|
result[0] = classNames;
|
|
|
|
result[1] = methodNames;
|
|
|
|
result[2] = offsets;
|
|
|
|
}
|
2014-10-14 22:25:31 +04:00
|
|
|
return result;
|
2014-07-19 04:55:09 +04:00
|
|
|
});
|
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Runtime.freeMemory.()J", function() {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Long.fromInt(0x800000);
|
|
|
|
});
|
2014-07-19 20:23:14 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Runtime.totalMemory.()J", function() {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Long.fromInt(0x1000000);
|
|
|
|
});
|
2014-07-19 20:23:14 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Runtime.gc.()V", function() {
|
2014-10-14 22:25:31 +04:00
|
|
|
});
|
2014-07-19 20:23:14 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Math.floor.(D)D", function(val, _) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Math.floor(val);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-27 02:00:19 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Math.asin.(D)D", function(val, _) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Math.asin(val);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-27 02:00:19 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Math.acos.(D)D", function(val, _) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Math.acos(val);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-27 02:00:19 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Math.atan.(D)D", function(val, _) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Math.atan(val);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-27 02:00:19 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Math.atan2.(DD)D", function(x, _1, y, _2) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Math.atan2(x, y);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-27 02:00:19 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Math.sin.(D)D", function(val, _) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Math.sin(val);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-27 02:00:19 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Math.cos.(D)D", function(val, _) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Math.cos(val);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-27 02:00:19 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Math.tan.(D)D", function(val, _) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Math.tan(val);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-27 02:00:19 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Math.sqrt.(D)D", function(val, _) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Math.sqrt(val);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-27 02:00:19 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Math.ceil.(D)D", function(val, _) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Math.ceil(val);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-27 02:00:19 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Math.floor.(D)D", function(val, _) {
|
2014-10-14 22:25:31 +04:00
|
|
|
return Math.floor(val);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-19 22:53:27 +04:00
|
|
|
|
2014-10-14 22:25:31 +04:00
|
|
|
Native.create("java/lang/Thread.currentThread.()Ljava/lang/Thread;", function(ctx) {
|
|
|
|
return ctx.thread;
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-20 11:35:00 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Thread.setPriority0.(II)V", function(oldPriority, newPriority) {
|
2014-10-15 00:18:50 +04:00
|
|
|
});
|
2014-07-20 11:35:00 +04:00
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
Native.create("java/lang/Thread.start0.()V", function(ctx) {
|
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-10-15 00:18:50 +04:00
|
|
|
if (this === ctx.runtime.mainThread || this.alive)
|
|
|
|
throw new JavaException("java/lang/IllegalThreadStateException");
|
|
|
|
this.alive = true;
|
|
|
|
this.pid = util.id();
|
|
|
|
var run = CLASSES.getMethod(this.class, "I.run.()V");
|
2014-07-28 10:39:41 +04:00
|
|
|
// Create a context for the thread and start it.
|
2014-08-07 04:04:44 +04:00
|
|
|
var ctx = new Context(ctx.runtime);
|
2014-10-15 00:18:50 +04:00
|
|
|
ctx.thread = this;
|
2014-10-01 04:23:24 +04:00
|
|
|
|
2014-10-10 03:20:18 +04:00
|
|
|
var syntheticMethod = new MethodInfo({
|
2014-10-01 02:16:38 +04:00
|
|
|
name: "ThreadStart0Synthetic",
|
|
|
|
signature: "()V",
|
2014-07-28 10:39:41 +04:00
|
|
|
classInfo: {
|
2014-10-15 00:18:50 +04:00
|
|
|
className: this.class.className,
|
2014-09-26 06:20:41 +04:00
|
|
|
vmc: {},
|
|
|
|
vfc: {},
|
2014-07-28 10:39:41 +04:00
|
|
|
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" },
|
|
|
|
],
|
|
|
|
},
|
2014-10-02 23:26:23 +04:00
|
|
|
code: new Uint8Array([
|
2014-07-28 10:39:41 +04:00
|
|
|
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
|
2014-10-10 03:20:18 +04:00
|
|
|
])
|
|
|
|
});
|
2014-10-01 04:23:24 +04:00
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
ctx.frames.push(new Frame(syntheticMethod, [ this ], 0));
|
2014-10-14 22:34:02 +04:00
|
|
|
ctx.resume();
|
2014-10-15 00:18:50 +04:00
|
|
|
});
|
2014-07-20 11:35:00 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Thread.internalExit.()V", function() {
|
2014-10-15 00:18:50 +04:00
|
|
|
this.alive = false;
|
|
|
|
});
|
2014-07-28 10:39:41 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Thread.isAlive.()Z", function() {
|
2014-10-15 00:18:50 +04:00
|
|
|
return !!this.alive;
|
|
|
|
});
|
2014-07-28 10:39:41 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Thread.sleep.(J)V", function(delay, _) {
|
2014-10-17 07:08:51 +04:00
|
|
|
return new Promise(function(resolve, reject) {
|
|
|
|
window.setTimeout(resolve, delay.toNumber());
|
|
|
|
})
|
2014-11-04 04:47:51 +03:00
|
|
|
}, true);
|
2014-07-29 02:19:07 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/Thread.yield.()V", function() {
|
2014-07-29 02:19:07 +04:00
|
|
|
throw VM.Yield;
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-21 09:24:07 +04:00
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
Native.create("java/lang/Thread.activeCount.()I", function(ctx) {
|
|
|
|
return ctx.runtime.threadCount;
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-08-07 21:10:54 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldchi/io/ConsoleOutputStream.write.(I)V", function(ch) {
|
2014-09-08 20:13:08 +04:00
|
|
|
console.print(ch);
|
2014-10-15 00:18:50 +04:00
|
|
|
});
|
2014-07-19 04:55:09 +04:00
|
|
|
|
2014-10-27 15:13:54 +03:00
|
|
|
Native.create("com/sun/cldc/io/ResourceInputStream.open.(Ljava/lang/String;)Ljava/lang/Object;", function(name) {
|
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) {
|
2014-10-27 15:13:54 +03:00
|
|
|
obj = util.newObject(CLASSES.java_lang_Object);
|
2014-08-05 22:54:38 +04:00
|
|
|
obj.data = new Uint8Array(data);
|
2014-07-26 00:06:48 +04:00
|
|
|
obj.pos = 0;
|
|
|
|
}
|
2014-10-15 00:18:50 +04:00
|
|
|
return obj;
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-19 04:55:09 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Override.create("com/sun/cldc/io/ResourceInputStream.available.()I", function() {
|
2014-10-15 00:18:50 +04:00
|
|
|
var handle = this.class.getField("I.fileDecoder.Ljava/lang/Object;").get(this);
|
2014-09-25 22:40:22 +04:00
|
|
|
|
|
|
|
if (!handle) {
|
2014-10-15 00:18:50 +04:00
|
|
|
throw new JavaException("java/io/IOException");
|
2014-09-25 22:40:22 +04:00
|
|
|
}
|
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
return handle.data.length - handle.pos;
|
|
|
|
});
|
2014-07-19 04:55:09 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Override.create("com/sun/cldc/io/ResourceInputStream.read.()I", function() {
|
2014-10-15 00:18:50 +04:00
|
|
|
var handle = this.class.getField("I.fileDecoder.Ljava/lang/Object;").get(this);
|
2014-09-25 22:40:22 +04:00
|
|
|
|
|
|
|
if (!handle) {
|
2014-10-15 00:18:50 +04:00
|
|
|
throw new JavaException("java/io/IOException");
|
2014-09-25 22:40:22 +04:00
|
|
|
}
|
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
return (handle.data.length - handle.pos > 0) ? handle.data[handle.pos++] : -1;
|
|
|
|
});
|
2014-07-19 04:55:09 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldc/io/ResourceInputStream.readBytes.(Ljava/lang/Object;[BII)I", function(handle, b, off, len) {
|
2014-07-19 04:55:09 +04:00
|
|
|
var data = handle.data;
|
|
|
|
var remaining = data.length - handle.pos;
|
2014-08-02 12:08:28 +04:00
|
|
|
if (len > remaining)
|
2014-07-19 04:55:09 +04:00
|
|
|
len = remaining;
|
|
|
|
for (var n = 0; n < len; ++n)
|
2014-08-19 02:44:28 +04:00
|
|
|
b[off+n] = data[handle.pos+n];
|
2014-07-19 04:55:09 +04:00
|
|
|
handle.pos += len;
|
2014-10-15 00:18:50 +04:00
|
|
|
return (len > 0) ? len : -1;
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-19 05:23:49 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldc/i18n/uclc/DefaultCaseConverter.toLowerCase.(C)C", function(char) {
|
2014-10-15 00:18:50 +04:00
|
|
|
return String.fromCharCode(char).toLowerCase().charCodeAt(0);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-07-19 22:53:27 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldc/i18n/uclc/DefaultCaseConverter.toUpperCase.(C)C", function(char) {
|
2014-10-15 00:18:50 +04:00
|
|
|
return String.fromCharCode(char).toUpperCase().charCodeAt(0);
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-08-01 09:59:34 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/ref/WeakReference.initializeWeakReference.(Ljava/lang/Object;)V", function(target) {
|
2014-10-15 00:18:50 +04:00
|
|
|
this.target = target;
|
|
|
|
});
|
2014-08-05 20:34:00 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/ref/WeakReference.get.()Ljava/lang/Object;", function() {
|
2014-10-15 00:18:50 +04:00
|
|
|
return this.target ? this.target : null;
|
|
|
|
});
|
2014-08-05 20:34:00 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("java/lang/ref/WeakReference.clear.()V", function() {
|
2014-10-15 00:18:50 +04:00
|
|
|
this.target = null;
|
|
|
|
});
|
2014-08-07 09:06:14 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldc/isolate/Isolate.registerNewIsolate.()V", function() {
|
2014-10-15 00:18:50 +04:00
|
|
|
this.id = util.id();
|
|
|
|
});
|
2014-08-07 09:43:05 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldc/isolate/Isolate.getStatus.()I", function() {
|
2014-10-15 00:18:50 +04:00
|
|
|
return this.runtime ? this.runtime.status : 1; // NEW
|
|
|
|
});
|
2014-08-07 10:57:44 +04:00
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
Native.create("com/sun/cldc/isolate/Isolate.nativeStart.()V", function(ctx) {
|
|
|
|
ctx.runtime.vm.startIsolate(this);
|
|
|
|
});
|
2014-08-07 22:46:11 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldc/isolate/Isolate.waitStatus.(I)V", function(status) {
|
2014-10-17 07:08:51 +04:00
|
|
|
return new Promise((function(resolve, reject) {
|
|
|
|
var runtime = this.runtime;
|
2014-08-08 02:44:38 +04:00
|
|
|
if (runtime.status >= status) {
|
2014-10-17 07:08:51 +04:00
|
|
|
resolve();
|
2014-08-07 23:12:57 +04:00
|
|
|
return;
|
2014-08-07 22:46:11 +04:00
|
|
|
}
|
2014-10-17 07:08:51 +04:00
|
|
|
function waitForStatus() {
|
|
|
|
if (runtime.status >= status) {
|
|
|
|
resolve();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
runtime.waitStatus(waitForStatus);
|
|
|
|
}
|
|
|
|
waitForStatus();
|
|
|
|
}).bind(this));
|
2014-11-04 04:47:51 +03:00
|
|
|
}, true);
|
2014-08-08 09:29:16 +04:00
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
Native.create("com/sun/cldc/isolate/Isolate.currentIsolate0.()Lcom/sun/cldc/isolate/Isolate;", function(ctx) {
|
|
|
|
return ctx.runtime.isolate;
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-08-09 00:04:40 +04:00
|
|
|
|
2014-10-27 15:13:54 +03:00
|
|
|
Native.create("com/sun/cldc/isolate/Isolate.getIsolates0.()[Lcom/sun/cldc/isolate/Isolate;", function() {
|
|
|
|
var isolates = util.newArray("[Ljava/lang/Object;", Runtime.all.keys().length);
|
2014-08-09 00:04:40 +04:00
|
|
|
var n = 0;
|
|
|
|
Runtime.all.forEach(function (runtime) {
|
2014-08-12 04:13:50 +04:00
|
|
|
isolates[n++] = runtime.isolate;
|
2014-08-09 00:04:40 +04:00
|
|
|
});
|
2014-10-15 00:18:50 +04:00
|
|
|
return isolates;
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-08-09 02:24:24 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldc/isolate/Isolate.id0.()I", function() {
|
2014-10-15 00:18:50 +04:00
|
|
|
return this.id;
|
|
|
|
});
|
2014-08-09 05:34:31 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldc/isolate/Isolate.setPriority0.(I)V", function(newPriority) {
|
2014-10-15 00:18:50 +04:00
|
|
|
});
|
2014-08-12 04:16:18 +04:00
|
|
|
|
2014-08-08 23:56:13 +04:00
|
|
|
var links = {};
|
|
|
|
var waitingForLinks = {};
|
|
|
|
|
2014-10-17 07:08:51 +04:00
|
|
|
Native.create("com/sun/midp/links/LinkPortal.getLinkCount0.()I", function(ctx) {
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
|
|
var isolateId = ctx.runtime.isolate.id;
|
2014-08-08 23:56:13 +04:00
|
|
|
|
2014-10-17 07:08:51 +04:00
|
|
|
if (!links[isolateId]) {
|
|
|
|
waitingForLinks[isolateId] = function() {
|
|
|
|
resolve(links[isolateId].length);
|
|
|
|
}
|
2014-08-09 00:07:52 +04:00
|
|
|
|
2014-10-17 07:08:51 +04:00
|
|
|
return;
|
|
|
|
}
|
2014-08-09 00:07:52 +04:00
|
|
|
|
2014-10-17 07:08:51 +04:00
|
|
|
resolve(links[isolateId].length);
|
|
|
|
});
|
2014-11-04 04:47:51 +03:00
|
|
|
}, true);
|
2014-08-08 23:56:13 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/midp/links/LinkPortal.getLinks0.([Lcom/sun/midp/links/Link;)V", function(linkArray, ctx) {
|
2014-08-08 23:56:13 +04:00
|
|
|
var isolateId = ctx.runtime.isolate.id;
|
|
|
|
|
|
|
|
for (var i = 0; i < links[isolateId].length; i++) {
|
2014-09-26 22:48:06 +04:00
|
|
|
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);
|
2014-08-08 23:56:13 +04:00
|
|
|
linkArray[i].sender = links[isolateId][i].sender;
|
|
|
|
linkArray[i].receiver = links[isolateId][i].receiver;
|
|
|
|
}
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-08-08 23:56:13 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/midp/links/LinkPortal.setLinks0.(I[Lcom/sun/midp/links/Link;)V", function(id, linkArray) {
|
2014-08-08 23:56:13 +04:00
|
|
|
links[id] = linkArray;
|
|
|
|
|
|
|
|
if (waitingForLinks[id]) {
|
|
|
|
waitingForLinks[id]();
|
|
|
|
}
|
2014-10-15 03:38:16 +04:00
|
|
|
});
|
2014-08-08 23:56:13 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/midp/links/Link.init0.(II)V", function(sender, receiver) {
|
2014-10-15 00:18:50 +04:00
|
|
|
this.sender = sender;
|
|
|
|
this.receiver = receiver;
|
|
|
|
this.class.getField("I.nativePointer.I").set(this, util.id());
|
|
|
|
});
|
2014-08-08 23:56:13 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/midp/links/Link.receive0.(Lcom/sun/midp/links/LinkMessage;Lcom/sun/midp/links/Link;)V", function(linkMessage, link) {
|
2014-08-08 23:56:13 +04:00
|
|
|
// TODO: Implement when something hits send0
|
2014-08-09 05:34:31 +04:00
|
|
|
console.warn("Called com/sun/midp/links/Link.receive0.(Lcom/sun/midp/links/LinkMessage;Lcom/sun/midp/links/Link;)V");
|
2014-10-17 07:08:51 +04:00
|
|
|
return new Promise(function(){});
|
2014-11-04 04:47:51 +03:00
|
|
|
}, true);
|
2014-09-26 03:26:39 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldc/i18n/j2me/UTF_8_Reader.init.([B)V", function(data) {
|
2014-10-15 00:18:50 +04:00
|
|
|
this.decoded = new TextDecoder("UTF-8").decode(data);
|
|
|
|
});
|
2014-09-26 03:26:39 +04:00
|
|
|
|
2014-11-11 01:14:12 +03:00
|
|
|
Native.create("com/sun/cldc/i18n/j2me/UTF_8_Reader.readNative.([CII)I", function(cbuf, off, len) {
|
2014-10-15 00:18:50 +04:00
|
|
|
if (this.decoded.length === 0) {
|
|
|
|
return -1;
|
2014-09-26 03:26:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < len; i++) {
|
2014-10-15 00:18:50 +04:00
|
|
|
cbuf[i + off] = this.decoded.charCodeAt(i);
|
2014-09-26 03:26:39 +04:00
|
|
|
}
|
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
this.decoded = this.decoded.substring(len);
|
2014-09-26 03:26:39 +04:00
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
return len;
|
|
|
|
});
|
2014-09-27 00:24:59 +04:00
|
|
|
|
2014-11-14 00:25:29 +03:00
|
|
|
Native.create("java/io/DataInputStream.bytesToUTF.([B)Ljava/lang/String;", function(bytearr) {
|
|
|
|
var array = new Uint8Array(bytearr.buffer);
|
|
|
|
try {
|
|
|
|
return util.decodeUtf8Array(array);
|
|
|
|
} catch(e) {
|
|
|
|
try {
|
|
|
|
return util.javaUTF8Decode(array);
|
|
|
|
} catch (e) {
|
|
|
|
throw new JavaException("java/io/UTFDataFormatException");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2014-11-19 20:00:23 +03:00
|
|
|
Native.create("java/io/DataOutputStream.UTFToBytes.(Ljava/lang/String;)[B", function(jStr) {
|
|
|
|
var str = util.fromJavaString(jStr);
|
|
|
|
|
|
|
|
var utflen = 0;
|
|
|
|
|
|
|
|
for (var i = 0; i < str.length; i++) {
|
|
|
|
var c = str.charCodeAt(i);
|
|
|
|
if ((c >= 0x0001) && (c <= 0x007F)) {
|
|
|
|
utflen++;
|
|
|
|
} else if (c > 0x07FF) {
|
|
|
|
utflen += 3;
|
|
|
|
} else {
|
|
|
|
utflen += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (utflen > 65535) {
|
|
|
|
throw new JavaException("java/io/UTFDataFormatException");
|
|
|
|
}
|
|
|
|
|
|
|
|
var count = 0;
|
|
|
|
var bytearr = util.newPrimitiveArray("B", utflen + 2);
|
|
|
|
bytearr[count++] = (utflen >>> 8) & 0xFF;
|
|
|
|
bytearr[count++] = (utflen >>> 0) & 0xFF;
|
|
|
|
for (var i = 0; i < str.length; i++) {
|
|
|
|
var c = str.charCodeAt(i);
|
|
|
|
if ((c >= 0x0001) && (c <= 0x007F)) {
|
|
|
|
bytearr[count++] = c;
|
|
|
|
} else if (c > 0x07FF) {
|
|
|
|
bytearr[count++] = 0xE0 | ((c >> 12) & 0x0F);
|
|
|
|
bytearr[count++] = 0x80 | ((c >> 6) & 0x3F);
|
|
|
|
bytearr[count++] = 0x80 | ((c >> 0) & 0x3F);
|
|
|
|
} else {
|
|
|
|
bytearr[count++] = 0xC0 | ((c >> 6) & 0x1F);
|
|
|
|
bytearr[count++] = 0x80 | ((c >> 0) & 0x3F);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return bytearr;
|
|
|
|
});
|
|
|
|
|
2014-10-27 15:13:54 +03:00
|
|
|
Native.create("com/sun/cldc/i18n/j2me/UTF_8_Writer.encodeUTF8.([CII)[B", function(cbuf, off, len) {
|
2014-09-27 00:24:59 +04:00
|
|
|
var outputArray = [];
|
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
var pendingSurrogate = this.class.getField("I.pendingSurrogate.I").get(this);
|
2014-09-27 00:24:59 +04:00
|
|
|
|
|
|
|
var inputChar = 0;
|
|
|
|
var outputSize = 0;
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
while (count < len) {
|
|
|
|
var outputByte = new Uint8Array(4); // Never more than 4 encoded bytes
|
|
|
|
inputChar = 0xffff & cbuf[off + count];
|
|
|
|
if (0 != pendingSurrogate) {
|
2014-09-27 08:42:37 +04:00
|
|
|
if (0xdc00 <= inputChar && inputChar <= 0xdfff) {
|
2014-09-27 00:24:59 +04:00
|
|
|
//000u uuuu xxxx xxxx xxxx xxxx
|
|
|
|
//1101 10ww wwxx xxxx 1101 11xx xxxx xxxx
|
|
|
|
var highHalf = (pendingSurrogate & 0x03ff) + 0x0040;
|
|
|
|
var lowHalf = inputChar & 0x03ff;
|
|
|
|
inputChar = (highHalf << 10) | lowHalf;
|
|
|
|
} else {
|
|
|
|
// write replacement value instead of unpaired surrogate
|
|
|
|
outputByte[0] = replacementValue;
|
|
|
|
outputSize = 1;
|
|
|
|
outputArray.push(outputByte.subarray(0, outputSize));
|
|
|
|
}
|
|
|
|
pendingSurrogate = 0;
|
|
|
|
}
|
|
|
|
if (inputChar < 0x80) {
|
|
|
|
outputByte[0] = inputChar;
|
|
|
|
outputSize = 1;
|
|
|
|
} else if (inputChar < 0x800) {
|
|
|
|
outputByte[0] = 0xc0 | ((inputChar >> 6) & 0x1f);
|
|
|
|
outputByte[1] = 0x80 | (inputChar & 0x3f);
|
|
|
|
outputSize = 2;
|
2014-09-27 08:42:37 +04:00
|
|
|
} else if (0xd800 <= inputChar && inputChar <= 0xdbff) {
|
2014-09-27 00:24:59 +04:00
|
|
|
pendingSurrogate = inputChar;
|
|
|
|
outputSize = 0;
|
2014-09-27 08:42:37 +04:00
|
|
|
} else if (0xdc00 <= inputChar && inputChar <= 0xdfff) {
|
2014-09-27 00:24:59 +04:00
|
|
|
// unpaired surrogate
|
|
|
|
outputByte[0] = replacementValue;
|
|
|
|
outputSize = 1;
|
|
|
|
} else if (inputChar < 0x10000) {
|
|
|
|
outputByte[0] = 0xe0 | ((inputChar >> 12) & 0x0f);
|
|
|
|
outputByte[1] = 0x80 | ((inputChar >> 6) & 0x3f);
|
|
|
|
outputByte[2] = 0x80 | (inputChar & 0x3f);
|
|
|
|
outputSize = 3;
|
|
|
|
} else {
|
|
|
|
/* 21 bits: 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
|
|
|
|
* a aabb bbbb cccc ccdd dddd
|
|
|
|
*/
|
|
|
|
outputByte[0] = 0xf0 | ((inputChar >> 18) & 0x07);
|
|
|
|
outputByte[1] = 0x80 | ((inputChar >> 12) & 0x3f);
|
|
|
|
outputByte[2] = 0x80 | ((inputChar >> 6) & 0x3f);
|
|
|
|
outputByte[3] = 0x80 | (inputChar & 0x3f);
|
|
|
|
outputSize = 4;
|
|
|
|
}
|
|
|
|
outputArray.push(outputByte.subarray(0, outputSize));
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
this.class.getField("I.pendingSurrogate.I").set(this, pendingSurrogate);
|
2014-09-27 00:24:59 +04:00
|
|
|
|
|
|
|
var totalSize = outputArray.reduce(function(total, cur) {
|
|
|
|
return total + cur.length;
|
|
|
|
}, 0);
|
|
|
|
|
2014-10-27 15:13:54 +03:00
|
|
|
var res = util.newPrimitiveArray("B", totalSize);
|
2014-09-27 00:24:59 +04:00
|
|
|
outputArray.reduce(function(total, cur) {
|
|
|
|
res.set(cur, total);
|
|
|
|
return total + cur.length;
|
|
|
|
}, 0);
|
|
|
|
|
2014-10-15 00:18:50 +04:00
|
|
|
return res;
|
|
|
|
});
|
2014-09-27 00:29:15 +04:00
|
|
|
|
2014-10-27 14:37:53 +03:00
|
|
|
Native.create("com/sun/cldc/i18n/j2me/UTF_8_Writer.sizeOf.([CII)I", function(cbuf, off, len) {
|
2014-09-27 00:29:15 +04:00
|
|
|
var inputChar = 0;
|
|
|
|
var outputSize = 0;
|
|
|
|
var outputCount = 0;
|
|
|
|
var count = 0;
|
2014-10-15 00:18:50 +04:00
|
|
|
var localPendingSurrogate = this.class.getField("I.pendingSurrogate.I").get(this);
|
2014-09-27 00:29:15 +04:00
|
|
|
while (count < length) {
|
|
|
|
inputChar = 0xffff & cbuf[offset + count];
|
|
|
|
if (0 != localPendingSurrogate) {
|
2014-09-27 08:42:37 +04:00
|
|
|
if (0xdc00 <= inputChar && inputChar <= 0xdfff) {
|
2014-09-27 00:29:15 +04:00
|
|
|
//000u uuuu xxxx xxxx xxxx xxxx
|
|
|
|
//1101 10ww wwxx xxxx 1101 11xx xxxx xxxx
|
|
|
|
var highHalf = (localPendingSurrogate & 0x03ff) + 0x0040;
|
|
|
|
var lowHalf = inputChar & 0x03ff;
|
|
|
|
inputChar = (highHalf << 10) | lowHalf;
|
|
|
|
} else {
|
|
|
|
// going to write replacement value instead of unpaired surrogate
|
|
|
|
outputSize = 1;
|
|
|
|
outputCount += outputSize;
|
|
|
|
}
|
|
|
|
localPendingSurrogate = 0;
|
|
|
|
}
|
|
|
|
if (inputChar < 0x80) {
|
|
|
|
outputSize = 1;
|
|
|
|
} else if (inputChar < 0x800) {
|
|
|
|
outputSize = 2;
|
2014-09-27 08:42:37 +04:00
|
|
|
} else if (0xd800 <= inputChar && inputChar <= 0xdbff) {
|
2014-09-27 00:29:15 +04:00
|
|
|
localPendingSurrogate = inputChar;
|
|
|
|
outputSize = 0;
|
2014-09-27 08:42:37 +04:00
|
|
|
} else if (0xdc00 <= inputChar && inputChar <= 0xdfff) {
|
2014-09-27 00:29:15 +04:00
|
|
|
// unpaired surrogate
|
|
|
|
// going to output replacementValue;
|
|
|
|
outputSize = 1;
|
|
|
|
} else if (inputChar < 0x10000) {
|
|
|
|
outputSize = 3;
|
|
|
|
} else {
|
|
|
|
/* 21 bits: 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
|
|
|
|
* a aabb bbbb cccc ccdd dddd
|
|
|
|
*/
|
|
|
|
outputSize = 4;
|
|
|
|
}
|
|
|
|
outputCount += outputSize;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return outputCount;
|
2014-10-15 00:18:50 +04:00
|
|
|
});
|