diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-03-22 12:32:25 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-03-22 12:32:53 -0700 |
commit | 716fcc6759e4230ccfd893b7b452c1dda2e9b9bc (patch) | |
tree | 25c13882bc5fcdcab4752f893b86a4a25f360779 /third_party | |
parent | a915398175171e65b43e4711e887044047b4e60d (diff) |
refactor jvm support into a JS library
Diffstat (limited to 'third_party')
-rw-r--r-- | third_party/jni/emjvm.js | 333 |
1 files changed, 169 insertions, 164 deletions
diff --git a/third_party/jni/emjvm.js b/third_party/jni/emjvm.js index e422d208..6a8da080 100644 --- a/third_party/jni/emjvm.js +++ b/third_party/jni/emjvm.js @@ -1,180 +1,185 @@ +mergeInto(LibraryManager.library, { + $EmJVM: { + debug: false, + + nextId: 0, + objects: {}, + classNames: {}, // class name => singleton object + + addObject: function(o) { + var ret = EmJVM.nextId++; + EmJVM.objects[ret] = o; + o.id = ret; + o.refs = 1; + o.nextMethodId = 0; + // XXX Module.print('add object ' + JSON.stringify(o).substr(0, 80) + (ret > 5285 ? new Error().stack : '')); + return ret; + }, + + addSingletonObject: function(o) { + EmJVM.classNames[o.name] = o; + return EmJVM.addObject(o); + }, + + createString: function(data) { + return EmJVM.addObject({ name: 'string', value: data }); + }, + + createByteArray: function(data) { + return EmJVM.addObject({ name: 'byteArray', value: data }); + }, + + // utils + + widecharToString: function(ptr, len) { + var nullTerminated = typeof(len) == "undefined"; + var ret = ""; + var i = 0; + var t; + while (1) { + t = getValue(ptr + 2 * i, 'i16'); + if (nullTerminated && t == 0) break; + if (t != 0) { + ret += String.fromCharCode(t); + } + ++i; + if (!nullTerminated && i == len) break; + }; + return ret; + }, + }, -var EmJVM = { - debug: false, + emjvm_newString__deps: ['$EmJVM'], + emjvm_newString: function(chars, len) { + return EmJVM.createString(EmJVM.widecharToString(chars, len)); + }, - nextId: 0, - objects: {}, - classNames: {}, // class name => singleton object + emjvm_getStringUTFChars: function(jniEnv, string, isCopy) { + var obj = EmJVM.objects[string]; + assert(obj.name == 'string'); + if (isCopy) setValue(isCopy, 'i8', 1); + var buffer = _malloc(obj.value.length+1); + writeStringToMemory(obj.value, buffer); + return buffer; + }, - addObject: function(o) { - var ret = EmJVM.nextId++; - EmJVM.objects[ret] = o; - o.id = ret; - o.refs = 1; - o.nextMethodId = 0; - // XXX Module.print('add object ' + JSON.stringify(o).substr(0, 80) + (ret > 5285 ? new Error().stack : '')); - return ret; + emjvm_getStringUTFLength: function(jniEnv, string) { + var obj = EmJVM.objects[string]; + if (obj.value) { + return obj.value.length; + } + return 0; }, - addSingletonObject: function(o) { - EmJVM.classNames[o.name] = o; - return EmJVM.addObject(o); + emjvm_releaseStringUTFChars: function(jniEnv, string, utf) { }, - createString: function(data) { - return EmJVM.addObject({ name: 'string', value: data }); + emjvm_getObjectClass__deps: ['$EmJVM'], + emjvm_getObjectClass: function(env, jobject) { + if (EmJVM.debug) { + console.log('EMJVM_GetObjectClass+AddLocalRef: ' + [jobject]); + } + var obj = EmJVM.objects[jobject]; + obj.refs++; + return jobject; }, - createByteArray: function(data) { - return EmJVM.addObject({ name: 'byteArray', value: data }); + emjvm_getMethodID: function(jclass, name, sig) { + if (EmJVM.debug) { + console.log('EMJVM_GetMethodID: ' + [jclass, Pointer_stringify(name), Pointer_stringify(sig)]); + console.log('EMJVM_GetMethodID: ' + [EmJVM.objects[jclass].name]); + } + // assumes class <--> object, just called on singletons + name = Pointer_stringify(name); + var obj = EmJVM.objects[jclass]; + if (!obj[name]) { + throw 'missing implementation for ' + obj.name + '::' + name + ' : ' + new Error().stack; + } + if (!obj[name + '__methodId']) { + var methodId = obj.nextMethodId++; + obj[name + '__methodId'] = methodId; + obj['method__' + methodId] = obj[name]; + obj['methodName__' + methodId] = name; + } + return obj[name + '__methodId']; }, -}; -function widecharToString(ptr, len) { - var nullTerminated = typeof(len) == "undefined"; - var ret = ""; - var i = 0; - var t; - while (1) { - t = getValue(ptr + 2 * i, 'i16'); - if (nullTerminated && t == 0) break; - if (t != 0) { - ret += String.fromCharCode(t); + emjvm_getStaticMethodID: function(jniEnv, jclass, name, sig) { + // Pretend this to be the same as looking up a non-static method + return _emjvm_getMethodID(jclass, name, sig); + }, + + emjvm_callObjectMethod: function(jniEnv, jobject, methodId, varargs) { + if (EmJVM.debug) { + console.log('EMJVM_CallObjectMethod: ' + [jobject, EmJVM.objects[jobject].name, methodId, EmJVM.objects[jobject]['methodName__' + methodId]]); } - ++i; - if (!nullTerminated && i == len) break; - }; - return ret; -} - -function _emjvm_newString(chars, len) { - return EmJVM.createString(widecharToString(chars, len)); -} - -function _emjvm_getStringUTFChars(jniEnv, string, isCopy) { - var obj = EmJVM.objects[string]; - assert(obj.name == 'string'); - if (isCopy) setValue(isCopy, 'i8', 1); - var buffer = _malloc(obj.value.length+1); - writeStringToMemory(obj.value, buffer); - return buffer; -} - -function _emjvm_getStringUTFLength(jniEnv, string) { - var obj = EmJVM.objects[string]; - if (obj.value) { + return EmJVM.objects[jobject]['method__' + methodId](varargs); + }, + + emjvm_callStaticObjectMethod: function(jniEnv, jclass, methodId, varargs) { + // Pretend this to be the same as calling a non-static method + return _emjvm_callObjectMethod(jniEnv, jclass, methodId, varargs); + }, + + emjvm_callStaticBooleanMethod: function(jniEnv, jclass, methodId, varargs) { + // Only differs in return type + return _emjvm_callStaticObjectMethod(jniEnv, jclass, methodId, varargs); + }, + + emjvm_callBooleanMethod: function(jniEnv, jobject, methodId, varargs) { + // Pretend this to be the same as calling a non-static method + return _emjvm_callStaticBooleanMethod(jniEnv, jobject, methodId, varargs); + }, + + emjvm_callVoidMethod: function(jniEnv, jobject, methodId, varargs) { + _emjvm_callObjectMethod(jniEnv, jobject, methodId, varargs); + }, + + emjvm_callIntMethod: function(jniEnv, jobject, methodId, varargs) { + return _emjvm_callObjectMethod(jniEnv, jobject, methodId, varargs); + }, + + emjvm_deleteLocalRef: function(jniEnv, jobject) { + if (EmJVM.debug) { + console.log('EMJVM_DeleteLocalRef: ' + [jobject]); + } + var obj = EmJVM.objects[jobject]; + obj.refs--; + if (obj.refs == 0) { + if (EmJVM.debug) { + console.log('EMJVM_DeleteLocalRef: remove ' + obj.name); + } + delete EmJVM.objects[jobject]; + } + }, + + emjvm_getArrayLength: function(jniEnv, jobject) { + var obj = EmJVM.objects[jobject]; + assert(obj.name == 'byteArray'); return obj.value.length; - } - return 0; -} - -function _emjvm_releaseStringUTFChars(jniEnv, string, utf) { -} - -function _emjvm_getObjectClass(env, jobject) { - if (EmJVM.debug) { - console.log('EMJVM_GetObjectClass+AddLocalRef: ' + [jobject]); - } - var obj = EmJVM.objects[jobject]; - obj.refs++; - return jobject; -} - -function _emjvm_getMethodID(jclass, name, sig) { - if (EmJVM.debug) { - console.log('EMJVM_GetMethodID: ' + [jclass, Pointer_stringify(name), Pointer_stringify(sig)]); - console.log('EMJVM_GetMethodID: ' + [EmJVM.objects[jclass].name]); - } - // assumes class <--> object, just called on singletons - name = Pointer_stringify(name); - var obj = EmJVM.objects[jclass]; - if (!obj[name]) { - throw 'missing implementation for ' + obj.name + '::' + name + ' : ' + new Error().stack; - } - if (!obj[name + '__methodId']) { - var methodId = obj.nextMethodId++; - obj[name + '__methodId'] = methodId; - obj['method__' + methodId] = obj[name]; - obj['methodName__' + methodId] = name; - } - return obj[name + '__methodId']; -} - -function _emjvm_getStaticMethodID(jniEnv, jclass, name, sig) { - // Pretend this to be the same as looking up a non-static method - return _emjvm_getMethodID(jclass, name, sig); -} - -function _emjvm_callObjectMethod(jniEnv, jobject, methodId, varargs) { - if (EmJVM.debug) { - console.log('EMJVM_CallObjectMethod: ' + [jobject, EmJVM.objects[jobject].name, methodId, EmJVM.objects[jobject]['methodName__' + methodId]]); - } - return EmJVM.objects[jobject]['method__' + methodId](varargs); -} - -function _emjvm_callStaticObjectMethod(jniEnv, jclass, methodId, varargs) { - // Pretend this to be the same as calling a non-static method - return _emjvm_callObjectMethod(jniEnv, jclass, methodId, varargs); -} - -function _emjvm_callStaticBooleanMethod(jniEnv, jclass, methodId, varargs) { - // Only differs in return type - return _emjvm_callStaticObjectMethod(jniEnv, jclass, methodId, varargs); -} - -function _emjvm_callBooleanMethod(jniEnv, jobject, methodId, varargs) { - // Pretend this to be the same as calling a non-static method - return _emjvm_callStaticBooleanMethod(jniEnv, jobject, methodId, varargs); -} - -function _emjvm_callVoidMethod(jniEnv, jobject, methodId, varargs) { - _emjvm_callObjectMethod(jniEnv, jobject, methodId, varargs); -} - -function _emjvm_callIntMethod(jniEnv, jobject, methodId, varargs) { - return _emjvm_callObjectMethod(jniEnv, jobject, methodId, varargs); -} - -function _emjvm_deleteLocalRef(jniEnv, jobject) { - if (EmJVM.debug) { - console.log('EMJVM_DeleteLocalRef: ' + [jobject]); - } - var obj = EmJVM.objects[jobject]; - obj.refs--; - if (obj.refs == 0) { + }, + + emjvm_getByteArrayRegion: function(jniEnv, jobject, start, len, buf) { + var obj = EmJVM.objects[jobject]; + assert(obj.name == 'byteArray'); + assert(obj.value); // we set this to null below and assume we are never called again if (EmJVM.debug) { - console.log('EMJVM_DeleteLocalRef: remove ' + obj.name); + console.log('emjvm_getByteArrayRegion: ' + [jobject, obj.value.length, start, len, buf]); } - delete EmJVM.objects[jobject]; - } -} - -function _emjvm_getArrayLength(jniEnv, jobject) { - var obj = EmJVM.objects[jobject]; - assert(obj.name == 'byteArray'); - return obj.value.length; -} - -function _emjvm_getByteArrayRegion(jniEnv, jobject, start, len, buf) { - var obj = EmJVM.objects[jobject]; - assert(obj.name == 'byteArray'); - assert(obj.value); // we set this to null below and assume we are never called again - if (EmJVM.debug) { - console.log('emjvm_getByteArrayRegion: ' + [jobject, obj.value.length, start, len, buf]); - } - assert(start + len <= obj.value.length); - assert(len == obj.value.length); // we assume users read it all, and we can now copy it all with set() and then free it - HEAPU8.set(obj.value, buf); - obj.value = null; // XXX assume byte arrays are one-shot -} - -function _emjvm_findClass(env, name) { - name = Pointer_stringify(name); - if (EmJVM.debug) { - console.log('emjvm_findClass: ' + [name]); - } - var obj = EmJVM.classNames[name]; - assert(obj); - return obj.id; -} + assert(start + len <= obj.value.length); + assert(len == obj.value.length); // we assume users read it all, and we can now copy it all with set() and then free it + HEAPU8.set(obj.value, buf); + obj.value = null; // XXX assume byte arrays are one-shot + }, + + emjvm_findClass: function(env, name) { + name = Pointer_stringify(name); + if (EmJVM.debug) { + console.log('emjvm_findClass: ' + [name]); + } + var obj = EmJVM.classNames[name]; + assert(obj); + return obj.id; + }, +}); |