proposal to make JSOPTION_VAROBJFIX mandatory

45 views
Skip to first unread message

Luke Wagner

unread,
Sep 25, 2010, 7:08:51 PM9/25/10
to
Bug 599585 (https://bugzilla.mozilla.org/show_bug.cgi?id=599585) wants
to simplify our handling of the "VariablesObject" (ES3 term) /
"Execution Context's Variable Environment" (ES5 term). When executing
global code (or an eval in global scope), the variables object should be
the global object. However, for historical reasons, when executing
global code with JS_ExecuteScript, the variables object is the 'obj'
parameter, even if that object is not the global object. The option
JSOPTION_VAROBJFIX fixes this by setting the variables object to be the
global object for 'obj'. For a while, JSAPI documentation has
recommended setting this option if a non-global object is ever passed as
'obj' to JS_ExecuteScript. Bug 599585 wants to effectively always have
this option set and remove the symbol JSOPTION_VAROBJFIX. Other than a
small syntactic change for any code using JSOPTION_VAROBJ, this change
would only affect code depending on the variables object not being the
global object, which would be a very strange thing indeed.

Any objections?

Wes Garland

unread,
Sep 25, 2010, 9:27:56 PM9/25/10
to Luke Wagner, Mike Moening, dev-tech-...@lists.mozilla.org
Luke;

FWIW -- stripping JSOPTION_VAROBJFIX breaks me according to my hg log.

*thinking*

I'm about 99% sure the problem is that using varobjfix forces all unbound
var declarations to be on the same global object, which is not the semantic
expected by CommonJS modules when I use JS_CompileFile (or similar) to load
them.

Of course, there are workarounds, like dynamically re-writing the module to
run in a closure, but that's obnoxious and makes some other stuff
impossible. ('other stuff' - other people's legacy code -- but frankly, API
has changed so much that no old code works with new spidermonkey anyhow)

Conclusion - from my POV - force it on if not doing so is a constant perf
hit for the engine or the coders, please try to leave it optional if it's
not. For me it means a couple days of re-engineering and a potential perf
/ RAM hit. The RAM hit is because there is no way that I know of to parse a
script piece-meal, so I'd have to load it into RAM in order to wrap it in a
closure.

I'd recommend checking in with MikeM, I forget exactly what he does with his
super-globals in his web server, but I bet this would affect that.... CCing
Mike with this message.

Wes

PS: Upon further reflection, does this mean that all loaded scripts will
have the same global object if they are on the same context? If so, a
documentation warning or something might be applicable for anybody who cares
about sandboxing.

--
Wesley W. Garland
Director, Product Development
PageMail, Inc.
+1 613 542 2787 x 102

Salvador Ortiz Garcia

unread,
Sep 26, 2010, 12:19:43 AM9/26/10
to Luke Wagner, dev-tech-...@lists.mozilla.org
Hi Luke,

Not so strange from my POV, I'm using this in some cases, mainly for
sandboxing, so I prefer to have the option.

Regards.

Salvador Ortiz.

Luke Wagner

unread,
Sep 26, 2010, 3:03:33 PM9/26/10
to
Ah, thank you for explaining your use case. There is no pressing
optimization that requires forcing JSOPTION_VAROBJFIX -- rather I
thought I had stumbled on an old unused corner of SM that could be
simplified (roughly ~60 lines removed in the patch). But until we have
a simple alternative, I will definitely hold off.

Luke

Brendan Eich

unread,
Sep 27, 2010, 5:59:02 AM9/27/10
to
On Sep 26, 3:27 am, Wes Garland <w...@page.ca> wrote:
> Luke;
>
> FWIW -- stripping JSOPTION_VAROBJFIX breaks me according to my hg log.
>
> *thinking*
>
> I'm about 99% sure the problem is that using varobjfix forces all unbound
> var declarations to be on the same global object, which is not the semantic
> expected by CommonJS modules when I use JS_CompileFile (or similar) to load
> them.

JSOPTION_VAROBJFIX affects only where declared global variables go.
Undeclared globals (created by assignment to free variables) go on the
last object on the scope chain.

Unless you rule those out by making them errors (ES5 strict mode does
this), I don't see how you can rely on the lack of JSOPTION_VAROBJFIX
safely.

/be

Wes Garland

unread,
Sep 27, 2010, 9:03:40 AM9/27/10
to Brendan Eich, dev-tech-...@lists.mozilla.org
> JSOPTION_VAROBJFIX affects only where declared global variables go.
> Undeclared globals (created by assignment to free variables) go on the
> last object on the scope chain.

Right -- when I say "unbound vars", I mean variables which are declared with
var but not in a function.

CommonJS effectively places a var object on the scope chain between each
module and the global object. Most implementations achieve this effect by
wrapping every module in a function before compiling it, however it can be
implemented in SpiderMonkey by simply passing a new object to
JS_ExecuteScript(), after directly loading the module with JS_CompileFile().

For example, consider the following CommonJS module and program. Recall that
CommonJS modules are dynamically loaded singletons.The correct answer is 3:

/** Program: program.js */
var a = 2;
var b = 1;
var aMod = require("./a");

print(aMod.a() + a);


/** Module: a.js */
var a = b;

exports.a = function() { return a };


CommonJS explicitly leaves the behaviour of un-var'd objects (which would be
errors in strict ES5) undefined, as there is no reasonable way to implement
the desired semantic (undeclared variables stay trapped at the module level
without percolating to the program [global object]) in a conformant ES3 or
ES5 environment.

This ambiguity will obviously be a source of bugs in poorly-written CommonJS
modules. Locally, we run JSOPTIONS_STRICT all the time, and often turn
warnings into errors. With the exception of eval'd code, we catch these
errors early with our build system.

Wes

Reply all
Reply to author
Forward
0 new messages