diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-03-03 12:03:48 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-03-03 12:03:48 -0800 |
commit | d6cff2177ec065aa14f228ab547abc29ef37b248 (patch) | |
tree | 285c3d737500e8a3ed6be56dcaf9357ffd5c7cd9 /tools | |
parent | dfd9488e0094a6b5433b406517338e0f757c1e27 (diff) | |
parent | 6f57ea8f0eeb220fc81726b4e3a3c02f4232b667 (diff) |
Merge branch 'master' into llvmsvn
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/bindings_generator.py | 109 | ||||
-rw-r--r-- | tools/js-optimizer.js | 33 | ||||
-rw-r--r-- | tools/make_minigzip.py | 13 | ||||
-rw-r--r-- | tools/shared.py | 9 |
4 files changed, 103 insertions, 61 deletions
diff --git a/tools/bindings_generator.py b/tools/bindings_generator.py index e1c1ab4b..4731abf3 100755 --- a/tools/bindings_generator.py +++ b/tools/bindings_generator.py @@ -95,24 +95,38 @@ all_h.write(text) all_h.close() parsed = CppHeaderParser.CppHeader(all_h_name) -for classname, clazz in parsed.classes.iteritems(): - print 'zz see', classname +print 'zz dir: ', parsed.__dict__.keys() +for classname, clazz in parsed.classes.items() + parsed.structs.items(): + print 'zz see', classname, clazz, type(clazz) classes[classname] = clazz - clazz['methods'] = clazz['methods']['public'] # CppHeaderParser doesn't have 'public' etc. in structs. so equalize to that + if type(clazz['methods']) == dict: + clazz['saved_methods'] = clazz['methods'] + clazz['methods'] = clazz['methods']['public'] # CppHeaderParser doesn't have 'public' etc. in structs. so equalize to that if '::' in classname: assert classname.count('::') == 1 parents[classname.split('::')[1]] = classname.split('::')[0] - for sname, struct in clazz._public_structs.iteritems(): - parents[sname] = classname - classes[classname + '::' + sname] = struct - struct['name'] = sname # Missing in CppHeaderParser - print 'zz seen struct %s in %s' % (sname, classname) - + if hasattr(clazz, '_public_structs'): # This is a class + for sname, struct in clazz._public_structs.iteritems(): + parents[sname] = classname + classes[classname + '::' + sname] = struct + struct['name'] = sname # Missing in CppHeaderParser + print 'zz seen struct %s in %s' % (sname, classname) + + if 'fields' in clazz: # This is a struct + print 'zz add properties!' + clazz['properties'] = { 'public': clazz['fields'] } + clazz['name'] = classname + clazz['inherits'] = [] print 'zz parents: ', parents -for classname, clazz in classes.iteritems(): +def check_has_constructor(clazz): + for method in clazz['methods']: + if method['constructor'] and not method['destructor']: return True + return False + +for classname, clazz in parsed.classes.items() + parsed.structs.items(): # Various precalculations print 'zz precalc', classname for method in clazz['methods'][:]: @@ -157,7 +171,7 @@ for classname, clazz in classes.iteritems(): print 'zz subsubsub ', classname, method['name'], method['parameters'][0] method['name'] = 'op_sub' if len(method['parameters'][0]) == 0: - method['operator'] = ' return -*self; // %d' % len(method['parameters'][0]) + method['operator'] = ' static %s ret; ret = -*self; return ret;' % method['returns'] else: method['operator'] = ' return *self -= arg0; // %d : %s' % (len(method['parameters'][0]), method['parameters'][0][0]['name']) elif 'imul' in method['name']: @@ -237,21 +251,31 @@ for classname, clazz in classes.iteritems(): }]], }) - # Add destroyer - if not clazz.get('abstract'): - clazz['methods'].append({ - 'destroyer': True, - 'name': '__destroy__', - 'constructor': False, - 'destructor': False, - 'static': False, - 'returns': 'void', - 'returns_text': 'void', - 'returns_reference': False, - 'returns_pointer': False, - 'pure_virtual': False, - 'parameters': [[]], - }) + print 'zz is effectively abstract?', clazz['name'], classname, '0' + if 'saved_methods' in clazz and not check_has_constructor(clazz): + print 'zz is effectively abstract?', clazz['name'], '1' + # Having a private constructor and no public constructor means you are, in effect, abstract + for private_method in clazz['saved_methods']['private']: + print 'zz is effectively abstract?', clazz['name'], '2' + if private_method['constructor']: + print 'zz is effectively abstract?', clazz['name'], '3' + clazz['effectively_abstract'] = True + + # Add destroyer + if not clazz.get('abstract') and not clazz.get('effectively_abstract'): + clazz['methods'].append({ + 'destroyer': True, + 'name': '__destroy__', + 'constructor': False, + 'destructor': False, + 'static': False, + 'returns': 'void', + 'returns_text': 'void', + 'returns_reference': False, + 'returns_pointer': False, + 'pure_virtual': False, + 'parameters': [[]], + }) clazz['methods'] = filter(lambda method: not method.get('ignore'), clazz['methods']) @@ -277,7 +301,7 @@ def copy_args(args): ret.append(copiedarg) return ret -for classname, clazz in parsed.classes.iteritems(): +for classname, clazz in parsed.classes.items() + parsed.structs.items(): clazz['final_methods'] = {} def explore(subclass, template_name=None, template_value=None): @@ -286,10 +310,16 @@ for classname, clazz in parsed.classes.iteritems(): print classname, 'exploring', subclass['name'], '::', method['name'] if method['constructor']: - if clazz != subclass: continue # Subclasses cannot directly use their parent's constructors - if method['destructor']: continue # Nothing to do there + if clazz != subclass: + print "zz Subclasses cannot directly use their parent's constructors" + continue + if method['destructor']: + print 'zz Nothing to do there' + continue - if method.get('operator') and subclass is not clazz: continue # Do not use parent class operators. Cast to that class if you need those operators (castObject) + if method.get('operator') and subclass is not clazz: + print 'zz Do not use parent class operators. Cast to that class if you need those operators (castObject)' + continue if method['name'] not in clazz['final_methods']: copied = clazz['final_methods'][method['name']] = {} @@ -485,6 +515,7 @@ def generate_wrapping_code(classname): # %(classname)s.prototype['fields'] = Runtime.generateStructInfo(null, '%(classname)s'); - consider adding this def generate_class(generating_classname, classname, clazz): # TODO: deprecate generating? + print 'zz generating:', generating_classname, classname generating_classname_head = generating_classname.split('::')[-1] classname_head = classname.split('::')[-1] @@ -498,6 +529,7 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge gen_js.write('''Module['%s'] = %s; ''' % (generating_classname_head, generating_classname_head)) + print 'zz methods: ', clazz['final_methods'].keys() for method in clazz['final_methods'].itervalues(): mname = method['name'] if classname_head + '::' + mname in ignored: @@ -509,7 +541,7 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge destructor = method['destructor'] static = method['static'] - #print 'zz generating %s::%s. gets %s and returns %s' % (generating_classname, method['name'], str([arg['type'] for arg in method['parameters']]), method['returns_text']) + print 'zz generating %s::%s' % (generating_classname, method['name']) if destructor: continue if constructor and inherited: continue @@ -644,7 +676,7 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge print 'zz making return', classname, method['name'], method['returns'], return_value if method['returns'] in classes: # Generate a wrapper - calls += 'return wrapPointer(%s, %s);' % (return_value, method['returns'].split('::')[-1]) + calls += '''return wrapPointer(%s, Module['%s']);''' % (return_value, method['returns'].split('::')[-1]) else: # Normal return calls += ('return ' if ret != 'void' else '') + return_value + ';' @@ -686,7 +718,7 @@ Module['%s'] = %s; # Main loop -for classname, clazz in classes.iteritems(): +for classname, clazz in parsed.classes.items() + parsed.structs.items(): if any([name in ignored for name in classname.split('::')]): print 'zz ignoring', classname continue @@ -727,18 +759,17 @@ for classname, clazz in classes.iteritems(): print 'zz ignoring pure virtual class', classname, 'due to', method['name'] return True - clazz['abstract'] = check_pure_virtual(clazz, []) + clazz['abstract'] = check_pure_virtual(clazz, []) or clazz.get('effectively_abstract') + print 'zz', classname, 'is abstract?', clazz['abstract'] #if check_pure_virtual(clazz, []): # continue # Add a constructor if none exist - has_constructor = False - for method in clazz['methods']: - has_constructor = has_constructor or (method['constructor'] and not method['destructor']) - + has_constructor = check_has_constructor(clazz) + print 'zz', classname, 'has constructor?', has_constructor - + if not has_constructor: if not clazz['abstract']: print 'zz no constructor for', classname, 'and not abstract, so ignoring' diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index a0595b88..213e2257 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -15,6 +15,7 @@ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIR if (ENVIRONMENT_IS_NODE) { // Expose functionality in the same simple way that the shells work + // Note that we pollute the global namespace here, otherwise we break in node print = function(x) { process['stdout'].write(x + '\n'); }; @@ -33,12 +34,16 @@ if (ENVIRONMENT_IS_NODE) { return ret; }; + load = function(f) { + globalEval(read(f)); + }; + arguments_ = process['argv'].slice(2); } else if (ENVIRONMENT_IS_SHELL) { // Polyfill over SpiderMonkey/V8 differences if (!this['read']) { - read = function(f) { snarf(f) }; + this['read'] = function(f) { snarf(f) }; } if (!this['arguments']) { @@ -48,11 +53,11 @@ if (ENVIRONMENT_IS_NODE) { } } else if (ENVIRONMENT_IS_WEB) { - print = printErr = function(x) { + this['print'] = printErr = function(x) { console.log(x); }; - read = function(url) { + this['read'] = function(url) { var xhr = new XMLHttpRequest(); xhr.open('GET', url, false); xhr.send(null); @@ -65,7 +70,7 @@ if (ENVIRONMENT_IS_NODE) { } else if (ENVIRONMENT_IS_WORKER) { // We can do very little here... - load = importScripts; + this['load'] = importScripts; } else { throw 'Unknown runtime environment. Where are we?'; @@ -76,17 +81,17 @@ function globalEval(x) { } if (typeof load == 'undefined' && typeof read != 'undefined') { - load = function(f) { + this['load'] = function(f) { globalEval(read(f)); }; } if (typeof printErr === 'undefined') { - printErr = function(){}; + this['printErr'] = function(){}; } if (typeof print === 'undefined') { - print = printErr; + this['print'] = printErr; } // *** Environment setup code *** @@ -576,16 +581,10 @@ function optimizeShiftsInternal(ast, conservative) { var name = node[2][1]; var data = vars[name]; var parent = stack[stack.length-3]; - var parentIndex; - if (parent[0] == 'defun') { - parentIndex = 3; - } else if (parent[0] == 'block') { - parentIndex = 1; - } else { - throw 'Invalid parent for assign-shift: ' + dump(parent); - } - var i = parent[parentIndex].indexOf(stack[stack.length-2]); - parent[parentIndex].splice(i+1, 0, ['stat', ['assign', true, ['name', name + '$s' + data.primaryShift], ['binary', '>>', ['name', name, true], ['num', data.primaryShift]]]]); + var statements = getStatements(parent); + assert(statements, 'Invalid parent for assign-shift: ' + dump(parent)); + var i = statements.indexOf(stack[stack.length-2]); + statements.splice(i+1, 0, ['stat', ['assign', true, ['name', name + '$s' + data.primaryShift], ['binary', '>>', ['name', name, true], ['num', data.primaryShift]]]]); } else if (node[0] == 'var') { var args = node[1]; for (var i = 0; i < args.length; i++) { diff --git a/tools/make_minigzip.py b/tools/make_minigzip.py new file mode 100644 index 00000000..cdd9c2ab --- /dev/null +++ b/tools/make_minigzip.py @@ -0,0 +1,13 @@ +import os, sys +from subprocess import Popen, PIPE, STDOUT + +import shared + +print 'Building zlib' + +zlib = shared.Building.build_library('zlib', shared.EMSCRIPTEN_TEMP_DIR, shared.EMSCRIPTEN_TEMP_DIR, ['libz.a'], make_args=['libz.a'], copy_project=True, source_dir=shared.path_from_root('tests', 'zlib'))[0] + +print 'Building minigzip' + +Popen([shared.EMCC, '-O2', shared.path_from_root('tests', 'zlib', 'minigzip.c'), zlib, '-o', shared.path_from_root('tools', 'minigzip.js')]).communicate() + diff --git a/tools/shared.py b/tools/shared.py index b5ae1ae1..fd51282b 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -607,11 +607,10 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' \ if unsafe: if not Building.can_inline(): opts.append('-disable-inlining') - # -Ox opts do -globaldce, which removes stuff that is needed for libraries and linkables - if Building.can_build_standalone(): - opts.append('-O%d' % optimization_level) - else: - opts.append('-std-compile-opts') + if not Building.can_build_standalone(): + # -O1 does not have -gobaldce, which removes stuff that is needed for libraries and linkables + optimization_level = min(1, optimization_level) + opts.append('-O%d' % optimization_level) #print '[unsafe: %s]' % ','.join(opts) else: allow_nonportable = False |