aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/library_browser.js7
-rw-r--r--src/library_fs.js12
-rw-r--r--src/library_memfs.js51
-rw-r--r--src/settings.js19
-rw-r--r--src/shell.html2
5 files changed, 74 insertions, 17 deletions
diff --git a/src/library_browser.js b/src/library_browser.js
index 558c9a59..591a3c11 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -821,6 +821,13 @@ mergeInto(LibraryManager.library, {
emscripten_set_canvas_size: function(width, height) {
Browser.setCanvasSize(width, height);
},
+
+ emscripten_get_canvas_size: function(width, height, isFullscreen) {
+ var canvas = Module['canvas'];
+ {{{ makeSetValue('width', '0', 'canvas.width', 'i32') }}};
+ {{{ makeSetValue('height', '0', 'canvas.height', 'i32') }}};
+ {{{ makeSetValue('isFullscreen', '0', 'Browser.isFullScreen ? 1 : 0', 'i32') }}};
+ },
emscripten_get_now: function() {
if (ENVIRONMENT_IS_NODE) {
diff --git a/src/library_fs.js b/src/library_fs.js
index 9d1f0cfd..e1397356 100644
--- a/src/library_fs.js
+++ b/src/library_fs.js
@@ -509,7 +509,7 @@ mergeInto(LibraryManager.library, {
var mode = FS.getMode(canRead, canWrite);
return FS.create(path, mode);
},
- createDataFile: function(parent, name, data, canRead, canWrite) {
+ createDataFile: function(parent, name, data, canRead, canWrite, canOwn) {
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name);
var mode = FS.getMode(canRead, canWrite);
var node = FS.create(path, mode);
@@ -522,7 +522,7 @@ mergeInto(LibraryManager.library, {
// make sure we can write to the file
FS.chmod(path, mode | {{{ cDefine('S_IWUGO') }}});
var stream = FS.open(path, 'w');
- FS.write(stream, data, 0, data.length, 0);
+ FS.write(stream, data, 0, data.length, 0, canOwn);
FS.close(stream);
FS.chmod(path, mode);
}
@@ -766,7 +766,7 @@ mergeInto(LibraryManager.library, {
// You can also call this with a typed array instead of a url. It will then
// do preloading for the Image/Audio part, as if the typed array were the
// result of an XHR that you did manually.
- createPreloadedFile: function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile) {
+ createPreloadedFile: function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
Browser.init();
// TODO we should allow people to just pass in a complete filename instead
// of parent and name being that we just join them anyways
@@ -774,7 +774,7 @@ mergeInto(LibraryManager.library, {
function processData(byteArray) {
function finish(byteArray) {
if (!dontCreateFile) {
- FS.createDataFile(parent, name, byteArray, canRead, canWrite);
+ FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
}
if (onload) onload();
removeRunDependency('cp ' + fullname);
@@ -1323,7 +1323,7 @@ mergeInto(LibraryManager.library, {
if (!seeking) stream.position += bytesRead;
return bytesRead;
},
- write: function(stream, buffer, offset, length, position) {
+ write: function(stream, buffer, offset, length, position, canOwn) {
if (length < 0 || position < 0) {
throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
}
@@ -1347,7 +1347,7 @@ mergeInto(LibraryManager.library, {
// seek to the end before writing in append mode
FS.llseek(stream, 0, {{{ cDefine('SEEK_END') }}});
}
- var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position);
+ var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
if (!seeking) stream.position += bytesWritten;
return bytesWritten;
},
diff --git a/src/library_memfs.js b/src/library_memfs.js
index 0fa6cdfb..63326c42 100644
--- a/src/library_memfs.js
+++ b/src/library_memfs.js
@@ -1,6 +1,22 @@
mergeInto(LibraryManager.library, {
$MEMFS__deps: ['$FS'],
$MEMFS: {
+ // content modes
+ CONTENT_OWNING: 1, // contains a subarray into the heap, and we own it - need to free() when no longer needed
+ CONTENT_FLEXIBLE: 2, // has been modified or never set to anything, and is a flexible js array that can grow/shrink
+ CONTENT_FIXED: 3, // contains some fixed-size content written into it, in a typed array
+ ensureFlexible: function(node) {
+ if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+ var contents = node.contents;
+ node.contents = Array.prototype.slice.call(contents);
+ if (node.contentMode === MEMFS.CONTENT_OWNING) {
+ assert(contents.byteOffset);
+ Module['_free'](contents.byteOffset);
+ }
+ node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+ }
+ },
+
mount: function(mount) {
return MEMFS.create_node(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0);
},
@@ -40,6 +56,7 @@ mergeInto(LibraryManager.library, {
mmap: MEMFS.stream_ops.mmap
};
node.contents = [];
+ node.contentMode = MEMFS.CONTENT_FLEXIBLE;
} else if (FS.isLink(node.mode)) {
node.node_ops = {
getattr: MEMFS.node_ops.getattr,
@@ -98,6 +115,7 @@ mergeInto(LibraryManager.library, {
node.timestamp = attr.timestamp;
}
if (attr.size !== undefined) {
+ MEMFS.ensureFlexible(node);
var contents = node.contents;
if (attr.size < contents.length) contents.length = attr.size;
else while (attr.size > contents.length) contents.push(0);
@@ -165,7 +183,7 @@ mergeInto(LibraryManager.library, {
var contents = stream.node.contents;
var size = Math.min(contents.length - position, length);
#if USE_TYPED_ARRAYS == 2
- if (contents.subarray) { // typed array
+ if (size > 8 && contents.subarray) { // non-trivial, and typed array
buffer.set(contents.subarray(position, position + size), offset);
} else
#endif
@@ -176,13 +194,30 @@ mergeInto(LibraryManager.library, {
}
return size;
},
- write: function(stream, buffer, offset, length, position) {
- var contents = stream.node.contents;
+ write: function(stream, buffer, offset, length, position, canOwn) {
+ var node = stream.node;
+ node.timestamp = Date.now();
+ var contents = node.contents;
+#if USE_TYPED_ARRAYS == 2
+ if (length && contents.length === 0 && position === 0 && buffer.subarray) {
+ // just replace it with the new data
+ assert(buffer.length);
+ if (canOwn && buffer.buffer === HEAP8.buffer && offset === 0) {
+ node.contents = buffer; // this is a subarray of the heap, and we can own it
+ node.contentMode = MEMFS.CONTENT_OWNING;
+ } else {
+ node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
+ node.contentMode = MEMFS.CONTENT_FIXED;
+ }
+ return length;
+ }
+#endif
+ MEMFS.ensureFlexible(node);
+ var contents = node.contents;
while (contents.length < position) contents.push(0);
for (var i = 0; i < length; i++) {
contents[position + i] = buffer[offset + i];
}
- stream.node.timestamp = Date.now();
return length;
},
llseek: function(stream, offset, whence) {
@@ -202,6 +237,7 @@ mergeInto(LibraryManager.library, {
return position;
},
allocate: function(stream, offset, length) {
+ MEMFS.ensureFlexible(stream.node);
var contents = stream.node.contents;
var limit = offset + length;
while (limit > contents.length) contents.push(0);
@@ -214,10 +250,10 @@ mergeInto(LibraryManager.library, {
var allocated;
var contents = stream.node.contents;
// Only make a new copy when MAP_PRIVATE is specified.
- if (!(flags & {{{ cDefine('MAP_PRIVATE') }}})) {
+ if ( !(flags & {{{ cDefine('MAP_PRIVATE') }}}) &&
+ (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
// We can't emulate MAP_SHARED when the file is not backed by the buffer
// we're mapping to (e.g. the HEAP buffer).
- assert(contents.buffer === buffer || contents.buffer === buffer.buffer);
allocated = false;
ptr = contents.byteOffset;
} else {
@@ -240,4 +276,5 @@ mergeInto(LibraryManager.library, {
},
}
}
-}); \ No newline at end of file
+});
+
diff --git a/src/settings.js b/src/settings.js
index cb64bfd9..03b4ed64 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -6,6 +6,11 @@
// emcc -s OPTION1=VALUE1 -s OPTION2=VALUE2 [..other stuff..]
//
// See https://github.com/kripken/emscripten/wiki/Code-Generation-Modes/
+//
+// Note that the values here are the defaults in -O0, that is, unoptimized
+// mode. See apply_opt_level in tools/shared.py for how -O1,2,3 affect these
+// flags.
+//
// Tuning
var QUANTUM_SIZE = 4; // This is the size of an individual field in a structure. 1 would
@@ -131,6 +136,16 @@ var OUTLINING_LIMIT = 0; // A function size above which we try to automatically
// large functions (JS engines often compile them very slowly,
// compile them with lower optimizations, or do not optimize them
// at all). If 0, we do not perform outlining at all.
+ // To see which funcs are large, you can inspect the source
+ // in a debug build (-g2 or -g for example), and can run
+ // tools/find_bigfuncs.py on that to get a sorted list by size.
+ // Another possibility is to look in the web console in firefox,
+ // which will note slowly-compiling functions.
+ // You will probably want to experiment with various values to
+ // see the impact on compilation time, code size and runtime
+ // throughput. It is hard to say what values to start testing
+ // with, but something around 20,000 to 100,000 might make sense.
+ // (The unit size is number of AST nodes.)
// Generated code debugging options
var SAFE_HEAP = 0; // Check each write to the heap, for example, this will give a clear
@@ -380,9 +395,7 @@ var HEADLESS = 0; // If 1, will include shim code that tries to 'fake' a browser
var BENCHMARK = 0; // If 1, will just time how long main() takes to execute, and not
// print out anything at all whatsoever. This is useful for benchmarking.
-var ASM_JS = 0; // If 1, generate code in asm.js format. XXX This is highly experimental,
- // and will not work on most codebases yet. It is NOT recommended that you
- // try this yet.
+var ASM_JS = 0; // If 1, generate code in asm.js format.
var PGO = 0; // Enables profile-guided optimization in the form of runtime checks for
// which functions are actually called. Emits a list during shutdown that you
diff --git a/src/shell.html b/src/shell.html
index 22bc9de9..ff5f6e35 100644
--- a/src/shell.html
+++ b/src/shell.html
@@ -87,6 +87,6 @@
};
Module.setStatus('Downloading...');
</script>
- <script type='text/javascript'>{{{ SCRIPT_CODE }}}</script>
+ <script async type='text/javascript'>{{{ SCRIPT_CODE }}}</script>
</body>
</html>