605
607
Object.defineProperty(aTarget, aName, { value: aValue, enumerable: true });
609
* Set up a ctype function template and create a helper function for
610
* wrapping JS functions as ctype functions, for use as an async callback
611
* in asynchronous API's
614
* The object to add the helper and function template to
616
* The type name of the callback. Note that the helper function
617
* will be "wrap<type>" (eg, "wrapGAsyncReadyCallback")
619
* The native return type of the async callback
621
* An array of native argument types to be passed to the callback
623
createAsyncCallbackWrapper: {
624
value: function CTypesUtils_createAsyncCallbackWrapper(aObj, aName,
630
Object.defineProperty(aObj, aName, {
631
value: ctypes.FunctionType(ctypes.default_abi, aRetType, aArgTypes).ptr,
635
Object.defineProperty(aObj, "wrap" + aName, {
636
value: function(aCallback) {
637
let cb = function() {
639
return aCallback.apply(null, arguments);
640
} catch(e) { ERROR("Async callback threw", e); }
641
delete callbacks[id];
643
let ccb = aObj[aName](cb);
645
while (callbacks[++serial]) {}
610
wrapCallback: { value: function CTypesUtils_wrapCallback(aCallback, aOptions) {
612
function CallbackRootData(aWrapper) {
613
this.wrapper = aWrapper;
617
if (typeof(aCallback) != "function") {
618
throw Error("Callback must be a function");
621
if (typeof(aOptions) != "object" ||
622
(!aOptions.type && !aOptions.rettype) ||
623
(aOptions.type && aOptions.rettype)) {
624
throw Error("Must specify a valid function type or return type");
627
if (aOptions.root && aCallback in gCallbacks) {
628
gCallbacks[aCallback].refcnt++;
629
return gCallbacks[aCallback].wrapper;
632
let wrapper = function() {
634
return aCallback.apply(null, arguments);
635
} catch(e) { ERROR("Callback threw", e); }
640
type = aOptions.type;
642
type = ctypes.FunctionType(ctypes.default_abi, aOptions.rettype,
643
aOptions.argtypes ? aOptions.argtypes : []).ptr;
645
wrapper = type(wrapper);
648
gCallbacks[aCallback] = new CallbackRootData(wrapper);
649
gCallbacksByWrapper[wrapper] = aCallback;
655
unrootCallback: { value: function CTypesUtils_unrootCallback(aCallback) {
656
if (!(aCallback in gCallbacks)) {
657
throw Error("The callback cannot be found in our roots");
660
if (gCallbacks[aCallback].refcnt <= 0) {
661
ERROR("Ugh, why is this callback still rooted");
664
if (--gCallbacks[aCallback].refcnt <= 0) {
665
let wrapper = gCallbacks[aCallback].wrapper;
666
delete gCallbacks[aCallback];
667
delete gCallbacksByWrapper[wrapper];
671
unrootCallbackByWrapper: { value: function CTypesUtils_unrootCallbackByWrapper(aCallback) {
672
if (!(aCallback in gCallbacksByWrapper)) {
673
throw Error("The callback cannot be found in our roots");
676
this.unrootCallback(gCallbacksByWrapper[aCallback]);
679
callbackIsRooted: { value: function CTypesUtils_callbackIsRooted(aCallback) {
680
if (aCallback in gCallbacks) {
684
if (aCallback in gCallbacksByWrapper &&
685
gCallbacksByWrapper[aCallback] in gCallbacks) {