Subj : Re: Calling functions without the lookup To : Brian Barnes From : Brendan Eich Date : Wed Jan 15 2003 09:31 am Brian Barnes wrote: > Brendan Eich wrote: > >> Brian Barnes wrote: >> >>> jsval myfunc; >>> >>> JS_GetProperty(cx,obj,"BLECH",&myfunc); >>> JS_CallFunctionValue(cx,obj,"BLECH",argc,&argv,&rval); >> >> >> You must mean >> >> JS_CallFunctionValue(cx, obj, >> (JSFunction *) JS_GetPrivate(cx, >> JSVAL_TO_OBJECT(myfunc), >> argc, &argv, &rval); >> >> a jsval is not a JSFunction*, or even a tagged JSFunction*. > > > Need to not type so fast. Me too! ;-) > What I meant was: > > JS_CallFunctionValue(cx,obj,myfunc,argc,&argv,&rval); > > JS_CallFunctionValue takes a jsval, not a JSFunction (from the code). Right -- I was clearly trying to show how to use JS_CallFunction. But JS_CallFunctionValue is better for the case you're interested in. > What I did was just to tear JS_CallFunctionName apart, so I could > avoid calling the same code (which is basically the JS_GetPrivate) > over and over again. > > So, trying again: > > jsval myfunc; > JS_GetProperty(cx,obj,"BLECH",&myfunc); > JS_CallFunctionValue(cx,obj,myfunc,argc,&argv,&rval); > > Should be equivalent to JS_CallFunctionName with BLECH. It's what the > JS_CallFunctionName does. I'm calling into a compiled script and I > don't expect somebody to redefine the function (if they do, they will > get an error, as they should.) > > I always miss something super technical when talking with you Brendan! > I'm not sure why I need to cast to JSFunction or do the getprivate > instead of what I have above. You don't, I was just showing the JS_CallFunction alternative (but I forgot to change the name). The short answer is you're doing the right thing. But (more super-technical detail alert) you may not be able to use that API anyway, if you need to preserve the scope chain (linked by the parent slot) of the object tagged in myfunc. If you extract that object's private data (a JSFunction*, call it fun), and then call that function via JS_CallFunction, the API will use fun->object as the callable object to invoke -- which means you'll get the scope chain that the compiler saw when it created fun. That is not necessarily the right scope chain, if you are using JS_CloneFunctionObject, or if the function object you got from the obj.BLECH property was cloned for you automatically. If it came from a nested function declared in JS, or even a top-level function in a script that you precompile in a null top-level object, or a "compile-time only" top-level object used for precompiling, if the script was executed against a different top-level, then the functions declared in it at top-level will be automatically cloned. Capturing the value of such a function in script, and storing it in obj.BLECH, could lead to a situation where you can't use JS_CallFunction from native code to invoke the function with the right scope chain. In other words, JSObject => JSFunction is many to one, while JSFunction => JSObject (fun->object) is a 1:1 link back to the compiler-created function object. I hope this helps. /be .