diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-11-08 10:09:17 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-11-08 10:09:17 -0800 |
commit | 02d5007d88926a07f0ba5addecc48d5bd540d8f5 (patch) | |
tree | 49fdf4d35b3d185dc7215b811f4c136c66b2299e | |
parent | 1ce3d883f105c22e431fd7c2d1bff33d8c0f73f5 (diff) |
optimal cwrap
-rw-r--r-- | src/preamble.js | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/src/preamble.js b/src/preamble.js index cf0a4c23..16865bd0 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -327,6 +327,25 @@ var globalScope = this; // Note that string arguments will be stored on the stack (the JS string will become a C string on the stack). // @return The return value, as a native JS value (as in returnType) function ccall(ident, returnType, argTypes, args) { + return ccallFunc(getCFunc(ident), returnType, argTypes, args); +} +Module["ccall"] = ccall; + +// Returns the C function with a specified identifier (for C++, you need to do manual name mangling) +function getCFunc(ident) { + try { + var func = eval('_' + ident); + } catch(e) { + try { + func = globalScope['Module']['_' + ident]; // closure exported function + } catch(e) {} + } + assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)'); + return func; +} + +// Internal function that does a C call using a function, not an identifier +function ccallFunc(func, returnType, argTypes, args) { var stack = 0; function toC(value, type) { if (type == 'string') { @@ -350,14 +369,6 @@ function ccall(ident, returnType, argTypes, args) { assert(type != 'array'); return value; } - try { - var func = eval('_' + ident); - } catch(e) { - try { - func = globalScope['Module']['_' + ident]; // closure exported function - } catch(e) {} - } - assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)'); var i = 0; var cArgs = args ? args.map(function(arg) { return toC(arg, argTypes[i++]); @@ -366,7 +377,6 @@ function ccall(ident, returnType, argTypes, args) { if (stack) Runtime.stackRestore(stack); return ret; } -Module["ccall"] = ccall; // Returns a native JS wrapper for a C function. This is similar to ccall, but // returns a function you can call repeatedly in a normal way. For example: @@ -376,9 +386,9 @@ Module["ccall"] = ccall; // alert(my_function(99, 12)); // function cwrap(ident, returnType, argTypes) { - // TODO: optimize this, eval the whole function once instead of going through ccall each time + var func = getCFunc(ident); return function() { - return ccall(ident, returnType, argTypes, Array.prototype.slice.call(arguments)); + return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments)); } } Module["cwrap"] = cwrap; |