Returning an integer

// JavaScript
return 23;

/* JSAPI
*
* Warning: This only works for integers that fit in 32 bits.
* Otherwise, convert the number to floating point (see the next example).
*/
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
args.rval().setInt32(23);
return true;

Returning a floating-point number

Exception handling

throw

The most common idiom is to create a new Error object and throw that. JS_ReportError does this. Note that JavaScript exceptions are not the same thing as C++ exceptions. The JSAPI code also has to return false to signal failure to the caller.

When JS_ReportError creates a new Error object, it sets the fileName and lineNumber properties to the line of JavaScript code currently at the top of the stack. This is usually the line of code that called your native function, so it's usually what you want. JSAPI code can override this by creating the Error object directly and passing additional arguments to the constructor:

The JSAPI code here is actually simulating throw Error(message) without the new, as new is a bit harder to simulate using the JSAPI. In this case, unless the script has redefined Error, it amounts to the same thing.

However, if cleanup() is actually a JavaScript function, there's a catch. When an error occurs, the JSContext's pending exception is set. If this happens in foo() or bar() in the above example, the pending exception will still be set when you call cleanup(), which would be bad. To avoid this, your JSAPI code implementing the finally block must:

save the old exception, if any

clear the pending exception so that your cleanup code can run

do your cleanup

restore the old exception, if any

return false if an exception occurred, so that the exception is propagated up.

That code will crash if y is not an object. That's often unacceptable. An alternative would be to simulate the behavior of the JavaScript . notation exactly. It's a nice thought—JavaScript wouldn't crash, at least—but implementing its exact behavior turns out to be quite complicated, and most of the work is not particularly helpful.

Usually it is best to check for !y.isObject() and throw an Error with a nice message.

Defining a constant property

This is the first of three examples involving the built-in function Object.defineProperty(), which gives JavaScript code fine-grained control over the behavior of individual properties of any object.

You can use this function to create a constant property, one that can't be overwritten or deleted. Specify writable: false to make the property read-only and configurable: false to prevent it from being deleted or redefined. The flag enumerable: true causes this property to be seen by for-in loops.

The analogous JSAPI function is JS_DefineProperty. The property attribute JSPROP_READONLY corresponds to writeable: false, JSPROP_ENUMERATE to enumerable: true, and JSPROP_PERMANENT to configurable: false. To get the opposite behavior for any of these settings, simply omit the property attribute bits you don't want.