| 599 | |
| 600 | // Internal function that does a C call using a function, not an identifier |
| 601 | function ccallFunc(func, returnType, argTypes, args) { |
| 602 | var stack = 0; |
| 603 | function toC(value, type) { |
| 604 | if (type == 'string') { |
| 605 | if (value === null || value === undefined || value === 0) return 0; // null string |
| 606 | value = intArrayFromString(value); |
| 607 | type = 'array'; |
| 608 | } |
| 609 | if (type == 'array') { |
| 610 | if (!stack) stack = Runtime.stackSave(); |
| 611 | var ret = Runtime.stackAlloc(value.length); |
| 612 | writeArrayToMemory(value, ret); |
| 613 | return ret; |
| 614 | } |
| 615 | return value; |
| 616 | } |
| 617 | function fromC(value, type) { |
| 618 | if (type == 'string') { |
| 619 | return Pointer_stringify(value); |
| 620 | } |
| 621 | assert(type != 'array'); |
| 622 | return value; |
| 623 | } |
| 624 | var i = 0; |
| 625 | var cArgs = args ? args.map(function(arg) { |
| 626 | return toC(arg, argTypes[i++]); |
| 627 | }) : []; |
| 628 | var ret = fromC(func.apply(null, cArgs), returnType); |
| 629 | if (stack) Runtime.stackRestore(stack); |
| 630 | return ret; |
| 631 | } |
| 632 | |
| 633 | // Returns a native JS wrapper for a C function. This is similar to ccall, but |
| 634 | // returns a function you can call repeatedly in a normal way. For example: |