aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-11-08 10:09:17 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-11-08 10:09:17 -0800
commit02d5007d88926a07f0ba5addecc48d5bd540d8f5 (patch)
tree49fdf4d35b3d185dc7215b811f4c136c66b2299e
parent1ce3d883f105c22e431fd7c2d1bff33d8c0f73f5 (diff)
optimal cwrap
-rw-r--r--src/preamble.js32
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;