0

I'm embedding SpiderMonkey and am attempting to use JS_BindCallable. However, I have a JSObject * that I want to use as the newThis, yet the function takes a JSRawObject. The documentation on JSRawObject seems sparse and the header files haven't provided any clues.

It appears to compile if I simply pass it a JSObject *, without crashing, but I'm not sure why, and that makes me uncomfortable. Further, it doesn't seem to work - not sure if that's because of this issue or because of something else. In particular, I'm doing this:

JSObject *result = JS_NewObject(cx, NULL, NULL, NULL);

//create .finish() callable
int props = JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE;
JS_DefineFunction(cx, result, "finish", my_native_func, 0, props);

//bind finish to always use 'this'
jsval jsvFinishFuncObj;
JS_GetProperty(cx, result, "finish", &jsvFinishFuncObj);
JSObject *finishFuncObj = JSVAL_TO_OBJECT(jsvFinishFuncObj);
JS_BindCallable(cx, finishFuncObj, result);
Claudiu
  • 224,032
  • 165
  • 485
  • 680

1 Answers1

1

JSRawObject was a typedef for JSObject*, so your usage is right. We did this, because in future version all APIs are going to take handles, so like JS::HandleObject. You might read about that upcoming change here: https://developer.mozilla.org/en-US/docs/SpiderMonkey/31#Migrating_to_SpiderMonkey_31

I think you have to use the return value of JS_BindCallable and overwrite "finish" with it. Actually you might do something like this:

//define a function on an object which is bound to the object it is defined on
JSBool JS_DefineBoundFunction(JSContext *cx, JSObject *obj, const char *name,
                              JSNative call, unsigned int nargs, unsigned int attrs) {
    JSFunction *func = JS_NewFunction(cx, call, nargs, 0, NULL, name);
    if (!func) {
        return JS_FALSE;
    }
    JSObject *funcObj = JS_GetFunctionObject(func);
    if (!funcObj) {
        return JS_FALSE;
    }
    JSObject *boundFuncObj = JS_BindCallable(cx, funcObj, obj);
    if (!boundFuncObj) {
        return JS_FALSE;
    }
    return JS_DefineProperty(cx, obj, name,
                             OBJECT_TO_JSVAL(boundFuncObj),
                             NULL, NULL, attrs);
}
Claudiu
  • 224,032
  • 165
  • 485
  • 680
evilpie
  • 2,718
  • 20
  • 21
  • ah that makes sense, thanks... now, how do I go from the `JSFunction *` to a `JSObject *`? – Claudiu Sep 27 '13 at 20:47
  • Just cast JSFunction is a subclass of JSObject: http://dxr.mozilla.org/mozilla-central/source/js/src/jsfun.h?from=JSFunction#l25 – evilpie Sep 27 '13 at 20:55
  • Oh gotcha. I used `JS_GetFunctionObject` which seems to just cast it. I made a helper function which works, I'll edit your test code w/ it & accept the answer. – Claudiu Sep 27 '13 at 20:57