aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-06-26 10:23:08 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-06-26 10:23:08 -0700
commit18a6854c28e0fcef76f31a5c552cc3a189213625 (patch)
treef4e97d5f10df57559bd7cc087cbf2d7af08115e1
parentc3ed656997ea4515d846debf45121af1bd174a51 (diff)
parent493d0dcf303d66726be5bb08c187f8183ee96a65 (diff)
Merge branch 'incoming'
-rwxr-xr-xemcc86
-rw-r--r--src/jsifier.js40
-rw-r--r--src/library_browser.js31
-rw-r--r--src/library_glut.js37
-rw-r--r--src/library_sdl.js24
-rw-r--r--src/modules.js3
-rw-r--r--src/relooper/Relooper.cpp10
-rw-r--r--src/relooper/test.txt108
-rw-r--r--src/relooper/test2.txt12
-rw-r--r--src/relooper/test3.txt34
-rw-r--r--src/relooper/test4.txt24
-rw-r--r--src/relooper/test5.txt46
-rw-r--r--src/relooper/test6.txt12
-rw-r--r--src/relooper/test_debug.txt12
-rw-r--r--src/relooper/test_fuzz1.txt40
-rw-r--r--src/relooper/test_fuzz2.txt10
-rw-r--r--src/relooper/test_fuzz3.txt2
-rw-r--r--src/relooper/test_fuzz4.txt16
-rw-r--r--src/relooper/test_fuzz5.txt82
-rw-r--r--src/relooper/test_fuzz6.txt186
-rw-r--r--src/relooper/test_inf.txt698
-rw-r--r--tests/cases/returnfp.ll23
-rwxr-xr-xtests/runner.py20
-rw-r--r--tests/sdl_audio_mix_channels.c59
-rw-r--r--tools/eliminator/asm-eliminator-test-output.js10076
-rw-r--r--tools/eliminator/asm-eliminator-test.js13537
-rw-r--r--tools/eliminator/eliminator-test-output.js11798
-rw-r--r--tools/eliminator/eliminator-test.js17258
-rw-r--r--tools/eliminator/safe-eliminator-test-output.js164
-rw-r--r--tools/eliminator/safe-eliminator-test.js198
-rw-r--r--tools/js-optimizer.js200
-rw-r--r--tools/js_optimizer.py33
-rw-r--r--tools/shared.py25
-rw-r--r--tools/test-js-optimizer-asm-last-output.js82
-rw-r--r--tools/test-js-optimizer-asm-last.js94
-rw-r--r--tools/test-js-optimizer-asm-pre-output.js978
-rw-r--r--tools/test-js-optimizer-asm-pre.js988
-rw-r--r--tools/test-js-optimizer-asm-regs-min-output.js50
-rw-r--r--tools/test-js-optimizer-asm-regs-min.js52
-rw-r--r--tools/test-js-optimizer-asm-regs-output.js180
-rw-r--r--tools/test-js-optimizer-asm-regs.js186
-rw-r--r--tools/test-js-optimizer-asm-relocate-output.js9
-rw-r--r--tools/test-js-optimizer-asm-relocate.js12
-rw-r--r--tools/test-js-optimizer-output.js482
-rw-r--r--tools/test-js-optimizer-regs-output.js426
-rw-r--r--tools/test-js-optimizer-regs.js436
-rw-r--r--tools/test-js-optimizer-t2-output.js176
-rw-r--r--tools/test-js-optimizer-t2.js176
-rw-r--r--tools/test-js-optimizer-t2c-output.js28
-rw-r--r--tools/test-js-optimizer-t2c.js30
-rw-r--r--tools/test-js-optimizer-t3-output.js90
-rw-r--r--tools/test-js-optimizer-t3.js90
-rw-r--r--tools/test-js-optimizer.js666
53 files changed, 30210 insertions, 29925 deletions
diff --git a/emcc b/emcc
index b8230e95..3bc35aa4 100755
--- a/emcc
+++ b/emcc
@@ -182,16 +182,31 @@ Options that are modified or new in %s include:
). Note that the path must be absolute, not
relative.
- -g Use debug info. Note that you need this during
- the last compilation phase from bitcode to
- JavaScript, or else we will remove it by
- default in -O1 and above.
- In -O0, line numbers wil be shown in the
- generated code. In -O1 and above, the optimizer
- removes those comments. This flag does however
- have the effect of disabling anything that
- causes name mangling or minification (closure
- or the registerize pass).
+ -g Use debug info. When compiling to bitcode,
+ this is the same as in clang and gcc, it
+ adds debug info to the object files. When
+ compiling from source to JS or bitcode to JS,
+ it is equivalent to -g3 (keep code as debuggable
+ as possible, except for discarding LLVM
+ debug info, so no C/C++ line numbers; use
+ -g4 to get line number debugging info in JS).
+
+ -g<level> When compiling from bitcode to JS, we can
+ keep the code debuggable to different
+ degrees. Each of these levels builds on the
+ previous:
+
+ -g0 Make no effort to keep code debuggable.
+ Will discard LLVM debug info. (default
+ in -O1+)
+ -g1 Preserve (do not minify) whitespace
+ -g2 Preserve function names
+ -g3 Preserve variable names
+ -g4 Preserve LLVM debug info (if -g was
+ used when compiling the C/C++ sources)
+ and show line number debug comments.
+ This is the highest level of debuggability.
+ (default in -O0)
--typed-arrays <mode> 0: No typed arrays
1: Parallel typed arrays
@@ -303,12 +318,7 @@ Options that are modified or new in %s include:
archive, which is given the same name as the
output HTML but with suffix .data.compress
- --minify <on> 0: Do not minify the generated JavaScript's
- whitespace (default in -O0, -O1, or if
- -g is used)
- 1: Minify the generated JavaScript's
- whitespace (default in -O2+, assuming
- -g is not used)
+ --minify 0 Identical to -g1
--split <size> Splits the resulting javascript file into pieces
to ease debugging. This option only works if
@@ -689,13 +699,13 @@ try:
newargs = sys.argv[1:]
opt_level = 0
+ debug_level = 0
llvm_opts = None
llvm_lto = None
closure = None
js_transform = None
pre_js = ''
post_js = ''
- minify_whitespace = None
split_js_file = None
preload_files = []
embed_files = []
@@ -703,8 +713,6 @@ try:
ignore_dynamic_linking = False
shell_path = shared.path_from_root('src', 'shell.html')
js_libraries = []
- keep_llvm_debug = False
- keep_js_debug = False
bind = False
jcache = False
save_bc = False
@@ -769,7 +777,7 @@ try:
newargs[i+1] = ''
elif newargs[i].startswith('--minify'):
check_bad_eq(newargs[i])
- minify_whitespace = int(newargs[i+1])
+ debug_level = max(1, debug_level)
newargs[i] = ''
newargs[i+1] = ''
elif newargs[i].startswith('--split'):
@@ -777,9 +785,14 @@ try:
split_js_file = int(newargs[i+1])
newargs[i] = ''
newargs[i+1] = ''
- elif newargs[i] == '-g':
- keep_llvm_debug = True
- keep_js_debug = True
+ elif newargs[i].startswith('-g'):
+ requested_level = newargs[i][2:] or '3'
+ try:
+ debug_level = int(requested_level)
+ assert 0 <= debug_level <= 4
+ except:
+ raise Exception('Invalid debug level: ' + newargs[i])
+ newargs[i] = '-g' # discard level for clang args
elif newargs[i] == '--bind':
bind = True
newargs[i] = ''
@@ -823,6 +836,7 @@ try:
DEBUG = 1
shared.set_logging()
logging.debug('invocation: ' + ' '.join(sys.argv))
+ shared.apply_configuration() # reset config to pick up change
newargs[i] = ''
elif newargs[i].startswith('--shell-file'):
check_bad_eq(newargs[i])
@@ -868,8 +882,7 @@ try:
if llvm_opts is None: llvm_opts = LLVM_OPT_LEVEL[opt_level]
if llvm_lto is None: llvm_lto = opt_level >= 3
- if opt_level <= 0: keep_llvm_debug = keep_js_debug = True # always keep debug in -O0
- if opt_level > 0: keep_llvm_debug = False # JS optimizer wipes out llvm debug info from being visible
+ if opt_level == 0: debug_level = 4
if closure is None and opt_level == 3: closure = True
if DEBUG: start_time = time.time() # done after parsing arguments, which might affect debug state
@@ -1019,15 +1032,12 @@ try:
logging.warning('ALIASING_FUNCTION_POINTERS is on, function pointer comparisons may be invalid across types')
if shared.Settings.CORRECT_SIGNS >= 2 or shared.Settings.CORRECT_OVERFLOWS >= 2 or shared.Settings.CORRECT_ROUNDINGS >= 2:
- keep_llvm_debug = True # must keep debug info to do line-by-line operations
+ debug_level = 4 # must keep debug info to do line-by-line operations
- if (keep_llvm_debug or keep_js_debug) and closure:
+ if debug_level > 0 and closure:
logging.warning('disabling closure because debug info was requested')
closure = False
- if minify_whitespace is None:
- minify_whitespace = opt_level >= 2 and not keep_js_debug
-
assert shared.LLVM_TARGET in shared.COMPILER_OPTS
if shared.LLVM_TARGET == 'i386-pc-linux-gnu':
shared.Settings.TARGET_X86 = 1
@@ -1054,7 +1064,7 @@ try:
output_file = in_temp(unsuffixed(uniquename(input_file)) + '.o')
temp_files.append(output_file)
args = newargs + ['-emit-llvm', '-c', input_file, '-o', output_file]
- logging.debug("running:" + call + ' '.join(args))
+ logging.debug("running:" + call + ' ' + ' '.join(args))
execute([call] + args) # let compiler frontend print directly, so colors are saved (PIPE kills that)
if not os.path.exists(output_file):
logging.error('compiler frontend failed to generate LLVM bitcode, halting')
@@ -1132,6 +1142,8 @@ try:
libcxx_symbols = read_symbols(shared.path_from_root('system', 'lib', 'libcxx', 'symbols'), exclude=libc_symbols)
libcxxabi_symbols = read_symbols(shared.path_from_root('system', 'lib', 'libcxxabi', 'symbols'), exclude=libc_symbols)
+ # XXX we should disable EMCC_DEBUG (and EMCC_OPTIMIZE_NORMALLY?) when building libs, just like in the relooper
+
def build_libc(lib_filename, files):
o_s = []
prev_cxx = os.environ.get('EMMAKEN_CXX')
@@ -1352,7 +1364,7 @@ try:
for haz in has: # remove symbols that are supplied by another of the inputs
if haz in need:
need.remove(haz)
- logging.debug('considering %s: we need %s and have %s' % (name, str(need), str(has)))
+ if shared.Settings.VERBOSE: logging.debug('considering %s: we need %s and have %s' % (name, str(need), str(has)))
if (force or len(need) > 0) and apply_(need):
# We need to build and link the library in
logging.debug('including %s' % name)
@@ -1396,7 +1408,7 @@ try:
# Optimize, if asked to
if not LEAVE_INPUTS_RAW:
- link_opts = [] if keep_llvm_debug else ['-strip-debug'] # remove LLVM debug info in -O1+, since the optimizer removes it anyhow
+ link_opts = [] if debug_level >= 4 else ['-strip-debug'] # remove LLVM debug if we are not asked for it
if llvm_opts > 0:
if not os.environ.get('EMCC_OPTIMIZE_NORMALLY'):
shared.Building.llvm_opt(in_temp(target_basename + '.bc'), llvm_opts)
@@ -1538,12 +1550,12 @@ try:
logging.debug('running post-closure post-opts')
js_optimizer_queue += ['simplifyExpressionsPost']
- if (not closure or shared.Settings.ASM_JS) and shared.Settings.RELOOP and not keep_js_debug:
- # do this if closure is not enabled (it gives similar speedups), and we do not need to keep debug info around
+ if (not closure or shared.Settings.ASM_JS) and shared.Settings.RELOOP and debug_level < 3:
js_optimizer_queue += ['registerize']
- if minify_whitespace:
- js_optimizer_queue += ['compress']
+ if opt_level > 0:
+ if debug_level < 2 and shared.Settings.ASM_JS: js_optimizer_queue = map(lambda p: p if p != 'registerize' else 'registerizeAndMinify', js_optimizer_queue)
+ if debug_level == 0: js_optimizer_queue += ['minifyWhitespace']
if closure and shared.Settings.ASM_JS:
js_optimizer_queue += ['closure']
diff --git a/src/jsifier.js b/src/jsifier.js
index e9bc9a79..ac6c259b 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -14,6 +14,8 @@ var asmLibraryFunctions = [];
var SETJMP_LABEL = -1;
+var INDENTATION = ' ';
+
// JSifier
function JSify(data, functionsOnly, givenFunctions) {
var mainPass = !functionsOnly;
@@ -591,13 +593,13 @@ function JSify(data, functionsOnly, givenFunctions) {
func.JS += 'function ' + func.ident + '(' + paramIdents.join(', ') + ') {\n';
if (PGO) {
- func.JS += ' PGOMonitor.called["' + func.ident + '"] = 1;\n';
+ func.JS += INDENTATION + 'PGOMonitor.called["' + func.ident + '"] = 1;\n';
}
if (ASM_JS) {
// spell out argument types
func.params.forEach(function(param) {
- func.JS += ' ' + param.ident + ' = ' + asmCoercion(param.ident, param.type) + ';\n';
+ func.JS += INDENTATION + param.ident + ' = ' + asmCoercion(param.ident, param.type) + ';\n';
});
// spell out local variables
@@ -611,7 +613,7 @@ function JSify(data, functionsOnly, givenFunctions) {
i += chunkSize;
}
for (i = 0; i < chunks.length; i++) {
- func.JS += ' var ' + chunks[i].map(function(v) {
+ func.JS += INDENTATION + 'var ' + chunks[i].map(function(v) {
var type = getImplementationType(v);
if (!isIllegalType(type) || v.ident.indexOf('$', 1) > 0) { // not illegal, or a broken up illegal
return v.ident + ' = ' + asmInitializer(type); //, func.variables[v.ident].impl);
@@ -627,7 +629,7 @@ function JSify(data, functionsOnly, givenFunctions) {
if (true) { // TODO: optimize away when not needed
if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */';
- func.JS += ' var label = 0;\n';
+ func.JS += INDENTATION + 'var label = 0;\n';
}
if (ASM_JS) {
@@ -636,12 +638,12 @@ function JSify(data, functionsOnly, givenFunctions) {
hasByVal = hasByVal || param.byVal;
});
if (hasByVal) {
- func.JS += ' var tempParam = 0;\n';
+ func.JS += INDENTATION + 'var tempParam = 0;\n';
}
}
// Prepare the stack, if we need one. If we have other stack allocations, force the stack to be set up.
- func.JS += ' ' + RuntimeGenerator.stackEnter(func.initialStack, func.otherStackAllocations) + ';\n';
+ func.JS += INDENTATION + RuntimeGenerator.stackEnter(func.initialStack, func.otherStackAllocations) + ';\n';
// Make copies of by-value params
// XXX It is not clear we actually need this. While without this we fail, it does look like
@@ -654,7 +656,7 @@ function JSify(data, functionsOnly, givenFunctions) {
if (param.byVal) {
var type = removePointing(param.type);
var typeInfo = Types.types[type];
- func.JS += ' ' + (ASM_JS ? '' : 'var ') + 'tempParam = ' + param.ident + '; ' + param.ident + ' = ' + RuntimeGenerator.stackAlloc(typeInfo.flatSize) + ';' +
+ func.JS += INDENTATION + (ASM_JS ? '' : 'var ') + 'tempParam = ' + param.ident + '; ' + param.ident + ' = ' + RuntimeGenerator.stackAlloc(typeInfo.flatSize) + ';' +
makeCopyValues(param.ident, 'tempParam', typeInfo.flatSize, 'null', null, param.byVal) + ';\n';
}
});
@@ -728,12 +730,12 @@ function JSify(data, functionsOnly, givenFunctions) {
}
ret += 'switch(' + asmCoercion('label', 'i32') + ') {\n';
ret += block.labels.map(function(label) {
- return indent + ' case ' + getLabelId(label.ident) + ': ' + (SHOW_LABELS ? '// ' + getOriginalLabelId(label.ident) : '') + '\n'
- + getLabelLines(label, indent + ' ');
+ return indent + INDENTATION + 'case ' + getLabelId(label.ident) + ': ' + (SHOW_LABELS ? '// ' + getOriginalLabelId(label.ident) : '') + '\n'
+ + getLabelLines(label, indent + INDENTATION + INDENTATION);
}).join('\n') + '\n';
if (func.setjmpTable && ASM_JS) {
// emit a label in which we write to the proper local variable, before jumping to the actual label
- ret += ' case ' + SETJMP_LABEL + ': ';
+ ret += INDENTATION + 'case ' + SETJMP_LABEL + ': ';
ret += func.setjmpTable.map(function(triple) { // original label, label we created for right after the setjmp, variable setjmp result goes into
return 'if ((setjmpLabel|0) == ' + getLabelId(triple.oldLabel) + ') { ' + triple.assignTo + ' = threwValue; label = ' + triple.newLabel + ' }\n';
}).join(' else ');
@@ -741,7 +743,7 @@ function JSify(data, functionsOnly, givenFunctions) {
ret += '__THREW__ = threwValue = 0;\n';
ret += 'break;\n';
}
- if (ASSERTIONS) ret += indent + ' default: assert(0' + (ASM_JS ? '' : ', "bad label: " + label') + ');\n';
+ if (ASSERTIONS) ret += indent + INDENTATION + 'default: assert(0' + (ASM_JS ? '' : ', "bad label: " + label') + ');\n';
ret += indent + '}\n';
if (func.setjmpTable && !ASM_JS) {
ret += ' } catch(e) { if (!e.longjmp || !(e.id in mySetjmpIds)) throw(e); setjmpTable[setjmpLabels[e.id]](e.value) }';
@@ -797,13 +799,13 @@ function JSify(data, functionsOnly, givenFunctions) {
}
return ret;
}
- func.JS += walkBlock(func.block, ' ');
+ func.JS += walkBlock(func.block, INDENTATION);
// Finalize function
if (LABEL_DEBUG && functionNameFilterTest(func.ident)) func.JS += " INDENT = INDENT.substr(0, INDENT.length-2);\n";
// Ensure a return in a function with a type that returns, even if it lacks a return (e.g., if it aborts())
if (RELOOP && func.lines.length > 0 && func.returnType != 'void') {
var returns = func.labels.filter(function(label) { return label.lines[label.lines.length-1].intertype == 'return' }).length;
- if (returns == 0) func.JS += ' return ' + asmCoercion('0', func.returnType);
+ if (returns == 0) func.JS += INDENTATION + 'return ' + asmCoercion('0', func.returnType);
}
func.JS += '}\n';
@@ -1121,7 +1123,7 @@ function JSify(data, functionsOnly, givenFunctions) {
ret += value + '{\n';
}
var phiSet = getPhiSetsForLabel(phiSets, targetLabel);
- ret += ' ' + phiSet + makeBranch(targetLabel, item.currLabelId || null) + '\n';
+ ret += INDENTATION + '' + phiSet + makeBranch(targetLabel, item.currLabelId || null) + '\n';
ret += '}\n';
if (RELOOP) {
item.groupedLabels.push({
@@ -1178,7 +1180,7 @@ function JSify(data, functionsOnly, givenFunctions) {
// in an assignment
var disabled = DISABLE_EXCEPTION_CATCHING == 2 && !(item.funcData.ident in EXCEPTION_CATCHING_WHITELIST);
var phiSets = calcPhiSets(item);
- var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type, ASM_JS && !disabled);
+ var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type, ASM_JS && !disabled, !!item.assignTo || !item.standalone);
var ret;
@@ -1335,7 +1337,7 @@ function JSify(data, functionsOnly, givenFunctions) {
return ret;
});
- function makeFunctionCall(ident, params, funcData, type, forceByPointer) {
+ function makeFunctionCall(ident, params, funcData, type, forceByPointer, hasReturn) {
// We cannot compile assembly. See comment in intertyper.js:'Call'
assert(ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!');
@@ -1463,8 +1465,8 @@ function JSify(data, functionsOnly, givenFunctions) {
}
}
- var returnType;
- if (byPointer || ASM_JS) {
+ var returnType = 'void';
+ if ((byPointer || ASM_JS) && hasReturn) {
returnType = getReturnType(type);
}
@@ -1509,7 +1511,7 @@ function JSify(data, functionsOnly, givenFunctions) {
makeFuncLineActor('getelementptr', function(item) { return finalizeLLVMFunctionCall(item) });
makeFuncLineActor('call', function(item) {
if (item.standalone && LibraryManager.isStubFunction(item.ident)) return ';';
- return makeFunctionCall(item.ident, item.params, item.funcData, item.type) + (item.standalone ? ';' : '');
+ return makeFunctionCall(item.ident, item.params, item.funcData, item.type, false, !!item.assignTo || !item.standalone) + (item.standalone ? ';' : '');
});
makeFuncLineActor('unreachable', function(item) {
diff --git a/src/library_browser.js b/src/library_browser.js
index 925b64e2..d007d9a7 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -426,8 +426,17 @@ mergeInto(LibraryManager.library, {
Browser.mouseMovementX = Browser.getMovementX(event);
Browser.mouseMovementY = Browser.getMovementY(event);
}
- Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
- Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
+
+ // check if SDL is available
+ if (typeof SDL != "undefined") {
+ Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
+ Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
+ } else {
+ // just add the mouse delta to the current absolut mouse position
+ // FIXME: ideally this should be clamped against the canvas size and zero
+ Browser.mouseX += Browser.mouseMovementX;
+ Browser.mouseY += Browser.mouseMovementY;
+ }
} else {
// Otherwise, calculate the movement based on the changes
// in the coordinates.
@@ -504,9 +513,12 @@ mergeInto(LibraryManager.library, {
this.windowedHeight = canvas.height;
canvas.width = screen.width;
canvas.height = screen.height;
- var flags = {{{ makeGetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'i32', 0, 1) }}};
- flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
- {{{ makeSetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'flags', 'i32') }}}
+ // check if SDL is available
+ if (typeof SDL != "undefined") {
+ var flags = {{{ makeGetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'i32', 0, 1) }}};
+ flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
+ {{{ makeSetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'flags', 'i32') }}}
+ }
Browser.updateResizeListeners();
},
@@ -514,9 +526,12 @@ mergeInto(LibraryManager.library, {
var canvas = Module['canvas'];
canvas.width = this.windowedWidth;
canvas.height = this.windowedHeight;
- var flags = {{{ makeGetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'i32', 0, 1) }}};
- flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
- {{{ makeSetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'flags', 'i32') }}}
+ // check if SDL is available
+ if (typeof SDL != "undefined") {
+ var flags = {{{ makeGetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'i32', 0, 1) }}};
+ flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
+ {{{ makeSetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'flags', 'i32') }}}
+ }
Browser.updateResizeListeners();
}
diff --git a/src/library_glut.js b/src/library_glut.js
index 38cfe55b..36d47787 100644
--- a/src/library_glut.js
+++ b/src/library_glut.js
@@ -117,9 +117,9 @@ var LibraryGLUT = {
if (48 <= keycode && keycode <= 57)
return keycode; // numeric TODO handle shift?
if (65 <= keycode && keycode <= 90)
- return event['shiftKey'] ? keycode : keycode + 32;
+ return event['shiftKey'] ? keycode : keycode + 32;
if (106 <= keycode && keycode <= 111)
- return keycode - 106 + 42; // *,+-./ TODO handle shift?
+ return keycode - 106 + 42; // *,+-./ TODO handle shift?
switch (keycode) {
case 27: // escape
@@ -227,7 +227,7 @@ var LibraryGLUT = {
} else {
width = GLUT.windowWidth;
height = GLUT.windowHeight;
- // TODO set position
+ // TODO set position
document.removeEventListener('fullscreenchange', GLUT.onFullScreenEventChange, true);
document.removeEventListener('mozfullscreenchange', GLUT.onFullScreenEventChange, true);
document.removeEventListener('webkitfullscreenchange', GLUT.onFullScreenEventChange, true);
@@ -255,13 +255,14 @@ var LibraryGLUT = {
document['cancelFullScreen'] ||
document['mozCancelFullScreen'] ||
document['webkitCancelFullScreen'] ||
- (function() {});
+ (function() {});
CFS.apply(document, []);
}
},
glutGetModifiers: function() { return GLUT.modifiers; },
+ glutInit__deps: ['$Browser'],
glutInit: function(argcp, argv) {
// Ignore arguments
GLUT.initTime = Date.now();
@@ -271,6 +272,12 @@ var LibraryGLUT = {
window.addEventListener("mousemove", GLUT.onMousemove, true);
window.addEventListener("mousedown", GLUT.onMouseButtonDown, true);
window.addEventListener("mouseup", GLUT.onMouseButtonUp, true);
+
+ Browser.resizeListeners.push(function(width, height) {
+ if (GLUT.reshapeFunc) {
+ Runtime.dynCall('vii', GLUT.reshapeFunc, [width, height]);
+ }
+ });
__ATEXIT__.push({ func: function() {
window.removeEventListener("keydown", GLUT.onKeydown, true);
@@ -294,21 +301,25 @@ var LibraryGLUT = {
glutGet: function(type) {
switch (type) {
case 100: /* GLUT_WINDOW_X */
- return 0; /* TODO */
+ return 0; /* TODO */
case 101: /* GLUT_WINDOW_Y */
- return 0; /* TODO */
+ return 0; /* TODO */
case 102: /* GLUT_WINDOW_WIDTH */
- return Module['canvas'].width;
+ return Module['canvas'].width;
case 103: /* GLUT_WINDOW_HEIGHT */
- return Module['canvas'].height;
+ return Module['canvas'].height;
+ case 200: /* GLUT_SCREEN_WIDTH */
+ return Module['canvas'].width;
+ case 201: /* GLUT_SCREEN_HEIGHT */
+ return Module['canvas'].height;
case 500: /* GLUT_INIT_WINDOW_X */
- return 0; /* TODO */
+ return 0; /* TODO */
case 501: /* GLUT_INIT_WINDOW_Y */
- return 0; /* TODO */
+ return 0; /* TODO */
case 502: /* GLUT_INIT_WINDOW_WIDTH */
- return GLUT.initWindowWidth;
+ return GLUT.initWindowWidth;
case 503: /* GLUT_INIT_WINDOW_HEIGHT */
- return GLUT.initWindowHeight;
+ return GLUT.initWindowHeight;
case 700: /* GLUT_ELAPSED_TIME */