diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-03-14 13:41:30 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-03-14 13:41:30 -0700 |
commit | e3f438b1088f4da77157d3240d25f4c62a8d0207 (patch) | |
tree | c51c7c0140b7f848b010f4557d4410954bd97e5d /tools/bindings_generator.py | |
parent | 5fd0826bb86bac11150ace522f652b66f02baa22 (diff) |
support c strings as parameters in bindings generator
Diffstat (limited to 'tools/bindings_generator.py')
-rwxr-xr-x | tools/bindings_generator.py | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/tools/bindings_generator.py b/tools/bindings_generator.py index 4731abf3..5f65c82e 100755 --- a/tools/bindings_generator.py +++ b/tools/bindings_generator.py @@ -42,8 +42,22 @@ bindings, and to prevent DFE from removing the code we care about. The JS bindings do more serious work, creating class structures in JS and linking them to the C bindings. -NOTE: ammo.js is currently the biggest consumer of this code. For some - more docs you can see that project's README +Notes: + * ammo.js is currently the biggest consumer of this code. For some + more docs you can see that project's README, + + https://github.com/kripken/ammo.js + + Another project using these bindings is box2d.js, + + https://github.com/kripken/box2d.js + + * C strings (char *) passed to functions are treated in a special way. + If you pass in a pointer, it is assumed to be a pointer and left as + is. Otherwise it must be a JS string, and we convert it to a C + string on the *stack*. The C string will live for the current + function call. If you need it for longer, you need to create a copy + in your C++ code. ''' import os, sys, glob, re @@ -507,6 +521,12 @@ function customizeVTable(object, replacementPairs) { return object; } Module['customizeVTable'] = customizeVTable; + +// Converts a value into a C-style string. +function ensureString(value) { + if (typeof value == 'number') return value; + return allocate(intArrayFromString(value), 'i8', ALLOC_STACK); +} ''') def generate_wrapping_code(classname): @@ -645,17 +665,25 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge #print 'zz types:', map(lambda arg: arg['type'], args) + has_string_convs = False + # We can assume that NULL is passed for null pointers, so object arguments can always # have .ptr done on them - def justargs_fixed(args): - ret = justargs(args)[:] - for i in range(len(args)): - arg = args[i] - if clean_type(arg['type']) in classes: - ret[i] += '.ptr' - return ret + justargs_fixed = justargs(args)[:] + for i in range(len(args)): + arg = args[i] + clean = clean_type(arg['type']) + if clean in classes: + justargs_fixed[i] += '.ptr' + elif arg['type'].replace(' ', '') == 'char*': + justargs_fixed[i] = 'ensureString(' + justargs_fixed[i] + ')' + has_string_convs = True calls = '' + if has_string_convs: + calls += 'var stack = Runtime.stackSave();\n'; + calls += 'try {\n' + #print 'js loopin', params, '|', len(args)#, args for args in params: i = len(args) @@ -667,12 +695,12 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge if constructor: if not dupe: calls += '''this.ptr = _%s_p%d(%s); -''' % (fullname, i, ', '.join(justargs_fixed(args)[:i])) +''' % (fullname, i, ', '.join(justargs_fixed[:i])) else: calls += '''this.ptr = _%s_p%d(%s); -''' % (fullname, i, ', '.join(justargs_fixed(args)[:i])) +''' % (fullname, i, ', '.join(justargs_fixed[:i])) else: - return_value = '''_%s_p%d(%s)''' % (fullname, i, ', '.join((['this.ptr'] if need_self else []) + justargs_fixed(args)[:i])) + return_value = '''_%s_p%d(%s)''' % (fullname, i, ', '.join((['this.ptr'] if need_self else []) + justargs_fixed[:i])) print 'zz making return', classname, method['name'], method['returns'], return_value if method['returns'] in classes: # Generate a wrapper @@ -682,6 +710,9 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge calls += ('return ' if ret != 'void' else '') + return_value + ';' calls += '\n' + if has_string_convs: + calls += '} finally { Runtime.stackRestore(stack) }\n'; + print 'Maekin:', classname, generating_classname, mname, mname_suffixed if constructor: calls += ''' |