JavaScript execution using Spidermonkey
Spidermonkey is a JavaScript runtime that is embeddable in C/C++/Rust projects and allows you to interpret JavaScript and define bindings for JavaScript.
In this example we will see how to execute a script using Spidermonkey and get information about the execution. The prerequisites for this project are some knowledge of C/C++.
#include <js/Initialization.h> // JS_InitWithFailureDiagnostic, JS_Shutdown
#include <jsapi.h> // JS_NewContext
#include <js/CompilationAndEvaluation.h> // EvaluateUtf8Path
#include <js/CompileOptions.h> // OwningCompileOptions
namespace global {
// describe the global object to spidermonkey
static JSClass globalClass = {
"global",
JSCLASS_GLOBAL_FLAGS,
&JS::DefaultGlobalClassOps,
};
};
int main(int argc, const char* argv[]) {
auto diagnosis = JS_InitWithFailureDiagnostic();
if (diagnosis) {
std::fprintf(stderr, diagnosis);
return EXIT_FAILURE;
}
// creates an execution context
JSContext *ctx = JS_NewContext(JS::DefaultHeapMaxBytes);
// initialize the parts of spidermonkey that are written in JavaScript
JS::InitSelfHostedCode(ctx);
// set up boundaries for objects in the execution context
JS::RealmOptions options;
JS::RootedObject global(ctx, JS_NewGlobalObject(ctx, &global::globalClass, nullptr, JS::FireOnNewGlobalHook, options));
// enter the boundaries for the execution context
JSAutoRealm ar(ctx, global);
// evaluate the test.js script and store the result in rval
JS::RootedValue rval(ctx);
JS::OwningCompileOptions compilationOptions(ctx);
JS::EvaluateUtf8Path(ctx, compilationOptions, "test.js", &rval);
// If an exception was encountered please print it.
// E.g. syntax error
if (JS_IsExceptionPending(ctx)) {
JS::ExceptionStack exnStack(ctx);
JS::StealPendingExceptionStack(ctx, &exnStack);
JS::ErrorReportBuilder builder(ctx);
builder.init(ctx, exnStack, JS::ErrorReportBuilder::NoSideEffects);
JS::PrintError(ctx, stderr, builder, false);
}
// tear down the execution context and stops Spidermonkey
JS_DestroyContext(ctx);
JS_ShutDown();
}