WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
141871
Throwing a frozen object makes it claim to be unfrozen
https://bugs.webkit.org/show_bug.cgi?id=141871
Summary
Throwing a frozen object makes it claim to be unfrozen
Mark S. Miller
Reported
2015-02-21 16:45:47 PST
This occurs on Safari 7.0.5 (9537.77.4). Discovered by Kevin Reid. Test case: var o = Object.freeze([1, 2]); try { console.log(Object.isFrozen(o)); throw o; } catch (e) { console.log(e.toString(), Object.isFrozen(e), e === o); } Output in Safari; [Log] true [Log] 1,2 false true Throwing o made the subsequent isFrozen claim that it isn't. But as far as we can tell so far by attempting to mutate it, it actually is so anyway.
Attachments
patch.
(52.46 KB, patch)
2015-03-31 14:30 PDT
,
Matthew Mirman
no flags
Details
Formatted Diff
Diff
patch.
(52.47 KB, patch)
2015-03-31 15:08 PDT
,
Matthew Mirman
ggaren
: review-
ggaren
: commit-queue-
Details
Formatted Diff
Diff
patch.
(69.81 KB, patch)
2015-04-03 12:54 PDT
,
Matthew Mirman
ggaren
: review-
ggaren
: commit-queue-
Details
Formatted Diff
Diff
patch
(76.03 KB, patch)
2015-04-06 16:21 PDT
,
Matthew Mirman
ggaren
: review+
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Alexey Proskuryakov
Comment 1
2015-02-22 01:27:54 PST
Does this only occur on 7.0.5, or on current versions too? 7.0.5 is not even the newest major release.
Mark S. Miller
Comment 2
2015-02-22 09:37:13 PST
Just verified that the same symptoms occur on Version 7.1.3 (9537.85.12.18)
Matthew Mirman
Comment 3
2015-03-31 14:30:05 PDT
Created
attachment 249851
[details]
patch. Small benchmark on octane looked fine. running a full benchmark now.
Filip Pizlo
Comment 4
2015-03-31 14:45:30 PDT
Can you rebase?
Matthew Mirman
Comment 5
2015-03-31 15:08:53 PDT
Created
attachment 249858
[details]
patch.
Geoffrey Garen
Comment 6
2015-03-31 15:49:51 PDT
Comment on
attachment 249858
[details]
patch. EWS is failing.
Matthew Mirman
Comment 7
2015-04-03 12:54:31 PDT
Created
attachment 250093
[details]
patch. patch did not cause any performance regression on my machine.
Geoffrey Garen
Comment 8
2015-04-03 13:37:07 PDT
Comment on
attachment 250093
[details]
patch. View in context:
https://bugs.webkit.org/attachment.cgi?id=250093&action=review
Which part of this patch removes error info that we used to add? You need to add a test for that part of the patch, both with frozen and unfrozen objects, and preferably with various types of objects, including DOM nodes, vanilla objects, arrays, and so on.
> LayoutTests/ChangeLog:3 > + Source and stack information should get appended only to native error constructors
I think you meant "native errors" and not "native error constructors". It's the error that holds the information, not the error's constructor.
> LayoutTests/ChangeLog:4 > + Source and stack information should get appended only to native error constructors > + and should be added at construction time rather than when thrown.
Why did you make this change? You should explain why this new behavior is preferable to the old behavior.
> LayoutTests/http/tests/w3c/resources/testharness.js:2070 > function AssertionError(message) > { > + var e = new Error(); > + this.stack = e.stack.substring(e.stack.indexOf('\n')+1, e.stack.length); > this.message = message; > }
It looks like this test was imported from the W3C, but it required modification in order to continue passing after your code changes. Doest this mean that the W3C test, when run from source, no longer passes? Does it pass in other browsers?
> LayoutTests/js/dom/stack-trace-expected.txt:359 > - 0 inlineableThrow at stack-trace.js:302:33 > + 0 inlineableThrow at stack-trace.js:302:40
Why did this result change? I think I might know, but I'm not sure. This is the kind of thing you should explain in your ChangeLog.
> LayoutTests/js/exception-properties-expected.txt:6 > -PASS enumerableProperties(error) is [] > +PASS enumerableProperties(error).sort() is ["column", "line", "sourceURL"]
Why is it good that these properties are enumerable now?
> Source/JavaScriptCore/ChangeLog:4 > + Source and stack information should get appended only to native error constructors > + and should be added at construction time rather than when thrown.
Same comment from other ChangeLog.
> Source/JavaScriptCore/parser/ParserError.h:97 > return addErrorInfo(
If we're only supposed to add error properties during construction, why do we still have an addErroInfo helper function, which adds those properties after construction?
> Source/JavaScriptCore/runtime/ErrorInstance.cpp:40 > +static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
Did any of this code change, or did you just move it? If you just moved it, why did you move it? This is the kind of thing you should explain in your ChangeLog.
> Source/WebCore/bindings/js/JSDOMBinding.cpp:219 > + addErrorInfo(exec, asObject(errorObject), true);
Why do we need to do this extra step after error construction? Can the error constructor do this step for us?
Matthew Mirman
Comment 9
2015-04-03 15:02:26 PDT
(In reply to
comment #8
)
> Comment on
attachment 250093
[details]
> patch. > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=250093&action=review
> > Which part of this patch removes error info that we used to add?
It doesn't remove the error info entirely, it just now adds it eagerly at error construction for native errors. The change that removes it from being added to all "throw" is in VM.cpp
> You need to add a test for that part of the patch, both with frozen and > unfrozen objects, and preferably with various types of objects, including > DOM nodes, vanilla objects, arrays, and so on. >
sure
> > LayoutTests/ChangeLog:3 > > + Source and stack information should get appended only to native error constructors > > I think you meant "native errors" and not "native error constructors". It's > the error that holds the information, not the error's constructor.
yes.
> > LayoutTests/ChangeLog:4 > > + Source and stack information should get appended only to native error constructors > > + and should be added at construction time rather than when thrown. > > Why did you make this change? You should explain why this new behavior is > preferable to the old behavior. > > > LayoutTests/http/tests/w3c/resources/testharness.js:2070 > > function AssertionError(message) > > { > > + var e = new Error(); > > + this.stack = e.stack.substring(e.stack.indexOf('\n')+1, e.stack.length); > > this.message = message; > > } > > It looks like this test was imported from the W3C, but it required > modification in order to continue passing after your code changes. Doest > this mean that the W3C test, when run from source, no longer passes? Does it > pass in other browsers?
the test passes in other browsers, and if our test which used the native W3C test passed, it would also pass, but it doesn't, and our tests currently expect a failure with a stack trace, which other browsers simply don't append.
> > LayoutTests/js/dom/stack-trace-expected.txt:359 > > - 0 inlineableThrow at stack-trace.js:302:33 > > + 0 inlineableThrow at stack-trace.js:302:40 > > Why did this result change? I think I might know, but I'm not sure. This is > the kind of thing you should explain in your ChangeLog.
I changed a few things along the lines of "throw {}" to "throw new Error()" which changed the precise location of the throw.
Mark S. Miller
Comment 10
2015-04-03 15:13:42 PDT
Please also check that throwing a frozen Error does not cause a violation of the frozenness contract.
Matthew Mirman
Comment 11
2015-04-06 16:21:14 PDT
Created
attachment 250238
[details]
patch
Matthew Mirman
Comment 12
2015-04-06 16:29:51 PDT
(In reply to
comment #8
)
> > LayoutTests/js/exception-properties-expected.txt:6 > > -PASS enumerableProperties(error) is [] > > +PASS enumerableProperties(error).sort() is ["column", "line", "sourceURL"] > > Why is it good that these properties are enumerable now?
Its not really either good nor bad. Throw shouldn't be modifying the object being thrown at all, and native errors were expected to have enumerable properties after being thrown. Now since those properties are added before they are thrown, it is reasonable to assume that those properties should be enumerable before being thrown.
> > Source/JavaScriptCore/ChangeLog:4 > > + Source and stack information should get appended only to native error constructors > > + and should be added at construction time rather than when thrown. > > Same comment from other ChangeLog.
Fixed.
> > Source/JavaScriptCore/parser/ParserError.h:97 > > return addErrorInfo( > > If we're only supposed to add error properties during construction, why do > we still have an addErroInfo helper function, which adds those properties > after construction?
Because WebCore adds "native" errors which do not inherit from any JSC native error, appending the error properties as a seperate call after construction of the error is required to avoid having to manually truncate the stack and gather local source information due to the stack being extended by a nested call to construct one of the native jsc error.
> > Source/JavaScriptCore/runtime/ErrorInstance.cpp:40 > > +static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset) > > Did any of this code change, or did you just move it? If you just moved it, > why did you move it? This is the kind of thing you should explain in your > ChangeLog.
nope, it moved since it was needed elsewhere and wasn't in the global namespace.
> > Source/WebCore/bindings/js/JSDOMBinding.cpp:219 > > + addErrorInfo(exec, asObject(errorObject), true); > > Why do we need to do this extra step after error construction? Can the error > constructor do this step for us?
In the JSC native error, yes, we could make this call in the error constructor and in fact we do. However, WebCore also has its own native error, and making these inherit from JSC's native errors would make the stack include an extra layer of indirection. Furthermore, there isn't just one native webcore error, there are quite a few with macro generated constructors. Calling it once just before the error is thrown in webcore is the simplest way of adding this information.
Matthew Mirman
Comment 13
2015-04-06 16:30:25 PDT
(In reply to
comment #10
)
> Please also check that throwing a frozen Error does not cause a violation of > the frozenness contract.
fixed in the current patch.
Geoffrey Garen
Comment 14
2015-04-07 14:03:46 PDT
Comment on
attachment 250238
[details]
patch r=me
Matthew Mirman
Comment 15
2015-04-07 14:36:54 PDT
Comment on
attachment 250238
[details]
patch landed:
http://trac.webkit.org/changeset/182495
Matthew Mirman
Comment 16
2015-04-07 14:37:27 PDT
Landed in:
http://trac.webkit.org/changeset/182495
Closing bug.
Geoffrey Garen
Comment 17
2015-04-08 13:31:11 PDT
***
Bug 141878
has been marked as a duplicate of this bug. ***
Brent Fulgham
Comment 18
2015-04-08 17:37:35 PDT
This change might have broken Web Inspector on Windows. See <
https://bugs.webkit.org/show_bug.cgi?id=143542
>.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug