WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
96798
[V8] Binding: Implement EnforceRange IDL Attribute for long long conversions
https://bugs.webkit.org/show_bug.cgi?id=96798
Summary
[V8] Binding: Implement EnforceRange IDL Attribute for long long conversions
Joshua Bell
Reported
2012-09-14 09:34:45 PDT
From the WebIDL spec:
http://dev.w3.org/2006/webapi/WebIDL/#es-long-long
1. If x is NaN, +∞, or −∞, then throw a TypeError. 2. Set x to sign(x) * floor(abs(x)). 3. If x < −(2^53 − 1) or x > 2^53 − 1, then throw a TypeError. 4. Return the IDL long long value that represents the same numeric value as x. Note that there are similar cases for unsigned long long. The binding code generator says: return "toInt64($value)" if $type eq "unsigned long long" or $type eq "long long"; and toInt64 defined in bindings/v8/V8Binding.h is: inline long long toInt64(v8::Local<v8::Value> value) { return static_cast<long long>(value->IntegerValue()); } ... so there are no guard checks. This causes IndexedDB to fail the test
http://w3c-test.org/webapps/IndexedDB/tests/submissions/Ms2ger/idbfactory_open9.htm
We could special case this in the IDB code, or change toInt64 to incorporate the checks from WebIDL and call throwTypeError().
Attachments
Patch
(24.41 KB, patch)
2012-09-20 15:09 PDT
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(62.86 KB, patch)
2012-12-27 14:40 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(94.74 KB, patch)
2013-01-08 14:25 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(124.43 KB, patch)
2013-02-12 16:42 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(71.06 KB, patch)
2013-02-13 14:34 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(71.47 KB, patch)
2013-02-13 17:11 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch for landing
(73.64 KB, patch)
2013-02-25 11:23 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch for landing
(75.46 KB, patch)
2013-02-26 09:19 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(109.04 KB, patch)
2013-03-08 11:49 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(118.78 KB, patch)
2013-03-08 12:16 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(127.19 KB, patch)
2013-03-11 12:15 PDT
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(127.63 KB, patch)
2013-03-12 12:07 PDT
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch for landing
(127.37 KB, patch)
2013-03-15 11:00 PDT
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Show Obsolete
(12)
View All
Add attachment
proposed patch, testcase, etc.
David Grogan
Comment 1
2012-09-14 13:58:12 PDT
Adding negative sign
Joshua Bell
Comment 2
2012-09-20 10:21:02 PDT
Note that this should only apply if the IDL has [EnforceRange] extended attribute.
Joshua Bell
Comment 3
2012-09-20 11:11:43 PDT
Debugging through this, NaN, Infinity and -Infinity are being coerced to -0x8000000000000000 via V8's IntegerValue(). It's IndexedDB that's generating the type error for those. So basically we need to implement all these tests.
Joshua Bell
Comment 4
2012-09-20 13:59:30 PDT
Huh, I'm a bit stumped. This should be a matter of dumping the appropriate tests into V8Binding.h's toInt64 (and then refactoring), and having toInt64() call throwTypeError(). However, when this is done the exception is not caught/rethrown by the v8::TryCatch block in EXCEPTION_BLOCK, so the script never sees the exception. Maybe v8 change
r11894
is to blame? Calling throwTypeError() winds its way into api.cc's ThrowException which calls Isolate::ScheduleThrow(). That method calls into Isolate::Throw(), then immediately moves the exception from "pending" to "scheduled" and clears the pending exception. Tracing through, nothing causes the "scheduled" exception to be "promoted" back to pending before the TryCatch block concludes. v8
r11894
monkeys with the contents of Isolate::ScheduleThrow, removing a call to PropagatePendingExceptionToExternalTryCatch() which seems to be needed. If I undo that change then throwTypeError() works as expected.
Joshua Bell
Comment 5
2012-09-20 15:09:06 PDT
Created
attachment 164990
[details]
Patch
Joshua Bell
Comment 6
2012-09-20 15:11:34 PDT
(In reply to
comment #5
)
> Created an attachment (id=164990) [details] > Patch
Uploaded a patch, but it won't work until we sort out the V8 issue. (If I revert
http://code.google.com/p/v8/source/diff?spec=svn11894&old=11882&r=11894&format=unidiff&path=%2Ftrunk%2Fsrc%2Fisolate.cc
locally it works!) Also: * Doesn't implement EnforceRange for "long" types, just "long long" * The logic should probably move from V8Binding.h to V8Binding.cpp * I didn't touch JSC at all
Joshua Bell
Comment 7
2012-09-20 16:29:54 PDT
(In reply to
comment #4
)
> This should be a matter of dumping the appropriate tests into V8Binding.h's toInt64 (and then refactoring), and having toInt64() call throwTypeError(). However, when this is done the exception is not caught/rethrown by the v8::TryCatch block in EXCEPTION_BLOCK, so the script never sees the exception.
haraken@ points out this is
http://code.google.com/p/v8/issues/detail?id=2166
- in summary, TryCatch is not nestable.
Joshua Bell
Comment 8
2012-12-04 08:59:32 PST
(In reply to
comment #7
)
> (In reply to
comment #4
) > > This should be a matter of dumping the appropriate tests into V8Binding.h's toInt64 (and then refactoring), and having toInt64() call throwTypeError(). However, when this is done the exception is not caught/rethrown by the v8::TryCatch block in EXCEPTION_BLOCK, so the script never sees the exception. > > haraken@ points out this is
http://code.google.com/p/v8/issues/detail?id=2166
- in summary, TryCatch is not nestable.
Once Chromium rolls v8 to
r13130
this should be unblocked on the v8 side.
Erik Arvidsson
Comment 9
2012-12-04 09:39:32 PST
(In reply to
comment #8
)
> (In reply to
comment #7
) > > (In reply to
comment #4
) > > > This should be a matter of dumping the appropriate tests into V8Binding.h's toInt64 (and then refactoring), and having toInt64() call throwTypeError(). However, when this is done the exception is not caught/rethrown by the v8::TryCatch block in EXCEPTION_BLOCK, so the script never sees the exception. > > > > haraken@ points out this is
http://code.google.com/p/v8/issues/detail?id=2166
- in summary, TryCatch is not nestable. > > Once Chromium rolls v8 to
r13130
this should be unblocked on the v8 side.
I don't understand why we need V8 changes for this. See
bug 101783
for a WIP patch that worked (to some extent). Maybe it is cleaner to wait for V8 to allow anything to throw but we can keep track of the success state as we do the conversions.
Joshua Bell
Comment 10
2012-12-04 09:53:48 PST
(In reply to
comment #9
)
> I don't understand why we need V8 changes for this. See
bug 101783
for a WIP patch that worked (to some extent). Maybe it is cleaner to wait for V8 to allow anything to throw but we can keep track of the success state as we do the conversions.
That's true, it's not technically blocked. I was favoring having the toIntXXX() methods throw for readability but passing in an bool& obviously works as well. The throwing approach works, apart from a v8 bug which has now been resolved, so we can choose either approach. I wasn't aware of the bug when I started this patch and as it wasn't urgent and the v8 fix seemed imminent I left it blocked rather than exploring other approaches.
Erik Arvidsson
Comment 11
2012-12-04 10:00:35 PST
(In reply to
comment #10
)
> (In reply to
comment #9
) > > I don't understand why we need V8 changes for this. See
bug 101783
for a WIP patch that worked (to some extent). Maybe it is cleaner to wait for V8 to allow anything to throw but we can keep track of the success state as we do the conversions. > > That's true, it's not technically blocked. I was favoring having the toIntXXX() methods throw for readability but passing in an bool& obviously works as well.
I'm not sure which approach is better. Today, where we do not handle any type conversion failures, I think using a throw is less invasive, but given that we really should handle all type conversion failures I'm not sure throw is a better solution?
Joshua Bell
Comment 12
2012-12-04 10:19:17 PST
(In reply to
comment #11
)
> I'm not sure which approach is better. Today, where we do not handle any type conversion failures, I think using a throw is less invasive, but given that we really should handle all type conversion failures I'm not sure throw is a better solution?
I was imagining we'd end up with a repeated pattern like this anyway in the API: XXX toXXX(x, options..., bool& ok); XXX toXXXMaybeThrow(x, options...) { bool ok; XXX r = toXXX(x, ok); if (!ok) throwTypeError(); return r; } So eliminating the toXXXMaybeThrow and relying on the generated code to throw seems like it will result in less code overall.
Kentaro Hara
Comment 13
2012-12-04 15:52:38 PST
(In reply to
comment #9
)
> > > haraken@ points out this is
http://code.google.com/p/v8/issues/detail?id=2166
- in summary, TryCatch is not nestable.
BTW, this bug is going to be fixed shortly.
Joshua Bell
Comment 14
2012-12-27 14:40:22 PST
Created
attachment 180821
[details]
Patch
Joshua Bell
Comment 15
2012-12-27 14:44:04 PST
Latest patch drops dependency on nested v8 try/catch blocks and implements this in the style of
bug 101783
- thanks arv@! To match the IDL it is more lenient for u/int32 conversions in some cases when [EnforceRange] is not specified. This does NOT YET implement the JSC version, only the V8 version, so it's not ready for landing but I wanted to see what the bots think and get feedback.
WebKit Review Bot
Comment 16
2012-12-27 18:42:56 PST
Comment on
attachment 180821
[details]
Patch
Attachment 180821
[details]
did not pass chromium-ews (chromium-xvfb): Output:
http://queues.webkit.org/results/15549644
New failing tests: fast/js/select-options-add.html fast/dom/non-numeric-values-numeric-parameters.html
Erik Arvidsson
Comment 17
2013-01-02 08:07:21 PST
Comment on
attachment 180821
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=180821&action=review
> Source/WebCore/bindings/v8/V8Binding.cpp:136 > + x = (x < 0 ? -1 : 1) * floor(fabs(x));
Can't this just be (int) x?
> Source/WebCore/bindings/v8/V8Binding.cpp:147 > + if (isnan(numberValue) || isinf(numberValue))
I'm concerned about this change. Why do we silently want to treat NaN and Infinity as 0?
Joshua Bell
Comment 18
2013-01-02 09:04:45 PST
Comment on
attachment 180821
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=180821&action=review
>> Source/WebCore/bindings/v8/V8Binding.cpp:136 >> + x = (x < 0 ? -1 : 1) * floor(fabs(x)); > > Can't this just be (int) x?
After reviewing the C standard: yes. "When a value of floating type is converted to integral type, the fractional part is discarded." (Unsurprising, as WebIDL is likely just specifying existing behavior of implementations.)
>> Source/WebCore/bindings/v8/V8Binding.cpp:147 >> + if (isnan(numberValue) || isinf(numberValue)) > > I'm concerned about this change. Why do we silently want to treat NaN and Infinity as 0?
WebIDL does not specify that an exception should be raised in non-finite cases if [EnforceRange] is not specified. That's the point of the attribute - to allow interfaces to turn on throwing behavior. I agree that this is the scariest part of the patch, as it changes the behavior of existing binding code. I will look more carefully at where toIntXX(value, ok) is called explicitly, since I think generated code never uses that form unless [EnforceRange] is specified.
Erik Arvidsson
Comment 19
2013-01-02 09:22:05 PST
(In reply to
comment #18
)
> WebIDL does not specify that an exception should be raised in non-finite cases if [EnforceRange] is not specified. That's the point of the attribute - to allow interfaces to turn on throwing behavior.
My assumption was wrong. I just double checked. I wonder if we could test these behaviors? One idea would be to have add an object to testRunner where we have all of these. I'll file a bug.
Joshua Bell
Comment 20
2013-01-02 10:42:20 PST
(In reply to
comment #18
)
> (From update of
attachment 180821
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=180821&action=review
> > >> Source/WebCore/bindings/v8/V8Binding.cpp:136 > >> + x = (x < 0 ? -1 : 1) * floor(fabs(x)); > > > > Can't this just be (int) x? > > After reviewing the C standard: yes. "When a value of floating type is converted to integral type, the fractional part is discarded."
Hrm, well, trickier than that as the subsequent tests look for values outside the range of the destination type. The C++ standard says "The behavior is undefined if the truncated value cannot be represented in the destination type". So... I'm not sure we can take a shortcut here.
Joshua Bell
Comment 21
2013-01-02 11:43:33 PST
Details on the two test failures: * fast/dom/non-numeric-values-numeric-parameters.html * fast/js/select-options-add.html Both are probing the behavior around: document.createElement('select').options.add(document.createElement('option'), x); ... for various values of X. x = Infinity ==> Chrome 23 throws, Safari 6 throws, FF17 throws, IE10 throws. x = -Infinity ==> Chrome 23 throws, Safari 6 throws, FF17 throws, IE10 throws. x = NaN ==> Chrome 23 throws, Safari 6 throws, FF17 ok, IE10 throws. x = -2 ==> Chrome 23 throws, Safari 6 throws, FF17 ok, IE10 throws. x = -1 ==> Chrome 23 ok, Safari 6 ok, FF17 ok, IE10 ok. x = 100 ==> Chrome 23 ok, Safari 6 ok, FF17 ok, IE10 ok. The HTML spec has: void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null); ... and the prose reads: "If before is omitted, null, or a number out of range, then element will be added at the end of the list" - therefore, I would not expect the throwing behavior in any of these cases. ... The fast/dom/non-numeric-values-numeric-parameters.html test actually has a bug in the test where it is setting NaNAllowed but testing nanAllowed, so it is not correctly probing NaN support for this method, which may explain the divergence between WebKit and Gecko.
Joshua Bell
Comment 22
2013-01-02 14:36:07 PST
Per discussion w/ Moz folks on #whatwg, this bit of Gecko code has crufty old custom binding code not based on the IDL, so the behavior there is not intentional. jwalden agrees that per-spec none of these should throw.
Joshua Bell
Comment 23
2013-01-02 14:55:10 PST
Filed
https://www.w3.org/Bugs/Public/show_bug.cgi?id=20553
against the HTML spec.
Joshua Bell
Comment 24
2013-01-08 14:25:04 PST
Created
attachment 181764
[details]
Patch
Joshua Bell
Comment 25
2013-01-08 14:27:44 PST
(In reply to
comment #24
)
> Created an attachment (id=181764) [details] > Patch
Updated patch still a WIP. Handles attribute setters via another macro (since return type is void). Adds more attributes to the TypeConversions object and corresponding tests. Still V8 only.
Joshua Bell
Comment 26
2013-02-12 16:42:02 PST
Created
attachment 187960
[details]
Patch
Joshua Bell
Comment 27
2013-02-12 16:43:36 PST
Rebased. Still V8 only. * Passes throwTypeError() the required isolate argument. * Introduces a ConversionAttributes enum of flags in V8Binding.h so that eventually [Clamp] can be supported without adding yet another boolean arg. I think this is good-to-go on the V8 side, but the JSC side needs some luv.
Adam Barth
Comment 28
2013-02-13 12:05:48 PST
Would you like me to review your patch?
Joshua Bell
Comment 29
2013-02-13 12:07:45 PST
Comment on
attachment 187960
[details]
Patch abarth@ - Sure, feedback at this point is welcome. r?
Adam Barth
Comment 30
2013-02-13 12:18:12 PST
Comment on
attachment 187960
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=187960&action=review
> Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp:202 > - int v = toInt32(value); > + V8TRYCATCH_FOR_TYPECHECK_VOID(int, v, toInt32(value, false, ok));
It looks like we're now always creating a try-catch block. Is that necessary? Does that impact performance when the [EnforceRange] attribute isn't specified?
Joshua Bell
Comment 31
2013-02-13 12:25:44 PST
Comment on
attachment 187960
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=187960&action=review
> Source/WebCore/bindings/v8/V8BindingMacros.h:77 > + throwTypeError(0, info.GetIsolate()); \
This should just be |isolate|
Joshua Bell
Comment 32
2013-02-13 12:29:20 PST
Comment on
attachment 187960
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=187960&action=review
>> Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp:202 >> + V8TRYCATCH_FOR_TYPECHECK_VOID(int, v, toInt32(value, false, ok)); > > It looks like we're now always creating a try-catch block. Is that necessary? Does that impact performance when the [EnforceRange] attribute isn't specified?
Thanks - no, shouldn't be necessary; probably residue from earlier iterations. In the ...TYPECHECK_VOID case there shouldn't need to be a try-catch block. This can reduce to a TYPECHECK macro.
Build Bot
Comment 33
2013-02-13 13:35:09 PST
Comment on
attachment 187960
[details]
Patch
Attachment 187960
[details]
did not pass mac-wk2-ews (mac-wk2): Output:
http://queues.webkit.org/results/16547013
New failing tests: fast/dom/non-numeric-values-numeric-parameters.html fast/js/webidl-type-mapping.html
Build Bot
Comment 34
2013-02-13 14:17:42 PST
Comment on
attachment 187960
[details]
Patch
Attachment 187960
[details]
did not pass mac-wk2-ews (mac-wk2): Output:
http://queues.webkit.org/results/16563012
New failing tests: fast/dom/non-numeric-values-numeric-parameters.html fast/js/webidl-type-mapping.html
Joshua Bell
Comment 35
2013-02-13 14:34:04 PST
Created
attachment 188184
[details]
Patch
Joshua Bell
Comment 36
2013-02-13 14:38:04 PST
Let's give that another whirl: * Minimized code generator output differences - callers to JSValueToNative call a helper to determine if type checking is necessary and only use type checking macro wrappers if necessary. Ugly, but safer. * Only need TYPECHECK_VOID and V8TRYCATCH_WITH_TYPECHECK macros. With more extensive refactoring could probably compose those. Alternately, these could be inlined but I think these will eventually end up being used in 1-2 more places (e.g. Dictionary value access) * Actually ran the tests, which turned up stupid logic bugs with the flags. Derp. * Updated the test for HTMLOptionsCollection to match the HTML spec, which matches the new behavior of the code (see
comment #21
)
Kentaro Hara
Comment 37
2013-02-13 16:06:12 PST
Comment on
attachment 188184
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=188184&action=review
> Source/WebCore/bindings/scripts/CodeGeneratorV8.pm:3928 > +sub ConversionThrowsTypeError
Will this method be useful for other purpose? Otherwise, I would hard-code $signature->extendedAttributes->{"EnforceRange"} in call sites and remove the method.
> Source/WebCore/bindings/v8/V8Binding.cpp:115 > v8::Local<v8::Number> numberObject = value->ToNumber();
This can throw. You need a try-catch block.
> Source/WebCore/bindings/v8/V8Binding.cpp:121 > + if (attributes & FEnforceRange) {
[EnforgeRange] must not be in conjunction with [Clamp]:
http://www.w3.org/TR/WebIDL/#EnforceRange
So it would be useless to use a bit-masking approach.
> Source/WebCore/bindings/v8/V8Binding.cpp:128 > + if (x < -0x8000000 || x > 0x7fffffff) {
Nit: Shall we use a constant variable for these magic numbers?
> Source/WebCore/bindings/v8/V8Binding.cpp:166 > + if (attributes & FEnforceRange) {
Ditto.
> Source/WebCore/bindings/v8/V8Binding.cpp:173 > + if (x < 0 || x > 0xffffffff) {
Nit: Use a constant variable for the magic number.
> Source/WebCore/bindings/v8/V8Binding.cpp:198 > + v8::Local<v8::Number> numberObject = value->ToNumber();
This can throw. You need a try-catch block.
> Source/WebCore/bindings/v8/V8Binding.cpp:206 > + if (attributes & FEnforceRange) {
Ditto.
> Source/WebCore/bindings/v8/V8Binding.cpp:237 > + if (result >= 0) > + return result;
Can we also add a fast path for result < 0 ?
> Source/WebCore/bindings/v8/V8Binding.cpp:241 > + v8::Local<v8::Number> numberObject = value->ToNumber();
This can throw. You need a try-catch block.
> Source/WebCore/bindings/v8/V8Binding.cpp:249 > + if (attributes & FEnforceRange) {
Ditto.
> Source/WebCore/bindings/v8/V8Binding.h:348 > + enum ConversionAttributes {
Nit: IntergerConversionConfiguration?
> Source/WebCore/bindings/v8/V8Binding.h:351 > + FNone = 0x0000, > + FEnforceRange = 0x0001, > + // FIXME: Implement FClamp = 0x0002
Nit: Are these hard-coded values (e.g. 0x0001) meaningful? Otherwise, we can drop them. Nit: Also is "FEnforceRange" a speced name somewhere? Otherwise, we can simply say "EnforceRange".
> Source/WebCore/bindings/v8/V8BindingMacros.h:46 > + bool ok = true; \ > + var = (value); \ > + if (UNLIKELY(!ok)) { \
Where is |ok| updated?
> Source/WebCore/bindings/v8/V8BindingMacros.h:71 > + if (UNLIKELY(!ok)) \
Ditto.
Kentaro Hara
Comment 38
2013-02-13 16:07:49 PST
Comment on
attachment 188184
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=188184&action=review
> LayoutTests/fast/js/webidl-type-mapping.html:45 > +function testNonNumericToNumericEnforceRange(attribute)
You might want to add more test cases for non numeric values, especially a case where an exception is thrown during value conversion.
Joshua Bell
Comment 39
2013-02-13 16:41:45 PST
(In reply to
comment #37
)
> (From update of
attachment 188184
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=188184&action=review
> > > Source/WebCore/bindings/scripts/CodeGeneratorV8.pm:3928 > > +sub ConversionThrowsTypeError > > Will this method be useful for other purpose? Otherwise, I would hard-code $signature->extendedAttributes->{"EnforceRange"} in call sites and remove the method.
I was imagining that it would be, but I also wasn't really paying attention to what [Clamp] meant. I can inline it.
> > Source/WebCore/bindings/v8/V8Binding.cpp:115 > > v8::Local<v8::Number> numberObject = value->ToNumber(); > > This can throw. You need a try-catch block.
Bleah. This is also in the existing code, which means existing conversions are buggy. To abarth@'s earlier point this probably means all numeric conversions will need to get wrapped in try-catch blocks, not just those with [EnforceRange] specified.
> > > Source/WebCore/bindings/v8/V8Binding.cpp:121 > > + if (attributes & FEnforceRange) { > > [EnforgeRange] must not be in conjunction with [Clamp]: >
http://www.w3.org/TR/WebIDL/#EnforceRange
> > So it would be useless to use a bit-masking approach.
Thanks. I should have looked more closely at [Clamp]. That simplifies things.
> > > Source/WebCore/bindings/v8/V8Binding.cpp:128 > > + if (x < -0x8000000 || x > 0x7fffffff) { > > Nit: Shall we use a constant variable for these magic numbers?
Sure. kMinInt32, kMaxUint32, etc?
> > Source/WebCore/bindings/v8/V8Binding.cpp:237 > > + if (result >= 0) > > + return result; > > Can we also add a fast path for result < 0 ?
Yep. Will depend on the attributes so will have multiple cases, but probably worth it.
> > Source/WebCore/bindings/v8/V8Binding.h:348 > > + enum ConversionAttributes { > > Nit: IntergerConversionConfiguration?
Sure.
> > Source/WebCore/bindings/v8/V8Binding.h:351 > > + FNone = 0x0000, > > + FEnforceRange = 0x0001, > > + // FIXME: Implement FClamp = 0x0002 > > Nit: Are these hard-coded values (e.g. 0x0001) meaningful? Otherwise, we can drop them. > > Nit: Also is "FEnforceRange" a speced name somewhere? Otherwise, we can simply say "EnforceRange".
Since [Clamp] and [EnforceRange] are exclusive, the values and 'F' prefixes can definitely be dropped. Thanks again, I should have looked more closely at the spec for [Clamp].
> > Source/WebCore/bindings/v8/V8BindingMacros.h:46 > > + bool ok = true; \ > > + var = (value); \ > > + if (UNLIKELY(!ok)) { \ > > Where is |ok| updated?
In the cases where these macros are used, the expression generated by JSValueToNative() passes ok into the ToIntXX functions, that expression is what ends up as the |value| macro parameter. (This was arv@'s suggestion.)
Kentaro Hara
Comment 40
2013-02-13 16:50:18 PST
> > > Source/WebCore/bindings/v8/V8Binding.cpp:115 > > > v8::Local<v8::Number> numberObject = value->ToNumber(); > > > > This can throw. You need a try-catch block. > > Bleah. This is also in the existing code, which means existing conversions are buggy. To abarth@'s earlier point this probably means all numeric conversions will need to get wrapped in try-catch blocks, not just those with [EnforceRange] specified.
Yeah, I think you can fix it in a separate patch. (Actually we have similar bugs in a lot of places in custom bindings... not only integer conversion but also string conversions.)
> > Nit: Shall we use a constant variable for these magic numbers? > > Sure. kMinInt32, kMaxUint32, etc?
Sounds good!
Joshua Bell
Comment 41
2013-02-13 17:11:32 PST
Created
attachment 188229
[details]
Patch
Kentaro Hara
Comment 42
2013-02-13 17:31:02 PST
Comment on
attachment 188229
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=188229&action=review
LGTM.
> Source/WebCore/bindings/scripts/CodeGeneratorV8.pm:1252 > + my $value = JSValueToNative($attribute->signature, "value", "info.GetIsolate()", 1);
1 is unclear. Let's pass a string "canThrowException".
Kentaro Hara
Comment 43
2013-02-13 17:32:27 PST
(In reply to
comment #40
)
> Yeah, I think you can fix it in a separate patch. (Actually we have similar bugs in a lot of places in custom bindings... not only integer conversion but also string conversions.)
Please add more test cases for non numeric values (exception cases) when you work on the follow-up patch.
Joshua Bell
Comment 44
2013-02-14 09:29:29 PST
(In reply to
comment #42
)
> > 1 is unclear. Let's pass a string "canThrowException".
Done. (We should do this for the other methods that take optional bools, too.) So... thoughts on the JSC side here? Tackle it now, handle it with TestExpectations, ...?
Joshua Bell
Comment 45
2013-02-25 11:23:04 PST
Created
attachment 190095
[details]
Patch for landing
WebKit Review Bot
Comment 46
2013-02-25 17:09:35 PST
Comment on
attachment 190095
[details]
Patch for landing Rejecting
attachment 190095
[details]
from commit-queue. Failed to run "['/mnt/git/webkit-commit-queue/Tools/Scripts/webkit-patch', '--status-host=queues.webkit.org', '--bot-id=gce-cq-02', 'apply-attachment', '--no-update', '--non-interactive', 190095, '--port=chromium-xvfb']" exit_code: 2 cwd: /mnt/git/webkit-commit-queue Last 500 characters of output: LayoutTests/fast/dom/script-tests/non-numeric-values-numeric-parameters.js patching file LayoutTests/fast/js/webidl-type-mapping-expected.txt patching file LayoutTests/fast/js/webidl-type-mapping.html patching file LayoutTests/storage/indexeddb/intversion-bad-parameters-expected.txt patching file LayoutTests/storage/indexeddb/resources/intversion-bad-parameters.js Failed to run "[u'/mnt/git/webkit-commit-queue/Tools/Scripts/svn-apply', '--force']" exit_code: 1 cwd: /mnt/git/webkit-commit-queue Full output:
http://queues.webkit.org/results/16760403
Joshua Bell
Comment 47
2013-02-26 09:19:29 PST
Created
attachment 190301
[details]
Patch for landing
Build Bot
Comment 48
2013-02-26 14:33:02 PST
Comment on
attachment 190301
[details]
Patch for landing
Attachment 190301
[details]
did not pass mac-wk2-ews (mac-wk2): Output:
http://webkit-commit-queue.appspot.com/results/16769502
New failing tests: fast/dom/non-numeric-values-numeric-parameters.html
WebKit Review Bot
Comment 49
2013-02-26 14:58:52 PST
Comment on
attachment 190301
[details]
Patch for landing
Attachment 190301
[details]
did not pass chromium-ews (chromium-xvfb): Output:
http://webkit-commit-queue.appspot.com/results/16781400
New failing tests: fast/js/select-options-add.html fast/js/webidl-type-mapping.html
Build Bot
Comment 50
2013-02-27 03:18:10 PST
Comment on
attachment 190301
[details]
Patch for landing
Attachment 190301
[details]
did not pass mac-ews (mac): Output:
http://webkit-commit-queue.appspot.com/results/16831130
New failing tests: fast/dom/non-numeric-values-numeric-parameters.html
Peter Beverloo (cr-android ews)
Comment 51
2013-02-27 18:57:27 PST
Comment on
attachment 190301
[details]
Patch for landing
Attachment 190301
[details]
did not pass cr-android-ews (chromium-android): Output:
http://webkit-commit-queue.appspot.com/results/16797184
Joshua Bell
Comment 52
2013-03-08 11:49:32 PST
Created
attachment 192258
[details]
Patch
Joshua Bell
Comment 53
2013-03-08 12:16:04 PST
Created
attachment 192267
[details]
Patch
Peter Beverloo (cr-android ews)
Comment 54
2013-03-08 12:45:10 PST
Comment on
attachment 192267
[details]
Patch
Attachment 192267
[details]
did not pass cr-android-ews (chromium-android): Output:
http://webkit-commit-queue.appspot.com/results/17016293
WebKit Review Bot
Comment 55
2013-03-08 14:37:44 PST
Comment on
attachment 192267
[details]
Patch
Attachment 192267
[details]
did not pass chromium-ews (chromium-xvfb): Output:
http://webkit-commit-queue.appspot.com/results/17110231
New failing tests: fast/dom/non-numeric-values-numeric-parameters.html
WebKit Review Bot
Comment 56
2013-03-08 15:25:43 PST
Comment on
attachment 192267
[details]
Patch
Attachment 192267
[details]
did not pass chromium-ews (chromium-xvfb): Output:
http://webkit-commit-queue.appspot.com/results/17016336
New failing tests: fast/dom/non-numeric-values-numeric-parameters.html
Joshua Bell
Comment 57
2013-03-11 12:15:07 PDT
Created
attachment 192526
[details]
Patch
Joshua Bell
Comment 58
2013-03-11 12:19:17 PDT
Needed the passing expectation for chromium on that test. ... Sorry about the patch churn. It's all about the previously mentioned case: document.createElement('select').options.add(document.createElement('option'), x); ... which per spec (and Firefox) shouldn't throw for non-finite x, but previously did. This patch will make it not throw in V8, but it will continue to throw in JSC. Therefore, I've updated the tests to match the spec, which leaves them with FAIL expectations in JSC and requires different expectations in V8. Do any JSC experts want to weigh in before landing? haraken@ - can you give it one last look?
Peter Beverloo (cr-android ews)
Comment 59
2013-03-11 14:07:09 PDT
Comment on
attachment 192526
[details]
Patch
Attachment 192526
[details]
did not pass cr-android-ews (chromium-android): Output:
http://webkit-commit-queue.appspot.com/results/17011690
Kentaro Hara
Comment 60
2013-03-11 18:07:24 PDT
Comment on
attachment 192526
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=192526&action=review
Getting closer!
> Source/WebCore/bindings/scripts/CodeGeneratorV8.pm:3994 > + my $intConversion = $signature->extendedAttributes->{"EnforceRange"} ? "EnforceRange" : "NormalConversion"; > + die "Can't handle [EnforceRange] unless called from context that handles failures." if $intConversion eq "EnforceRange" and !$mayFail;
Maybe you can simply remove $mayFail because you want to throw anyway if $signature->extendedAttributes->{"EnforceRange"} is true. If you remove $mayFail, call sites of JSValueToNative() become much simpler.
> Source/WebCore/bindings/v8/V8Binding.cpp:267 > + if (x < 0 || x > (kJSMaxInteger - 1)) {
Is this correct? c.f. You are doing 'if (x < -(kJSMaxInteger - 1) || x > (kJSMaxInteger - 1))' in toInt64().
> Source/WebCore/bindings/v8/V8Binding.h:59 > + const long long kJSMaxInteger = 0x20000000000000LL;
You can put it in V8Binding.cpp. Also this should be 0x1fffffffffffffLL. (Then you can remove '- 1' from V8Binding.cpp.)
> Source/WebCore/bindings/v8/V8BindingMacros.h:45 > +#define TYPECHECK_VOID(type, var, value, isolate) \ > + type var; \ > + { \ > + bool ok = true; \ > + var = (value); \ > + if (UNLIKELY(!ok)) { \ > + throwTypeError(0, isolate); \ > + return; \ > + } \ > + }
'var = (value)' can throw, so you need to protect it with a TryCatch block. You can rename the macro to V8TRYCATCH_WITH_TYPECHECK_VOID().
Joshua Bell
Comment 61
2013-03-12 11:38:22 PDT
(In reply to
comment #60
)
> Maybe you can simply remove $mayFail because you want to throw anyway if $signature->extendedAttributes->{"EnforceRange"} is true. If you remove $mayFail, call sites of JSValueToNative() become much simpler.
This was added to ensure that callers of JSValueToNative() were "opting in" to the new behavior and would then use the correct macro wrappers around the conversion. But I agree it's not required, so will remove it.
> > Source/WebCore/bindings/v8/V8Binding.cpp:267 > > + if (x < 0 || x > (kJSMaxInteger - 1)) { > > Is this correct? > > c.f. You are doing 'if (x < -(kJSMaxInteger - 1) || x > (kJSMaxInteger - 1))' in toInt64().
Yes. Unless there's a typo I'm not seeing. Spec has, for unsigned long long: If x < 0 or x > 2^53 − 1, then throw a TypeError. Spec has, for long long: If x < −(2^53 − 1) or x > 2^53 − 1, then throw a TypeError. Are you asking because it seems unusual for the upper bounds to be the same for both int64 and uint64 conversion? If so, the reason is that the maximum integer value exactly representable (due to the limited mantissa range) in an ECMAScript Number (a.k.a. a 64-bit IEEE754 float) is 2^53-1, which is less than either 2^64-1 (max uint64) or 2^63-1 (max int64). So the WebIDL conversion logic is not "is this number in the int64/uint64 range?" but "if I put the floor of this exact number into an int64/uint64 will I get the same number out again?" If you're asking for another reason then I'm probably missing something, so please point it out!
> > Source/WebCore/bindings/v8/V8Binding.h:59 > > + const long long kJSMaxInteger = 0x20000000000000LL; > > You can put it in V8Binding.cpp. Also this should be 0x1fffffffffffffLL. (Then you can remove '- 1' from V8Binding.cpp.)
Done. The WebIDL spec uses "2^53 - 1" hence that style, but I'll move it and clarify the constant.
> > Source/WebCore/bindings/v8/V8BindingMacros.h:45 > > +#define TYPECHECK_VOID(type, var, value, isolate) \ > > + type var; \ > > + { \ > > + bool ok = true; \ > > + var = (value); \ > > + if (UNLIKELY(!ok)) { \ > > + throwTypeError(0, isolate); \ > > + return; \ > > + } \ > > + } > > 'var = (value)' can throw, so you need to protect it with a TryCatch block. You can rename the macro to V8TRYCATCH_WITH_TYPECHECK_VOID().
That's actually what I had prior to
comment #30
from abarth@. But now that the call sites inspect EnforceRange I can revert - thanks!
Joshua Bell
Comment 62
2013-03-12 12:07:02 PDT
Created
attachment 192784
[details]
Patch
Joshua Bell
Comment 63
2013-03-12 12:10:10 PDT
(In reply to
comment #60
)
> > 'var = (value)' can throw, so you need to protect it with a TryCatch block. You can rename the macro to V8TRYCATCH_WITH_TYPECHECK_VOID().
Fixing this macro also revealed a flaw in the previous patch where conversions that threw (e.g. { valueOf: function() { throw new Error('foo'); }) were eating the thrown error and throwing a TypeError instead. Updated the tests to double-check that the error thrown during "var = (value)" are what makes it out.
Kentaro Hara
Comment 64
2013-03-12 17:41:08 PDT
Thanks for all the fixes! (In reply to
comment #61
)
> Spec has, for unsigned long long: If x < 0 or x > 2^53 − 1, then throw a TypeError. > Spec has, for long long: If x < −(2^53 − 1) or x > 2^53 − 1, then throw a TypeError. > > Are you asking because it seems unusual for the upper bounds to be the same for both int64 and uint64 conversion?
Yes, I was asking for the reason. Thanks for the detailed clarification.
Kentaro Hara
Comment 65
2013-03-12 17:41:27 PDT
Comment on
attachment 192784
[details]
Patch LGTM
Erik Arvidsson
Comment 66
2013-03-13 11:10:03 PDT
Comment on
attachment 192784
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=192784&action=review
This looks great
> Source/WebCore/bindings/scripts/CodeGeneratorV8.pm:1904 > + if ($parameter->extendedAttributes->{"EnforceRange"}) { > + my $value = JSValueToNative($parameter, $optional && $optional eq "DefaultIsNullString" ? "argumentOrNull(args, $paramIndex)" : "args[$paramIndex]", "args.GetIsolate()"); > + $parameterCheckString .= " V8TRYCATCH_WITH_TYPECHECK($nativeType, $parameterName, $value, args.GetIsolate());\n"; > + } else { > + my $value = JSValueToNative($parameter, $optional && $optional eq "DefaultIsNullString" ? "argumentOrNull(args, $paramIndex)" : "args[$paramIndex]", "args.GetIsolate()"); > + $parameterCheckString .= " V8TRYCATCH($nativeType, $parameterName, $value);\n"; > + }
Can you move the "my $value = ..." line out of the if to reduce code duplication?
Joshua Bell
Comment 67
2013-03-15 10:56:48 PDT
(In reply to
comment #66
)
> Can you move the "my $value = ..." line out of the if to reduce code duplication?
Nice catch, done.
Joshua Bell
Comment 68
2013-03-15 11:00:31 PDT
Created
attachment 193338
[details]
Patch for landing
WebKit Review Bot
Comment 69
2013-03-15 12:00:22 PDT
Comment on
attachment 193338
[details]
Patch for landing Clearing flags on attachment: 193338 Committed
r145929
: <
http://trac.webkit.org/changeset/145929
>
WebKit Review Bot
Comment 70
2013-03-15 12:00:31 PDT
All reviewed patches have been landed. Closing bug.
Kenneth Russell
Comment 71
2013-03-15 20:32:34 PDT
FYI: this caused a build failure on Windows which was fixed in
http://trac.webkit.org/changeset/145975
.
Joshua Bell
Comment 72
2013-03-18 09:09:24 PDT
(In reply to
comment #71
)
> FYI: this caused a build failure on Windows which was fixed in
http://trac.webkit.org/changeset/145975
.
Thanks for the fix, sorry about the breakage.
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