Closed Bug 652375 Opened 10 years ago Closed 8 years ago

Possible Web Console bug: valueOf() yields global object

Categories

(Core :: JavaScript Engine, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: erights, Unassigned)

References

Details

Attachments

(1 file)

On the Nightly 6.0a1 (2011-04-23) built in Web Console:

    valueOf()
    [object Window]

I have reviewed the ES5 spec carefully and this is clearly wrong -- if code entered at the Web Console top level is supposed to be equivalent to global code. As https://bugzilla.mozilla.org/show_bug.cgi?id=619283#c52 points out, the Web Console may not be, and the bug does not manifest otherwise.

For example, if code entered at the Web Console executes as if in a "with (globalObject) {...}", then the behavior reported here would be correct.
See Also: → 619283
Should alert 'ok' and does on FF4
The Web Console uses evalInSandbox() to evaluate the script.  

By the time we land in obj_valueOf, vp[1] is non-null; it's null for a normal evaluation at global scope (e.g. via javascript: URI).  One difference is that the stack to obj_valueOf for the javascript: case is this:

#0  obj_valueOf (cx=0x21897340, argc=0, vp=0x1f82c060) at /Users/bzbarsky/mozilla/vanilla/mozilla/js/src/jsobj.cpp:900
#1  0x046e296a in js::CallJSNative (cx=0x21897340, native=0x4705068 <obj_valueOf(JSContext*, unsigned int, js::Value*)>, argc=0, vp=0x1f82c060) at jscntxtinlines.h:698
#2  0x046d1d3d in js::Interpret () at /Users/bzbarsky/mozilla/vanilla/mozilla/js/src/jsinterp.cpp:4727
#3  0x046e6b0f in js::RunScript (cx=0x21897340, script=0x22f63980, fp=0x1f82c030) at jsinterp.cpp:636
#4  0x046e8b51 in js::Execute (cx=0x21897340, chain=0x216ec0a0, script=0x22f63980, prev=0x0, flags=0, result=0xbfffc668) at jsinterp.cpp:996
#5  0x04608eab in EvaluateUCScriptForPrincipalsCommon (cx=0x21897340, obj=0x216ec0a0, principals=0x21c31e04, chars=0xbfffc748, length=18, filename=0x2dcc5518 "javascript:valueOf();%20void(0)", lineno=1, rval=0xbfffc668, compileVersion=JSVERSION_DEFAULT) at /Users/bzbarsky/mozilla/vanilla/mozilla/js/src/jsapi.cpp:5039

while for the console case it's this:

#0  obj_valueOf (cx=0x2dcb2bb0, argc=0, vp=0x1f82c248) at /Users/bzbarsky/mozilla/vanilla/mozilla/js/src/jsobj.cpp:900
#1  0x046e296a in js::CallJSNative (cx=0x2dcb2bb0, native=0x4705068 <obj_valueOf(JSContext*, unsigned int, js::Value*)>, argc=0, vp=0x1f82c248) at jscntxtinlines.h:698
#2  0x046e6fe0 in js::Invoke (cx=0x2dcb2bb0, argsRef=@0xbfffa1e0, flags=0) at jsinterp.cpp:679
#3  0x046e7ab6 in js::ExternalInvoke (cx=0x2dcb2bb0, thisv=@0x1f82c1f0, fval=@0x2da24588, argc=0, argv=0x1f82c1f8, rval=0xbfffa248) at jsinterp.cpp:839
#4  0x0475a73e in js::JSProxyHandler::call (this=0x49bbdc4, cx=0x2dcb2bb0, proxy=0x2da24548, argc=0, vp=0x1f82c1e8) at /Users/bzbarsky/mozilla/vanilla/mozilla/js/src/jsproxy.cpp:270
#5  0x047c03ad in JSWrapper::call (this=0x49bbdc4, cx=0x2dcb2bb0, wrapper=0x2da24548, argc=0, vp=0x1f82c1e8) at /Users/bzbarsky/mozilla/vanilla/mozilla/js/src/jswrapper.cpp:248
#6  0x047c0508 in JSCrossCompartmentWrapper::call (this=0x49bbdc4, cx=0x2dcb2bb0, wrapper=0x2da24548, argc=0, vp=0x1f82c1e8) at /Users/bzbarsky/mozilla/vanilla/mozilla/js/src/jswrapper.cpp:628
#7  0x0475c1b7 in js::JSProxy::call (cx=0x2dcb2bb0, proxy=0x2da24548, argc=0, vp=0x1f82c1e8) at /Users/bzbarsky/mozilla/vanilla/mozilla/js/src/jsproxy.cpp:836
#8  0x0475c23a in js::proxy_Call (cx=0x2dcb2bb0, argc=0, vp=0x1f82c1e8) at /Users/bzbarsky/mozilla/vanilla/mozilla/js/src/jsproxy.cpp:1088
#9  0x046e296a in js::CallJSNative (cx=0x2dcb2bb0, native=0x475c1cd <js::proxy_Call(JSContext*, unsigned int, js::Value*)>, argc=0, vp=0x1f82c1e8) at jscntxtinlines.h:698
#10 0x046e6f46 in js::Invoke (cx=0x2dcb2bb0, argsRef=@0xbfffa8d0, flags=0) at jsinterp.cpp:672
#11 0x046d1eaa in js::Interpret () at /Users/bzbarsky/mozilla/vanilla/mozilla/js/src/jsinterp.cpp:4738
#12 0x046e6b0f in js::RunScript (cx=0x2dcb2bb0, script=0x2dce89d0, fp=0x1f82c1b8) at jsinterp.cpp:636
#13 0x046e8b51 in js::Execute (cx=0x2dcb2bb0, chain=0x2da2d028, script=0x2dce89d0, prev=0x0, flags=0, result=0xbfffb458) at jsinterp.cpp:996
#14 0x04608eab in EvaluateUCScriptForPrincipalsCommon (cx=0x2dcb2bb0, obj=0x2da2d028, principals=0x21c31e04, chars=0x2dce1468, length=9, filename=0x2dce8088 "Web Console", lineno=1, rval=0xbfffb458, compileVersion=JSVERSION_1_8) at /Users/bzbarsky/mozilla/vanilla/mozilla/js/src/jsapi.cpp:5039
I smell the bug 634590 rat.
I think the key part is this function proxy bit:

614     JSCrossCompartmentWrapper::call(JSContext *cx, JSObject *wrapper, uintN argc, Value *vp)
...
616         AutoCompartment call(cx, wrappedObject(wrapper));
...
621         if (!call.destination->wrap(cx, &vp[1]))

This ensures that the |this| seen by the wrapped callee is the wrappedObject of the wrapper.  And the |wrapper| in this case is the callee we have in the function proxy's [[Call]].  The |this| for the function proxy seems to be altogether ignored if I read this right.

No idea what the "right" behavior here is per spec, or even whether it's defined.
Hrm.  Or maybe I'm on crack in comment 4...  We have a non-null vp[1] by the time we enter js::proxy_Call.
And in fact by the time we enter js::CallJSNative.
Jeff, I think you're right.  The patches for bug 636364 made us skip converting undefined to an object in the function proxy case under this condition:

  if (fun->isInterpreted() && fun->inStrictMode())

But maybe that should instead be:

  if (!fun->isInterpreted() || fun->inStrictMode())

?
Blocks: 636364
Fixed by bug 671947.
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.