aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc10
-rw-r--r--src/compiler.js3
-rw-r--r--src/library_sdl.js40
-rw-r--r--src/preamble.js6
-rw-r--r--src/shell.html32
-rw-r--r--src/shell.js3
-rw-r--r--tests/hello_world.js3
-rw-r--r--tests/hello_world_sdl.cpp29
-rw-r--r--tests/runner.py14
9 files changed, 113 insertions, 27 deletions
diff --git a/emcc b/emcc
index 6a498c1f..6e2f95d2 100755
--- a/emcc
+++ b/emcc
@@ -290,8 +290,14 @@ elif use_compiler:
shared.Building.emscripten(target_basename + '.bc', append_ext=False)
shutil.move(target_basename + '.bc.o.js', target_basename + '.js')
- ## TODO: If we were asked to also generate HTML, do that
- #if final_suffix == 'html':
+ # If we were asked to also generate HTML, do that
+ if final_suffix == 'html':
+ shell = open(shared.path_from_root('src', 'shell.html')).read()
+ html = open(target_basename + '.html', 'w')
+ html.write(shell.replace('{{{ SCRIPT_CODE }}}', open(target_basename + '.js').read()))
+ html.close()
+ temp_files.note(target_basename + '.js')
+
finally:
temp_files.clean()
diff --git a/src/compiler.js b/src/compiler.js
index 94085c3f..2015a09d 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -54,6 +54,9 @@ if (ENVIRONMENT_IS_NODE) {
printErr = function(x) {
console.log(x);
};
+ if (typeof print === 'undefined') {
+ print = printErr;
+ }
read = function(url) {
var xhr = new XMLHttpRequest();
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 45b0bb53..806ed0ec 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -22,8 +22,12 @@
// noInitialRun: true
// };
//
-// which is defined BEFORE you load the compiled code. Here
-// is a full example:
+// which is defined BEFORE you load the compiled code.
+
+// The test_emcc test in the tests/runner.py will test this
+// in its last phase, where it generates HTML. You can see
+// a concrete example there. The HTML source is in src/shell.html.
+// Here is a more comprehensive example:
/*
<html>
@@ -141,19 +145,19 @@ mergeInto(LibraryManager.library, {
},
makeSurface: function(width, height, flags) {
- var surf = _malloc(14*QUANTUM_SIZE); // SDL_Surface has 14 fields of quantum size
+ var surf = _malloc(14*Runtime.QUANTUM_SIZE); // SDL_Surface has 14 fields of quantum size
var buffer = _malloc(width*height*4);
- var pixelFormat = _malloc(18*QUANTUM_SIZE);
+ var pixelFormat = _malloc(18*Runtime.QUANTUM_SIZE);
flags |= 1; // SDL_HWSURFACE - this tells SDL_MUSTLOCK that this needs to be locked
- {{{ makeSetValue('surf+QUANTUM_SIZE*0', '0', 'flags', 'i32') }}} // SDL_Surface.flags
- {{{ makeSetValue('surf+QUANTUM_SIZE*1', '0', 'pixelFormat', 'void*') }}} // SDL_Surface.format TODO
- {{{ makeSetValue('surf+QUANTUM_SIZE*2', '0', 'width', 'i32') }}} // SDL_Surface.w
- {{{ makeSetValue('surf+QUANTUM_SIZE*3', '0', 'height', 'i32') }}} // SDL_Surface.h
- {{{ makeSetValue('surf+QUANTUM_SIZE*4', '0', 'width*4', 'i16') }}} // SDL_Surface.pitch, assuming RGBA for now,
+ {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*0', '0', 'flags', 'i32') }}} // SDL_Surface.flags
+ {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*1', '0', 'pixelFormat', 'void*') }}} // SDL_Surface.format TODO
+ {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*2', '0', 'width', 'i32') }}} // SDL_Surface.w
+ {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*3', '0', 'height', 'i32') }}} // SDL_Surface.h
+ {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*4', '0', 'width*4', 'i16') }}} // SDL_Surface.pitch, assuming RGBA for now,
// since that is what ImageData gives us in browsers
- {{{ makeSetValue('surf+QUANTUM_SIZE*5', '0', 'buffer', 'void*') }}} // SDL_Surface.pixels
- {{{ makeSetValue('surf+QUANTUM_SIZE*6', '0', '0', 'i32*') }}} // SDL_Surface.offset
+ {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*5', '0', 'buffer', 'void*') }}} // SDL_Surface.pixels
+ {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*6', '0', '0', 'i32*') }}} // SDL_Surface.offset
{{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.palette', '0', '0', 'i32') }}} // TODO
{{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.BitsPerPixel', '0', '32', 'i8') }}} // TODO
@@ -239,12 +243,12 @@ mergeInto(LibraryManager.library, {
SDL_GetVideoInfo: function() {
// %struct.SDL_VideoInfo = type { i32, i32, %struct.SDL_PixelFormat*, i32, i32 } - 5 fields of quantum size
- var ret = _malloc(5*QUANTUM_SIZE);
- {{{ makeSetValue('ret+QUANTUM_SIZE*0', '0', '0', 'i32') }}} // TODO
- {{{ makeSetValue('ret+QUANTUM_SIZE*1', '0', '0', 'i32') }}} // TODO
- {{{ makeSetValue('ret+QUANTUM_SIZE*2', '0', '0', 'void*') }}}
- {{{ makeSetValue('ret+QUANTUM_SIZE*3', '0', 'SDL.defaults.width', 'i32') }}}
- {{{ makeSetValue('ret+QUANTUM_SIZE*4', '0', 'SDL.defaults.height', 'i32') }}}
+ var ret = _malloc(5*Runtime.QUANTUM_SIZE);
+ {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*0', '0', '0', 'i32') }}} // TODO
+ {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*1', '0', '0', 'i32') }}} // TODO
+ {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*2', '0', '0', 'void*') }}}
+ {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*3', '0', 'SDL.defaults.width', 'i32') }}}
+ {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*4', '0', 'SDL.defaults.height', 'i32') }}}
return ret;
},
@@ -298,7 +302,7 @@ mergeInto(LibraryManager.library, {
// SDL_Surface has the following fields: Uint32 flags, SDL_PixelFormat *format; int w, h; Uint16 pitch; void *pixels; ...
// So we have fields all of the same size, and 5 of them before us.
// TODO: Use macros like in library.js
- {{{ makeSetValue('surf', '5*QUANTUM_SIZE', 'surfData.buffer', 'void*') }}};
+ {{{ makeSetValue('surf', '5*Runtime.QUANTUM_SIZE', 'surfData.buffer', 'void*') }}};
},
SDL_UnlockSurface: function(surf) {
diff --git a/src/preamble.js b/src/preamble.js
index 1e9e1f11..cd9138d4 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -690,12 +690,6 @@ Module['String_copy'] = String_copy;
// Tools
-if (typeof console === 'object' && typeof console.log === 'function') {
- this['print'] = function(x) { console.log(x) }; // web console
-} else if (typeof print === 'undefined') {
- this['print'] = function(){}; // harmless no-op
-}
-
// This processes a JS string into a C-line array of numbers, 0-terminated.
// For LLVM-originating strings, see parser.js:parseLLVMString function
function intArrayFromString(stringy, dontAddNull) {
diff --git a/src/shell.html b/src/shell.html
new file mode 100644
index 00000000..284bc8d6
--- /dev/null
+++ b/src/shell.html
@@ -0,0 +1,32 @@
+<html>
+ <head>
+ <title>Emscripten-Generated Code</title>
+ <body>
+ <center>
+ <canvas id='canvas' width='256' height='256'></canvas>
+ </center>
+ <hr>
+ <div id='output'></div>
+ <hr>
+ <script type='text/javascript'>
+ // implement print
+ var print = (function() {
+ var element = document.getElementById('output');
+ return function(text) {
+ element.innerHTML += text.replace('\n', '<br>', 'g') + '<br>';
+ };
+ })();
+
+ // connect to canvas
+ var Module = {
+ canvas: document.getElementById('canvas'),
+ ctx2D: document.getElementById('canvas').getContext('2d')
+ };
+ if (!Module.ctx2D) alert('Canvas not available :(');
+
+ // The compiled code
+ {{{ SCRIPT_CODE }}}
+ </script>
+ </body>
+</html>
+
diff --git a/src/shell.js b/src/shell.js
index d52cd77d..038fde02 100644
--- a/src/shell.js
+++ b/src/shell.js
@@ -46,6 +46,9 @@ if (ENVIRONMENT_IS_NODE) {
printErr = function(x) {
console.log(x);
};
+ if (typeof print === 'undefined') {
+ print = printErr;
+ }
read = function(url) {
var xhr = new XMLHttpRequest();
diff --git a/tests/hello_world.js b/tests/hello_world.js
index 3fd19d53..530f5d4c 100644
--- a/tests/hello_world.js
+++ b/tests/hello_world.js
@@ -43,6 +43,9 @@ if (ENVIRONMENT_IS_NODE) {
printErr = function(x) {
console.log(x);
};
+ if (typeof print === 'undefined') {
+ print = printErr;
+ }
read = function(url) {
var xhr = new XMLHttpRequest();
diff --git a/tests/hello_world_sdl.cpp b/tests/hello_world_sdl.cpp
new file mode 100644
index 00000000..a317c0c5
--- /dev/null
+++ b/tests/hello_world_sdl.cpp
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <SDL/SDL.h>
+
+
+int main() {
+ printf("hello, world!\n");
+
+ SDL_Init(SDL_INIT_VIDEO);
+ SDL_Surface *screen = SDL_SetVideoMode(256, 256, 32, SDL_SWSURFACE);
+
+ SDL_LockSurface(screen);
+ for (int i = 0; i < 256; i++) {
+ for (int j = 0; j < 256; j++) {
+ *((char*)screen->pixels + i*256*4 + j*4 + 0) = i;
+ *((char*)screen->pixels + i*256*4 + j*4 + 1) = j;
+ *((char*)screen->pixels + i*256*4 + j*4 + 2) = 255-i;
+ *((char*)screen->pixels + i*256*4 + j*4 + 3) = 255;
+ }
+ }
+ SDL_UnlockSurface(screen);
+ SDL_Flip(screen);
+
+ printf("you should see a colored cube.");
+
+ // SDL_Quit(); // Don't call SDL_Quit so that the canvas is not cleared
+
+ return 0;
+}
+
diff --git a/tests/runner.py b/tests/runner.py
index e8564585..ef99a7b1 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -12,7 +12,7 @@ will use 4 processes. To install nose do something like
'''
from subprocess import Popen, PIPE, STDOUT
-import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, tempfile, re, difflib
+import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, tempfile, re, difflib, webbrowser
# Setup
@@ -4963,6 +4963,18 @@ JavaScript in the final linking stage of building.
# TODO: when ready, switch tools/shared building to use emcc over emmaken
# TODO: add shebang to generated .js files, using JS_ENGINES[0]? #!/usr/bin/python etc
+ # Finally, test HTML generation. (Coincidentally we also test that compiling a .cpp works in EMCC here.)
+ clear()
+ output = Popen([EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.html'], stdout=PIPE, stderr=PIPE).communicate(input)
+ assert len(output[0]) == 0, output[0]
+ assert os.path.exists('something.html'), output
+ webbrowser.open_new(os.path.join(self.get_dir(), 'something.html'))
+ print 'A web browser window should have opened a page containing the results of a part of this test.'
+ print 'You need to manually look at the page to see that it works ok: You should see "hello, world!" and a colored cube.'
+ print '(sleeping for a bit to keep the directory alive for the web browser..)'
+ time.sleep(5)
+ print '(moving on..)'
+
def test_eliminator(self):
input = open(path_from_root('tools', 'eliminator', 'eliminator-test.js')).read()
expected = open(path_from_root('tools', 'eliminator', 'eliminator-test-output.js')).read()