My favorites | Sign in
v8
Project Home Downloads Wiki Issues Source Code Search
New issue   Search
for
  Advanced search   Search tips   Subscriptions
Issue 2407: Object.isFrozen() throws when called on a function whose caller is strict
2 people starred this issue and may be notified of changes. Back to list
 
Project Member Reported by adamk@chromium.org, Nov 13, 2012
This code throws in Chrome and returns false in Safari and Firefox:

function nonStrict() { return Object.isFrozen(nonStrict) }
function strict() { "use strict"; return nonStrict() }
strict()

Chrome throws "TypeError: Illegal access to a strict mode caller function." All three browsers (properly) throw that error in the following case:

function nonStrict() { return nonStrict.caller }
function strict() { "use strict"; return nonStrict() }
strict()

Presumably v8 fails the first test because it uses the same machinery inside Object.isFrozen that it uses inside the "nonStrict.caller" get in the second case.
Nov 13, 2012
Project Member #1 arv@chromium.org
Looking at https://code.google.com/searchframe#W9JxUuHYyMg/trunk/src/v8natives.js&q=isFrozen%20package:v8%5C.googlecode%5C.com&l=1228. Nothing stands out as [[Get]]'ing the value of a property.

However, it is strange that we are iterating over all the properties. Don't we keep a flag on the object for this?
Nov 13, 2012
Project Member #2 adamk@chromium.org
I actually have the stack trace for this. Here's a shorthand version:

Accessors::FunctionGetCaller
JSObject::GetPropertyWithCallback
Object::GetProperty
GetOwnProperty (runtime.cc)
%GetOwnProperty (Runtime_GetOwnProperty, now we're in C++)
GetOwnProperty (JS)
ObjectIsFrozen (JS)

So it's the GetOwnProperty() call in ObjectIsFrozen that leads to this, because the non-strict caller property presents itself as a value property (despite being implemented internally with a getter) and thus getting the descriptor requires getting the value.
Nov 14, 2012
Project Member #3 adamk@chromium.org
Note that Object.freeze() has a similar problem: 

function nonStrict() { Object.freeze(nonStrict); }
function strict() { "use strict"; nonStrict() }
strict();

throws as well (and doesn't in other engines).
Nov 14, 2012
Project Member #4 rossb...@chromium.org
The same problem is likely to apply to seal/isSealed.

@arv: No, there is no flag currently. Presumably, the rational was that you don't need to perform such a check very often. Note also that it would only help as a fast case anyway, in general you still have to iterate.
Status: Accepted
Owner: rossb...@chromium.org
Cc: adamk@chromium.org rafaelw@chromium.org arv@chromium.org mstarzinger@chromium.org
Labels: Type-Bug Priority-Medium ES5
Dec 13, 2012
Project Member #6 rossb...@chromium.org
Fixed by changing the semantics of caller poisoning, in accordance with spec change decided at TC39. See:

https://bugs.ecmascript.org/show_bug.cgi?id=310
https://bugs.ecmascript.org/show_bug.cgi?id=982

Status: Fixed
Sign in to add a comment

Powered by Google Project Hosting