aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library.js32
-rw-r--r--tools/js-optimizer.js122
-rw-r--r--tools/test-js-optimizer-output.js7
-rw-r--r--tools/test-js-optimizer.js10
4 files changed, 108 insertions, 63 deletions
diff --git a/src/library.js b/src/library.js
index fea3a588..53a572c9 100644
--- a/src/library.js
+++ b/src/library.js
@@ -1863,6 +1863,10 @@ LibraryManager.library = {
return 0;
}
},
+ getpagesize: function() {
+ // int getpagesize(void);
+ return PAGE_SIZE;
+ },
getopt: function(argc, argv, optstring) {
// int getopt(int argc, char * const argv[], const char *optstring);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html
@@ -5593,6 +5597,34 @@ LibraryManager.library = {
pthread_mutex_lock: function() {},
pthread_mutex_unlock: function() {},
pthread_cond_broadcast: function() {},
+ pthread_self: function() {
+ //FIXME: assumes only a single thread
+ return 0;
+ },
+ pthread_attr_init: function(attr) {
+ /* int pthread_attr_init(pthread_attr_t *attr); */
+ //FIXME: should allocate a pthread_attr_t
+ return 0;
+ },
+ pthread_getattr_np: function(thread, attr) {
+ /* int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr); */
+ //FIXME: should fill in attributes of the given thread in pthread_attr_t
+ return 0;
+ },
+ pthread_attr_destroy: function(attr) {
+ /* int pthread_attr_destroy(pthread_attr_t *attr); */
+ //FIXME: should destroy the pthread_attr_t struct
+ return 0;
+ },
+ pthread_attr_getstack: function(attr, stackaddr, stacksize) {
+ /* int pthread_attr_getstack(const pthread_attr_t *restrict attr,
+ void **restrict stackaddr, size_t *restrict stacksize); */
+ /*FIXME: assumes that there is only one thread, and that attr is the
+ current thread*/
+ {{{ makeSetValue('stackaddr', '0', 'STACK_ROOT', 'i8*') }}}
+ {{{ makeSetValue('stacksize', '0', 'TOTAL_STACK', 'i32') }}}
+ return 0;
+ },
// ==========================================================================
// malloc.h
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index c5d3a79f..7ac2195f 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -101,7 +101,7 @@ function traverse(node, pre, post, stack) {
// Only walk through the generated functions
function traverseGenerated(ast, pre, post, stack) {
- ast[1].forEach(function(node, i) {
+ traverse(ast, function(node) {
if (node[0] == 'defun' && isGenerated(node[1])) {
traverse(node, pre, post, stack);
}
@@ -109,7 +109,7 @@ function traverseGenerated(ast, pre, post, stack) {
}
function traverseGeneratedFunctions(ast, callback) {
- ast[1].forEach(function(node, i) {
+ traverse(ast, function(node) {
if (node[0] == 'defun' && isGenerated(node[1])) {
callback(node);
}
@@ -717,72 +717,69 @@ function vacuum(ast) {
var more = true;
while (more) {
more = false;
- ast[1].forEach(function(node, i) {
- function simplifyList(node, i) {
- var changed = false;
- var pre = node[i].length;
- node[i] = node[i].filter(function(node) { return !isEmpty(node) });
- if (node[i].length < pre) changed = true;
- // Also, seek blocks with single items we can simplify
- node[i] = node[i].map(function(subNode) {
- if (subNode[0] == 'block' && typeof subNode[1] == 'object' && subNode[1].length == 1 && subNode[1][0][0] == 'if') {
- return subNode[1][0];
- }
- return subNode;
- });
- if (changed) {
- more = true;
- return node;
+ function simplifyList(node, i) {
+ var changed = false;
+ var pre = node[i].length;
+ node[i] = node[i].filter(function(node) { return !isEmpty(node) });
+ if (node[i].length < pre) changed = true;
+ // Also, seek blocks with single items we can simplify
+ node[i] = node[i].map(function(subNode) {
+ if (subNode[0] == 'block' && typeof subNode[1] == 'object' && subNode[1].length == 1 && subNode[1][0][0] == 'if') {
+ return subNode[1][0];
}
+ return subNode;
+ });
+ if (changed) {
+ more = true;
+ return node;
}
- var type = node[0];
- if (type == 'defun' && isGenerated(node[1])) {
- simplifyNotComps(node);
- traverse(node, function(node, type) {
- if (type == 'block' && node[1] && node[1].length == 1 && node[1][0][0] == 'block') {
- more = true;
- return node[1][0];
- } else if (type == 'stat' && node[1][0] == 'block') {
- more = true;
- return node[1];
- } else if (type == 'block' && typeof node[1] == 'object') {
- ret = simplifyList(node, 1);
- if (ret) return ret;
- } else if (type == 'defun' && node[3].length == 1 && node[3][0][0] == 'block') {
+ }
+ traverseGeneratedFunctions(ast, function(node) {
+ simplifyNotComps(node);
+ traverse(node, function(node, type) {
+ if (type == 'block' && node[1] && node[1].length == 1 && node[1][0][0] == 'block') {
+ more = true;
+ return node[1][0];
+ } else if (type == 'stat' && node[1][0] == 'block') {
+ more = true;
+ return node[1];
+ } else if (type == 'block' && typeof node[1] == 'object') {
+ ret = simplifyList(node, 1);
+ if (ret) return ret;
+ } else if (type == 'defun' && node[3].length == 1 && node[3][0][0] == 'block') {
+ more = true;
+ node[3] = node[3][0][1];
+ return node;
+ } else if (type == 'defun') {
+ ret = simplifyList(node, 3);
+ if (ret) return ret;
+ } else if (type == 'do' && node[1][0] == 'num' && jsonCompare(node[2], emptyNode())) {
+ more = true;
+ return emptyNode();
+ } else if (type == 'label' && jsonCompare(node[2], emptyNode())) {
+ more = true;
+ return emptyNode();
+ } else if (type == 'if') {
+ var empty2 = isEmpty(node[2]), empty3 = isEmpty(node[3]), has3 = node.length == 4;
+ if (!empty2 && empty3 && has3) { // empty else clauses
more = true;
- node[3] = node[3][0][1];
- return node;
- } else if (type == 'defun') {
- ret = simplifyList(node, 3);
- if (ret) return ret;
- } else if (type == 'do' && node[1][0] == 'num' && jsonCompare(node[2], emptyNode())) {
+ return node.slice(0, 3);
+ } else if (empty2 && !empty3) { // empty if blocks
more = true;
- return emptyNode();
- } else if (type == 'label' && jsonCompare(node[2], emptyNode())) {
+ return ['if', ['unary-prefix', '!', node[1]], node[3]];
+ } else if (empty2 && empty3) {
more = true;
- return emptyNode();
- } else if (type == 'if') {
- var empty2 = isEmpty(node[2]), empty3 = isEmpty(node[3]), has3 = node.length == 4;
- if (!empty2 && empty3 && has3) { // empty else clauses
- more = true;
- return node.slice(0, 3);
- } else if (empty2 && !empty3) { // empty if blocks
- more = true;
- return ['if', ['unary-prefix', '!', node[1]], node[3]];
- } else if (empty2 && empty3) {
- more = true;
- if (hasSideEffects(node[1])) {
- return ['stat', node[1]];
- } else {
- return emptyNode();
- }
+ if (hasSideEffects(node[1])) {
+ return ['stat', node[1]];
+ } else {
+ return emptyNode();
}
- } else if (type == 'do' && isEmpty(node[2]) && !hasSideEffects(node[1])) {
- more = true;
- return emptyNode();
}
- });
- }
+ } else if (type == 'do' && isEmpty(node[2]) && !hasSideEffects(node[1])) {
+ more = true;
+ return emptyNode();
+ }
+ });
});
}
}
@@ -803,8 +800,7 @@ function getStatements(node) {
// if (condition) { __label__ == x } else ..
// We can hoist the multiple block into the condition, thus removing code and one 'if' check
function hoistMultiples(ast) {
- ast[1].forEach(function(node, i) {
- if (!(node[0] == 'defun' && isGenerated(node[1]))) return;
+ traverseGeneratedFunctions(ast, function(node) {
traverse(node, function(node, type) {
var statements = getStatements(node);
if (!statements) return;
diff --git a/tools/test-js-optimizer-output.js b/tools/test-js-optimizer-output.js
index b1bdc0f8..acf48008 100644
--- a/tools/test-js-optimizer-output.js
+++ b/tools/test-js-optimizer-output.js
@@ -174,6 +174,13 @@ function hoisting() {
var $79 = $_pr6;
}
}
+function innerShouldAlsoBeHoisted() {
+ function hoisting() {
+ if ($i < $N) {
+ callOther();
+ }
+ }
+}
var FS = {
absolutePath: (function(relative, base) {
if (typeof relative !== "string") return null;
diff --git a/tools/test-js-optimizer.js b/tools/test-js-optimizer.js
index 155aa647..f9c499f4 100644
--- a/tools/test-js-optimizer.js
+++ b/tools/test-js-optimizer.js
@@ -217,6 +217,16 @@ function hoisting() {
}
} while (0);
}
+function innerShouldAlsoBeHoisted() {
+ function hoisting() {
+ if ($i < $N) {
+ __label__ = 2;
+ }
+ if (__label__ == 2) {
+ callOther();
+ }
+ }
+}
var FS = {
absolutePath: function(relative, base) { // Don't touch this!
if (typeof relative !== 'string') return null;