Re: How can I call variable in script like this global.var

muhammad sami <[email protected]> Mon, 1 Apr 2019 13:19:13 -0700 (PDT)
Newsgroups gmane.comp.mozilla.devel.jseng
Message-ID <[email protected]>
document is the global object
dialog is the child object
// following code might be needed in some case
// #define __STDC_LIMIT_MACROS
// #include <stdint.h>
#include <mozjs-45/js/TypeDecls.h>
#include <mozjs-45/js/RootingAPI.h>
#include <mozjs-45/js/Class.h>

#include "jsapi.h"
#include "js/Initialization.h"
#include "js/Conversions.h"

using namespace JS;

class JavaScriptEngine {
public:
    static JSClass document_class;
    static JSClass dialog_class;

    JSRuntime *rt = NULL;
    JSContext *cx = NULL;
    RootedObject* document;
    RootedObject* dialog;
    RootedObject* anonymous;

    JavaScriptEngine() {

        JS_Init();

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

        // Create a context.
        cx = JS_NewContext(rt, 8192);

        // Enter a request before running anything in the context.
        JSAutoRequest ar(cx);

        // Create the global object and a new compartment.
        document = new RootedObject(cx, JS_NewGlobalObject(cx, &document_class, nullptr,
                JS::DontFireOnNewGlobalHook));

        JSAutoCompartment ac(cx, *document);

        JS_InitStandardClasses(cx, *document);

        JS_SetErrorReporter(rt, reportError);

    }

    ~JavaScriptEngine() {

        // Shut everything down.
        JS_DestroyContext(cx);
        JS_DestroyRuntime(rt);
        JS_ShutDown();

        delete document;
        delete dialog;
        delete anonymous;
    }

    static 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);
    }

    bool run(JSContext *cx, RootedObject *globaloObj, const char *script, const char *filename = "noname", int lineno = 1) {
        JSAutoRequest ar(cx);
        JSAutoCompartment ac(cx, *globaloObj);

        JS::RootedValue rval(cx);

        JS::CompileOptions opts(cx);
        opts.setFileAndLine(filename, lineno);

        bool ok = JS::Evaluate(cx, opts, script, strlen(script), &rval);

        if (!ok)
            return 1;

        JSString *str = rval.toString();
        if (rval.isObject()) {

            char result[500];
            strcpy(result, script);
            bool ok = JS::Evaluate(cx, opts, strcat(result, " + ' '"), strlen(strcat(result, " + ' '")), &rval);

            if (!ok)
                return 1;
            str = rval.toString();

            if (str != NULL)
                printf("output: %s\n", JS_EncodeString(cx, str));

        } else if (rval.isInt32()) {

            size_t i = rval.toInt32();

            printf("output: is number  %d\n", i);

        } else if (rval.isNull()) {

            printf("rval.isNull\n");

        } else if (rval.isUndefined()) {

            printf("rval.undefined()\n");

        } else if (str != NULL) {
            printf("output: %s\n", JS_EncodeString(cx, str));

        } else {
            printf("output: no match \n");

        }

        return true;

    }

    bool changeScope() {

        JSAutoRequest ar(cx);
        JSAutoCompartment ac(cx, *document);

        JS::HandleObject parent = JS::HandleObject::fromMarkedLocation(&document->get());
        JS::MutableHandleObject protop = JS::MutableHandleObject::fromMarkedLocation(&document->get());
       
        if (JS_GetPrototype(cx, parent, protop)) {

            JS::HandleObject parentprotop = JS::HandleObject::fromMarkedLocation(&protop.get());
            dialog = new RootedObject(cx, JS_NewObjectWithGivenProto(cx, &dialog_class, parentprotop));
        }
       
    }

};

JSClass JavaScriptEngine::document_class = {
    "document",
    JSCLASS_GLOBAL_FLAGS,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr, nullptr, nullptr, nullptr,
    JS_GlobalObjectTraceHook
};

JSClass JavaScriptEngine::dialog_class = {
    "dialog",
    JSCLASS_GLOBAL_FLAGS,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr, nullptr, nullptr, nullptr,
    JS_GlobalObjectTraceHook
};

int main(int argc, const char *argv[]) {

    JavaScriptEngine e;
    e.run(e.cx, e.document, "var document = this; var x = 5;");
    e.run(e.cx, e.document, "document.x");
    e.changeScope();
    e.run(e.cx, e.dialog, "x");
    e.run(e.cx, e.dialog, "var dialog = this;");
    e.run(e.cx, e.dialog, "x=10");
    e.run(e.cx, e.dialog, "dialog.x");
    e.run(e.cx, e.dialog, "document.x");
   
}