Tag Archives: javascript

Embedding javascript via spidermonkey into C

You’ve probably read that before in my old blog …

and here’s the code:


#include <stdio.h>
#include <js/jsapi.h>

#define TESTSCRIPT "print(\"hello world\");"

JSBool js_print(JSContext *cx, uintN argc, jsval *vp);

/* The class of the global object. */
static JSClass global_class =
{
    "global", JSCLASS_GLOBAL_FLAGS,
    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
    JS_StrictPropertyStub,
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
    JSCLASS_NO_OPTIONAL_MEMBERS
};

static JSFunctionSpec myjs_global_functions[] =
{
    JS_FS("print",   js_print,   1, 0),
    JS_FS_END
};

/* The error reporter callback. */
void reportError(JSContext *cx, const char *message, JSErrorReport *report)
{
    fprintf(stderr, "%s:%u:%s\n",
            report->filename ? report->filename : "<no filename>",
            (unsigned int) report->lineno,
            message);
}

JSBool js_print(JSContext *cx, uintN argc, jsval *vp)
{
    JSString* u16_txt;
    unsigned int length;
    char *txt;

    if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S", &u16_txt))
        return JS_FALSE;

    length = JS_GetStringEncodingLength(cx, u16_txt);
    txt = alloca(sizeof(char)*(length+1));
    JS_EncodeStringToBuffer(u16_txt, txt, length);

    printf("%.*s\n", length, txt);

    //free(txt);
    return JS_TRUE;
}

void test(JSContext *cx)
{
    JSBool ok;
    jsval rval;
    JSObject *script;

    // interpret:
    ok = JS_EvaluateScript(cx, JS_GetGlobalObject(cx), TESTSCRIPT, strlen(
         TESTSCRIPT), "TEST", 0, &rval);
    // compile:
    //script = JS_CompileScript(cx, JS_GetGlobalObject(cx), TESTSCRIPT,
               strlen(TESTSCRIPT), "TEST", 0);
    //JS_ExecuteScript(cx, JS_GetGlobalObject(cx), script, &rval);
}

int main(int argc, const char *argv[])
{
    /* JS variables. */
    JSRuntime *rt;
    JSContext *cx;
    JSObject  *global;

    /* Create a JS runtime. */
    rt = JS_NewRuntime(8L * 1024L * 1024L);
    if (rt == NULL)
        return 1;

    /* Create a context. */
    cx = JS_NewContext(rt, 8192);
    if (cx == NULL)
        return 1;
    JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT |
                  JSOPTION_METHODJIT);
    JS_SetVersion(cx, JSVERSION_LATEST);
    JS_SetErrorReporter(cx, reportError);

    /* Create the global object in a new compartment. */
    global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
    if (global == NULL)
        return 1;

    if (!JS_DefineFunctions(cx, global, myjs_global_functions))
        return JS_FALSE;

    /* Populate the global object with the standard globals,
       like Object and Array. */
    if (!JS_InitStandardClasses(cx, global))
        return 1;

    /* Your application code here. This may include JSAPI calls
       to create your own custom JS objects and run scripts. */
    test(cx);

    /* Cleanup. */
    JS_DestroyContext(cx);
    JS_DestroyRuntime(rt);
    JS_ShutDown();
    return 0;
}

Compile:

 gcc -lmozjs185 test.c