Re: How can I call variable in script like this global.var
Boris Zbarsky <[email protected]> Mon, 1 Apr 2019 17:06:16 -0400
| Newsgroups | gmane.comp.mozilla.devel.jseng |
|---|---|
| Message-ID | <[email protected]> |
Where to start...
On 4/1/19 4:19 PM, muhammad sami wrote:
> RootedObject* document;
> RootedObject* dialog;
> RootedObject* anonymous;
You do know that RootedObject should only be used on the stack, right?
Heap-allocating them is pretty much guaranteed to not work well in the
end. But that's not the immediate problem here...
> JSString *str = rval.toString();
> if (rval.isObject()) {
That toString() should really not happen until you know it's a string...
I strongly urge you to run this in debug mode, then fix all the
resulting assertion failures.
> bool changeScope() {
> JS::HandleObject parent = JS::HandleObject::fromMarkedLocation(&document->get());
> JS::MutableHandleObject protop = JS::MutableHandleObject::fromMarkedLocation(&document->get());
OK. So both "parent" and "protop" are pointing to the same memory.
> if (JS_GetPrototype(cx, parent, protop)) {
And therefore this overwrites "document" with its prototype. After this
point, "document" stores the thing that used to be its prototype
(Object.prototype in the original "document" global, I would guess?
You should pretty much never create HandleObject or MutableHandleObject
explicitly. What this cod should have looked like, I suspect:
RootedObject proto(cx);
if (!JS_GetPrototype(cx, *document, &proto)) {
// handle failure here
}
dialog = new RootedObject(cx, JS_NewObjectWithGivenProto(cx,
&dialog_class, proto));
But none of that matters for the real issue at hand, because...
> dialog = new RootedObject(cx, JS_NewObjectWithGivenProto(cx, &dialog_class, parentprotop));
OK, so this is creating a new object that is _not_ a global.
Then when you call run() and pass it "dialog" as globaloObj, and enter
its compartment, you are actually entering the compartment of the global
of "dialog", which is the compartment you were in when you called
JS_NewObjectWithGivenProto, which is the compartment of "document". So
all the run() calls evaluate things at global scope, with the global
being "document".
It sounds like you want to run things with a non-global "dialog" on the
scope chain. To do that, you need to use the version of JS::Evaluate
that takes an AutoObjectVector scope chain. See
https://searchfox.org/mozilla-central/rev/09a322c117d64de4c652dd007daf515a13be1254/js/src/jsapi.h#3210-3216
(though the line numbers may not match up in SpiderMonkey 45; I would
check on that).
Hope that helps,
Boris