Question

I've written a portable framework in JavaScript, and I'd like to run some performance tests under various JavaScript interpreter shell environments. In order to accomplish this, I need to be able to pass command-line arguments (argv) to the script context. Rhino and Spidermonkey interpreters do this by default already, exposing all arguments after the script file as an array bound to the the "arguments" identifier on the global object. It was originally my intention to bring the same functionality to the v8 sample shell, as well as the JavaScriptCore jsc shell, but I soon realized that this would require much more effort, and I really only need the last command-line argument in order to run my tests. So, I have been able to get this working in v8, converting the last char* element in argv to a v8::String and binding it to the identifier "lastArg" on the global object.

Unfortunately, I'm having much more trouble accomplishing the same thing with JavaScriptCore. I haven't been able to find much documentation on the JavaScriptCore C++ API, and the code in the JavaScriptCore jsc interpreter (in Source/JavaScriptCore/jsc.cpp) is more difficult for me to understand than the code in the v8 sample shell.

Specifically, I'd appreciate any resources (documentation, tutorials, sample code, etc.) that could help illustrate the following tasks:

  • creating a new JavaScriptCore JSString instance from a char*
  • binding the JSString instance to an identifier on the GlobalObject global object instance.

I intend to simply patch function jscmain of jsc.cpp:

int jscmain(int argc, char** argv, JSGlobalData* globalData)
{
    JSLock lock(SilenceAssertionsOnly);

    Options options;
    parseArguments(argc, argv, options, globalData);

    GlobalObject* globalObject = GlobalObject::create(*globalData, GlobalObject::createStructure(*globalData, jsNull()), options.arguments);

    //TODO: my patch would go here: create a new javascript string, and assign it to an identifier on globalObject instance

    bool success = runWithScripts(globalObject, options.scripts, options.dump);
    if (options.interactive && success)
        runInteractive(globalObject);

    return success ? 0 : 3;
}

I'd greatly appreciate any guidance anyone can offer.

Was it helpful?

Solution

To create a JSString from a char*:

JSC::JSGlobalData * globalData;

JSString * CreateJSString(const char * chars, size_t length)
{   
    const char * string = chars;
    if (0 == length)
    {
        length = strlen(chars);
    }

    if (isASCII(string, length))
    {
        JSString * jsstr = JSC::jsString(globalData, JSC::UString(string, length));
        return jsstr;
    }

    // Fall through
    return NULL;
}

Adding to global object:

JSC::JSGlobalObject * globalObject;
JSC::JSGlobalData * globalData;
JSC::Identifier name;
JSC::JSString * str;

globalObject->putDirect(*globalData, name, JSC::JSValue(str));

Note:: Assumes you create the stubbed objects properly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top