aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-11-11 11:56:51 -0800
committerAlon Zakai <alonzakai@gmail.com>2013-11-11 11:56:51 -0800
commit117f357f9c08fd3297f5c34cdd0a43227079f059 (patch)
tree85f85b3785b2390a3681d497f8849be0447b80c0
parent0ea99d4659ec686115c70f0b7e67fa829739c1e0 (diff)
parent37d0e6c55f9f48255b5ac34426196ddf6d5072a2 (diff)
Merge branch 'incoming' into f32
-rw-r--r--src/intertyper.js3
-rw-r--r--src/library.js41
-rw-r--r--src/library_gl.js80
-rw-r--r--src/parseTools.js6
-rw-r--r--tests/lua/Makefile3
-rw-r--r--tests/lua/src/Makefile3
-rw-r--r--tests/test_core.py7
-rw-r--r--tools/response_file.py6
-rw-r--r--tools/shared.py21
9 files changed, 109 insertions, 61 deletions
diff --git a/src/intertyper.js b/src/intertyper.js
index fceeb38d..fa53c652 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -680,6 +680,9 @@ function intertyper(lines, sidePass, baseLineNums) {
args.push(ident);
});
}
+ item.ident = expandLLVMString(item.ident).replace(/(#[^\n]*)/g, function(m) {
+ return '/* ' + m.substr(1) + ' */'; // fix asm comments to js comments
+ });
if (item.assignTo) item.ident = 'return ' + item.ident;
item.ident = '(function(' + params + ') { ' + item.ident + ' })(' + args + ');';
return { ret: item, item: item };
diff --git a/src/library.js b/src/library.js
index 31f531e9..7a954662 100644
--- a/src/library.js
+++ b/src/library.js
@@ -847,10 +847,7 @@ LibraryManager.library = {
___setErrNo(ERRNO_CODES.ERANGE);
return 0;
} else {
- for (var i = 0; i < cwd.length; i++) {
- {{{ makeSetValue('buf', 'i', 'cwd.charCodeAt(i)', 'i8') }}}
- }
- {{{ makeSetValue('buf', 'i', '0', 'i8') }}}
+ writeAsciiToMemory(cwd, buf);
return buf;
}
},
@@ -1293,10 +1290,7 @@ LibraryManager.library = {
if (namesize < ret.length + 1) {
return ___setErrNo(ERRNO_CODES.ERANGE);
} else {
- for (var i = 0; i < ret.length; i++) {
- {{{ makeSetValue('name', 'i', 'ret.charCodeAt(i)', 'i8') }}}
- }
- {{{ makeSetValue('name', 'i', '0', 'i8') }}}
+ writeAsciiToMemory(ret, name);
return 0;
}
},
@@ -2699,10 +2693,7 @@ LibraryManager.library = {
var result = dir + '/' + name;
if (!_tmpnam.buffer) _tmpnam.buffer = _malloc(256);
if (!s) s = _tmpnam.buffer;
- for (var i = 0; i < result.length; i++) {
- {{{ makeSetValue('s', 'i', 'result.charCodeAt(i)', 'i8') }}};
- }
- {{{ makeSetValue('s', 'i', '0', 'i8') }}};
+ writeAsciiToMemory(result, s);
return s;
},
tempnam__deps: ['tmpnam'],
@@ -3343,10 +3334,7 @@ LibraryManager.library = {
var ptrSize = {{{ Runtime.getNativeTypeSize('i8*') }}};
for (var i = 0; i < strings.length; i++) {
var line = strings[i];
- for (var j = 0; j < line.length; j++) {
- {{{ makeSetValue('poolPtr', 'j', 'line.charCodeAt(j)', 'i8') }}};
- }
- {{{ makeSetValue('poolPtr', 'j', '0', 'i8') }}};
+ writeAsciiToMemory(line, poolPtr);
{{{ makeSetValue('envPtr', 'i * ptrSize', 'poolPtr', 'i8*') }}};
poolPtr += line.length + 1;
}
@@ -3976,10 +3964,7 @@ LibraryManager.library = {
return ___setErrNo(ERRNO_CODES.ERANGE);
} else {
var msg = ERRNO_MESSAGES[errnum];
- for (var i = 0; i < msg.length; i++) {
- {{{ makeSetValue('strerrbuf', 'i', 'msg.charCodeAt(i)', 'i8') }}}
- }
- {{{ makeSetValue('strerrbuf', 'i', 0, 'i8') }}}
+ writeAsciiToMemory(msg, strerrbuf);
return 0;
}
} else {
@@ -5067,10 +5052,7 @@ LibraryManager.library = {
var layout = {{{ JSON.stringify(C_STRUCTS.utsname) }}};
function copyString(element, value) {
var offset = layout[element];
- for (var i = 0; i < value.length; i++) {
- {{{ makeSetValue('name', 'offset + i', 'value.charCodeAt(i)', 'i8') }}}
- }
- {{{ makeSetValue('name', 'offset + i', '0', 'i8') }}}
+ writeAsciiToMemory(value, name + offset);
}
if (name === 0) {
return -1;
@@ -6131,8 +6113,10 @@ LibraryManager.library = {
// int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
var seconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_sec, 'i32') }}};
var nanoseconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_nsec, 'i32') }}};
- {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_sec, '0', 'i32') }}}
- {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_nsec, '0', 'i32') }}}
+ if (rmtp !== 0) {
+ {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_sec, '0', 'i32') }}}
+ {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_nsec, '0', 'i32') }}}
+ }
return _usleep((seconds * 1e6) + (nanoseconds / 1000));
},
// TODO: Implement these for real.
@@ -6572,10 +6556,7 @@ LibraryManager.library = {
var me = _nl_langinfo;
if (!me.ret) me.ret = _malloc(32);
- for (var i = 0; i < result.length; i++) {
- {{{ makeSetValue('me.ret', 'i', 'result.charCodeAt(i)', 'i8') }}}
- }
- {{{ makeSetValue('me.ret', 'i', '0', 'i8') }}}
+ writeAsciiToMemory(result, me.ret);
return me.ret;
},
diff --git a/src/library_gl.js b/src/library_gl.js
index ecb72f0f..4b6ea579 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -530,7 +530,11 @@ var LibraryGL = {
ret = allocate(intArrayFromString('OpenGL ES GLSL 1.00 (WebGL)'), 'i8', ALLOC_NORMAL);
break;
default:
- throw 'Failure: Invalid glGetString value: ' + name_;
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glGetString: Unknown parameter ' + name_ + '!');
+#endif
+ return 0;
}
GL.stringCache[name_] = ret;
return ret;
@@ -561,7 +565,11 @@ var LibraryGL = {
{{{ makeSetValue('p', '0', 'result ? 1 : 0', 'i8') }}};
break;
case "string":
- throw 'Native code calling glGetIntegerv(' + name_ + ') on a name which returns a string!';
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glGetIntegerv: Native code calling glGetIntegerv(' + name_ + ') on a name which returns a string!');
+#endif
+ return;
case "object":
if (result === null) {
{{{ makeSetValue('p', '0', '0', 'i32') }}};
@@ -583,13 +591,19 @@ var LibraryGL = {
} else if (result instanceof WebGLTexture) {
{{{ makeSetValue('p', '0', 'result.name | 0', 'i32') }}};
} else {
- throw 'Unknown object returned from WebGL getParameter';
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glGetIntegerv: Unknown object returned from WebGL getParameter(' + name_ + ')!');
+#endif
+ return;
}
break;
- case "undefined":
- throw 'Native code calling glGetIntegerv(' + name_ + ') and it returns undefined';
default:
- throw 'Why did we hit the default case?';
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glGetIntegerv: Native code calling glGetIntegerv(' + name_ + ') and it returns ' + result + ' of type ' + typeof(result) + '!');
+#endif
+ return;
}
},
@@ -607,7 +621,11 @@ var LibraryGL = {
{{{ makeSetValue('p', '0', '0', 'float') }}};
case "object":
if (result === null) {
- throw 'Native code calling glGetFloatv(' + name_ + ') and it returns null';
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glGetFloatv: Native code calling glGetFloatv(' + name_ + ') and it returns null!');
+#endif
+ return;
} else if (result instanceof Float32Array ||
result instanceof Uint32Array ||
result instanceof Int32Array ||
@@ -626,13 +644,19 @@ var LibraryGL = {
} else if (result instanceof WebGLTexture) {
{{{ makeSetValue('p', '0', 'result.name | 0', 'float') }}};
} else {
- throw 'Unknown object returned from WebGL getParameter';
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glGetFloatv: Native code calling glGetFloatv(' + name_ + ') and it returns ' + result + ' of type ' + typeof(result) + '!');
+#endif
+ return;
}
break;
- case "undefined":
- throw 'Native code calling glGetFloatv(' + name_ + ') and it returns undefined';
default:
- throw 'Why did we hit the default case?';
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glGetFloatv: Native code calling glGetFloatv(' + name_ + ') and it returns ' + result + ' of type ' + typeof(result) + '!');
+#endif
+ return;
}
},
@@ -647,7 +671,11 @@ var LibraryGL = {
{{{ makeSetValue('p', '0', 'result != 0', 'i8') }}};
break;
case "string":
- throw 'Native code calling glGetBooleanv(' + name_ + ') on a name which returns a string!';
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glGetBooleanv: Native code calling glGetBooleanv(' + name_ + ') on a name which returns a string!');
+#endif
+ return;
case "object":
if (result === null) {
{{{ makeSetValue('p', '0', '0', 'i8') }}};
@@ -665,13 +693,19 @@ var LibraryGL = {
result instanceof WebGLTexture) {
{{{ makeSetValue('p', '0', '1', 'i8') }}}; // non-zero ID is always 1!
} else {
- throw 'Unknown object returned from WebGL getParameter';
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glGetBooleanv: Unknown object returned from WebGL getParameter(' + name_ + ')!');
+#endif
+ return;
}
break;
- case "undefined":
- throw 'Unknown object returned from WebGL getParameter';
default:
- throw 'Why did we hit the default case?';
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glGetBooleanv: Native code calling glGetBooleanv(' + name_ + ') and it returns ' + result + ' of type ' + typeof(result) + '!');
+#endif
+ return;
}
},
@@ -759,7 +793,12 @@ var LibraryGL = {
case 0x1908 /* GL_RGBA */:
sizePerPixel = 4;
break;
- default: throw 'unsupported glReadPixels format';
+ default:
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glReadPixels: Unsupported format ' + format + '!');
+#endif
+ return;
}
var totalSize = width*height*sizePerPixel;
Module.ctx.readPixels(x, y, width, height, format, type, HEAPU8.subarray(pixels, pixels + totalSize));
@@ -2191,7 +2230,12 @@ var LibraryGL = {
attribute = GLImmediate.clientAttributes[GLImmediate.COLOR]; break;
case 0x8092: // GL_TEXTURE_COORD_ARRAY_POINTER
attribute = GLImmediate.clientAttributes[GLImmediate.TEXTURE0 + GLImmediate.clientActiveTexture]; break;
- default: throw 'TODO: glGetPointerv for ' + name;
+ default:
+ GL.recordError(0x0500/*GL_INVALID_ENUM*/);
+#if GL_ASSERTIONS
+ Module.printErr('GL_INVALID_ENUM in glGetPointerv: Unsupported name ' + name + '!');
+#endif
+ return;
}
{{{ makeSetValue('p', '0', 'attribute ? attribute.pointer : 0', 'i32') }}};
},
diff --git a/src/parseTools.js b/src/parseTools.js
index e806c861..3c2eeece 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -983,6 +983,12 @@ function parseLLVMString(str) {
return ret;
}
+function expandLLVMString(str) {
+ return str.replace(/\\../g, function(m) {
+ return String.fromCharCode(parseInt(m.substr(1), '16'));
+ });
+}
+
function getLabelIds(labels) {
return labels.map(function(label) { return label.ident });
}
diff --git a/tests/lua/Makefile b/tests/lua/Makefile
index bd9515fd..9f0a2edd 100644
--- a/tests/lua/Makefile
+++ b/tests/lua/Makefile
@@ -51,8 +51,9 @@ R= $V.1
# Targets start here.
all: $(PLAT)
+# XXX Emscripten Added quotes to $(MAKE) to properly call make when the path contains spaces
$(PLATS) clean:
- cd src && $(MAKE) $@
+ cd src && "$(MAKE)" $@
test: dummy
src/lua -v
diff --git a/tests/lua/src/Makefile b/tests/lua/src/Makefile
index 401e7367..a9cf0911 100644
--- a/tests/lua/src/Makefile
+++ b/tests/lua/src/Makefile
@@ -59,8 +59,9 @@ o: $(ALL_O)
a: $(ALL_A)
+# XXX EMSCRIPTEN: add AR_ARGS
$(LUA_A): $(BASE_O)
- $(AR) $(AR_ARGS) $@ $(BASE_O) # XXX EMSCRIPTEN: add AR_ARGS
+ $(AR) $(AR_ARGS) $@ $(BASE_O)
$(RANLIB) $@
$(LUA_T): $(LUA_O) $(LUA_A)
diff --git a/tests/test_core.py b/tests/test_core.py
index 30b9c70f..37179ff1 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -3851,6 +3851,10 @@ def process(filename):
double get() {
double ret = 0;
__asm __volatile__("Math.abs(-12/3.3)":"=r"(ret)); // write to a variable
+ asm("#comment1");
+ asm volatile("#comment2");
+ asm volatile("#comment3\n"
+ "#comment4\n");
return ret;
}
@@ -3869,6 +3873,9 @@ def process(filename):
'''
self.do_run(src, 'Inline JS is very cool\n3.64\n') # TODO 1\n2\n3\n1\n2\n3\n')
+ if self.emcc_args == []: # opts will eliminate the comments
+ out = open('src.cpp.o.js').read()
+ for i in range(1, 5): assert ('comment%d' % i) in out
def test_inlinejs2(self):
if not self.is_le32(): return self.skip('le32 needed for inline js')
diff --git a/tools/response_file.py b/tools/response_file.py
index f19cf8af..7f916752 100644
--- a/tools/response_file.py
+++ b/tools/response_file.py
@@ -1,4 +1,5 @@
import tempfile, os, sys, shlex
+import shared
# Routes the given cmdline param list in args into a new response file and returns the filename to it.
# The returned filename has a suffix '.rsp'.
@@ -9,6 +10,11 @@ def create_response_file(args, directory):
args = map(lambda p: p.replace('\\', '\\\\').replace('"', '\\"'), args)
response_fd.write('"' + '" "'.join(args) + '"')
response_fd.close()
+
+ # Register the created .rsp file to be automatically cleaned up once this process finishes, so that
+ # caller does not have to remember to do it.
+ shared.configuration.get_temp_files().note(response_filename)
+
return response_filename
# Reads a response file, and returns the list of cmdline params found in the file.
diff --git a/tools/shared.py b/tools/shared.py
index edbe8701..a2654bef 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -3,7 +3,7 @@ from subprocess import Popen, PIPE, STDOUT
from tempfile import mkstemp
from distutils.spawn import find_executable
import jsrun, cache, tempfiles
-from response_file import create_response_file
+import response_file
import logging, platform
def listify(x):
@@ -41,8 +41,8 @@ class WindowsPopen:
# emscripten.py supports reading args from a response file instead of cmdline.
# Use .rsp to avoid cmdline length limitations on Windows.
if len(args) >= 2 and args[1].endswith("emscripten.py"):
- self.response_filename = create_response_file(args[2:], TEMP_DIR)
- args = args[0:2] + ['@' + self.response_filename]
+ response_filename = response_file.create_response_file(args[2:], TEMP_DIR)
+ args = args[0:2] + ['@' + response_filename]
try:
# Call the process with fixed streams.
@@ -78,13 +78,6 @@ class WindowsPopen:
def kill(self):
return self.process.kill()
- def __del__(self):
- try:
- # Clean up the temporary response file that was used to spawn this process, so that we don't leave temp files around.
- tempfiles.try_delete(self.response_filename)
- except:
- pass # Mute all exceptions in dtor, particularly if we didn't use a response file, self.response_filename doesn't exist.
-
__rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
def path_from_root(*pathelems):
return os.path.join(__rootpath__, *pathelems)
@@ -1214,7 +1207,13 @@ class Building:
# Run Emscripten
Settings.RELOOPER = Cache.get_path('relooper.js')
settings = Settings.serialize()
- compiler_output = jsrun.timeout_run(Popen([PYTHON, EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + settings + extra_args, stdout=PIPE), None, 'Compiling')
+ args = settings + extra_args
+ if WINDOWS:
+ args = ['@' + response_file.create_response_file(args, TEMP_DIR)]
+ cmdline = [PYTHON, EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + args
+ if jsrun.TRACK_PROCESS_SPAWNS:
+ logging.info('Executing emscripten.py compiler with cmdline "' + ' '.join(cmdline) + '"')
+ compiler_output = jsrun.timeout_run(Popen(cmdline, stdout=PIPE), None, 'Compiling')
#print compiler_output
# Detect compilation crashes and errors