aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-03-22 16:22:16 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-03-22 16:22:16 -0700
commita8e4801c7d38033fff760ea26a4579aa324e303e (patch)
tree01c8c9862f7a6e1b60569aa9be97fd2751be8709
parent669c786e3554b280e31dcb7bd92931482547dae0 (diff)
parentf99012f271c056ddc171f6a4ec011ad31ad936cd (diff)
Merge branch 'incoming'
-rwxr-xr-xemcc5
-rwxr-xr-xemscripten.py1
-rw-r--r--src/analyzer.js3
-rw-r--r--src/compiler.js2
-rw-r--r--src/jsifier.js17
-rw-r--r--src/library.js12
-rw-r--r--src/library_browser.js2
-rw-r--r--src/library_glut.js2
-rw-r--r--src/library_openal.js28
-rw-r--r--src/parseTools.js2
-rw-r--r--src/postamble.js20
-rw-r--r--src/settings.js6
-rw-r--r--src/utility.js7
-rw-r--r--tests/cases/floatreturningfuncptr.ll18
-rw-r--r--tests/emscripten_api_browser_infloop.cpp12
-rwxr-xr-xtests/runner.py8
-rw-r--r--third_party/jni/emjvm.js333
-rw-r--r--tools/shared.py2
18 files changed, 254 insertions, 226 deletions
diff --git a/emcc b/emcc
index 488f0788..fc580d0f 100755
--- a/emcc
+++ b/emcc
@@ -993,6 +993,8 @@ try:
# Apply effects from settings
if shared.Settings.ASM_JS:
+ assert opt_level == 2, 'asm.js requires -O2'
+
if closure:
print >> sys.stderr, 'emcc: warning: disabling closure because it is not compatible with asm.js code generation'
closure = False
@@ -1228,7 +1230,8 @@ try:
shutil.move(temp_files[0], in_temp(target_basename + '.bc'))
final = in_temp(target_basename + '.bc')
else:
- final = input_files[0]
+ final = in_temp(input_files[0])
+ shutil.copyfile(input_files[0], final)
if DEBUG:
print >> sys.stderr, 'emcc: saving intermediate processing steps to %s' % shared.EMSCRIPTEN_TEMP_DIR
diff --git a/emscripten.py b/emscripten.py
index c9d8505d..1b62d977 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -161,6 +161,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
open(pre_file, 'w').write(pre_input)
out = jsrun.run_js(compiler, compiler_engine, [settings_file, pre_file, 'pre'] + libraries, stdout=subprocess.PIPE,
cwd=path_from_root('src'))
+ assert '//FORWARDED_DATA:' in out, 'Did not receive forwarded data in pre output - process failed?'
if jcache:
if DEBUG: print >> sys.stderr, ' saving pre to jcache'
jcache.set(shortkey, keys, out)
diff --git a/src/analyzer.js b/src/analyzer.js
index 92b7d8cf..b1991c3f 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -979,6 +979,9 @@ function analyzer(data, sidePass) {
if (variable.origin === 'alloca') {
variable.allocatedNum = item.allocatedNum;
}
+ if (variable.origin === 'call') {
+ variable.type = getReturnType(variable.type);
+ }
}
});
diff --git a/src/compiler.js b/src/compiler.js
index bb72c7dd..7cf43f09 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -178,7 +178,7 @@ assert(!(USE_TYPED_ARRAYS === 2 && QUANTUM_SIZE !== 4), 'For USE_TYPED_ARRAYS ==
if (ASM_JS) {
assert(!ALLOW_MEMORY_GROWTH, 'Cannot grow asm.js heap');
assert((TOTAL_MEMORY&(TOTAL_MEMORY-1)) == 0, 'asm.js heap must be power of 2');
- assert(DISABLE_EXCEPTION_CATCHING == 1, 'asm.js does not support C++ exceptions yet');
+ assert(DISABLE_EXCEPTION_CATCHING == 1, 'asm.js does not support C++ exceptions yet, you must compile with -s DISABLE_EXCEPTION_CATCHING=1');
}
assert(!(!NAMED_GLOBALS && BUILD_AS_SHARED_LIB)); // shared libraries must have named globals
diff --git a/src/jsifier.js b/src/jsifier.js
index 7db2ee70..c55072b4 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -495,10 +495,10 @@ function JSify(data, functionsOnly, givenFunctions) {
EXPORTED_FUNCTIONS[ident] = 1;
delete Functions.libraryFunctions[ident.substr(1)];
}
- } else {
- if (EXPORT_ALL || (ident in EXPORTED_FUNCTIONS)) {
- contentText += '\nModule["' + ident + '"] = ' + ident + ';';
- }
+ }
+ if ((!ASM_JS || phase == 'pre') &&
+ (EXPORT_ALL || (ident in EXPORTED_FUNCTIONS))) {
+ contentText += '\nModule["' + ident + '"] = ' + ident + ';';
}
return depsText + contentText;
}
@@ -515,7 +515,7 @@ function JSify(data, functionsOnly, givenFunctions) {
if (!(item.ident in DEAD_FUNCTIONS) && !UNRESOLVED_AS_DEAD) {
item.JS = 'var ' + item.ident + '; // stub for ' + item.ident;
if (ASM_JS) {
- throw 'Unresolved symbol: ' + item.ident + ', this must be corrected for asm.js validation to succeed. Consider adding it to DEAD_FUNCTIONS.';
+ error('Unresolved symbol: ' + item.ident + ', this must be corrected for asm.js validation to succeed. Consider adding it to DEAD_FUNCTIONS.');
} else if (WARN_ON_UNDEFINED_SYMBOLS) {
warn('Unresolved symbol: ' + item.ident);
}
@@ -1167,6 +1167,11 @@ function JSify(data, functionsOnly, givenFunctions) {
return ret + ';';
});
makeFuncLineActor('resume', function(item) {
+ if (item.ident == 0) {
+ // No exception to resume, so we can just bail.
+ // This is related to issue #917 and http://llvm.org/PR15518
+ return (EXCEPTION_DEBUG ? 'Module.print("no exception to resume")' : '') + ';';
+ }
// If there is no current exception, set this one as it (during a resume, the current exception can be wiped out)
var ptr = makeStructuralAccess(item.ident, 0);
return (EXCEPTION_DEBUG ? 'Module.print("Resuming exception");' : '') +
@@ -1566,6 +1571,8 @@ function JSify(data, functionsOnly, givenFunctions) {
}
}
+ if (abortExecution) throw 'Aborting compilation due to previous warnings';
+
if (phase == 'pre' || phase == 'funcs') {
PassManager.serialize();
return;
diff --git a/src/library.js b/src/library.js
index aebad63b..f8ea67ba 100644
--- a/src/library.js
+++ b/src/library.js
@@ -2061,24 +2061,19 @@ LibraryManager.library = {
// void _exit(int status);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html
-#if CATCH_EXIT_CODE
function ExitStatus() {
this.name = "ExitStatus";
this.message = "Program terminated with exit(" + status + ")";
this.status = status;
+ Module.print('Exit Status: ' + status);
};
ExitStatus.prototype = new Error();
ExitStatus.prototype.constructor = ExitStatus;
-#endif
exitRuntime();
ABORT = true;
-#if CATCH_EXIT_CODE
throw new ExitStatus();
-#else
- throw 'exit(' + status + ') called, at ' + new Error().stack;
-#endif
},
fork__deps: ['__setErrNo', '$ERRNO_CODES'],
fork: function() {
@@ -3717,6 +3712,11 @@ LibraryManager.library = {
__exit(status);
},
+ _ZSt9terminatev__deps: ['exit'],
+ _ZSt9terminatev: function() {
+ _exit(-1234);
+ },
+
atexit: function(func, arg) {
__ATEXIT__.unshift({ func: func, arg: arg });
},
diff --git a/src/library_browser.js b/src/library_browser.js
index e61f84b5..b1e4190b 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -637,7 +637,7 @@ mergeInto(LibraryManager.library, {
Browser.mainLoop.scheduler();
if (simulateInfiniteLoop) {
- throw 'emscripten_set_main_loop simulating infinite loop by throwing so we get right into the JS event loop';
+ throw 'SimulateInfiniteLoop';
}
},
diff --git a/src/library_glut.js b/src/library_glut.js
index bb4dfefa..49380367 100644
--- a/src/library_glut.js
+++ b/src/library_glut.js
@@ -433,7 +433,7 @@ var LibraryGLUT = {
glutMainLoop: function() {
_glutReshapeWindow(Module['canvas'].width, Module['canvas'].height);
_glutPostRedisplay();
- throw 'GLUT mainloop called, simulating infinite loop by throwing so we get right into the JS event loop';
+ throw 'SimulateInfiniteLoop';
},
};
diff --git a/src/library_openal.js b/src/library_openal.js
index 719d8cf8..df1d15db 100644
--- a/src/library_openal.js
+++ b/src/library_openal.js
@@ -57,7 +57,6 @@ var LibraryOpenAL = {
}
if (ctx) {
- ctx.listener.panningModel = "equalpower";
AL.contexts.push({ctx: ctx, err: 0, src: [], buf: []});
return AL.contexts.length;
} else {
@@ -73,6 +72,12 @@ var LibraryOpenAL = {
}
},
+ alcGetError__deps: ['alGetError'],
+ alcGetError: function(device) {
+ // We have only one audio device, so just return alGetError.
+ return _alGetError();
+ },
+
alDeleteSources: function(count, sources)
{
if (!AL.currentContext) {
@@ -97,14 +102,9 @@ var LibraryOpenAL = {
for (var i = 0; i < count; ++i) {
var gain = AL.currentContext.ctx.createGain();
var panner = AL.currentContext.ctx.createPanner();
- if (typeof(webkitAudioContext) == 'function') {
- gain.connect(panner);
- panner.connect(AL.currentContext.ctx.destination);
- } else {
- // Work around a Firefox bug (bug 849916)
- gain.connect(AL.currentContext.ctx.destination);
- }
- gain.gain.value = 1; // work around a Firefox bug (bug 850970)
+ panner.panningModel = "equalpower";
+ gain.connect(panner);
+ panner.connect(AL.currentContext.ctx.destination);
AL.currentContext.src.push({
loop: false,
buffer: null,
@@ -404,8 +404,7 @@ var LibraryOpenAL = {
src.buffer = AL.currentContext.src[source - 1].buffer;
src.connect(AL.currentContext.src[source - 1].gain);
src.start(0, offset);
- // Work around Firefox bug 851338
- AL.currentContext.src[source - 1].playTime = AL.currentContext.ctx.currentTime || 0;
+ AL.currentContext.src[source - 1].playTime = AL.currentContext.ctx.currentTime;
AL.currentContext.src[source - 1].paused = false;
AL.currentContext.src[source - 1]['src'] = src;
},
@@ -445,8 +444,7 @@ var LibraryOpenAL = {
if ("src" in AL.currentContext.src[source - 1] &&
!AL.currentContext.src[source - 1].paused) {
AL.currentContext.src[source - 1].paused = true;
- // Work around Firefox bug 851338
- AL.currentContext.src[source - 1].pausedTime = AL.currentContext.ctx.currentTime || 0;
+ AL.currentContext.src[source - 1].pausedTime = AL.currentContext.ctx.currentTime;
AL.currentContext.src[source - 1]["src"].stop(0);
delete AL.currentContext.src[source - 1].src;
}
@@ -572,10 +570,6 @@ var LibraryOpenAL = {
alcGetProcAddress: function(device, fname) {
return 0;
},
-
- alcGetError: function(device) {
- return 0;
- },
};
autoAddDeps(LibraryOpenAL, '$AL');
diff --git a/src/parseTools.js b/src/parseTools.js
index 9fddacbb..d0d3e89f 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -999,7 +999,7 @@ function getHeapOffset(offset, type, forceAsm) {
offset = '(' + offset + ')';
if (shifts != 0) {
if (CHECK_HEAP_ALIGN) {
- return '(CHECK_ALIGN_' + sz + '(' + offset + ')>>' + shifts + ')';
+ return '(CHECK_ALIGN_' + sz + '(' + offset + '|0)>>' + shifts + ')';
} else {
return '(' + offset + '>>' + shifts + ')';
}
diff --git a/src/postamble.js b/src/postamble.js
index 00205abc..dd4f4f37 100644
--- a/src/postamble.js
+++ b/src/postamble.js
@@ -23,18 +23,21 @@ Module.callMain = function callMain(args) {
var ret;
-#if CATCH_EXIT_CODE
var initialStackTop = STACKTOP;
try {
ret = Module['_main'](argc, argv, 0);
}
- catch(e) { if (e.name == "ExitStatus") return e.status; throw e; }
- finally {
+ catch(e) {
+ if (e.name == 'ExitStatus') {
+ return e.status;
+ } else if (e == 'SimulateInfiniteLoop') {
+ Module['noExitRuntime'] = true;
+ } else {
+ throw e;
+ }
+ } finally {
STACKTOP = initialStackTop;
}
-#else
- ret = Module['_main'](argc, argv, 0);
-#endif
#if BENCHMARK
Module.realPrint('main() took ' + (Date.now() - start) + ' milliseconds');
@@ -121,10 +124,7 @@ if (Module['noInitialRun']) {
}
if (shouldRunNow) {
- var ret = run();
-#if CATCH_EXIT_CODE
- Module.print('Exit Status: ' + ret);
-#endif
+ run();
}
// {{POST_RUN_ADDITIONS}}
diff --git a/src/settings.js b/src/settings.js
index 97963ac5..9ed87bd6 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -113,12 +113,6 @@ var INLINING_LIMIT = 0; // A limit on inlining. If 0, we will inline normally i
// we will prevent inlining of functions of this size or larger
// in closure. 50 is a reasonable setting if you do not want
// inlining
-var CATCH_EXIT_CODE = 0; // If set, causes exit() to throw an exception object which is caught
- // in a try..catch block and results in the exit status being
- // returned from run(). If zero (the default), the program is just
- // terminated with an error message, that is, the exception thrown
- // by exit() is not handled in any way (in particular, the stack
- // position will not be reset).
// Generated code debugging options
var SAFE_HEAP = 0; // Check each write to the heap, for example, this will give a clear
diff --git a/src/utility.js b/src/utility.js
index 19444675..b67e6c21 100644
--- a/src/utility.js
+++ b/src/utility.js
@@ -85,6 +85,13 @@ function warnOnce(a, msg) {
}
}
+var abortExecution = false;
+
+function error(msg) {
+ abortExecution = true;
+ printErr('Error: ' + msg);
+}
+
function dedup(items, ident) {
var seen = {};
if (ident) {
diff --git a/tests/cases/floatreturningfuncptr.ll b/tests/cases/floatreturningfuncptr.ll
new file mode 100644
index 00000000..e07e97b3
--- /dev/null
+++ b/tests/cases/floatreturningfuncptr.ll
@@ -0,0 +1,18 @@
+; ModuleID = 'tests/hello_world.bc'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
+target triple = "i386-pc-linux-gnu"
+
+@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*]
+
+; [#uses=0]
+define i32 @main() {
+entry:
+ %retval = alloca i32, align 4 ; [#uses=1 type=i32*]
+ store i32 0, i32* %retval
+ %call = call float (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32]
+ %call2 = call float (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0), float %call) ; [#uses=0 type=i32]
+ ret i32 1
+}
+
+; [#uses=1]
+declare float @printf(i8*, ...)
diff --git a/tests/emscripten_api_browser_infloop.cpp b/tests/emscripten_api_browser_infloop.cpp
index 0fd41922..1e9808da 100644
--- a/tests/emscripten_api_browser_infloop.cpp
+++ b/tests/emscripten_api_browser_infloop.cpp
@@ -8,17 +8,15 @@ struct Class {
int x;
Class() : x(0) {}
+ ~Class() { x = -9999; }
void print() {
- char buf[18];
- memset(buf, 0, 18); // clear stack. if we did not simulate infinite loop, this clears x and is a bug!
- x += buf[7];
-
printf("waka %d\n", x++);
- if (x == 7) {
+ if (x == 7 || x < 0) {
int result = x;
REPORT_RESULT();
+ emscripten_cancel_main_loop();
}
}
@@ -28,7 +26,9 @@ struct Class {
void start() {
instance = this;
- emscripten_set_main_loop(Class::callback, 3, 1); // important if we simulate an infinite loop here or not
+ // important if we simulate an infinite loop here or not. With an infinite loop, the
+ // destructor should *NOT* have been called
+ emscripten_set_main_loop(Class::callback, 3, 1);
}
};
diff --git a/tests/runner.py b/tests/runner.py
index 168567d2..f0b5445c 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -2716,7 +2716,6 @@ Exiting setjmp function, level: 0, prev_jmp: -1
if Settings.ASM_JS: return self.skip('uses report_stack without exporting')
Settings.INLINING_LIMIT = 50
- Settings.CATCH_EXIT_CODE = 1
src = r'''
#include <stdio.h>
@@ -2757,7 +2756,7 @@ Exiting setjmp function, level: 0, prev_jmp: -1
''')
self.emcc_args += ['--pre-js', 'pre.js']
- self.do_run(src, '''reported\npostRun\nok.\nExit Status: 1\n''')
+ self.do_run(src, '''reported\nExit Status: 1\npostRun\nok.\n''')
def test_class(self):
src = '''
@@ -8673,8 +8672,6 @@ def process(filename):
Settings.CORRECT_SIGNS = 0
def test_exit_status(self):
- Settings.CATCH_EXIT_CODE = 1
-
src = r'''
#include <stdio.h>
#include <stdlib.h>
@@ -8869,7 +8866,6 @@ class %s(T):
Settings.INCLUDE_FULL_LIBRARY = 0
Settings.BUILD_AS_SHARED_LIB = 0
Settings.RUNTIME_LINKED_LIBS = []
- Settings.CATCH_EXIT_CODE = 0
Settings.EMULATE_UNALIGNED_ACCESSES = int(Settings.USE_TYPED_ARRAYS == 2 and Building.LLVM_OPTS == 2)
Settings.DOUBLE_MODE = 1 if Settings.USE_TYPED_ARRAYS and Building.LLVM_OPTS == 0 else 0
Settings.PRECISE_I64_MATH = 0
@@ -10079,7 +10075,7 @@ f.close()
(1, 0, 3, 2), (1, 1, 3, 4)
]:
print asm, linkable, chunks, js_chunks
- output, err = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_libcxx.cpp'), '-O1', '-s', 'LINKABLE=%d' % linkable, '-s', 'ASM_JS=%d' % asm, '-s', 'UNRESOLVED_AS_DEAD=1'], stdout=PIPE, stderr=PIPE).communicate()
+ output, err = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_libcxx.cpp'), '-O1', '-s', 'LINKABLE=%d' % linkable, '-s', 'ASM_JS=%d' % asm, '-s', 'UNRESOLVED_AS_DEAD=1'] + (['-O2'] if asm else []), stdout=PIPE, stderr=PIPE).communicate()
ok = False
for c in range(chunks, chunks+2):
ok = ok or ('phase 2 working on %d chunks' % c in err)
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;
+ },
+});
diff --git a/tools/shared.py b/tools/shared.py
index 3d0f90b9..49b456f9 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -181,7 +181,7 @@ def check_node_version():
# we re-check sanity when the settings are changed)
# We also re-check sanity and clear the cache when the version changes
-EMSCRIPTEN_VERSION = '1.3.1'
+EMSCRIPTEN_VERSION = '1.3.2'
def check_sanity(force=False):
try: