diff --git a/docs/paper.pdf b/docs/paper.pdf
index 755eaddc2..401162ace 100644
Binary files a/docs/paper.pdf and b/docs/paper.pdf differ
diff --git a/docs/paper.tex b/docs/paper.tex
index 5687788f8..4ad795b88 100644
--- a/docs/paper.tex
+++ b/docs/paper.tex
@@ -30,7 +30,7 @@
 \begin{abstract}
 We present Emscripten, a compiler from LLVM (Low Level Virtual Machine) assembly to JavaScript. This
 opens up two avenues for running code written
-in languages other than JavaScript on the web: (1) Compile code directly into LLVM assemby, and
+in languages other than JavaScript on the web: (1) Compile code directly into LLVM assembly, and
 then compile that into JavaScript using Emscripten, or (2) Compile
 a language's entire runtime into LLVM and then JavaScript, as in the previous
 approach, and then use the compiled runtime to run code written in that language. For example, the
@@ -477,7 +477,7 @@ reading from memory before a value was written (somewhat similarly to tools
 like Valgrind\footnote{\url{http://valgrind.org/}}). When such problems are detected, possible solutions are to ignore the issue (if it has no actual
 consqeuences), or alter the source code.
 
-Note that it is somewhat wasteful to allocation 4 memory locations for
+Note that it is somewhat wasteful to allocate 4 memory locations for
 a 32-bit integer, and use only one of them. It is possible to change
 that behavior with the QUANTUM\_SIZE parameter to Emscripten, however,
 the difficulty is that LLVM assembly has hardcoded values that depend on
diff --git a/settings.py b/settings.py
index 31f115c23..9773aa1ea 100644
--- a/settings.py
+++ b/settings.py
@@ -13,13 +13,11 @@ COMPILER_OPTS = ['-m32', '-g'] # Need to build as 32bit arch, for now -
                                # various errors on 64bit compilation
                                # WARNING: '-g' here will generate llvm bitcode that lli will crash on!
 
-SPIDERMONKEY_ENGINE = [os.path.expanduser('~/Dev/tracemonkey/js/src/js'), '-m', '-j', '-p']
+SPIDERMONKEY_ENGINE = [os.path.expanduser('~/Dev/mozilla-central/js/src/js'), '-m', '-j', '-p']
 V8_ENGINE = [os.path.expanduser('~/Dev/v8/d8')]
 
-# XXX Warning: Compiling the 'cubescript' test in SpiderMonkey can lead to an extreme amount of memory being
-#              used, see Mozilla bug 593659. Possibly also some other tests as well.
-#COMPILER_ENGINE=SPIDERMONKEY_ENGINE
-COMPILER_ENGINE=V8_ENGINE
+COMPILER_ENGINE=SPIDERMONKEY_ENGINE
+#COMPILER_ENGINE=V8_ENGINE # XXX Warning: currently appears to be broken on v8 trunk, some arguments issue
 
 JS_ENGINE=V8_ENGINE
 
diff --git a/src/library.js b/src/library.js
index 031cf42da..e6fee62e2 100644
--- a/src/library.js
+++ b/src/library.js
@@ -1783,7 +1783,7 @@ LibraryManager.library = {
       return -1;
     }
   },
-  getlogin: ['getlogin_r'],
+  getlogin__deps: ['getlogin_r'],
   getlogin: function() {
     // char *getlogin(void);
     // http://pubs.opengroup.org/onlinepubs/000095399/functions/getlogin.html
diff --git a/src/modules.js b/src/modules.js
index 04b777fe1..6b8d880a4 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -235,7 +235,7 @@ var LibraryManager = {
   load: function() {
     assert(!this.library);
 
-    for (suffix in set('', '_sdl', '_gl', '_browser')) {
+    for (var suffix in set('', '_sdl', '_gl', '_browser')) {
       eval(processMacros(preprocess(read('library' + suffix + '.js'), CONSTANTS)));
     }
   },
diff --git a/src/parseTools.js b/src/parseTools.js
index 4a3867efb..2985ccb60 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -13,7 +13,7 @@ function processMacros(text) {
 // Simple #if/else/endif preprocessing for a file. Checks if the
 // ident checked is true in our global. Also replaces some constants.
 function preprocess(text, constants) {
-  for (constant in constants) {
+  for (var constant in constants) {
     text = text.replace(eval('/' + constant + '/g'), constants[constant]);
   }
   var lines = text.split('\n');
diff --git a/src/preamble.js b/src/preamble.js
index 21e9021e4..99288244c 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -301,6 +301,43 @@ function assert(condition, text) {
   }
 }
 
+// Sets a value in memory in a dynamic way at run-time. Uses the
+// type data. This is the same as makeSetValue, except that
+// makeSetValue is done at compile-time and generates the needed
+// code then, whereas this function picks the right code at
+// run-time.
+
+function setValue(ptr, value, type) {
+  if (type[type.length-1] === '*') type = 'i32'; // pointers are 32-bit
+  switch(type) {
+    case 'i1': {{{ makeSetValue('ptr', '0', 'value', 'i1') }}}; break;
+    case 'i8': {{{ makeSetValue('ptr', '0', 'value', 'i8') }}}; break;
+    case 'i16': {{{ makeSetValue('ptr', '0', 'value', 'i16') }}}; break;
+    case 'i32': {{{ makeSetValue('ptr', '0', 'value', 'i32') }}}; break;
+    case 'i64': {{{ makeSetValue('ptr', '0', 'value', 'i64') }}}; break;
+    case 'float': {{{ makeSetValue('ptr', '0', 'value', 'float') }}}; break;
+    case 'double': {{{ makeSetValue('ptr', '0', 'value', 'double') }}}; break;
+    default: abort('invalid type for setValue: ' + type);
+  }
+}
+
+// Parallel to setValue.
+
+function getValue(ptr, type) {
+  if (type[type.length-1] === '*') type = 'i32'; // pointers are 32-bit
+  switch(type) {
+    case 'i1': return {{{ makeGetValue('ptr', '0', 'i1') }}};
+    case 'i8': return {{{ makeGetValue('ptr', '0', 'i8') }}};
+    case 'i16': return {{{ makeGetValue('ptr', '0', 'i16') }}};
+    case 'i32': return {{{ makeGetValue('ptr', '0', 'i32') }}};
+    case 'i64': return {{{ makeGetValue('ptr', '0', 'i64') }}};
+    case 'float': return {{{ makeGetValue('ptr', '0', 'float') }}};
+    case 'double': return {{{ makeGetValue('ptr', '0', 'double') }}};
+    default: abort('invalid type for setValue: ' + type);
+  }
+  return null;
+}
+
 // Allocates memory for some data and initializes it properly.
 
 var ALLOC_NORMAL = 0; // Tries to use _malloc()
@@ -338,30 +375,8 @@ function allocate(slab, types, allocator) {
     assert(type, 'Must know what type to store in allocate!');
 #endif
 
-    if (type === 'i1') {
-      {{{ makeSetValue(0, 'ret+i', 'curr', 'i1') }}}
-      i += {{{ getNativeFieldSize('i1', true) }}};
-    } else if (type === 'i8') {
-      {{{ makeSetValue(0, 'ret+i', 'curr', 'i8') }}}
-      i += {{{ getNativeFieldSize('i8', true) }}};
-    } else if (type === 'i16') {
-      {{{ makeSetValue(0, 'ret+i', 'curr', 'i16') }}}
-      i += {{{ getNativeFieldSize('i16', true) }}};
-    } else if (type === 'i32' || type[type.length-1] === '*') { // hardcoded pointers as 32-bit
-      {{{ makeSetValue(0, 'ret+i', 'curr', 'i32') }}}
-      i += {{{ getNativeFieldSize('i32', true) }}};
-    } else if (type === 'float') {
-      {{{ makeSetValue(0, 'ret+i', 'curr', 'float') }}}
-      i += {{{ getNativeFieldSize('float', true) }}};
-    } else if (type === 'i64') {
-      {{{ makeSetValue(0, 'ret+i', 'curr', 'i64') }}}
-      i += {{{ getNativeFieldSize('i64', true) }}};
-    } else if (type === 'double') {
-      {{{ makeSetValue(0, 'ret+i', 'curr', 'double') }}}
-      i += {{{ getNativeFieldSize('double', true) }}};
-    } else {
-      abort('invalid type for allocate: ' + type);
-    }
+    setValue(ret+i, curr, type);
+    i += Runtime.getNativeFieldSize(type, true);
   }
 
   return ret;
diff --git a/src/shell.js b/src/shell.js
index c73cf6e4e..06cf4175d 100644
--- a/src/shell.js
+++ b/src/shell.js
@@ -13,9 +13,13 @@ if (!this['Module']) {
   this['Module'] = {};
 }
 try {
-  Module.arguments = arguments;
+  Module.arguments = scriptArgs;
 } catch(e) {
-  Module.arguments = [];
+  try {
+    Module.arguments = arguments;
+  } catch(e) {
+    Module.arguments = [];
+  }
 }
 //*/
 
diff --git a/tests/runner.py b/tests/runner.py
index 10cb35c84..e3f0e0e60 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -2895,7 +2895,7 @@ if 'benchmark' not in sys.argv:
                       lambda: map(ord, open(path_from_root('tests', 'poppler', 'ref.ppm'), 'r').read()).__str__().replace(' ', ''),
                       args='-scale-to 512 paper.pdf filename'.split(' '),
                       post_build=post,
-                      js_engines=[SPIDERMONKEY_ENGINE]) # V8 bug 1257
+                      js_engines=[V8_ENGINE]) # XXX Moz bug 675269
                       #, build_ll_hook=self.do_autodebug)
 
     def test_openjpeg(self):
@@ -3141,12 +3141,14 @@ if 'benchmark' not in sys.argv:
             Child1(int val) : Parent(val*2) { value -= 1; printf("Child1:%d\\n", value); };
             int getValSqr() { return value*value; }
             int getValSqr(int more) { return value*value*more; }
+            int getValTimes(int times=1) { return value*times; }
           };
 
-          class Child2 : Parent {
+          class Child2 : public Parent {
           public:
             Child2() : Parent(9) { printf("Child2:%d\\n", value); };
             int getValCube() { return value*value*value; }
+            static void printStatic() { printf("*static*\\n"); }
           private:
             void doSomethingSecret() { printf("security breached!\\n"); }; // we should not be able to do this
           };
@@ -3155,6 +3157,7 @@ if 'benchmark' not in sys.argv:
 
         basename = os.path.join(self.get_dir(), 'bindingtest')
         output = Popen([BINDINGS_GENERATOR, basename, header_filename], stdout=PIPE, stderr=STDOUT).communicate()[0]
+        #print output
         assert 'Traceback' not in output, 'Failure in binding generation: ' + output
 
         src = '''
@@ -3179,16 +3182,18 @@ if 'benchmark' not in sys.argv:
           c1.mulVal(2);
           print(c1.getVal());
           print(c1.getValSqr());
-          print(c1.getValSqr_2(3));
+          print(c1.getValSqr(3));
+          print(c1.getValTimes()); // default argument should be 1
+          print(c1.getValTimes(2));
 
           print('c1 v2');
 
-          c1 = new Child1_2(8);
+          c1 = new Child1(8); // now with a parameter, we should handle the overloading automatically and properly and use constructor #2
           print(c1.getVal());
           c1.mulVal(2);
           print(c1.getVal());
           print(c1.getValSqr());
-          print(c1.getValSqr_2(3));
+          print(c1.getValSqr(3));
 
           print('c2')
 
@@ -3217,6 +3222,8 @@ if 'benchmark' not in sys.argv:
           } catch(e) {}
           print(succeeded);
 
+          Child2.prototype.printStatic(); // static calls go through the prototype
+
           print('*ok*');
         '''
 
@@ -3236,6 +3243,8 @@ Child1:7
 14
 196
 588
+14
+28
 c1 v2
 Parent:16
 Child1:15
@@ -3252,6 +3261,7 @@ Child2:9
 0
 0
 1
+*static*
 *ok*
 ''', post_build=post2)
 
@@ -3668,7 +3678,8 @@ else:
   USE_CLOSURE_COMPILER = 1
 
   if USE_CLOSURE_COMPILER:
-    SPIDERMONKEY_ENGINE = filter(lambda x: x != '-s', SPIDERMONKEY_ENGINE) # closure generates non-strict
+    index = SPIDERMONKEY_ENGINE.index("options('strict')")
+    SPIDERMONKEY_ENGINE = SPIDERMONKEY_ENGINE[:index-1] + SPIDERMONKEY_ENGINE[index+1:] # closure generates non-strict
 
   COMPILER = CLANG
   JS_ENGINE = SPIDERMONKEY_ENGINE
diff --git a/tools/bindings_generator.py b/tools/bindings_generator.py
index 61d049425..2abc5bf3d 100755
--- a/tools/bindings_generator.py
+++ b/tools/bindings_generator.py
@@ -47,7 +47,7 @@ import CppHeaderParser
 
 basename = sys.argv[1]
 
-processor = lambda line: line
+processor = lambda text: text
 ignored = []
 
 if '--' in sys.argv:
@@ -62,54 +62,124 @@ if '--' in sys.argv:
 classes = {}
 struct_parents = {}
 
+text = ''
+for header in sys.argv[2:]:
+  text += '//// ' + header + '\n'
+  text += open(header, 'r').read()
 all_h_name = basename + '.all.h'
 all_h = open(all_h_name, 'w')
 
-for header in sys.argv[2:]:
-  all_h.write('//// ' + header + '\n')
-  all_h.write(processor(open(header, 'r').read()))
-
+all_h.write(processor(text))
 all_h.close()
 
 parsed = CppHeaderParser.CppHeader(all_h_name)
-for cname, clazz in parsed.classes.iteritems():
-  #print 'zz see', cname
-  if len(clazz['methods']['public']) > 0: # Do not notice stub classes 
-    #print 'zz for real', cname, clazz, dir(clazz)
-    classes[cname] = clazz
-    for sname, struct in clazz._public_structs.iteritems():
-      struct_parents[sname] = cname
-      #print 'zz seen struct %s in %s' % (sname, cname)
+for classname, clazz in parsed.classes.iteritems():
+  print 'zz see', classname
+  classes[classname] = clazz
+  for sname, struct in clazz._public_structs.iteritems():
+    struct_parents[sname] = classname
+    #print 'zz seen struct %s in %s' % (sname, classname)
+
+  # Various precalculations
+  for method in clazz['methods']['public'][:]:
+    constructor = method['name'] == classname
+    method['constructor'] = constructor # work around cppheaderparser issue
+    args = method['parameters']
+
+    default_param = len(args)+1
+    for i in range(len(args)):
+      if args[i].get('default'):
+        default_param = i+1
+        break
+
+    method['num_args'] = set(range(default_param-1, len(args)+1))
+    print 'zz ', classname, 'has num_args of', method['num_args']
+
+    if method['static']:
+      method['rtnType'] = method['rtnType'].replace('static', '')
+
+# Explore all functions we need to generate, including parent classes, handling of overloading, etc.
+
+for classname, clazz in parsed.classes.iteritems():
+  clazz['final_methods'] = {}
+
+  def explore(subclass):
+    # Do our functions first, and do not let later classes override
+    for method in subclass['methods']['public']:
+      if method['constructor']:
+        if clazz != subclass: continue # Subclasses cannot directly use their parent's constructors
+      if method['destructor']: continue # Nothing to do there
+
+      if method['name'] not in clazz['final_methods']:
+        clazz['final_methods'][method['name']] = {}
+        for key in ['name', 'constructor', 'static', 'rtnType', 'destructor', 'pure_virtual']:
+          clazz['final_methods'][method['name']][key] = method[key]
+        clazz['final_methods'][method['name']]['num_args'] = method['num_args'].copy()
+        clazz['final_methods'][method['name']]['parameters'] = method['parameters'][:]
+        clazz['final_methods'][method['name']]['origin'] = subclass
+      else:
+        # Merge the new function in the best way we can. Shared arguments must match!
+
+        curr = clazz['final_methods'][method['name']]
+
+        if curr['origin'] is not subclass: continue # child class functions mask/hide parent functions of the same name in C++
+
+        if any([curr['parameters'][i]['type'] != method['parameters'][i]['type'] for i in range(min(len(curr['parameters']), len(method['parameters'])))]):
+          print 'Warning: Cannot mix in overloaded functions', method['name'], 'in class', classname, ', skipping'
+          continue
+        # TODO: Other compatibility checks, if any?
+
+        if len(method['parameters']) > len(curr['parameters']):
+          curr['parameters'] = method['parameters']
+
+        curr['num_args'] = curr['num_args'].union(method['num_args'])
+        print 'zz ', classname, 'has an updated num_args of ', curr['num_args']
+
+    # Recurse
+    for parent in subclass['inherits']:
+      if parent['class'] not in classes:
+        print 'Warning: parent class', parent, 'not a known class. Ignoring.'
+        return
+      explore(classes[parent['class']])
+
+  explore(clazz)
+
+  for method in clazz['final_methods'].itervalues():
+    method['num_args'] = list(method['num_args'])
+    method['num_args'].sort()
 
 # Second pass - generate bindings
 # TODO: Bind virtual functions using dynamic binding in the C binding code
 
 funcs = {} # name -> # of copies in the original, and originalname in a copy
+c_funcs = []
 
 gen_c = open(basename + '.c', 'w')
 gen_js = open(basename + '.js', 'w')
 
 gen_c.write('extern "C" {\n')
 
-def generate_class(generating_cname, cname, clazz):
-  inherited = generating_cname != cname
+def generate_class(generating_classname, classname, clazz): # TODO: deprecate generating?
+  inherited = generating_classname != classname
 
-  for method in clazz['methods']['public']:
+  for method in clazz['final_methods'].itervalues():
     mname = method['name']
-    #print "zz generating: ", generating_cname, cname, mname
-    if cname + '::' + mname in ignored: continue
+    if classname + '::' + mname in ignored: continue
 
     args = method['parameters']
-    constructor = mname == cname
+    constructor = method['constructor'] # we fixed this before
     destructor = method['destructor']
+    static = method['static']
+
+    print "zz generating: ", generating_classname, classname, mname, constructor, method['rtnType']
 
     if destructor: continue
     if constructor and inherited: continue
-    if method['pure_virtual']: continue
 
     skip = False
     for i in range(len(args)):
-      #print 'zz   arggggggg', cname, 'x', mname, 'x', args[i]['name'], 'x', args[i]['type'], 'x'
+      #print 'zz   arggggggg', classname, 'x', mname, 'x', args[i]['name'], 'x', args[i]['type'], 'x', dir(args[i]), 'y', args[i].get('default'), 'z', args[i].get('defaltValue'), args[i].keys()
+
       if args[i]['name'].replace(' ', '') == '':
         args[i]['name'] = 'arg' + str(i+1)
       elif args[i]['name'] == '&':
@@ -117,7 +187,7 @@ def generate_class(generating_cname, cname, clazz):
         args[i]['type'] += '&'
 
       if '>' in args[i]['name']:
-        print 'WARNING: odd ">" in %s, skipping' % cname
+        print 'WARNING: odd ">" in %s, skipping' % classname
         skip = True
         break
       #print 'c1', struct_parents.keys()
@@ -129,14 +199,12 @@ def generate_class(generating_cname, cname, clazz):
         elif sname.replace('const ', '') in struct_parents:
           sname = sname.replace('const ', '')
           args[i]['type'] = 'const ' + struct_parents[sname] + '::' + sname + '&'
-      #print 'POST arggggggg', cname, 'x', mname, 'x', args[i]['name'], 'x', args[i]['type']
+      #print 'POST arggggggg', classname, 'x', mname, 'x', args[i]['name'], 'x', args[i]['type']
     if skip:
       continue
 
-    # C
-
-    ret = ((cname + ' *') if constructor else method['rtnType']).replace('virtual ', '')
-    callprefix = 'new ' if constructor else 'self->'
+    ret = ((classname + ' *') if constructor else method['rtnType']).replace('virtual ', '')
+    callprefix = 'new ' if constructor else ('self->' if not static else (classname + '::'))
 
     actualmname = ''
     if mname == '__operator___assignment_':
@@ -170,100 +238,145 @@ def generate_class(generating_cname, cname, clazz):
       callprefix = '*self - '
       continue # TODO
     else:
-      actualmname = mname
+      actualmname = method.get('truename') or mname
 
-    typedargs = ', '.join( ([] if constructor else [cname + ' * self']) + map(lambda arg: arg['type'] + ' ' + arg['name'], args) )
-    justargs = ', '.join(map(lambda arg: arg['name'], args))
-    fullname = 'emscripten_bind_' + generating_cname + '__' + mname
-    generating_cname_suffixed = generating_cname
+    need_self = not constructor and not static
+    typedargs = ([] if not need_self else [classname + ' * self']) + map(lambda arg: arg['type'] + ' ' + arg['name'], args)
+    justargs = map(lambda arg: arg['name'], args)
+    fullname = 'emscripten_bind_' + generating_classname + '__' + mname
+    generating_classname_suffixed = generating_classname
     mname_suffixed = mname
     count = funcs.setdefault(fullname, 0)
     funcs[fullname] += 1
 
     # handle overloading
+    dupe = False
     if count > 0:
+      dupe = True
       suffix = '_' + str(count+1)
-      funcs[fullname + suffix] = fullname # this should never change
+      funcs[fullname + suffix] = 0
       fullname += suffix
       mname_suffixed += suffix
       if constructor:
-        generating_cname_suffixed += suffix
+        generating_classname_suffixed += suffix
 
-    gen_c.write('''
-%s %s(%s) {
+    argfixes = '\n'.join(map(lambda arg: '''  %s = (%s && %s.ptr) ? %s.ptr : %s;''' % (arg['name'], arg['name'], arg['name'], arg['name'], arg['name']), args))
+
+    for i in method['num_args']:
+      # C
+
+      gen_c.write('''
+%s %s_p%d(%s) {
   %s%s%s(%s);
 }
-''' % (ret, fullname, typedargs, 'return ' if ret.replace(' ', '') != 'void' else '', callprefix, actualmname, justargs))
+''' % (ret, fullname, i, ', '.join(typedargs[:i + (0 if not need_self else 1)]), 'return ' if ret.replace(' ', '') != 'void' else '', callprefix, actualmname, ', '.join(justargs[:i])))
+
+      c_funcs.append(fullname + '_p' + str(i))
 
     # JS
-
-    if constructor:
-      dupe = type(funcs[fullname]) is str
-      if not dupe:
-        gen_js.write('''
-function %s(%s) {
-  this.ptr = _%s(%s);
-}
-''' % (generating_cname_suffixed, justargs, fullname, justargs))
+    calls = ''
+    print 'js loopin', method['num_args'], '|', len(args), args
+    for i in method['num_args']:
+      print '    ', i, type(i)
+      if i != method['num_args'][0]:
+        calls += '  else '
+      if i != method['num_args'][-1]:
+        calls += '  if (' + justargs[i] + ' === undefined)'
+      calls += '\n  ' + ('  ' if len(method['num_args']) > 0 else '')
+      if constructor:
+        if not dupe:
+          calls += '''this.ptr = _%s_p%d(%s);
+''' % (fullname, i, ', '.join(justargs[:i]))
+        else:
+          calls += '''this.ptr = _%s_p%d(%s);
+''' % (fullname, i, ', '.join(justargs[:i]))
       else:
-        gen_js.write('''
+        calls += '''%s_%s_p%d(%s);
+''' % ('return ' if ret != 'void' else '', fullname, i, ', '.join((['this.ptr'] if need_self else []) + justargs[:i]))
+
+    print 'Maekin:', classname, generating_classname, mname, mname_suffixed
+    if constructor:
+      if not dupe:
+        js_text = '''
 function %s(%s) {
-  this.ptr = _%s(%s);
+%s
+%s
+}
+''' % (mname_suffixed, ', '.join(justargs), argfixes, calls)
+      else:
+        js_text = '''
+function %s(%s) {
+%s
+%s
 }
 %s.prototype = %s.prototype;
-''' % (generating_cname_suffixed, justargs, fullname, justargs, generating_cname_suffixed, cname))
+''' % (mname_suffixed, ', '.join(justargs), argfixes, calls, mname_suffixed, classname)
     else:
-      gen_js.write('''
+      js_text = '''
 %s.prototype.%s = function(%s) {
-  %s_%s(this.ptr%s);
+%s
+%s
 }
-''' % (generating_cname, mname_suffixed, justargs, 'return ' if ret != 'void' else '', fullname, (', ' if len(justargs) > 0 else '') + justargs))
+''' % (generating_classname, mname_suffixed, ', '.join(justargs), argfixes, calls)
 
-for cname, clazz in classes.iteritems():
-  if cname in ignored: continue
+    js_text = js_text.replace('\n\n', '\n').replace('\n\n', '\n')
+    gen_js.write(js_text)
+
+# Main loop
+
+for classname, clazz in classes.iteritems():
+  if classname in ignored: continue
 
   # Nothing to generate for pure virtual classes
 
   def check_pure_virtual(clazz, progeny):
-    if any([check_pure_virtual(classes[parent['class']], [clazz] + progeny) for parent in clazz['inherits']]): return True
+    print 'Checking pure virtual for', clazz['name'], clazz['inherits']
+    # If we do not recognize any of the parent classes, assume this is pure virtual - ignore it
+    if any([((not parent['class'] in classes) or check_pure_virtual(classes[parent['class']], [clazz] + progeny)) for parent in clazz['inherits']]): return True
 
     def dirtied(mname):
+      #print 'zz checking dirtiness for', mname, 'in', progeny
       for progen in progeny:
-        for method in clazz['methods']['public']:
-          if method['name'] == mname and not method['pure_virtual']: return True
+        for method in progen['methods']['public']:
+          if method['name'] == mname and not method['pure_virtual']:
+            #print 'zz dirty'
+            return True
+      #print 'zz not dirtied'
       return False
 
     for method in clazz['methods']['public']:
-      if method['pure_virtual'] and not dirtied(method['name']): return True
+      if method['pure_virtual'] and not dirtied(method['name']):
+        print 'zz ignoring pure virtual class', classname, 'due to', method['name']
+        return True
 
-  if check_pure_virtual(clazz, []): continue
+  if check_pure_virtual(clazz, []):
+    continue
 
   # Add a constructor if none exist
   has_constructor = False
   for method in clazz['methods']['public']:
     mname = method['name']
-    has_constructor = has_constructor or (cname == mname)
+    has_constructor = has_constructor or (classname == mname and not method['destructor'])
+
+  print 'zz ', classname, 'has constructor?', has_constructor
 
   if not has_constructor:
+    print 'zz no constructor for', classname, 'so ignoring'
+    continue
+
     clazz['methods']['public'] = [{
-      'name': cname,
+      'name': classname,
       'parameters': [],
       'pure_virtual': False,
       'destructor': False,
     }] + clazz['methods']['public']
 
-  generate_class(cname, cname, clazz)
-
-  # In addition, generate all methods of parent classes. We do not inherit in JS (how would we do multiple inheritance etc.?)
-  for parent in clazz['inherits']:
-    generate_class(cname, parent['class'], classes[parent['class']])
+  generate_class(classname, classname, clazz)
 
   # TODO: Add a destructor
 
 # Finish up
 
-funcs = funcs.keys()
-
 gen_c.write('''
 }
 
@@ -275,9 +388,9 @@ struct EmscriptenEnsurer
     // Actually use the binding functions, so DFE will not eliminate them
     int sum = 0;
     void *seen = (void*)%s;
-''' % funcs[0])
+''' % c_funcs[0])
 
-for func in funcs[1:]:
+for func in c_funcs[1:]:
   gen_c.write('''    sum += (void*)%s == seen;
 ''' % func)
 
diff --git a/tools/emmaken.py b/tools/emmaken.py
index e6e33cb6e..8539d7b66 100755
--- a/tools/emmaken.py
+++ b/tools/emmaken.py
@@ -87,8 +87,8 @@ try:
   CC_ARG_SKIP = ['-O1', '-O2', '-O3']
   CC_ADDITIONAL_ARGS = ['-m32', '-g', '-U__i386__', '-U__x86_64__', '-U__i386', '-U__x86_64', '-U__SSE__', '-U__SSE2__', '-UX87_DOUBLE_ROUNDING', '-UHAVE_GCC_ASM_FOR_X87']
   ALLOWED_LINK_ARGS = ['-f', '-help', '-o', '-print-after', '-print-after-all', '-print-before',
-                       '-print-before-all', '-time-passes', '-v', '-verify-dom-info', '-version' ]  
-  DISALLOWED_LINK_ARGS = []#['rc']
+                       '-print-before-all', '-time-passes', '-v', '-verify-dom-info', '-version' ]
+  TWO_PART_DISALLOWED_LINK_ARGS = ['-L'] # Ignore thingsl like |-L .|
 
   EMMAKEN_CFLAGS = os.environ.get('EMMAKEN_CFLAGS')
   if EMMAKEN_CFLAGS: CC_ADDITIONAL_ARGS += EMMAKEN_CFLAGS.split(' ')
@@ -125,7 +125,7 @@ try:
   if '--version' in opts:
     use_linker = False
 
-  if set(sys.argv[1]).issubset(set('cru')): # ar
+  if set(sys.argv[1]).issubset(set('cruqs')): # ar
     sys.argv = sys.argv[:1] + sys.argv[3:] + ['-o='+sys.argv[2]]
     assert use_linker, 'Linker should be used in this case'
 
@@ -133,7 +133,10 @@ try:
     call = LLVM_LINK
     newargs = []
     found_o = False
-    for arg in sys.argv[1:]:
+    i = 0
+    while i < len(sys.argv)-1:
+      i += 1
+      arg = sys.argv[i]
       if found_o:
         newargs.append('-o=%s' % arg)
         found_o = False
@@ -145,12 +148,13 @@ try:
         prefix = arg.split('=')[0]
         if prefix in ALLOWED_LINK_ARGS:
           newargs.append(arg)
+        if arg in TWO_PART_DISALLOWED_LINK_ARGS:
+          i += 1
       elif arg.endswith('.so'):
         continue # .so's do not exist yet, in many cases
       else:
         # not option, so just append
-        if arg not in DISALLOWED_LINK_ARGS:
-          newargs.append(arg)
+        newargs.append(arg)
   elif not header:
     call = CXX if use_cxx else CC
     newargs = [ arg for arg in sys.argv[1:] if arg not in CC_ARG_SKIP ] + CC_ADDITIONAL_ARGS
@@ -170,6 +174,6 @@ try:
 
   os.execvp(call, [call] + newargs)
 except Exception, e:
-  print 'Error in emmaken.py. Is the config file ~/.emscripten set up properly?', e
+  print 'Error in emmaken.py. (Is the config file ~/.emscripten set up properly?) Error:', e
   raise
 
diff --git a/tools/shared.py b/tools/shared.py
index 9ccc21054..0ee9a0ac6 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -25,8 +25,8 @@ BINDINGS_GENERATOR = path_from_root('tools', 'bindings_generator.py')
 
 # Engine tweaks
 
-if '-s' not in SPIDERMONKEY_ENGINE:
-  SPIDERMONKEY_ENGINE += ['-s'] # Strict mode in SpiderMonkey. With V8 we check that fallback to non-strict works too
+if 'strict' not in str(SPIDERMONKEY_ENGINE):
+  SPIDERMONKEY_ENGINE += ['-e', "options('strict')"] # Strict mode in SpiderMonkey. With V8 we check that fallback to non-strict works too
 
 if 'gcparam' not in str(SPIDERMONKEY_ENGINE):
   SPIDERMONKEY_ENGINE += ['-e', "gcparam('maxBytes', 1024*1024*1024);"] # Our very large files need lots of gc heap