Changeset 288066 in webkit
- Timestamp:
- Jan 15, 2022 1:35:01 PM (6 months ago)
- Location:
- trunk
- Files:
-
- 4 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/test262/expectations.yaml (modified) (1 diff)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/runtime/DatePrototype.cpp (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r288065 r288066 1 2022-01-15 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Fix Date functions' argument coercion 4 https://bugs.webkit.org/show_bug.cgi?id=235271 5 6 Reviewed by Alexey Shvayka. 7 8 * test262/expectations.yaml: 9 1 10 2022-01-15 Yusuke Suzuki <ysuzuki@apple.com> 2 11 -
trunk/JSTests/test262/expectations.yaml
r288062 r288066 607 607 default: 'Test262Error: order of operations / precision in MakeTime Expected SameValue(«NaN», «29312») to be true' 608 608 strict mode: 'Test262Error: order of operations / precision in MakeTime Expected SameValue(«NaN», «29312») to be true' 609 test/built-ins/Date/prototype/setDate/arg-coercion-order.js:610 default: 'Test262Error: ToNumber invoked exactly once Expected SameValue(«0», «1») to be true'611 strict mode: 'Test262Error: ToNumber invoked exactly once Expected SameValue(«0», «1») to be true'612 test/built-ins/Date/prototype/setHours/arg-coercion-order.js:613 default: 'Test262Error: Expected [] and [valueOf hour, valueOf min, valueOf sec, valueOf ms] to have the same contents. '614 strict mode: 'Test262Error: Expected [] and [valueOf hour, valueOf min, valueOf sec, valueOf ms] to have the same contents. '615 test/built-ins/Date/prototype/setMilliseconds/arg-coercion-order.js:616 default: 'Test262Error: ToNumber invoked exactly once Expected SameValue(«0», «1») to be true'617 strict mode: 'Test262Error: ToNumber invoked exactly once Expected SameValue(«0», «1») to be true'618 test/built-ins/Date/prototype/setMinutes/arg-coercion-order.js:619 default: 'Test262Error: Expected [] and [valueOf min, valueOf sec, valueOf ms] to have the same contents. '620 strict mode: 'Test262Error: Expected [] and [valueOf min, valueOf sec, valueOf ms] to have the same contents. '621 test/built-ins/Date/prototype/setMonth/arg-coercion-order.js:622 default: 'Test262Error: Expected [] and [valueOf month, valueOf date] to have the same contents. '623 strict mode: 'Test262Error: Expected [] and [valueOf month, valueOf date] to have the same contents. '624 test/built-ins/Date/prototype/setSeconds/arg-coercion-order.js:625 default: 'Test262Error: Expected [] and [valueOf sec, valueOf ms] to have the same contents. '626 strict mode: 'Test262Error: Expected [] and [valueOf sec, valueOf ms] to have the same contents. '627 test/built-ins/Date/prototype/setUTCDate/arg-coercion-order.js:628 default: 'Test262Error: ToNumber invoked exactly once Expected SameValue(«0», «1») to be true'629 strict mode: 'Test262Error: ToNumber invoked exactly once Expected SameValue(«0», «1») to be true'630 test/built-ins/Date/prototype/setUTCHours/arg-coercion-order.js:631 default: 'Test262Error: Expected [] and [valueOf hour, valueOf min, valueOf sec, valueOf ms] to have the same contents. '632 strict mode: 'Test262Error: Expected [] and [valueOf hour, valueOf min, valueOf sec, valueOf ms] to have the same contents. '633 test/built-ins/Date/prototype/setUTCMilliseconds/arg-coercion-order.js:634 default: 'Test262Error: ToNumber invoked exactly once Expected SameValue(«0», «1») to be true'635 strict mode: 'Test262Error: ToNumber invoked exactly once Expected SameValue(«0», «1») to be true'636 test/built-ins/Date/prototype/setUTCMinutes/arg-coercion-order.js:637 default: 'Test262Error: Expected [] and [valueOf min, valueOf sec, valueOf ms] to have the same contents. '638 strict mode: 'Test262Error: Expected [] and [valueOf min, valueOf sec, valueOf ms] to have the same contents. '639 test/built-ins/Date/prototype/setUTCMonth/arg-coercion-order.js:640 default: 'Test262Error: Expected [] and [valueOf month, valueOf date] to have the same contents. '641 strict mode: 'Test262Error: Expected [] and [valueOf month, valueOf date] to have the same contents. '642 test/built-ins/Date/prototype/setUTCSeconds/arg-coercion-order.js:643 default: 'Test262Error: Expected [] and [valueOf sec, valueOf ms] to have the same contents. '644 strict mode: 'Test262Error: Expected [] and [valueOf sec, valueOf ms] to have the same contents. '645 609 test/built-ins/Function/internals/Construct/derived-return-val-realm.js: 646 610 default: 'Test262Error: Expected a TypeError but got a different error constructor with the same name' -
trunk/Source/JavaScriptCore/ChangeLog
r288065 r288066 1 2022-01-15 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Fix Date functions' argument coercion 4 https://bugs.webkit.org/show_bug.cgi?id=235271 5 6 Reviewed by Alexey Shvayka. 7 8 Even if the input Date is NaN or the result looks like NaN, we need to coerce passed 9 arguments to Number[1] since it has observable side effect. 10 11 [1]: https://github.com/tc39/ecma262/pull/2136 12 13 * runtime/DatePrototype.cpp: 14 (JSC::applyToNumbersToTrashedArguments): 15 (JSC::fillStructuresUsingTimeArgs): 16 (JSC::fillStructuresUsingDateArgs): 17 (JSC::setNewValueFromTimeArgs): 18 (JSC::setNewValueFromDateArgs): 19 1 20 2022-01-15 Yusuke Suzuki <ysuzuki@apple.com> 2 21 -
trunk/Source/JavaScriptCore/runtime/DatePrototype.cpp
r286994 r288066 110 110 } 111 111 112 113 static void applyToNumbersToTrashedArguments(JSGlobalObject* globalObject, CallFrame* callFrame, unsigned maxArgs) 114 { 115 VM& vm = globalObject->vm(); 116 auto scope = DECLARE_THROW_SCOPE(vm); 117 118 unsigned numArgs = std::min<unsigned>(callFrame->argumentCount(), maxArgs); 119 for (unsigned index = 0; index < numArgs; ++index) { 120 callFrame->uncheckedArgument(index).toNumber(globalObject); 121 RETURN_IF_EXCEPTION(scope, void()); 122 } 123 } 124 112 125 // Converts a list of arguments sent to a Date member function into milliseconds, updating 113 126 // ms (representing milliseconds) and t (representing the rest of the date structure) appropriately. 114 127 // 115 128 // Format of member function: f([hour,] [min,] [sec,] [ms]) 116 static bool fillStructuresUsingTimeArgs(JSGlobalObject* globalObject, CallFrame* callFrame, intmaxArgs, double* ms, GregorianDateTime* t)129 static bool fillStructuresUsingTimeArgs(JSGlobalObject* globalObject, CallFrame* callFrame, unsigned maxArgs, double* ms, GregorianDateTime* t) 117 130 { 118 131 VM& vm = globalObject->vm(); … … 120 133 121 134 double milliseconds = 0; 122 bool ok = true; 123 int idx = 0; 124 int numArgs = callFrame->argumentCount(); 125 126 // JS allows extra trailing arguments -- ignore them 127 if (numArgs > maxArgs) 128 numArgs = maxArgs; 135 unsigned idx = 0; 136 unsigned numArgs = std::min<unsigned>(callFrame->argumentCount(), maxArgs); 129 137 130 138 // hours … … 133 141 double hours = callFrame->uncheckedArgument(idx++).toIntegerPreserveNaN(globalObject); 134 142 RETURN_IF_EXCEPTION(scope, false); 135 ok = std::isfinite(hours);136 143 milliseconds += hours * msPerHour; 137 144 } 138 145 139 146 // minutes 140 if (maxArgs >= 3 && idx < numArgs && ok) {147 if (maxArgs >= 3 && idx < numArgs) { 141 148 t->setMinute(0); 142 149 double minutes = callFrame->uncheckedArgument(idx++).toIntegerPreserveNaN(globalObject); 143 150 RETURN_IF_EXCEPTION(scope, false); 144 ok = std::isfinite(minutes);145 151 milliseconds += minutes * msPerMinute; 146 152 } 147 153 148 154 // seconds 149 if (maxArgs >= 2 && idx < numArgs && ok) {155 if (maxArgs >= 2 && idx < numArgs) { 150 156 t->setSecond(0); 151 157 double seconds = callFrame->uncheckedArgument(idx++).toIntegerPreserveNaN(globalObject); 152 158 RETURN_IF_EXCEPTION(scope, false); 153 ok = std::isfinite(seconds);154 159 milliseconds += seconds * msPerSecond; 155 160 } 156 157 if (!ok) 158 return false; 159 161 160 162 // milliseconds 161 163 if (idx < numArgs) { 162 164 double millis = callFrame->uncheckedArgument(idx).toIntegerPreserveNaN(globalObject); 163 165 RETURN_IF_EXCEPTION(scope, false); 164 ok = std::isfinite(millis);165 166 milliseconds += millis; 166 167 } else 167 168 milliseconds += *ms; 168 169 169 170 *ms = milliseconds; 170 return ok;171 return std::isfinite(milliseconds); 171 172 } 172 173 … … 175 176 // 176 177 // Format of member function: f([years,] [months,] [days]) 177 static bool fillStructuresUsingDateArgs(JSGlobalObject* globalObject, CallFrame* callFrame, int maxArgs, double *ms, GregorianDateTime *t) 178 { 179 VM& vm = globalObject->vm(); 180 auto scope = DECLARE_THROW_SCOPE(vm); 181 182 int idx = 0; 178 static bool fillStructuresUsingDateArgs(JSGlobalObject* globalObject, CallFrame* callFrame, unsigned maxArgs, double *ms, GregorianDateTime *t) 179 { 180 VM& vm = globalObject->vm(); 181 auto scope = DECLARE_THROW_SCOPE(vm); 182 183 183 bool ok = true; 184 int numArgs = callFrame->argumentCount(); 185 186 // JS allows extra trailing arguments -- ignore them 187 if (numArgs > maxArgs) 188 numArgs = maxArgs; 184 unsigned idx = 0; 185 unsigned numArgs = std::min<unsigned>(callFrame->argumentCount(), maxArgs); 189 186 190 187 // years … … 192 189 double years = callFrame->uncheckedArgument(idx++).toIntegerPreserveNaN(globalObject); 193 190 RETURN_IF_EXCEPTION(scope, false); 194 ok = std::isfinite(years);191 ok = (ok && std::isfinite(years)); 195 192 t->setYear(toInt32(years)); 196 193 } 197 194 // months 198 if (maxArgs >= 2 && idx < numArgs && ok) {195 if (maxArgs >= 2 && idx < numArgs) { 199 196 double months = callFrame->uncheckedArgument(idx++).toIntegerPreserveNaN(globalObject); 200 197 RETURN_IF_EXCEPTION(scope, false); 201 ok = std::isfinite(months);198 ok = (ok && std::isfinite(months)); 202 199 t->setMonth(toInt32(months)); 203 200 } 204 201 // days 205 if (idx < numArgs && ok) {202 if (idx < numArgs) { 206 203 double days = callFrame->uncheckedArgument(idx++).toIntegerPreserveNaN(globalObject); 207 204 RETURN_IF_EXCEPTION(scope, false); 208 ok = std::isfinite(days);205 ok = (ok && std::isfinite(days)); 209 206 t->setMonthDay(0); 210 207 *ms += days * msPerDay; … … 669 666 } 670 667 671 static EncodedJSValue setNewValueFromTimeArgs(JSGlobalObject* globalObject, CallFrame* callFrame, intnumArgsToUse, WTF::TimeType inputTimeType)668 static EncodedJSValue setNewValueFromTimeArgs(JSGlobalObject* globalObject, CallFrame* callFrame, unsigned numArgsToUse, WTF::TimeType inputTimeType) 672 669 { 673 670 VM& vm = globalObject->vm(); … … 683 680 684 681 if (!callFrame->argumentCount() || std::isnan(milli)) { 682 applyToNumbersToTrashedArguments(globalObject, callFrame, numArgsToUse); 683 RETURN_IF_EXCEPTION(scope, { }); 685 684 thisDateObj->setInternalNumber(PNaN); 686 685 return JSValue::encode(jsNaN()); … … 693 692 ? thisDateObj->gregorianDateTimeUTC(cache) 694 693 : thisDateObj->gregorianDateTime(cache); 695 if (!other) 696 return JSValue::encode(jsNaN()); 694 if (!other) { 695 applyToNumbersToTrashedArguments(globalObject, callFrame, numArgsToUse); 696 RETURN_IF_EXCEPTION(scope, { }); 697 return JSValue::encode(jsNaN()); 698 } 697 699 698 700 GregorianDateTime gregorianDateTime(*other); 699 701 bool success = fillStructuresUsingTimeArgs(globalObject, callFrame, numArgsToUse, &ms, &gregorianDateTime); 700 RETURN_IF_EXCEPTION(scope, encodedJSValue());702 RETURN_IF_EXCEPTION(scope, { }); 701 703 if (!success) { 702 704 thisDateObj->setInternalNumber(PNaN); … … 710 712 } 711 713 712 static EncodedJSValue setNewValueFromDateArgs(JSGlobalObject* globalObject, CallFrame* callFrame, intnumArgsToUse, WTF::TimeType inputTimeType)714 static EncodedJSValue setNewValueFromDateArgs(JSGlobalObject* globalObject, CallFrame* callFrame, unsigned numArgsToUse, WTF::TimeType inputTimeType) 713 715 { 714 716 VM& vm = globalObject->vm(); … … 722 724 723 725 if (!callFrame->argumentCount()) { 726 applyToNumbersToTrashedArguments(globalObject, callFrame, numArgsToUse); 727 RETURN_IF_EXCEPTION(scope, { }); 724 728 thisDateObj->setInternalNumber(PNaN); 725 729 return JSValue::encode(jsNaN()); … … 737 741 ? thisDateObj->gregorianDateTimeUTC(cache) 738 742 : thisDateObj->gregorianDateTime(cache); 739 if (!other) 743 if (!other) { 744 applyToNumbersToTrashedArguments(globalObject, callFrame, numArgsToUse); 745 RETURN_IF_EXCEPTION(scope, { }); 740 746 return JSValue::encode(jsNaN()); 747 } 741 748 gregorianDateTime = *other; 742 749 } 743 750 744 751 bool success = fillStructuresUsingDateArgs(globalObject, callFrame, numArgsToUse, &ms, &gregorianDateTime); 745 RETURN_IF_EXCEPTION(scope, encodedJSValue());752 RETURN_IF_EXCEPTION(scope, { }); 746 753 if (!success) { 747 754 thisDateObj->setInternalNumber(PNaN);
Note: See TracChangeset
for help on using the changeset viewer.