In order to run any JavaScript code in SpiderMonkey, an application must
have two key elements: a JSContext, and a global object.
This section describes what these things are.
The next section explains how to set them up, using JSAPI functions.
Contexts. A JSContext, or context, is like a little machine that
can do many things involving JavaScript code and objects.
It can compile and execute scripts, get and set object properties, call
JavaScript functions, convert JavaScript data from one type to another,
create objects, and so on.
Almost all JSAPI functions require a JSContext* as the first argument.
Use JS_NewContext and JS_DestroyContext to create and destroy a
context.
Use JS_SetContextPrivate and JS_GetContextPrivate to associate
application-specific data with a context.
When your application is done with SpiderMonkey altogether, use
JS_ShutDown to free any remaining cached resources.
(This is a mere nicety if the process is about to exit anyway. But as
that is not always the case, calling JS_Shutdown is a good habit to
get into.)
Global objects. Then, the global object contains all the
classes, functions, and variables that are available for JavaScript code
to use.
Whenever JavaScript code does something like
window.open("http://www.mozilla.org/"), it is accessing a global
property, in this case window.
JSAPI applications have full control over what global properties scripts
can see.
The application starts out by creating an object and populating it with
the standard JavaScript classes, like Array and Object.
Then it adds whatever custom classes, functions, and variables (like
window) the application wants to provide; see Custom
objects below.
Each time the application runs a JS script (using, for example,
JS::Evaluate), it provides the global object for that script to
use.
As the script runs, it can create global functions and variables of its
own.
All of these functions, classes, and variables are stored as properties
of the global object.
To create this object, you first need a JSClass with the
JSCLASS_GLOBAL_FLAGS option.
The example hello.cpp defines a very basic JSClass (named
globalClass) with no methods or properties of its own.
Use JS_NewGlobalObject to create a global object.
Use JS_InitStandardClasses to populate it with the standard JavaScript
globals.
C++ functions that can be called by JavaScript code have the type
JSNative, which is a typedef for
bool (*)(JSContext* cx, unsigned argc, JS::Value* vp.
Each JSNative has the same signature, regardless of what arguments it
expects to receive from JavaScript.
The JavaScript arguments to the function are given in argc and vp.
This signature is obsolescent and in the future will be replaced with
a JS::CallArgs& args parameter.
For now, the first line of your JSNative function should always be
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);args functions as an array of those arguments.
The arguments do not have native C++ types like int and float;
rather, they are JS::Values, JavaScript values.
The native function uses conversion functions such as JS::ToNumber()
to convert the arguments
to C++ types and store them in local variables.
The native function must store its JavaScript return value in
args.rval().
On success, a JSNative must call args.rval() and return true.
The value stored in args.rval() is returned to the JavaScript caller.
On failure, a JSNative calls an error-reporting function, e.g.
JS_ReportErrorUTF8, and returns false.
This causes a JavaScript exception to be thrown.
The caller can catch the exception using a JavaScript try/catch
statement.
To make native functions callable from JavaScript, declare a table of
JSFunctionSpecs describing the functions.
Then call JS_DefineFunctions.
static JSFunctionSpec myjs_global_functions[] = {
JS_FN("rand", myjs_rand, 0, 0),
JS_FN("srand", myjs_srand, 0, 0),
JS_FN("system", myjs_system, 1, 0),
JS_FS_END
};
...
if (!JS_DefineFunctions(cx, global, myjs_global_functions))
return false;
...Once the functions are defined in global, any script that uses
global as the global object can call them, just as any web page can
call alert.